Repository navigation
✨ Show a window of rendered text with <Slice> (#942) - #952
Merged
Merged
Conversation
An author who needs part of something too long to read whole — the tail of a
build log, the first screen of a diff — had no way to say so. Writing the
arithmetic in an eval block puts it on every author who has something to quote,
and bounding the producer instead would change what the document did rather than
what it showed.
```xmd
<Slice offset={-4096} length={4096}>
<File path="build.log" />
</Slice>
```
**It bounds the rendered text and nothing else.** The content expands and
`content()` is called exactly once, so the window comes off a finished string:
the file is still read whole, a command inside still runs to completion, and a
value a nested element captured is still that whole value. Reaching the
requested number of characters stops, cancels, retries and reruns nothing. The
same completion is waited for when the offset is positive, because one component
answering two different questions depending on the sign of a prop is worse than
reading a string twice.
**Positions are Unicode code points.** An astral character is one position, so a
window never lands between the halves of one — which is what a selection taken
in UTF-16 units would do, and is why S1 puts an emoji exactly on the 4096 point
boundary of a 4097 point log.
`offset` is an integer defaulting to `0`, `length` an integer of at least `1`
defaulting to `4096` with no maximum. A negative offset resolves from the end, a
start before the beginning clamps to zero, and the closed schema is the engine's
ordinary prop validation — so a fractional position, a nonpositive length and an
unknown prop are all refused before the content expands and before any enclosed
effect runs.
A partial window returns a note, one line feed, then the selection:
```text
Text excerpt: code points [1, 4) of 7 (zero-based, end exclusive).
😀BC
```
That note is what tells a short excerpt from a short input, and an empty window
from work that produced nothing. A window covering the whole input returns the
body exactly as it arrived, with no note; nothing is trimmed or normalized on
either path, and authored whitespace counts toward the total.
**Everything else is deliberately ordinary.** The note is text written outside
the payload it describes, so an outer `<Slice>` counts the inner one and may cut
through it — no protected annotation and no metadata channel. One window covers
the whole enclosed rendering in the order `content()` supplies it; siblings
outside the element are untouched. A child's `as` keeps its complete value, and
Slice's own `as` binds the exact resulting string and emits nothing at its site.
A content failure stays the failure it was: no successful excerpt, no successful
capture, no range note. The component opens no scope, owns no task or resource,
and adds no recovery — the invocation it already runs in owns its lifetime, and
S7 reads the source to hold it to that.
**What is intentionally unchanged.** No engine branch, Component API change,
generated-use grant, public slicing service, dependency, lockfile, persistence
record, build adapter, terminal-channel interceptor or Sidekick protocol. The
registration is an ordinary overridable default, so a repository `Slice.md`
outranks it. Live foreground exec still forwards its channels as it does today:
an author captures stdout and renders it before a window can be taken of it.
Evidence, all on this tree:
- `deno task test packages/core/tests/slice-component.test.ts
packages/core/tests/component-registration.test.ts` — S1–S7 and the two
registration lists, 16 passed.
- `deno task test packages/cli/tests/repl-sidekick-controls.test.ts` — S8 in a
real open REPL session: the entry renders a window of a captured value's JSON,
and a reply reads it back through the existing `REPL.EntryOutput` and
`REPL.Bindings`, with `record` complete and `excerpt` exact. 8 passed.
- `deno task validate:docs` — the documentation index builds, which is what
refuses a registered name with no `components.md` section.
- `deno task xmd syntax Slice` — both forms, the closed schema, the `as` and
content fields, and the long-form section read as one entry.
Beyond the frozen list, because a new registered component name trips gates no
feature's own suites cover: `pnpm lint` to completion (oxlint, the prose pass,
`oxfmt --check` and the dead-code gate) exits 0, and
`packages/cli/tests/run-composition.test.ts`,
`scripts/tests/runtime-exclusions.test.ts` and
`scripts/tests/test-file-discovery.test.ts` pass — the new suite is portable and
needs no exclusion entry.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
PR #952: ✨ Show a window of rendered text with (#942)8 files, +774 / -0 Scope🟡 774 lines changed. PRs under 400 receive more thorough review. Structural✅ No structural bloat detected. Slop✅ Slop indicators look low. Static AnalysisOxlint: 1 diagnostic across 1 file (1 rule) no-shadow (1): packages/core/src/components/Slice.ts CorrectnessNo extraneous code patterns detected. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #942.
Why
Authors need to quote part of a long build log, diff or file without writing their own text-selection code.
<Slice>shows a window of completed rendered text while the enclosed work finishes normally.What changes
Before: authors rendered the whole result or selected text in an eval block.
After: an ordinary core component selects the text to show:
offsetdefaults to0;lengthdefaults to4096. Both count Unicode code points. Negative offsets count from the end, and positions clamp to the input bounds. Length must be a positive integer, with no additional maximum.A complete window returns the original text. A partial window adds a range and total before its payload. For
A😀BCDEF, offset1and length3produce:An empty input stays empty. A start at or beyond a nonempty input's end returns the empty-range note and its line feed.
How it works
Ordinary prop validation runs before the body. Slice calls existing
content()once, waits for its completed string, then selects code points locally.One window covers the combined enclosed rendering in order; outside siblings remain unchanged. Child captures retain their complete values. Slice's own
ascaptures its exact resulting text, including any note, and emits nothing at that site.Nested Slices finish inside out. An outer Slice counts and may cut an inner range note as ordinary text. Content errors, cancellation and teardown retain their existing behavior; selecting a short window never cancels the producer.
Review guide
Start with
packages/core/src/components/Slice.tsand specification §6.21, then the ordinary registry entry and focused tests.Both independent reviews are PASS for signed commit
73d3c2aa2b677a580ccd9af7eb9eb218ce2673ab: the Planner accepted the frozen criteria and evidence; the Architect accepted the settled structural invariants. Their detailed reports remain in the central #942 records.How to verify it
The four focused commands passed after formatting and before commit creation on identical tracked content:
deno task test packages/core/tests/slice-component.test.ts packages/core/tests/component-registration.test.ts— 16 passed; Unicode/defaults/clamping, validation before effects, completion once, full captures, composition, errors, cancellation and registration.deno task test packages/cli/tests/repl-sidekick-controls.test.ts— 8 passed; includes real entry execution and explicit EntryOutput/Bindings reads with complete structured data and exact excerpt text.deno task validate:docs— component documentation complete.deno task xmd syntax Slice— named syntax and documentation rendered successfully.The additional run-composition, runtime-exclusions and test-file-discovery suites recorded 12 passes. Delivery checks on the exact commit also passed:
deno task check,deno task check:jsr(Success Dry run complete) anddeno task lint(zero errors; formatting and dead-code checks clean).Initial fixture type errors, the missing documentation entry and test formatting failures were fixed before the successful evidence above. The delivery addendum preserves the first outputs, including the limited retained lint tail; these were concrete corrections, not unchanged-revision flakes.
Scope
Included
Intentionally unchanged
Risks and limitations
Slice bounds rendered text, not producer work or memory: the completed string and its code-point array may both be large. Foreground exec keeps forwarding terminal channels; authors capture stdout and render it before selecting that text.
Rollback removes this focused change; no data migration is involved.
Scope confirmation