@workerdeck/ui 2.7.1 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -30
- package/build/{SessionPanel-B5FfiBxE.mjs → SessionPanel-Dg4xf-ql.mjs} +46 -46
- package/build/SessionPanel-Dg4xf-ql.mjs.map +1 -0
- package/build/format.mjs +1 -1
- package/build/index.d.mts +11 -11
- package/build/index.mjs +4 -4
- package/build/index.mjs.map +1 -1
- package/build/scoped.css +2 -2
- package/build/{status-BO9wJloK.mjs → status-kmsBhuFG.mjs} +3 -3
- package/build/status-kmsBhuFG.mjs.map +1 -0
- package/build/workspace.mjs +4 -4
- package/build/workspace.mjs.map +1 -1
- package/package.json +18 -18
- package/src/components/agent/Composer.tsx +2 -2
- package/src/components/agent/ContextDialog.tsx +1 -1
- package/src/components/agent/EntryIcon.tsx +1 -1
- package/src/components/agent/FileTree.tsx +1 -1
- package/src/components/agent/FileViewer.tsx +1 -1
- package/src/components/agent/HostFilesDialog.tsx +2 -2
- package/src/components/agent/PermissionModeSelect.tsx +2 -2
- package/src/components/agent/PermissionPrompt.tsx +2 -2
- package/src/components/agent/SessionBrowser.tsx +1 -1
- package/src/components/agent/SessionItem.tsx +1 -1
- package/src/components/agent/SessionPanel.tsx +2 -2
- package/src/components/agent/SkillsDialog.tsx +3 -3
- package/src/components/agent/StatusBar.tsx +1 -1
- package/src/components/agent/TaskList.tsx +2 -2
- package/src/components/agent/TranscriptRows.tsx +1 -1
- package/src/components/agent/UsageDialog.tsx +1 -1
- package/src/components/agent/use-subagent-frame.ts +2 -2
- package/src/components/agent/use-transcript-jumps.ts +2 -2
- package/src/components/prompt-area/clipboard-helpers.ts +2 -2
- package/src/components/prompt-area/cursor-helpers.ts +7 -7
- package/src/components/prompt-area/dom-helpers.ts +8 -8
- package/src/components/prompt-area/html-to-markdown.ts +2 -2
- package/src/components/prompt-area/prompt-area-engine.ts +4 -4
- package/src/components/prompt-area/prompt-area-list-ops.ts +10 -10
- package/src/components/prompt-area/prompt-area.tsx +2 -2
- package/src/components/prompt-area/trigger-presets.ts +6 -6
- package/src/components/prompt-area/types.ts +6 -6
- package/src/components/prompt-area/use-chip-editing.ts +8 -8
- package/src/components/prompt-area/use-markdown-mode.ts +3 -3
- package/src/components/prompt-area/use-prompt-area-events.ts +3 -3
- package/src/components/prompt-area/use-prompt-area-keydown.ts +3 -3
- package/src/components/prompt-area/use-prompt-area-state.ts +4 -4
- package/src/components/prompt-area/use-prompt-area.ts +5 -5
- package/src/components/prompt-area/use-trigger-search.ts +1 -1
- package/src/components/terminal/PermissionPrompt.tsx +4 -4
- package/src/components/terminal/affordances.tsx +1 -1
- package/src/components/terminal/height.ts +2 -2
- package/src/components/terminal/items.tsx +2 -2
- package/src/components/terminal/scrubber.tsx +1 -1
- package/src/components/terminal/todos.ts +1 -1
- package/src/components/ui/Splitter.tsx +1 -1
- package/src/lib/context-note.ts +3 -3
- package/src/lib/format.ts +2 -2
- package/src/styles/scoped.entry.css +2 -2
- package/src/styles/terminal.css +79 -79
- package/src/styles/theme.css +39 -39
- package/build/SessionPanel-B5FfiBxE.mjs.map +0 -1
- package/build/status-BO9wJloK.mjs.map +0 -1
|
@@ -88,7 +88,7 @@ type UsePromptAreaReturn = {
|
|
|
88
88
|
const UNDO_DEBOUNCE_MS = 300
|
|
89
89
|
|
|
90
90
|
// Shared default so an omitted `triggers` prop keeps a stable identity across
|
|
91
|
-
// renders
|
|
91
|
+
// renders - a fresh [] would re-create renderSegmentsToDOM (and everything
|
|
92
92
|
// keyed on it) on every parent render.
|
|
93
93
|
const NO_TRIGGERS: TriggerConfig[] = []
|
|
94
94
|
|
|
@@ -401,7 +401,7 @@ export function usePromptArea({
|
|
|
401
401
|
// pending passive effects before rendering that keystroke's onChange. The
|
|
402
402
|
// stale flush would compare an older render's `value` against the
|
|
403
403
|
// lastRenderedValue that handleInput just advanced, read its own echo lag as
|
|
404
|
-
// an external change, and rewrite the editor to pre-keystroke content
|
|
404
|
+
// an external change, and rewrite the editor to pre-keystroke content -
|
|
405
405
|
// leaving the caret behind the character once the echo re-rendered it.
|
|
406
406
|
// Inside the commit, `value` can never be older than lastRenderedValue.
|
|
407
407
|
useLayoutEffect(() => {
|
|
@@ -423,7 +423,7 @@ export function usePromptArea({
|
|
|
423
423
|
}
|
|
424
424
|
|
|
425
425
|
// A rebuild churns the caret and the decorations, so skip it when the
|
|
426
|
-
// editor already shows exactly this content
|
|
426
|
+
// editor already shows exactly this content - e.g. a consumer echoed our
|
|
427
427
|
// onChange back re-chunked, or the DOM is split by decorations. Adopt the
|
|
428
428
|
// value so the equality guard above short-circuits from here on.
|
|
429
429
|
if (segmentsContentEqual(readSegmentsFromDOM(), value)) {
|
|
@@ -520,7 +520,7 @@ export function usePromptArea({
|
|
|
520
520
|
// Native structural edits (e.g. a Backspace that deleted or merged a list
|
|
521
521
|
// row) bypass applyEditResult, so rebuild ordered-list numbering here too.
|
|
522
522
|
// handleInput fires on every keystroke, so gate on a genuine ordered-list
|
|
523
|
-
// run
|
|
523
|
+
// run - this renumbers a real list (1,2,4 → 1,2,3) but leaves incidental
|
|
524
524
|
// numeric prose ("1985. Born / 2020. Died") untouched.
|
|
525
525
|
let nextSegments = segments
|
|
526
526
|
let renumberedCursor: number | null = null
|
|
@@ -643,7 +643,7 @@ export function usePromptArea({
|
|
|
643
643
|
|
|
644
644
|
const selectSuggestion = selectSuggestionInternal
|
|
645
645
|
|
|
646
|
-
// Handle key events
|
|
646
|
+
// Handle key events - the numbered router and its chip-deletion helpers live in
|
|
647
647
|
// use-prompt-area-keydown.ts.
|
|
648
648
|
|
|
649
649
|
const handleKeyDown = usePromptAreaKeydown({
|
|
@@ -25,7 +25,7 @@ export function useTriggerSearch(): UseTriggerSearchReturn {
|
|
|
25
25
|
const [suggestionsLoading, setSuggestionsLoading] = useState(false)
|
|
26
26
|
const [suggestionsError, setSuggestionsError] = useState<string | null>(null)
|
|
27
27
|
|
|
28
|
-
// Version counter
|
|
28
|
+
// Version counter - belt-and-suspenders alongside AbortController
|
|
29
29
|
const searchVersion = useRef(0)
|
|
30
30
|
const abortController = useRef<AbortController | null>(null)
|
|
31
31
|
const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
@@ -42,8 +42,8 @@ export function TerminalPermissionPrompt({ request, onApprove, onDeny, className
|
|
|
42
42
|
onCancel={() => setDenying(false)}
|
|
43
43
|
placeholder={
|
|
44
44
|
plan
|
|
45
|
-
? 'What should change? (optional)
|
|
46
|
-
: 'Reason (optional)
|
|
45
|
+
? 'What should change? (optional) - the agent keeps planning and reads this'
|
|
46
|
+
: 'Reason (optional) - the agent reads this and can try something else'
|
|
47
47
|
}
|
|
48
48
|
/>
|
|
49
49
|
) : undefined
|
|
@@ -51,7 +51,7 @@ export function TerminalPermissionPrompt({ request, onApprove, onDeny, className
|
|
|
51
51
|
const options = plan
|
|
52
52
|
? [
|
|
53
53
|
{ key: 'allow', label: 'Approve plan' },
|
|
54
|
-
{ key: 'deny', label: 'Keep planning
|
|
54
|
+
{ key: 'deny', label: 'Keep planning - tell it what to change', detail: reasonInput },
|
|
55
55
|
{ key: 'stop', label: 'No, and stop the turn', danger: true },
|
|
56
56
|
]
|
|
57
57
|
: [
|
|
@@ -116,7 +116,7 @@ export function TerminalPermissionPrompt({ request, onApprove, onDeny, className
|
|
|
116
116
|
<Hint>
|
|
117
117
|
{denying
|
|
118
118
|
? 'Enter to send · Shift+Enter for a new line · Esc to go back'
|
|
119
|
-
: 'Enter to select · ↑/↓ to navigate · 1
|
|
119
|
+
: 'Enter to select · ↑/↓ to navigate · 1-3 to choose · Esc to cancel'}
|
|
120
120
|
</Hint>
|
|
121
121
|
</div>
|
|
122
122
|
)
|
|
@@ -44,7 +44,7 @@ export function WithActions({ actions, children, className }: { actions: ReactNo
|
|
|
44
44
|
|
|
45
45
|
// Bookmarks are a host concern (which items, where they persist); the transcript only needs
|
|
46
46
|
// membership and a toggle. A missing provider renders no action at all, so embeddings that
|
|
47
|
-
// never wire bookmarks pay nothing
|
|
47
|
+
// never wire bookmarks pay nothing - the same contract AffordanceContext has.
|
|
48
48
|
export type BookmarkHandle = {
|
|
49
49
|
has: (itemId: string) => boolean
|
|
50
50
|
toggle: (itemId: string) => void
|
|
@@ -102,7 +102,7 @@ type Token = { kind: 'word' | 'space'; w: number; exact: boolean }
|
|
|
102
102
|
const TAB_SIZE = 2
|
|
103
103
|
|
|
104
104
|
// Break after these unless a digit follows; `?` is here because Chrome breaks long URLs after it (verified against real break rects).
|
|
105
|
-
const BREAK_AFTER = new Set(['-', '
|
|
105
|
+
const BREAK_AFTER = new Set(['-', '-', '-', '?'])
|
|
106
106
|
|
|
107
107
|
const PLAIN_ASCII = /^[\x20-\x7e]*$/
|
|
108
108
|
|
|
@@ -181,7 +181,7 @@ function tokenize(line: string): Token[] {
|
|
|
181
181
|
const { w, exact } = clusterCells(segment)
|
|
182
182
|
const cp = segment.codePointAt(0) ?? 0
|
|
183
183
|
if (isWide(cp) || PICTOGRAPHIC.test(segment)) {
|
|
184
|
-
// Each wide cluster is its own token
|
|
184
|
+
// Each wide cluster is its own token - a break may fall between any two.
|
|
185
185
|
flushWord()
|
|
186
186
|
tokens.push({ kind: 'word', w, exact })
|
|
187
187
|
col += w
|
|
@@ -173,8 +173,8 @@ export function ToolRow({ item }: { item: ToolCallItem }) {
|
|
|
173
173
|
}}
|
|
174
174
|
>
|
|
175
175
|
{truncated
|
|
176
|
-
? `… +${missing.toLocaleString()} chars
|
|
177
|
-
: `… +${hidden} line${hidden === 1 ? '' : 's'}
|
|
176
|
+
? `… +${missing.toLocaleString()} chars - fetch the rest`
|
|
177
|
+
: `… +${hidden} line${hidden === 1 ? '' : 's'} - show all ${text.length.toLocaleString()} chars`}
|
|
178
178
|
</button>
|
|
179
179
|
) : (
|
|
180
180
|
<>
|
|
@@ -351,7 +351,7 @@ export function TerminalScrubber(props: TerminalScrubberProps) {
|
|
|
351
351
|
setPeek(null)
|
|
352
352
|
}, [props.items])
|
|
353
353
|
|
|
354
|
-
// Manual listener because it must `preventDefault`
|
|
354
|
+
// Manual listener because it must `preventDefault` - React's root wheel listeners are passive.
|
|
355
355
|
useEffect(() => {
|
|
356
356
|
if (!interactive) {
|
|
357
357
|
return
|
|
@@ -29,7 +29,7 @@ export function todoPreview(name: string, input: unknown): TodoPreview | undefin
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
// Height and render both draw this exact string
|
|
32
|
+
// Height and render both draw this exact string - `toolRowHeight` counts what `TerminalTodos` paints.
|
|
33
33
|
export function todoLine(todo: TodoEntry): string {
|
|
34
34
|
return `${GLYPH[todo.status]} ${todo.text}`
|
|
35
35
|
}
|
|
@@ -59,7 +59,7 @@ export function Splitter({
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
// Reached after `endDrag`
|
|
62
|
+
// Reached after `endDrag` - the second click of a double-click has already started a drag, and dblclick fires after pointerup.
|
|
63
63
|
const onDoubleClick = () => {
|
|
64
64
|
if (defaultValue !== undefined) {
|
|
65
65
|
onValueChange(clamp(defaultValue))
|
package/src/lib/context-note.ts
CHANGED
|
@@ -9,11 +9,11 @@ export interface ContextNote {
|
|
|
9
9
|
|
|
10
10
|
const CODEX_CONTEXT_NOTE: ContextNote = {
|
|
11
11
|
summary:
|
|
12
|
-
'Codex budgets 272K input by default and reports 95% of it, so a 1M-class model reads ~258k. That is codex’s price tier, not the model’s ceiling
|
|
13
|
-
hint: 'Raising it is yours to set: model_context_window in ~/.codex/config.toml
|
|
12
|
+
'Codex budgets 272K input by default and reports 95% of it, so a 1M-class model reads ~258k. That is codex’s price tier, not the model’s ceiling - and it is the number auto-compaction fires on, so the meter is honest.',
|
|
13
|
+
hint: 'Raising it is yours to set: model_context_window in ~/.codex/config.toml - and watch for auto-compaction failing afterwards.',
|
|
14
14
|
detail: [
|
|
15
15
|
'To raise it, set model_context_window in ~/.codex/config.toml, up to 872000 (reported as 828400). Codex clamps to its own max_context_window, itself below OpenAI’s stated 922,000 max input.',
|
|
16
|
-
'Above 272K input, a request bills at 2x input / 1.5x output for the whole request. WorkerDeck never writes this setting
|
|
16
|
+
'Above 272K input, a request bills at 2x input / 1.5x output for the whole request. WorkerDeck never writes this setting - it is a cost decision on your account.',
|
|
17
17
|
],
|
|
18
18
|
caveat:
|
|
19
19
|
'Raise it and watch for auto-compaction failing: openai/codex #16068 reports it stops firing after the first overflow. Unverified here on 0.149.0.',
|
package/src/lib/format.ts
CHANGED
|
@@ -28,7 +28,7 @@ export function compactionText(item: {
|
|
|
28
28
|
|
|
29
29
|
export function formatCost(usd: number | undefined): string {
|
|
30
30
|
if (usd === undefined || Number.isNaN(usd)) {
|
|
31
|
-
return '
|
|
31
|
+
return '-'
|
|
32
32
|
}
|
|
33
33
|
if (usd === 0) {
|
|
34
34
|
return '$0.00'
|
|
@@ -92,7 +92,7 @@ export function formatCountdown(untilEpochMs: number, now = Date.now()): string
|
|
|
92
92
|
|
|
93
93
|
export function formatRelativeTime(epochMs: number | undefined, now = Date.now()): string {
|
|
94
94
|
if (!epochMs) {
|
|
95
|
-
return '
|
|
95
|
+
return '-'
|
|
96
96
|
}
|
|
97
97
|
const diff = Math.max(0, now - epochMs)
|
|
98
98
|
const s = Math.floor(diff / 1000)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Build entry for the SCOPED stylesheet (`@workerdeck/ui/scoped.css`)
|
|
2
|
+
* Build entry for the SCOPED stylesheet (`@workerdeck/ui/scoped.css`) - see
|
|
3
3
|
* `scripts/build-scoped-css.mjs`, which compiles this with the Tailwind CLI and
|
|
4
4
|
* then rewrites every selector under `.wd-root`. Not shipped as-is and not an
|
|
5
5
|
* export: embedders import the compiled `scoped.css` artifact.
|
|
6
6
|
*
|
|
7
7
|
* `source(none)` + explicit `@source`: the utilities compiled here are exactly
|
|
8
8
|
* the ones this package's own components (and streamdown, whose markdown
|
|
9
|
-
* renderer ships Tailwind-classed markup) use
|
|
9
|
+
* renderer ships Tailwind-classed markup) use - hermetic, independent of any
|
|
10
10
|
* host app's Tailwind build.
|
|
11
11
|
*/
|
|
12
12
|
@import 'tailwindcss' source(none);
|