@cmodjs/core 4.0.3 → 4.1.1

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 (143) hide show
  1. package/docs/commands.md +44 -9
  2. package/docs/index.md +3 -3
  3. package/docs/install-steps.md +8 -8
  4. package/docs/jobs.md +2 -1
  5. package/docs/mod.md +1 -1
  6. package/docs/options.md +1 -1
  7. package/docs/permissions.md +1 -1
  8. package/docs/session.md +46 -13
  9. package/docs/testing.md +15 -11
  10. package/docs/ui.md +43 -11
  11. package/installer.d.ts +3 -2
  12. package/installer.d.ts.map +1 -1
  13. package/jobs/program.d.ts +1 -0
  14. package/jobs/program.d.ts.map +1 -1
  15. package/jobs/program.js +39 -23
  16. package/mod.d.ts +3 -2
  17. package/mod.d.ts.map +1 -1
  18. package/mod.js +1 -0
  19. package/package.json +1 -1
  20. package/records.d.ts +15 -1
  21. package/records.d.ts.map +1 -1
  22. package/records.js +39 -1
  23. package/register.d.ts.map +1 -1
  24. package/register.js +8 -5
  25. package/runtime/before.d.ts +6 -2
  26. package/runtime/before.d.ts.map +1 -1
  27. package/runtime/before.js +56 -18
  28. package/runtime/buttons.d.ts +10 -0
  29. package/runtime/buttons.d.ts.map +1 -0
  30. package/runtime/buttons.js +12 -0
  31. package/runtime/conversations.d.ts +3 -0
  32. package/runtime/conversations.d.ts.map +1 -1
  33. package/runtime/conversations.js +164 -27
  34. package/runtime/engine.d.ts +2 -0
  35. package/runtime/engine.d.ts.map +1 -1
  36. package/runtime/grants.d.ts +1 -0
  37. package/runtime/grants.d.ts.map +1 -1
  38. package/runtime/grants.js +5 -2
  39. package/runtime/hotkeys.d.ts.map +1 -1
  40. package/runtime/hotkeys.js +7 -4
  41. package/runtime/installer.d.ts +10 -6
  42. package/runtime/installer.d.ts.map +1 -1
  43. package/runtime/installer.js +106 -48
  44. package/runtime/lifecycle.d.ts +2 -2
  45. package/runtime/lifecycle.d.ts.map +1 -1
  46. package/runtime/lifecycle.js +144 -42
  47. package/runtime/pages.d.ts +3 -1
  48. package/runtime/pages.d.ts.map +1 -1
  49. package/runtime/pages.js +48 -14
  50. package/runtime/parts.d.ts +1 -0
  51. package/runtime/parts.d.ts.map +1 -1
  52. package/runtime/parts.js +6 -3
  53. package/runtime/programs.d.ts +1 -0
  54. package/runtime/programs.d.ts.map +1 -1
  55. package/runtime/programs.js +4 -1
  56. package/runtime/sessions.d.ts +10 -3
  57. package/runtime/sessions.d.ts.map +1 -1
  58. package/runtime/sessions.js +104 -59
  59. package/runtime/toaster.d.ts.map +1 -1
  60. package/runtime/toaster.js +23 -9
  61. package/runtime/ui.d.ts +22 -4
  62. package/runtime/ui.d.ts.map +1 -1
  63. package/runtime/ui.js +161 -59
  64. package/runtime/watches.d.ts.map +1 -1
  65. package/runtime/watches.js +18 -4
  66. package/runtime/widgets.d.ts +7 -5
  67. package/runtime/widgets.d.ts.map +1 -1
  68. package/runtime/widgets.js +31 -21
  69. package/session/context/turn/message/attached-file.d.ts +13 -0
  70. package/session/context/turn/message/attached-file.d.ts.map +1 -0
  71. package/session/context/turn/message/attached-file.js +21 -0
  72. package/session/context/turn/message/message.d.ts +3 -2
  73. package/session/context/turn/message/message.d.ts.map +1 -1
  74. package/session/context/turn/message/message.js +20 -6
  75. package/session/conversation.d.ts +15 -3
  76. package/session/conversation.d.ts.map +1 -1
  77. package/session/conversation.js +23 -4
  78. package/session/goal/task.d.ts +5 -0
  79. package/session/goal/task.d.ts.map +1 -1
  80. package/session/session.d.ts +36 -7
  81. package/session/session.d.ts.map +1 -1
  82. package/session/session.js +2 -1
  83. package/src/installer.ts +3 -2
  84. package/src/jobs/program.ts +41 -21
  85. package/src/mod.ts +3 -2
  86. package/src/records.ts +49 -1
  87. package/src/register.ts +11 -8
  88. package/src/runtime/before.ts +61 -22
  89. package/src/runtime/buttons.ts +22 -0
  90. package/src/runtime/conversations.ts +170 -34
  91. package/src/runtime/engine.ts +2 -0
  92. package/src/runtime/grants.ts +6 -2
  93. package/src/runtime/hotkeys.ts +7 -4
  94. package/src/runtime/installer.ts +147 -83
  95. package/src/runtime/lifecycle.ts +149 -48
  96. package/src/runtime/pages.ts +56 -12
  97. package/src/runtime/parts.ts +8 -4
  98. package/src/runtime/programs.ts +5 -1
  99. package/src/runtime/sessions.ts +106 -59
  100. package/src/runtime/toaster.ts +27 -9
  101. package/src/runtime/ui.ts +166 -62
  102. package/src/runtime/watches.ts +20 -5
  103. package/src/runtime/widgets.ts +35 -23
  104. package/src/session/context/turn/message/attached-file.ts +36 -0
  105. package/src/session/context/turn/message/message.ts +20 -7
  106. package/src/session/conversation.ts +31 -6
  107. package/src/session/goal/task.ts +6 -0
  108. package/src/session/session.ts +18 -7
  109. package/src/testing/fake-claude.ts +21 -6
  110. package/src/testing/fake-elements.ts +57 -8
  111. package/src/testing/fake-sessions.ts +72 -24
  112. package/src/testing.ts +114 -33
  113. package/src/ui/areas.ts +1 -0
  114. package/src/ui/components.ts +14 -8
  115. package/src/ui/elements.ts +6 -2
  116. package/src/ui/markdown.ts +3 -3
  117. package/src/ui/panes.ts +2 -2
  118. package/src/ui/styles.ts +6 -2
  119. package/testing/fake-claude.d.ts +3 -0
  120. package/testing/fake-claude.d.ts.map +1 -1
  121. package/testing/fake-claude.js +18 -5
  122. package/testing/fake-elements.d.ts.map +1 -1
  123. package/testing/fake-elements.js +52 -7
  124. package/testing/fake-sessions.d.ts +24 -10
  125. package/testing/fake-sessions.d.ts.map +1 -1
  126. package/testing/fake-sessions.js +66 -20
  127. package/testing.d.ts +8 -12
  128. package/testing.d.ts.map +1 -1
  129. package/testing.js +113 -27
  130. package/ui/areas.d.ts +4 -0
  131. package/ui/areas.d.ts.map +1 -1
  132. package/ui/components.d.ts +1 -0
  133. package/ui/components.d.ts.map +1 -1
  134. package/ui/components.js +11 -7
  135. package/ui/elements.d.ts +3 -0
  136. package/ui/elements.d.ts.map +1 -1
  137. package/ui/elements.js +6 -1
  138. package/ui/markdown.d.ts +2 -2
  139. package/ui/markdown.d.ts.map +1 -1
  140. package/ui/panes.d.ts +2 -1
  141. package/ui/panes.d.ts.map +1 -1
  142. package/ui/styles.d.ts +11 -2
  143. package/ui/styles.d.ts.map +1 -1
@@ -1,10 +1,10 @@
1
- import { isObject, widgetsPath } from '../records.js';
1
+ import { isObject, storeChangedPath, widgetsPath } from '../records.js';
2
2
  import { AbovePrompt, areas, BelowPrompt, TurnEnd, Working } from '../ui/areas.js';
3
3
  import { Box, drawWith } from '../ui/elements.js';
4
4
  import { ifMissing } from '../utils/paths.js';
5
5
  import { messageOf } from '../utils/text.js';
6
6
  import { cmodPluginName } from './dependencies.js';
7
- import { partMethods } from './ui.js';
7
+ import { partMethods, styledAt, viewportColumns } from './ui.js';
8
8
  export const claudeHint = 'claude/hint';
9
9
  export const claudeModes = 'claude/modes';
10
10
  export const builtInWidgets = [
@@ -13,7 +13,7 @@ export const builtInWidgets = [
13
13
  ];
14
14
  const promptIndent = 4;
15
15
  const transcriptIndent = 2;
16
- const terminalColumns = 80;
16
+ const widgetSizes = { fit: { flexShrink: 0 }, fill: { flexGrow: 1, flexShrink: 1, minWidth: 0 } };
17
17
  const separator = '';
18
18
  export function layoutOf(value) {
19
19
  const keys = (list) => (Array.isArray(list) ? list.filter((key) => typeof key === 'string') : []);
@@ -66,10 +66,12 @@ function declarationsOf(input) {
66
66
  const listed = isObject(input) && Array.isArray(input['widgets']) ? input['widgets'] : [];
67
67
  return listed.filter(isObject).flatMap((each) => {
68
68
  const known = Array.isArray(each['areas']) ? each['areas'].filter((area) => areas.includes(area)) : [];
69
- return typeof each['id'] === 'string' && typeof each['title'] === 'string' && known.length > 0 ? [{ id: each['id'], title: each['title'], areas: known }] : [];
69
+ const { side, size } = isObject(each['place']) ? each['place'] : {};
70
+ const place = { ...(side === 'left' || side === 'right' ? { side } : {}), ...(size === 'fit' || size === 'fill' ? { size } : {}) };
71
+ return typeof each['id'] === 'string' && typeof each['title'] === 'string' && known.length > 0 ? [{ id: each['id'], title: each['title'], areas: known, place }] : [];
70
72
  });
71
73
  }
72
- export function serveWidgets({ claude, router, store, report, turnClosedBy, parts, }) {
74
+ export function serveWidgets({ claude, router, store, report, turnClosedBy, parts, markdownIn, }) {
73
75
  const path = widgetsPath(store);
74
76
  const declared = new Map();
75
77
  let stored = layoutOf({});
@@ -83,7 +85,7 @@ export function serveWidgets({ claude, router, store, report, turnClosedBy, part
83
85
  };
84
86
  const read = async () => layoutOf(await readFile());
85
87
  const redraw = () => claude.ui.invalidate('ui.render');
86
- const placed = () => [...builtInWidgets, ...[...declared].flatMap(([mod, list]) => list.map(({ id, title, areas: listed }) => ({ key: `${mod}/${id}`, mod, title, areas: listed })))];
88
+ const placed = () => [...builtInWidgets, ...[...declared].flatMap(([mod, list]) => list.map(({ id, title, areas: listed, place }) => ({ key: `${mod}/${id}`, mod, title, areas: listed, ...(place === undefined ? {} : { place }) })))];
87
89
  const change = (edit) => {
88
90
  saving = saving
89
91
  .then(async () => {
@@ -94,6 +96,7 @@ export function serveWidgets({ claude, router, store, report, turnClosedBy, part
94
96
  if (next !== current) {
95
97
  const kept = isObject(file) ? file : {};
96
98
  await claude.fs.write(path, `${JSON.stringify({ ...kept, ...next, areas: { ...(isObject(kept['areas']) ? kept['areas'] : {}), ...next.areas } }, null, 2)}\n`);
99
+ await claude.fs.write(storeChangedPath(store), '');
97
100
  stored = next;
98
101
  }
99
102
  place();
@@ -107,9 +110,11 @@ export function serveWidgets({ claude, router, store, report, turnClosedBy, part
107
110
  };
108
111
  const withNewWidgets = (current) => placed()
109
112
  .filter(({ key, mod }) => mod !== 'claude' && placedIn(current, key) === undefined && !placedKeys.has(key))
110
- .reduce((next, { key, areas: [area = AbovePrompt] }) => {
113
+ .reduce((next, { key, areas: [area = AbovePrompt], place }) => {
111
114
  const [first, ...rest] = next.areas[area];
112
- return { ...next, areas: { ...next.areas, [area]: [{ ...first, left: [...(first?.left ?? []), key], right: first?.right ?? [] }, ...rest] } };
115
+ const row = { ...first, left: first?.left ?? [], right: first?.right ?? [] };
116
+ const side = place?.side ?? 'left';
117
+ return { ...next, areas: { ...next.areas, [area]: [{ ...row, [side]: [...row[side], key] }, ...rest] } };
113
118
  }, current);
114
119
  const ask = async (mod) => {
115
120
  try {
@@ -129,7 +134,8 @@ export function serveWidgets({ claude, router, store, report, turnClosedBy, part
129
134
  };
130
135
  const reload = async () => {
131
136
  stored = await read();
132
- place();
137
+ if (JSON.stringify(withNewWidgets(stored)) !== JSON.stringify(layout))
138
+ place();
133
139
  };
134
140
  saving = (async () => {
135
141
  const recorded = (await claude.fs.list(`${store}/records`).catch(ifMissing([]))).map((entry) => entry.name).filter((name) => name.endsWith('.json')).map((name) => name.slice(0, -'.json'.length));
@@ -152,7 +158,10 @@ export function serveWidgets({ claude, router, store, report, turnClosedBy, part
152
158
  };
153
159
  const elementFor = (key, area, columns, turn) => {
154
160
  const widget = widgetOf(key);
155
- return widget === undefined ? undefined : parts.element(widget.mod, cacheKey(key, area, columns, turn), `${key}:`, nameOf(widget), `widget:${key}`);
161
+ if (widget === undefined)
162
+ return undefined;
163
+ const element = parts.element(widget.mod, cacheKey(key, area, columns, turn), `${key}:`, nameOf(widget), `widget:${key}`);
164
+ return element === undefined ? undefined : Box({ ...widgetSizes[widget.place?.size ?? 'fit'], children: element });
156
165
  };
157
166
  const isHidden = (key) => layout.hidden.includes(key);
158
167
  const shown = (keys) => keys.filter((key) => !isHidden(key));
@@ -160,37 +169,38 @@ export function serveWidgets({ claude, router, store, report, turnClosedBy, part
160
169
  const side = (keys) => shown(keys).map((key) => elementFor(key, area, columns, turn)).filter((each) => each !== undefined);
161
170
  const left = side(row.left);
162
171
  const right = side(row.right);
163
- return left.length + right.length === 0 ? [] : [Box({ justifyContent: 'space-between', width: columns, children: [Box({ gap: 2, children: left }), Box({ gap: 2, children: right })] })];
172
+ const group = (keys, children) => Box({ flexShrink: shown(keys).some((key) => widgetOf(key)?.place?.size === 'fill') ? 1 : 0, minWidth: 0, columnGap: 2, children });
173
+ return left.length + right.length === 0 ? [] : [Box({ justifyContent: 'space-between', width: columns, columnGap: 2, children: [group(row.left, left), group(row.right, right)] })];
164
174
  });
165
175
  const keysIn = (area) => layout.areas[area].flatMap((row) => shown([...row.left, ...row.right]));
166
- const draw = async (area, table, columns, turn) => {
167
- await Promise.all(keysIn(area).map((key) => fill(key, area, columns, turn)));
168
- return drawWith(table, () => rowsNow(area, columns, turn));
176
+ const draw = async (area, table, at, turn) => {
177
+ await Promise.all(keysIn(area).map((key) => fill(key, area, at.columns, turn)));
178
+ return drawWith(table, () => rowsNow(area, at.columns, turn), markdownIn(table, at));
169
179
  };
170
180
  const rows = (area, columns) => {
171
181
  const started = keysIn(area).flatMap((key) => fill(key, area, columns, undefined) ?? []);
172
182
  if (started.length > 0)
173
- void Promise.all(started).then(() => claude.ui.invalidate('ui.render'));
183
+ void Promise.all(started).then(redraw);
174
184
  return rowsNow(area, columns, undefined);
175
185
  };
176
186
  const column = (table, children) => drawWith(table, () => Box({ flexDirection: 'column', children }));
177
187
  const below = (table, above, added) => (added.length === 0 ? above : column(table, [above, ...added]));
178
188
  router.add('ui.render', async (e, next) => {
179
189
  const table = claude.ui.resolve(e);
180
- const columns = (e.viewport?.columns ?? terminalColumns) - transcriptIndent;
190
+ const inTranscript = styledAt(e, viewportColumns(e) - transcriptIndent);
181
191
  if (e.component === 'AbovePrompt')
182
- return e.props.hasSurvey ? next(e) : below(table, await next(e), await draw(AbovePrompt, table, e.props.bodyColumns));
192
+ return e.props.hasSurvey ? next(e) : below(table, await next(e), await draw(AbovePrompt, table, styledAt(e, e.props.bodyColumns)));
183
193
  if (e.component === 'PromptHint') {
184
- const added = await draw(BelowPrompt, table, (e.viewport?.columns ?? terminalColumns) - promptIndent);
194
+ const added = await draw(BelowPrompt, table, styledAt(e, viewportColumns(e) - promptIndent));
185
195
  return isHidden(claudeHint) ? column(table, added) : below(table, await next(e), added);
186
196
  }
187
197
  if (e.component === 'SessionMode')
188
198
  return isHidden(claudeModes) ? column(table, []) : next(e);
189
199
  if (e.component === 'Spinner')
190
- return below(table, await next(e), await draw(Working, table, columns));
200
+ return below(table, await next(e), await draw(Working, table, inTranscript));
191
201
  if (e.component === 'TurnDuration') {
192
202
  const turn = turnClosedBy(e.requestId);
193
- return below(table, await next(e), turn === undefined ? [] : await draw(TurnEnd, table, columns, turn));
203
+ return below(table, await next(e), turn === undefined ? [] : await draw(TurnEnd, table, inTranscript, turn));
194
204
  }
195
205
  return next(e);
196
206
  });
@@ -204,7 +214,7 @@ export function serveWidgets({ claude, router, store, report, turnClosedBy, part
204
214
  const isNewList = JSON.stringify(listed) !== JSON.stringify(declared.get(mod) ?? []);
205
215
  declared.set(mod, listed);
206
216
  if (isNewList)
207
- place();
217
+ return place();
208
218
  }
209
219
  claude.ui.invalidate('ui.render');
210
220
  },
@@ -0,0 +1,13 @@
1
+ import type { MessageOf } from './message.js';
2
+ export declare const AttachedFile = "attachedFile";
3
+ export type AttachmentType = 'contents' | 'reference' | 'change';
4
+ export type AttachedFile = MessageOf<typeof AttachedFile> & {
5
+ readonly path: string;
6
+ readonly attachmentType: AttachmentType;
7
+ readonly text: string;
8
+ };
9
+ export declare const attachmentTypes: Readonly<Record<string, AttachmentType>>;
10
+ export declare function attachmentTypeOf(name: string | undefined): AttachmentType | undefined;
11
+ export declare function attachmentNameOf(type: AttachmentType): string;
12
+ export declare function attachedPathOf(text: string): string;
13
+ //# sourceMappingURL=attached-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attached-file.d.ts","sourceRoot":"","sources":["../../../../src/session/context/turn/message/attached-file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE7C,eAAO,MAAM,YAAY,iBAAiB,CAAA;AAE1C,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAA;AAEhE,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,YAAY,CAAC,GAAG;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAA;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAIpE,CAAA;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CAErF;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAI7D;AAMD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGnD"}
@@ -0,0 +1,21 @@
1
+ export const AttachedFile = 'attachedFile';
2
+ export const attachmentTypes = {
3
+ file: 'contents',
4
+ compact_file_reference: 'reference',
5
+ edited_text_file: 'change',
6
+ };
7
+ export function attachmentTypeOf(name) {
8
+ return name !== undefined && Object.hasOwn(attachmentTypes, name) ? attachmentTypes[name] : undefined;
9
+ }
10
+ export function attachmentNameOf(type) {
11
+ const name = Object.keys(attachmentTypes).find((each) => attachmentTypes[each] === type);
12
+ if (name === undefined)
13
+ throw new Error(`Claude Code writes no attachment row for a ${type} file.`);
14
+ return name;
15
+ }
16
+ const readPath = /^Called the Read tool with the following input: \{.*?"file_path":\s*("(?:[^"\\]|\\["\\/bfnrt]|\\u[0-9a-fA-F]{4})*")/m;
17
+ const noted = /^Note: (.+?) (?:was read before the last conversation was summarized|changed on disk since you last read it)/m;
18
+ export function attachedPathOf(text) {
19
+ const read = readPath.exec(text)?.[1];
20
+ return read === undefined ? (noted.exec(text)?.[1] ?? '') : JSON.parse(read);
21
+ }
@@ -1,3 +1,4 @@
1
+ import { AttachedFile } from './attached-file.js';
1
2
  import { InstructionFile } from './instruction-file.js';
2
3
  import { Note } from './note.js';
3
4
  import { Notice } from './notice.js';
@@ -7,7 +8,7 @@ import { Skill } from './skill.js';
7
8
  import { ToolCall, type CallFiles } from './tool-call.js';
8
9
  import { ToolResult } from './tool-result.js';
9
10
  export declare const Message = "message";
10
- export type MessageType = typeof Prompt | typeof Note | typeof Reply | typeof ToolCall | typeof ToolResult | typeof Skill | typeof InstructionFile | typeof Notice;
11
+ export type MessageType = typeof Prompt | typeof Note | typeof Reply | typeof ToolCall | typeof ToolResult | typeof Skill | typeof InstructionFile | typeof AttachedFile | typeof Notice;
11
12
  export type MessageOf<Type extends MessageType> = {
12
13
  readonly id: string;
13
14
  readonly type: Type;
@@ -17,7 +18,7 @@ export type MessageOf<Type extends MessageType> = {
17
18
  readonly turn?: string;
18
19
  readonly task?: string;
19
20
  };
20
- export type Message = Prompt | Note | Reply | ToolCall | ToolResult | Skill | InstructionFile | Notice;
21
+ export type Message = Prompt | Note | Reply | ToolCall | ToolResult | Skill | InstructionFile | AttachedFile | Notice;
21
22
  export type Placed = 'session' | 'context' | 'turn' | 'task';
22
23
  export type Unplaced<M extends Message = Message> = M extends Message ? Omit<M, Placed> : never;
23
24
  export type Row = {
@@ -1 +1 @@
1
- {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../../src/session/context/turn/message/message.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../../src/session/context/turn/message/message.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { isObject } from '../../../../records.js';
2
2
  import { Task } from '../../../goal/task.js';
3
+ import { AttachedFile, attachedPathOf, attachmentTypeOf } from './attached-file.js';
3
4
  import { InstructionFile, isRulePath } from './instruction-file.js';
4
5
  import { modNote, modNoteBlock, modNotesIn, Note } from './note.js';
5
6
  import { Notice } from './notice.js';
@@ -10,7 +11,7 @@ import { Skill } from './skill.js';
10
11
  import { ToolCall } from './tool-call.js';
11
12
  import { ToolResult } from './tool-result.js';
12
13
  export const Message = 'message';
13
- export const messageTypes = [Prompt, Note, Reply, ToolCall, ToolResult, Skill, InstructionFile, Notice];
14
+ export const messageTypes = [Prompt, Note, Reply, ToolCall, ToolResult, Skill, InstructionFile, AttachedFile, Notice];
14
15
  export const skillPrefix = 'Base directory for this skill:';
15
16
  const rowTypes = ['user', 'assistant', 'attachment', 'system'];
16
17
  const interruption = /^\[Request interrupted by user( for tool use)?\]$/;
@@ -24,8 +25,9 @@ export function rowOfLine(row) {
24
25
  return undefined;
25
26
  const message = isObject(row['message']) ? row['message'] : {};
26
27
  const attachment = isObject(row['attachment']) ? row['attachment'] : {};
27
- const content = type === 'attachment' ? attachment['content'] : type === 'system' ? row['content'] : message['content'];
28
28
  const name = type === 'attachment' ? attachment['type'] : row['subtype'];
29
+ const content = type === 'attachment' ? attachedContentOf(attachment) : type === 'system' ? row['content'] : message['content'];
30
+ const path = attachment['path'] ?? attachment['filename'];
29
31
  return {
30
32
  id: uuid,
31
33
  at: timestamp,
@@ -36,14 +38,20 @@ export function rowOfLine(row) {
36
38
  content: blocksOf(content),
37
39
  ...(row['origin'] === undefined ? {} : { origin: row['origin'] }),
38
40
  ...(typeof row['cwd'] === 'string' ? { cwd: row['cwd'] } : {}),
39
- ...(typeof attachment['path'] === 'string' ? { path: attachment['path'] } : {}),
41
+ ...(typeof path === 'string' ? { path } : {}),
40
42
  ...(typeof message['model'] === 'string' ? { model: message['model'] } : {}),
41
43
  };
42
44
  }
45
+ function attachedContentOf(attachment) {
46
+ if (attachment['type'] === 'edited_text_file')
47
+ return attachment['snippet'];
48
+ const file = isObject(attachment['content']) ? attachment['content']['file'] : undefined;
49
+ return attachment['type'] === 'file' && isObject(file) ? file['content'] : attachment['content'];
50
+ }
43
51
  export function rowOfAppend(append, at, cwd) {
44
52
  const { message, origin } = append;
45
53
  const text = textOf(message.content);
46
- const path = message.type === 'attachment' ? instructionPathOf(text) || undefined : undefined;
54
+ const path = message.type === 'attachment' ? (attachmentTypeOf(message.name) !== undefined ? attachedPathOf(text) : instructionPathOf(text)) || undefined : undefined;
47
55
  const model = isObject(origin) && origin['kind'] === 'model' && typeof origin['model'] === 'string' ? origin['model'] : undefined;
48
56
  return {
49
57
  id: append.uuid,
@@ -72,8 +80,12 @@ function unplacedOf(row, isInTask) {
72
80
  return row.name === 'turn_duration' || row.name === 'compact_boundary' || text === '' ? [] : [{ ...base, type: Notice, text }];
73
81
  if (row.type === 'attachment' && row.name === 'hook_additional_context')
74
82
  return notesFrom(row.content.flatMap((entry) => modNotesIn(typeof entry === 'string' ? entry : textOf([entry]))));
75
- if (row.type === 'attachment')
76
- return row.name === 'nested_memory' ? [{ ...base, type: InstructionFile, path: row.path ?? '', text, isRule: isRulePath(row.path ?? '') }] : [];
83
+ if (row.type === 'attachment' && row.name === 'nested_memory')
84
+ return [{ ...base, type: InstructionFile, path: row.path ?? '', text, isRule: isRulePath(row.path ?? '') }];
85
+ if (row.type === 'attachment') {
86
+ const attachmentType = attachmentTypeOf(row.name);
87
+ return attachmentType === undefined ? [] : [{ ...base, type: AttachedFile, path: row.path ?? '', attachmentType, text }];
88
+ }
77
89
  if (isModNotesRow(row))
78
90
  return notesFrom(modNotesIn(text));
79
91
  if (row.type === 'assistant') {
@@ -187,6 +199,8 @@ export function searchText(message) {
187
199
  return '';
188
200
  if (message.type === InstructionFile)
189
201
  return `${message.path}\n${message.text}`;
202
+ if (message.type === AttachedFile)
203
+ return message.path;
190
204
  return message.text;
191
205
  }
192
206
  function blocksOf(content) {
@@ -3,11 +3,12 @@ import { Message, type Row } from './context/turn/message/message.js';
3
3
  import { ToolCall } from './context/turn/message/tool-call.js';
4
4
  import { TurnEnd, TurnStart, type Turn } from './context/turn/turn.js';
5
5
  import { GoalChange } from './goal/goal.js';
6
- import { Task, TaskEnd, TaskStart } from './goal/task.js';
6
+ import { Task, TaskEnd, TaskStart, type TaskStatus } from './goal/task.js';
7
7
  import type { UsageChange, Usage } from './session.js';
8
8
  export type SessionData = {
9
9
  readonly id: string;
10
10
  readonly title: string;
11
+ readonly color?: string;
11
12
  readonly project: string;
12
13
  readonly cwd: string;
13
14
  readonly model: string;
@@ -20,11 +21,21 @@ export type SessionData = {
20
21
  export type ContextData = Pick<Context, 'number' | 'openedAt' | 'closedAt' | 'task'>;
21
22
  export type TurnData = Pick<Turn, 'prompt' | 'context' | 'openedAt' | 'closedAt' | 'answer' | 'reason' | 'failure'>;
22
23
  export type TurnEnding = Pick<Turn, 'answer' | 'reason' | 'failure'>;
23
- export type TaskData = Pick<Task, 'id' | 'title' | 'openedBy' | 'openedAt' | 'closedAt'> & {
24
- readonly agentType: string;
24
+ export type TaskData = Pick<Task, 'id' | 'title' | 'openedBy' | 'openedAt' | 'closedAt' | 'status' | 'name' | 'spawnedBy' | 'isBackground'> & {
25
+ readonly agentType?: string;
25
26
  readonly model?: string;
26
27
  readonly parent?: string;
28
+ readonly forkedFrom?: string;
29
+ };
30
+ export declare const forkAgentType = "fork";
31
+ export declare function ownerOfSpawn(agentType: string | undefined, session: string): Pick<TaskData, 'agentType' | 'forkedFrom'>;
32
+ type Agent = {
33
+ readonly id: string;
34
+ readonly status: TaskStatus;
35
+ readonly name?: string;
36
+ readonly spawnedBy?: string;
27
37
  };
38
+ export declare function tasksWithAgents(tasks: readonly TaskData[], agents: readonly Agent[]): TaskData[];
28
39
  export type RunningTask = TaskData & {
29
40
  readonly context: number;
30
41
  readonly contextOpenedAt?: string;
@@ -68,6 +79,7 @@ type OpenCall = Pick<ToolCall, 'name' | 'input' | 'cwd'>;
68
79
  export type Conversation = {
69
80
  add(row: Row, task?: string): SessionChange[];
70
81
  startTask(task: TaskData): SessionChange[];
82
+ endTask(task: TaskData, at: string): SessionChange[];
71
83
  startContext(at: string): SessionChange[];
72
84
  endTurn(at: string, ending: TurnEnding, task?: string): SessionChange[];
73
85
  changeGoal(text: string): SessionChange[];
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../src/session/conversation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../src/session/conversation.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,17 @@ import { ToolResult } from './context/turn/message/tool-result.js';
7
7
  import { TurnEnd, TurnStart } from './context/turn/turn.js';
8
8
  import { GoalChange } from './goal/goal.js';
9
9
  import { Task, TaskEnd, TaskStart } from './goal/task.js';
10
+ export const forkAgentType = 'fork';
11
+ export function ownerOfSpawn(agentType, session) {
12
+ return agentType === forkAgentType ? { forkedFrom: session } : { agentType: agentType ?? 'general-purpose' };
13
+ }
14
+ export function tasksWithAgents(tasks, agents) {
15
+ const byId = new Map(agents.map((agent) => [agent.id, agent]));
16
+ return tasks.map((task) => {
17
+ const agent = byId.get(task.id);
18
+ return agent === undefined ? task : { ...task, status: agent.status, ...(agent.name === undefined ? {} : { name: agent.name }), ...(agent.spawnedBy === undefined ? {} : { spawnedBy: agent.spawnedBy }) };
19
+ });
20
+ }
10
21
  export const searchLimit = 50;
11
22
  const agentTools = ['Agent', 'Task'];
12
23
  const asyncLaunch = 'Async agent launched';
@@ -51,7 +62,7 @@ export function createConversation(start) {
51
62
  turn = undefined;
52
63
  return [{ type: TurnEnd, turn: ended }];
53
64
  };
54
- const endTask = (call, at, only) => {
65
+ const endCall = (call, at, only) => {
55
66
  const opened = [...tasks.values()].filter((each) => each.openedBy === call && (only === undefined || each.id === only));
56
67
  if (opened.length === 0) {
57
68
  if (agentCalls.has(call))
@@ -113,11 +124,11 @@ export function createConversation(start) {
113
124
  if (placed.type === ToolCall && agentTools.includes(placed.name))
114
125
  agentCalls.add(placed.callId);
115
126
  if (placed.type === ToolResult && agentCalls.has(placed.callId) && !String(placed.output).startsWith(asyncLaunch))
116
- changes.push(...endTask(placed.callId, row.at));
127
+ changes.push(...endCall(placed.callId, row.at));
117
128
  if (placed.type === Note && placed.from.type === Task) {
118
129
  const call = tagOf(textOf(row.content), 'tool-use-id');
119
130
  if (call !== undefined && agentCalls.has(call))
120
- changes.push(...endTask(call, row.at, tagOf(textOf(row.content), 'task-id')));
131
+ changes.push(...endCall(call, row.at, tagOf(textOf(row.content), 'task-id')));
121
132
  }
122
133
  }
123
134
  return changes;
@@ -131,9 +142,17 @@ export function createConversation(start) {
131
142
  const changes = [{ type: TaskStart, task: started }];
132
143
  const endedAt = endedCalls.get(data.openedBy);
133
144
  if (endedAt !== undefined)
134
- changes.push(...endTask(data.openedBy, endedAt, data.id));
145
+ changes.push(...endCall(data.openedBy, endedAt, data.id));
135
146
  return changes;
136
147
  },
148
+ endTask(data, at) {
149
+ const open = tasks.get(data.id) ?? { ...data, context };
150
+ if (open.closedAt !== undefined)
151
+ return [];
152
+ const ended = { ...open, closedAt: at };
153
+ tasks.set(data.id, ended);
154
+ return [...endTaskTurn(data.id, at), { type: TaskEnd, task: ended }];
155
+ },
137
156
  startContext,
138
157
  endTurn: (at, ending, task) => (task === undefined ? endTurn(at, ending) : endTaskTurn(task, at, ending)),
139
158
  changeGoal,
@@ -3,6 +3,7 @@ import type { RecordPart, TaskOwner } from '../session.js';
3
3
  export declare const Task = "task";
4
4
  export declare const TaskStart = "taskStart";
5
5
  export declare const TaskEnd = "taskEnd";
6
+ export type TaskStatus = 'pending' | 'running' | 'waiting' | 'idle' | 'completed' | 'failed' | 'killed';
6
7
  export type Task = RecordPart & {
7
8
  readonly id: string;
8
9
  readonly title: string;
@@ -10,6 +11,10 @@ export type Task = RecordPart & {
10
11
  readonly openedBy: string;
11
12
  readonly openedAt: string;
12
13
  readonly closedAt?: string;
14
+ readonly status?: TaskStatus;
15
+ readonly name?: string;
16
+ readonly spawnedBy?: string;
17
+ readonly isBackground?: true;
13
18
  tasks(): Promise<Task[]>;
14
19
  messages(): Promise<Message[]>;
15
20
  };
@@ -1 +1 @@
1
- {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../src/session/goal/task.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAA;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE1D,eAAO,MAAM,IAAI,SAAS,CAAA;AAE1B,eAAO,MAAM,SAAS,cAAc,CAAA;AAEpC,eAAO,MAAM,OAAO,YAAY,CAAA;AAEhC,MAAM,MAAM,IAAI,GAAG,UAAU,GAAG;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IACxB,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;CAC/B,CAAA"}
1
+ {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../src/session/goal/task.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAA;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE1D,eAAO,MAAM,IAAI,SAAS,CAAA;AAE1B,eAAO,MAAM,SAAS,cAAc,CAAA;AAEpC,eAAO,MAAM,OAAO,YAAY,CAAA;AAEhC,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAEvG,MAAM,MAAM,IAAI,GAAG,UAAU,GAAG;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAA;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,YAAY,CAAC,EAAE,IAAI,CAAA;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IACxB,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;CAC/B,CAAA"}
@@ -2,6 +2,7 @@ import type { Subscription } from '../utils/subscription.js';
2
2
  import type { Matcher } from '../utils/matcher.js';
3
3
  import type { Sender } from './context/turn/message/sender.js';
4
4
  import type { Context, ContextEnd, ContextStart } from './context/context.js';
5
+ import type { AttachedFile } from './context/turn/message/attached-file.js';
5
6
  import type { InstructionFile } from './context/turn/message/instruction-file.js';
6
7
  import type { Message, MessageType } from './context/turn/message/message.js';
7
8
  import type { Note } from './context/turn/message/note.js';
@@ -27,6 +28,7 @@ export type SessionPayload = {
27
28
  readonly toolResult: ToolResult;
28
29
  readonly skill: Skill;
29
30
  readonly instructionFile: InstructionFile;
31
+ readonly attachedFile: AttachedFile;
30
32
  readonly notice: Notice;
31
33
  readonly contextStart: Context;
32
34
  readonly contextEnd: Context;
@@ -55,13 +57,18 @@ export type BeforeAnswer = {
55
57
  readonly instructionFile: {
56
58
  readonly text: string;
57
59
  } | Refusal;
60
+ readonly attachedFile: {
61
+ readonly text: string;
62
+ } | Refusal;
58
63
  readonly reply: {
59
64
  readonly text: string;
60
65
  };
61
66
  readonly toolCall: {
62
- readonly input: Readonly<Record<string, unknown>>;
67
+ readonly input?: Readonly<Record<string, unknown>>;
68
+ readonly note?: string;
63
69
  } | {
64
70
  readonly result: string;
71
+ readonly note?: string;
65
72
  } | Refusal;
66
73
  readonly toolResult: {
67
74
  readonly output?: unknown;
@@ -72,11 +79,18 @@ export type BeforeAnswer = {
72
79
  readonly text: string;
73
80
  };
74
81
  readonly taskStart: {
75
- readonly owner: {
76
- readonly model: string;
82
+ readonly prompt?: string;
83
+ readonly title?: string;
84
+ readonly owner?: {
85
+ readonly agentType?: string;
86
+ readonly model?: string;
87
+ readonly cwd?: string;
77
88
  };
89
+ readonly isAsync?: boolean;
90
+ } | Refusal;
91
+ readonly turnEnd: {
92
+ readonly note: string;
78
93
  } | Refusal;
79
- readonly turnEnd: Refusal;
80
94
  readonly contextEnd: Refusal;
81
95
  };
82
96
  export type BeforeEvent = keyof BeforeAnswer;
@@ -87,10 +101,16 @@ export type Usage = {
87
101
  readonly size?: number;
88
102
  readonly percent?: number;
89
103
  };
104
+ readonly rateLimits?: readonly RateLimit[];
90
105
  readonly cost?: {
91
106
  readonly usd: number;
92
107
  };
93
108
  };
109
+ export type RateLimit = {
110
+ readonly type: string;
111
+ readonly percent: number;
112
+ readonly resetsAt?: string;
113
+ };
94
114
  export type Surface = 'terminal' | 'desktop' | 'mobile' | 'vscode';
95
115
  export declare const sessionEvents: {
96
116
  readonly Message: 'message';
@@ -101,6 +121,7 @@ export declare const sessionEvents: {
101
121
  readonly ToolResult: 'toolResult';
102
122
  readonly Skill: 'skill';
103
123
  readonly InstructionFile: 'instructionFile';
124
+ readonly AttachedFile: 'attachedFile';
104
125
  readonly Notice: 'notice';
105
126
  readonly ContextStart: 'contextStart';
106
127
  readonly ContextEnd: 'contextEnd';
@@ -111,7 +132,7 @@ export declare const sessionEvents: {
111
132
  readonly GoalChange: 'goalChange';
112
133
  readonly UsageChange: 'usageChange';
113
134
  };
114
- export declare const beforeEvents: readonly ["Prompt", "Note", "Skill", "InstructionFile", "Reply", "ToolCall", "ToolResult", "Notice", "TaskStart", "TurnEnd", "ContextEnd"];
135
+ export declare const beforeEvents: readonly ["Prompt", "Note", "Skill", "InstructionFile", "AttachedFile", "Reply", "ToolCall", "ToolResult", "Notice", "TaskStart", "TurnEnd", "ContextEnd"];
115
136
  export type EventName = keyof typeof sessionEvents;
116
137
  export type BeforeName = (typeof beforeEvents)[number];
117
138
  export type PayloadOf<Name extends EventName> = SessionPayload[(typeof sessionEvents)[Name]];
@@ -156,6 +177,7 @@ export type TaskStartArgs = {
156
177
  readonly title: string;
157
178
  readonly name?: string;
158
179
  readonly cwd?: string;
180
+ readonly isBackground?: boolean;
159
181
  };
160
182
  export type ToolCallArgs = {
161
183
  readonly name: string;
@@ -164,6 +186,7 @@ export type ToolCallArgs = {
164
186
  export type Session = RecordPart & {
165
187
  readonly id: string;
166
188
  readonly title: string;
189
+ readonly color?: string;
167
190
  readonly project: string;
168
191
  readonly agentType?: string;
169
192
  readonly model: string;
@@ -185,11 +208,13 @@ export type Session = RecordPart & {
185
208
  }): Promise<Message[]>;
186
209
  send(message: SessionSend): Promise<void>;
187
210
  startTask(task: TaskStartArgs): Promise<Task>;
211
+ fork(task: Pick<TaskStartArgs, 'prompt' | 'title'>): Promise<Task>;
212
+ clone(task: Pick<TaskStartArgs, 'prompt' | 'title'>): Promise<Task>;
188
213
  callTool(call: ToolCallArgs): Promise<ToolResult>;
189
214
  usage(): Promise<Usage>;
190
215
  surfaces(): Promise<Surface[]>;
191
216
  };
192
- export type TaskOwner = Omit<Session, 'startTask' | 'callTool'>;
217
+ export type TaskOwner = Omit<Session, 'startTask' | 'callTool' | 'fork' | 'clone'>;
193
218
  export declare const processEvents: {
194
219
  readonly ProjectSetup: {
195
220
  readonly on: 'Setup';
@@ -429,7 +454,9 @@ export type ProcessAsked = Omit<ProcessPayload, 'SessionStart'> & {
429
454
  readonly SessionStart: SessionStartAsked;
430
455
  };
431
456
  export type ProcessAnswer = {
432
- readonly ProjectSetup: Record<never, never>;
457
+ readonly ProjectSetup: {
458
+ readonly note: string;
459
+ };
433
460
  readonly SessionStart: {
434
461
  readonly note?: string;
435
462
  readonly title?: string;
@@ -438,6 +465,8 @@ export type ProcessAnswer = {
438
465
  };
439
466
  readonly ModelChange: {
440
467
  readonly ask: string;
468
+ } | {
469
+ readonly note: string;
441
470
  } | Refusal;
442
471
  readonly WorktreeCreate: {
443
472
  readonly result: string;