@agi-fans/dsh-tui 0.18.0 → 0.19.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.
Files changed (68) hide show
  1. package/lib/CHANGELOG.md +31 -0
  2. package/lib/chrome/box.d.ts +2 -0
  3. package/lib/chrome/box.js +5 -1
  4. package/lib/chrome/box.js.map +1 -1
  5. package/lib/chrome/main-screen-renderer.d.ts +61 -11
  6. package/lib/chrome/main-screen-renderer.js +1674 -71
  7. package/lib/chrome/main-screen-renderer.js.map +1 -1
  8. package/lib/chrome/markdown.js +21 -13
  9. package/lib/chrome/markdown.js.map +1 -1
  10. package/lib/chrome/renderer.d.ts +75 -0
  11. package/lib/chrome/renderer.js.map +1 -1
  12. package/lib/chrome/theme.d.ts +18 -0
  13. package/lib/chrome/theme.js +18 -0
  14. package/lib/chrome/theme.js.map +1 -1
  15. package/lib/chrome/tool-args.d.ts +24 -1
  16. package/lib/chrome/tool-args.js +40 -1
  17. package/lib/chrome/tool-args.js.map +1 -1
  18. package/lib/chrome/tool-renderers.d.ts +11 -0
  19. package/lib/chrome/tool-renderers.js +55 -5
  20. package/lib/chrome/tool-renderers.js.map +1 -1
  21. package/lib/chrome/welcome-tips.js +1 -1
  22. package/lib/chrome/welcome-tips.js.map +1 -1
  23. package/lib/definition.d.ts +59 -7
  24. package/lib/definition.js.map +1 -1
  25. package/lib/input/keybindings-config.d.ts +1 -1
  26. package/lib/input/keybindings-config.js +2 -1
  27. package/lib/input/keybindings-config.js.map +1 -1
  28. package/lib/input/keys.d.ts +7 -0
  29. package/lib/input/keys.js +11 -4
  30. package/lib/input/keys.js.map +1 -1
  31. package/lib/runtime/provider-local.d.ts +20 -4
  32. package/lib/runtime/provider-local.js +435 -63
  33. package/lib/runtime/provider-local.js.map +1 -1
  34. package/lib/runtime/tool-presentation.js +43 -30
  35. package/lib/runtime/tool-presentation.js.map +1 -1
  36. package/lib/session/feature-toggles.d.ts +100 -0
  37. package/lib/session/feature-toggles.js +170 -0
  38. package/lib/session/feature-toggles.js.map +1 -0
  39. package/lib/session/fold-policy.d.ts +21 -0
  40. package/lib/session/fold-policy.js +15 -0
  41. package/lib/session/fold-policy.js.map +1 -0
  42. package/lib/session/job-notice.d.ts +4 -0
  43. package/lib/session/job-notice.js +44 -3
  44. package/lib/session/job-notice.js.map +1 -1
  45. package/lib/session/session-controller.js +51 -13
  46. package/lib/session/session-controller.js.map +1 -1
  47. package/lib/session/tui-settings.d.ts +6 -1
  48. package/lib/session/tui-settings.js +3 -1
  49. package/lib/session/tui-settings.js.map +1 -1
  50. package/lib/views/event-views.d.ts +26 -2
  51. package/lib/views/event-views.js +160 -43
  52. package/lib/views/event-views.js.map +1 -1
  53. package/lib/views/hotkeys.d.ts +2 -0
  54. package/lib/views/hotkeys.js +7 -3
  55. package/lib/views/hotkeys.js.map +1 -1
  56. package/lib/views/settings-list.d.ts +10 -4
  57. package/lib/views/settings-list.js +41 -18
  58. package/lib/views/settings-list.js.map +1 -1
  59. package/lib/views/transcript-render.d.ts +133 -18
  60. package/lib/views/transcript-render.js +1179 -112
  61. package/lib/views/transcript-render.js.map +1 -1
  62. package/lib/views/transcript-types.d.ts +79 -1
  63. package/lib/views/transcript-types.js +11 -0
  64. package/lib/views/transcript-types.js.map +1 -1
  65. package/lib/views/workspace-changes.d.ts +27 -0
  66. package/lib/views/workspace-changes.js +128 -0
  67. package/lib/views/workspace-changes.js.map +1 -0
  68. package/package.json +36 -35
@@ -1 +1 @@
1
- {"version":3,"file":"tool-presentation.js","sourceRoot":"","sources":["../../src/runtime/tool-presentation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-presentation.js","sourceRoot":"","sources":["../../src/runtime/tool-presentation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Optional product features and the Profile-patch block that turns them off.
3
+ *
4
+ * A feature is a composition row a deployment may not want: it costs context,
5
+ * runtime, or transcript noise. The row's `disabled` field is a Loader option
6
+ * rather than plugin config, so the settings service cannot write it — the
7
+ * Loader does read a Profile patch's `disabled`, and that patch is the
8
+ * documented, user-authored surface for exactly this.
9
+ *
10
+ * The writes therefore maintain one clearly delimited block in the Profile
11
+ * patch and touch nothing else in the file, so hand-written rows, `!!js`
12
+ * expressions, and comments all survive a toggle. Toggling takes effect on the
13
+ * next launch: the Harness reads the patch once while composing the tree.
14
+ * @module @agi-fans/dsh-tui
15
+ */
16
+ /** One optional product feature, addressed by the row id it disables. */
17
+ export interface FeatureToggle {
18
+ /** Composition row id; the key a Profile patch keys its override by. */
19
+ id: string;
20
+ /** Short row label for the settings overlay. */
21
+ label: string;
22
+ /** What the feature does, and what turning it off costs. */
23
+ description: string;
24
+ /** Whether the shipped composition mounts it. */
25
+ enabledByDefault: boolean;
26
+ }
27
+ /**
28
+ * Features this build can turn off.
29
+ *
30
+ * Rows that make the agent non-functional (`tool-fs`, `tool-bash`, `todo`), rows
31
+ * that back a command (`session-query` backs `/sessions`, `workspace` backs
32
+ * `@` mentions), and rows that are already conditional at no cost
33
+ * (`mcp-resources` appears only with a connected MCP server) are deliberately
34
+ * absent. `tool-web` is absent for a different reason: `web_search` and
35
+ * `web_fetch` share one row, so no row-level toggle can express "search off,
36
+ * fetch on".
37
+ */
38
+ export declare const FEATURE_TOGGLES: readonly FeatureToggle[];
39
+ /** Opening delimiter of the block this module owns. */
40
+ export declare const FEATURE_BLOCK_BEGIN = "# >>> omdsh feature toggles >>>";
41
+ /** Closing delimiter of the block this module owns. */
42
+ export declare const FEATURE_BLOCK_END = "# <<< omdsh feature toggles <<<";
43
+ /** Current on/off state of every feature, keyed by row id. */
44
+ export type FeatureStates = Readonly<Record<string, boolean>>;
45
+ /** The shipped composition's state, before any Profile patch override. */
46
+ export declare function defaultFeatureStates(features?: readonly FeatureToggle[]): Record<string, boolean>;
47
+ /**
48
+ * Apply the `disabled` rows a Profile patch declares on top of the defaults.
49
+ *
50
+ * Only rows this build knows a feature for are read: a patch may disable any
51
+ * row for its own reasons, and an unknown id is not a feature toggle.
52
+ *
53
+ * @param states - the shipped defaults.
54
+ * @param disabled - row ids the patch marks `disabled: true`.
55
+ * @returns a new state map with those features off.
56
+ */
57
+ export declare function applyDisabledRows(states: Record<string, boolean>, disabled: readonly string[]): Record<string, boolean>;
58
+ /**
59
+ * Row ids that must be disabled to make `states` true, ignoring rows already
60
+ * off in the shipped composition.
61
+ *
62
+ * @param states - desired feature state.
63
+ * @returns the row ids a patch has to mark `disabled: true`.
64
+ */
65
+ export declare function rowsToDisable(states: FeatureStates): string[];
66
+ /**
67
+ * Render the managed block for the features that are off.
68
+ *
69
+ * The block is written unconditionally so it always states the full set the
70
+ * build manages; re-enabling a feature is removing its row from here.
71
+ *
72
+ * @param states - desired feature state.
73
+ * @returns the block text, including a trailing newline.
74
+ */
75
+ export declare function renderFeatureBlock(states: FeatureStates): string;
76
+ /**
77
+ * Replace the managed block, leaving every other byte of the patch untouched.
78
+ *
79
+ * A patch that carries no block is simply appended to, so a file the user has
80
+ * been editing by hand keeps its formatting, comments, and `!!js` expressions.
81
+ *
82
+ * @param text - current patch file contents.
83
+ * @param block - the block to install.
84
+ * @returns the new patch file contents.
85
+ */
86
+ export declare function replaceFeatureBlock(text: string, block: string): string;
87
+ /**
88
+ * Read the feature state a patch file currently declares.
89
+ *
90
+ * Only the managed block is parsed, by row id, so a hand-written
91
+ * `disabled: true` elsewhere in the file is left for the composition to honour
92
+ * and is not double-counted as a feature toggle.
93
+ *
94
+ * @param text - patch file contents.
95
+ * @param features - known features; defaults to the shipped registry.
96
+ * @returns the state the block declares over the shipped defaults.
97
+ */
98
+ export declare function featureStatesFromPatch(text: string, features?: readonly FeatureToggle[]): Record<string, boolean>;
99
+ /** Absolute path of the Profile patch this build edits. */
100
+ export declare function featurePatchPath(dshHome: string): string;
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Optional product features and the Profile-patch block that turns them off.
3
+ *
4
+ * A feature is a composition row a deployment may not want: it costs context,
5
+ * runtime, or transcript noise. The row's `disabled` field is a Loader option
6
+ * rather than plugin config, so the settings service cannot write it — the
7
+ * Loader does read a Profile patch's `disabled`, and that patch is the
8
+ * documented, user-authored surface for exactly this.
9
+ *
10
+ * The writes therefore maintain one clearly delimited block in the Profile
11
+ * patch and touch nothing else in the file, so hand-written rows, `!!js`
12
+ * expressions, and comments all survive a toggle. Toggling takes effect on the
13
+ * next launch: the Harness reads the patch once while composing the tree.
14
+ * @module @agi-fans/dsh-tui
15
+ */
16
+ import { join } from 'node:path';
17
+ /**
18
+ * Features this build can turn off.
19
+ *
20
+ * Rows that make the agent non-functional (`tool-fs`, `tool-bash`, `todo`), rows
21
+ * that back a command (`session-query` backs `/sessions`, `workspace` backs
22
+ * `@` mentions), and rows that are already conditional at no cost
23
+ * (`mcp-resources` appears only with a connected MCP server) are deliberately
24
+ * absent. `tool-web` is absent for a different reason: `web_search` and
25
+ * `web_fetch` share one row, so no row-level toggle can express "search off,
26
+ * fetch on".
27
+ */
28
+ export const FEATURE_TOGGLES = [
29
+ {
30
+ id: 'workspace-changes',
31
+ label: 'Changed-file summary',
32
+ description: 'End every turn with the files it changed and their line counts. Off skips two Git snapshots per turn and the transcript row.',
33
+ enabledByDefault: true,
34
+ },
35
+ {
36
+ id: 'tool-session-query',
37
+ label: 'Session history tools',
38
+ description: 'Five tools that let the model search, trace and read its own earlier sessions. Off removes five tool schemas from every request.',
39
+ enabledByDefault: true,
40
+ },
41
+ {
42
+ id: 'tool-ralph',
43
+ label: 'Ralph loop',
44
+ description: 'Let the model re-run a task until it reports completion. Off by default because the tool is a self-report, not an evaluation.',
45
+ enabledByDefault: false,
46
+ },
47
+ {
48
+ id: 'repeat-tool-reminder',
49
+ label: 'Repeat-tool reminder',
50
+ description: 'Nudge the model out of identical tool-call loops. Off removes the advisory text those nudges add to the context.',
51
+ enabledByDefault: true,
52
+ },
53
+ ];
54
+ /** Opening delimiter of the block this module owns. */
55
+ export const FEATURE_BLOCK_BEGIN = '# >>> omdsh feature toggles >>>';
56
+ /** Closing delimiter of the block this module owns. */
57
+ export const FEATURE_BLOCK_END = '# <<< omdsh feature toggles <<<';
58
+ /** The shipped composition's state, before any Profile patch override. */
59
+ export function defaultFeatureStates(features = FEATURE_TOGGLES) {
60
+ return Object.fromEntries(features.map(feature => [feature.id, feature.enabledByDefault]));
61
+ }
62
+ /**
63
+ * Apply the `disabled` rows a Profile patch declares on top of the defaults.
64
+ *
65
+ * Only rows this build knows a feature for are read: a patch may disable any
66
+ * row for its own reasons, and an unknown id is not a feature toggle.
67
+ *
68
+ * @param states - the shipped defaults.
69
+ * @param disabled - row ids the patch marks `disabled: true`.
70
+ * @returns a new state map with those features off.
71
+ */
72
+ export function applyDisabledRows(states, disabled) {
73
+ const known = new Set(FEATURE_TOGGLES.map(feature => feature.id));
74
+ const next = { ...states };
75
+ for (const id of disabled)
76
+ if (known.has(id))
77
+ next[id] = false;
78
+ return next;
79
+ }
80
+ /**
81
+ * Row ids that must be disabled to make `states` true, ignoring rows already
82
+ * off in the shipped composition.
83
+ *
84
+ * @param states - desired feature state.
85
+ * @returns the row ids a patch has to mark `disabled: true`.
86
+ */
87
+ export function rowsToDisable(states) {
88
+ return FEATURE_TOGGLES
89
+ .filter(feature => feature.enabledByDefault && states[feature.id] === false)
90
+ .map(feature => feature.id);
91
+ }
92
+ /**
93
+ * Render the managed block for the features that are off.
94
+ *
95
+ * The block is written unconditionally so it always states the full set the
96
+ * build manages; re-enabling a feature is removing its row from here.
97
+ *
98
+ * @param states - desired feature state.
99
+ * @returns the block text, including a trailing newline.
100
+ */
101
+ export function renderFeatureBlock(states) {
102
+ const off = FEATURE_TOGGLES
103
+ .filter(feature => feature.enabledByDefault && states[feature.id] === false)
104
+ .map(feature => feature.id);
105
+ const lines = [FEATURE_BLOCK_BEGIN];
106
+ for (const id of off)
107
+ lines.push(`- id: ${id}`, ' disabled: true');
108
+ lines.push(FEATURE_BLOCK_END, '');
109
+ return lines.join('\n');
110
+ }
111
+ /**
112
+ * Replace the managed block, leaving every other byte of the patch untouched.
113
+ *
114
+ * A patch that carries no block is simply appended to, so a file the user has
115
+ * been editing by hand keeps its formatting, comments, and `!!js` expressions.
116
+ *
117
+ * @param text - current patch file contents.
118
+ * @param block - the block to install.
119
+ * @returns the new patch file contents.
120
+ */
121
+ export function replaceFeatureBlock(text, block) {
122
+ const begin = text.indexOf(FEATURE_BLOCK_BEGIN);
123
+ const end = text.indexOf(FEATURE_BLOCK_END);
124
+ if (begin < 0 || end < 0 || end < begin) {
125
+ const head = text.trimEnd();
126
+ return head === '' ? block : `${head}\n\n${block}`;
127
+ }
128
+ const before = text.slice(0, begin).trimEnd();
129
+ const after = text.slice(end + FEATURE_BLOCK_END.length).replace(/^\n+/, '');
130
+ const head = before === '' ? '' : `${before}\n\n`;
131
+ const tail = after.trim() === '' ? '' : `\n${after}`;
132
+ return `${head}${block.trimEnd()}${tail}\n`;
133
+ }
134
+ /**
135
+ * Read the feature state a patch file currently declares.
136
+ *
137
+ * Only the managed block is parsed, by row id, so a hand-written
138
+ * `disabled: true` elsewhere in the file is left for the composition to honour
139
+ * and is not double-counted as a feature toggle.
140
+ *
141
+ * @param text - patch file contents.
142
+ * @param features - known features; defaults to the shipped registry.
143
+ * @returns the state the block declares over the shipped defaults.
144
+ */
145
+ export function featureStatesFromPatch(text, features = FEATURE_TOGGLES) {
146
+ const begin = text.indexOf(FEATURE_BLOCK_BEGIN);
147
+ const end = text.indexOf(FEATURE_BLOCK_END);
148
+ const states = Object.fromEntries(features.map(f => [f.id, f.enabledByDefault]));
149
+ if (begin < 0 || end < 0 || end < begin)
150
+ return states;
151
+ let current;
152
+ for (const raw of text.slice(begin, end).split('\n')) {
153
+ const id = raw.match(/^\s*-\s*id:\s*(\S+)\s*$/u);
154
+ if (id !== null) {
155
+ current = id[1];
156
+ continue;
157
+ }
158
+ if (/^\s*disabled:\s*true\s*$/u.test(raw) && current !== undefined) {
159
+ if (Object.hasOwn(states, current))
160
+ states[current] = false;
161
+ current = undefined;
162
+ }
163
+ }
164
+ return states;
165
+ }
166
+ /** Absolute path of the Profile patch this build edits. */
167
+ export function featurePatchPath(dshHome) {
168
+ return join(dshHome, 'profiles', 'omdsh', 'cordis.patch.yml');
169
+ }
170
+ //# sourceMappingURL=feature-toggles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-toggles.js","sourceRoot":"","sources":["../../src/session/feature-toggles.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /** Compatibility for stored transcript preferences from earlier versions. */
2
+ export declare const FOLD_DENSITIES: readonly ["compact", "standard", "detailed", "verbose"];
3
+ export type FoldDensity = typeof FOLD_DENSITIES[number];
4
+ /** @deprecated Turns now use one presentation policy. */
5
+ export interface FoldPolicy {
6
+ groups: boolean;
7
+ tools: boolean;
8
+ reasoning: boolean;
9
+ detail: boolean;
10
+ subject: boolean;
11
+ }
12
+ export declare const DEFAULT_FOLD_DENSITY: FoldDensity;
13
+ /** All legacy values resolve to the current turn presentation. */
14
+ export declare function foldPolicy(_density: FoldDensity): FoldPolicy;
15
+ export declare function isFoldDensity(value: string): value is FoldDensity;
16
+ /** Old preferences remain readable but no longer select a different layout. */
17
+ export declare function resolveFoldDensity(_prefs: {
18
+ foldDensity?: FoldDensity;
19
+ expandTools?: boolean;
20
+ }): FoldDensity;
21
+ export declare function foldPolicyKey(_policy: FoldPolicy): string;
@@ -0,0 +1,15 @@
1
+ /** Compatibility for stored transcript preferences from earlier versions. */
2
+ export const FOLD_DENSITIES = ['compact', 'standard', 'detailed', 'verbose'];
3
+ export const DEFAULT_FOLD_DENSITY = 'standard';
4
+ const TURN_POLICY = { groups: true, tools: true, reasoning: false, detail: false, subject: true };
5
+ /** All legacy values resolve to the current turn presentation. */
6
+ export function foldPolicy(_density) { return TURN_POLICY; }
7
+ export function isFoldDensity(value) {
8
+ return FOLD_DENSITIES.includes(value);
9
+ }
10
+ /** Old preferences remain readable but no longer select a different layout. */
11
+ export function resolveFoldDensity(_prefs) {
12
+ return DEFAULT_FOLD_DENSITY;
13
+ }
14
+ export function foldPolicyKey(_policy) { return 'turn'; }
15
+ //# sourceMappingURL=fold-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fold-policy.js","sourceRoot":"","sources":["../../src/session/fold-policy.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,CAAU,CAAA;AAYrF,MAAM,CAAC,MAAM,oBAAoB,GAAgB,UAAU,CAAA;AAC3D,MAAM,WAAW,GAAe,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAE7G,kEAAkE;AAClE,MAAM,UAAU,UAAU,CAAC,QAAqB,IAAgB,OAAO,WAAW,CAAA,CAAC,CAAC;AAEpF,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAQ,cAAoC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AAC9D,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,kBAAkB,CAAC,MAA4D;IAC7F,OAAO,oBAAoB,CAAA;AAC7B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAmB,IAAY,OAAO,MAAM,CAAA,CAAC,CAAC"}
@@ -5,6 +5,10 @@
5
5
  */
6
6
  import type { Agent } from '@deepseek-ai/dsh-agent';
7
7
  import type { JobStatus, JobView } from '@deepseek-ai/dsh-jobs';
8
+ import type { TuiNoticeOptions } from '../definition.ts';
9
+ import type { TranscriptState } from '../views/transcript-types.ts';
10
+ /** Merge only an identified job or an unambiguous command still awaiting its result. */
11
+ export declare function mergeJobSettlement(state: TranscriptState, job: NonNullable<TuiNoticeOptions['job']>): TranscriptState | undefined;
8
12
  /** Past- or present-tense word for one lifecycle status. */
9
13
  export declare const JOB_STATUS_WORD: Record<JobStatus, string>;
10
14
  /** One human-facing completion line for a background job. */
@@ -3,6 +3,45 @@
3
3
  * notice, so one job reads the same in both surfaces.
4
4
  * @module @agi-fans/dsh-tui/job-notice
5
5
  */
6
+ import { toolArgsObject } from "../chrome/tool-args.js";
7
+ import { truncateToWidth, visibleWidth } from "../chrome/width.js";
8
+ /** Merge only an identified job or an unambiguous command still awaiting its result. */
9
+ export function mergeJobSettlement(state, job) {
10
+ const identified = [];
11
+ const pending = [];
12
+ state.blocks.forEach((block, index) => {
13
+ if (block.kind !== 'tool')
14
+ return;
15
+ if (!/^(bash|shell|pwsh|exec)$/u.test(block.name) && block.presentation?.call?.card !== 'terminal')
16
+ return;
17
+ const explicitId = /^started background job (\S+)\s*$/u.exec(block.output)?.[1]
18
+ ?? /\[still running after \d+ms; moved to background job ([^\s\]]+)\]/u.exec(block.output)?.[1];
19
+ const id = block.job?.id ?? explicitId;
20
+ if (id !== undefined) {
21
+ if (id === job.id)
22
+ identified.push(index);
23
+ return;
24
+ }
25
+ const args = toolArgsObject(block.args);
26
+ if (block.status === 'running' && block.startedAt !== undefined && block.startedAt <= job.startedAt
27
+ && typeof args?.['command'] === 'string' && args['command'] === job.label)
28
+ pending.push(index);
29
+ });
30
+ const matches = identified.length > 0 ? identified : pending;
31
+ if (matches.length !== 1)
32
+ return undefined;
33
+ const index = matches[0];
34
+ const block = state.blocks[index];
35
+ if (block.kind !== 'tool')
36
+ return undefined;
37
+ const blocks = [...state.blocks];
38
+ blocks[index] = {
39
+ ...block,
40
+ status: job.status === 'completed' && block.status !== 'error' ? 'ok' : 'error',
41
+ job: { id: job.id, status: job.status, detail: job.detail?.trim() || JOB_STATUS_WORD[job.status] },
42
+ };
43
+ return { ...state, blocks };
44
+ }
6
45
  /** Past- or present-tense word for one lifecycle status. */
7
46
  export const JOB_STATUS_WORD = {
8
47
  running: 'running',
@@ -13,9 +52,11 @@ export const JOB_STATUS_WORD = {
13
52
  };
14
53
  /** One human-facing completion line for a background job. */
15
54
  export function formatJobNotice(snapshot) {
16
- const label = snapshot.label.trim();
17
- const detail = snapshot.detail === undefined ? '' : snapshot.detail.trim();
18
- return `Background job ${snapshot.id} ${JOB_STATUS_WORD[snapshot.status]}`
55
+ const head = `Background job ${snapshot.id} ${JOB_STATUS_WORD[snapshot.status]}`;
56
+ const detail = truncateToWidth(snapshot.detail?.trim().split('\n')[0] ?? '', 28);
57
+ const room = Math.max(0, 76 - visibleWidth(head) - (detail === '' ? 0 : visibleWidth(detail) + 3) - 3);
58
+ const label = room < 8 ? '' : truncateToWidth(snapshot.label.trim().split('\n')[0] ?? '', room);
59
+ return head
19
60
  + (label === '' ? '' : ` · ${label}`)
20
61
  + (detail === '' ? '' : ` · ${detail}`);
21
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"job-notice.js","sourceRoot":"","sources":["../../src/session/job-notice.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,eAAe,GAA8B;IACxD,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,SAAS;IACjB,MAAM,EAAE,QAAQ;CACjB,CAAA;AAED,6DAA6D;AAC7D,MAAM,UAAU,eAAe,CAAC,QAK/B;IACC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAA;IACnC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;IAC1E,OAAO,kBAAkB,QAAQ,CAAC,EAAE,IAAI,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;UACtE,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC;UACnC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAA;AAC3C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC1B,QAA+I,EAC/I,KAAwB,EACxB,MAAyB;IAEzB,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,SAAS,CAAA;IAClD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,SAAS,CAAA;IAC7D,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAA;AAClC,CAAC"}
1
+ {"version":3,"file":"job-notice.js","sourceRoot":"","sources":["../../src/session/job-notice.ts"],"names":[],"mappings":"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"}
@@ -460,8 +460,16 @@ export class SessionRuntime {
460
460
  return;
461
461
  const owner = event.job.owner === undefined ? undefined : this.#ctx.get('agents')?.get(event.job.owner);
462
462
  const notice = jobNoticeFor(event.job, owner, this.#active?.handle.agent);
463
- if (notice !== undefined)
464
- tui.notice(notice);
463
+ if (notice !== undefined) {
464
+ const job = event.job;
465
+ tui.notice(notice, {
466
+ process: true, processSource: `job:${job.id}`,
467
+ ...(/^(bash|pwsh)$/u.test(job.kind) && (job.status === 'completed' || job.status === 'failed' || job.status === 'killed')
468
+ ? { job: { id: job.id, label: job.label, status: job.status, startedAt: job.startedAt, ...(job.detail === undefined ? {} : { detail: job.detail }) } }
469
+ : {}),
470
+ ...(job.status === 'failed' || job.status === 'killed' ? { level: 'error' } : {}),
471
+ });
472
+ }
465
473
  }));
466
474
  }
467
475
  this.#off.push(ctx.on('agent/status', (payload) => {
@@ -494,6 +502,8 @@ export class SessionRuntime {
494
502
  if (this.#inspectedId === undefined) {
495
503
  tui.event(event, ctx.get('tuiToolPresentation')?.event(active.handle.agent, event));
496
504
  }
505
+ if (event.type === 'workspace/changes')
506
+ this.#serveWorkspaceSummary(ctx, tui, session, event);
497
507
  if (event.type === 'subagent/catalog')
498
508
  this.#tracker.observeCatalog(session, [event]);
499
509
  if (shouldRefreshSessionInfoAfter(event))
@@ -579,7 +589,7 @@ export class SessionRuntime {
579
589
  if (defaults === undefined)
580
590
  throw new Error('agent default model is unavailable');
581
591
  await this.refreshRecent();
582
- await this.#activate(await this.#create(defaults));
592
+ await this.#activate(await this.#create(defaults), 'initial');
583
593
  }
584
594
  /** Submit one human composer value; active turns retain it as a later follow-up. */
585
595
  async send(input, agent = this.#requiredAgent()) {
@@ -640,9 +650,9 @@ export class SessionRuntime {
640
650
  this.#tui.restoreInput({ text: line, images });
641
651
  if (result.text !== undefined) {
642
652
  if (result.kind === 'error')
643
- this.#tui.notice(result.text, { level: 'error' });
653
+ this.#tui.notice(result.text, { level: 'error', focus: true });
644
654
  else
645
- this.#tui.commandOutput(parsed.name, result.text);
655
+ this.#tui.commandOutput(parsed.name, result.text, { focus: true });
646
656
  }
647
657
  return true;
648
658
  }
@@ -681,7 +691,7 @@ export class SessionRuntime {
681
691
  /** Start a new top-level session with the current model selection. */
682
692
  async newSession(agent) {
683
693
  this.assertActive(agent);
684
- await this.#activate(await this.#create(this.selection(agent)));
694
+ await this.#activate(await this.#create(this.selection(agent)), 'new');
685
695
  await this.refreshRecent();
686
696
  }
687
697
  /** Replace the active top-level session with one durable session. */
@@ -901,6 +911,34 @@ export class SessionRuntime {
901
911
  this.#pushSessionInfo();
902
912
  return outcome;
903
913
  }
914
+ /**
915
+ * Resolve and attach the changed-file summary a `workspace/changes` event
916
+ * announces.
917
+ *
918
+ * The Harness appends the event and only then files the summary under its
919
+ * sequence, so a listener running inside that append always reads
920
+ * `undefined`. The lookup is therefore deferred by one microtask, which runs
921
+ * after the recorder's own synchronous store, and enriches the turn-only
922
+ * block the transcript already rendered. A session without the plugin, or a
923
+ * recorder that has already been disposed, simply keeps the fallback.
924
+ *
925
+ * @param ctx - host context carrying the optional service.
926
+ * @param tui - the mounted presentation service.
927
+ * @param session - the Session that appended the event.
928
+ * @param event - the `workspace/changes` event.
929
+ */
930
+ #serveWorkspaceSummary(ctx, tui, session, event) {
931
+ const service = ctx.get('workspaceChanges');
932
+ if (service === undefined)
933
+ return;
934
+ const { id } = session;
935
+ const { seq, data } = event;
936
+ queueMicrotask(() => {
937
+ const summary = service.summary(id, seq);
938
+ if (summary !== undefined)
939
+ tui.setWorkspaceSummary(data.turn, summary);
940
+ });
941
+ }
904
942
  /**
905
943
  * Publish a current-format generation for every stored session an earlier
906
944
  * release wrote. A read open never upgrades a log, so without this pass
@@ -1106,7 +1144,7 @@ export class SessionRuntime {
1106
1144
  return undefined;
1107
1145
  }
1108
1146
  }
1109
- async #activate(next) {
1147
+ async #activate(next, reason = 'open') {
1110
1148
  // Reject a late create before it publishes UI on a disposed tree.
1111
1149
  if (this.#disposed) {
1112
1150
  this.#releaseHandle(next.handle);
@@ -1117,7 +1155,7 @@ export class SessionRuntime {
1117
1155
  this.#active = next;
1118
1156
  void this.#claimWorkspace(next);
1119
1157
  try {
1120
- this.#presentAgent(next);
1158
+ this.#presentAgent(next, reason);
1121
1159
  const selected = this.selection(next.handle.agent);
1122
1160
  const info = await this.#resolveModelInfo(selected);
1123
1161
  if (this.#disposed || this.#activationEpoch !== epoch) {
@@ -1178,7 +1216,7 @@ export class SessionRuntime {
1178
1216
  this.#releaseHandle(previous.handle);
1179
1217
  }
1180
1218
  /** Show one active session on the terminal: transcript, tools, controls, model. */
1181
- #presentAgent(active) {
1219
+ #presentAgent(active, reason = 'open') {
1182
1220
  const agent = active.handle.agent;
1183
1221
  this.#inspectedId = undefined;
1184
1222
  this.#tui.setInspectedSubagent(undefined);
@@ -1187,7 +1225,7 @@ export class SessionRuntime {
1187
1225
  // Seed welcome metadata before replaceSession commits the startup header to
1188
1226
  // native scrollback; later updates cannot rewrite that frozen first frame.
1189
1227
  this.#pushSessionInfo();
1190
- this.#replaceTranscript(agent);
1228
+ this.#replaceTranscript(agent, reason);
1191
1229
  this.#pushTools();
1192
1230
  this.#pushCommands();
1193
1231
  const selected = this.selection(agent);
@@ -1309,10 +1347,10 @@ export class SessionRuntime {
1309
1347
  controls: this.#sessionControls(active, projection),
1310
1348
  });
1311
1349
  }
1312
- #replaceTranscript(agent) {
1350
+ #replaceTranscript(agent, reason = 'refresh') {
1313
1351
  const events = agent.session.snapshotEvents();
1314
1352
  this.#tracker.observeCatalog(agent.session, events);
1315
- this.#tui.replaceSession(events, this.#ctx.get('tuiToolPresentation')?.session(agent, events), agent.status);
1353
+ this.#tui.replaceSession(events, this.#ctx.get('tuiToolPresentation')?.session(agent, events), agent.status, reason);
1316
1354
  this.#replayLivePrefix(agent.session.id);
1317
1355
  }
1318
1356
  #replaceVisibleTranscript() {
@@ -1367,7 +1405,7 @@ export class SessionRuntime {
1367
1405
  return;
1368
1406
  this.#inspectedId = id;
1369
1407
  const child = this.#ctx.get('agents')?.get(SessionId(id));
1370
- this.#tui.replaceSession(events, child === undefined ? undefined : this.#ctx.get('tuiToolPresentation')?.session(child, events), child?.status ?? 'idle');
1408
+ this.#tui.replaceSession(events, child === undefined ? undefined : this.#ctx.get('tuiToolPresentation')?.session(child, events), child?.status ?? 'idle', 'refresh');
1371
1409
  this.#replayLivePrefix(id);
1372
1410
  this.#tui.setInspectedSubagent(this.#inspectView(id, child?.status === 'running' ? 'running' : 'waiting'));
1373
1411
  this.#tui.setStatus(child?.status ?? 'idle');