@cmodjs/core 4.0.2 → 4.1.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/docs/commands.md +43 -8
- package/docs/index.md +3 -3
- package/docs/install-steps.md +6 -6
- package/docs/jobs.md +2 -1
- package/docs/mod.md +1 -1
- package/docs/options.md +1 -1
- package/docs/permissions.md +1 -1
- package/docs/session.md +44 -13
- package/docs/testing.md +14 -10
- package/docs/ui.md +43 -11
- package/installer.d.ts +3 -2
- package/installer.d.ts.map +1 -1
- package/jobs/program.d.ts +1 -0
- package/jobs/program.d.ts.map +1 -1
- package/jobs/program.js +39 -23
- package/mod.d.ts +3 -2
- package/mod.d.ts.map +1 -1
- package/mod.js +1 -0
- package/package.json +1 -1
- package/records.d.ts +15 -1
- package/records.d.ts.map +1 -1
- package/records.js +39 -1
- package/register.d.ts.map +1 -1
- package/register.js +5 -2
- package/runtime/before.d.ts +6 -2
- package/runtime/before.d.ts.map +1 -1
- package/runtime/before.js +56 -18
- package/runtime/buttons.d.ts +10 -0
- package/runtime/buttons.d.ts.map +1 -0
- package/runtime/buttons.js +12 -0
- package/runtime/conversations.d.ts.map +1 -1
- package/runtime/conversations.js +134 -25
- package/runtime/engine.d.ts +2 -0
- package/runtime/engine.d.ts.map +1 -1
- package/runtime/grants.d.ts +1 -0
- package/runtime/grants.d.ts.map +1 -1
- package/runtime/grants.js +5 -2
- package/runtime/hotkeys.d.ts.map +1 -1
- package/runtime/hotkeys.js +7 -4
- package/runtime/installer.d.ts +9 -6
- package/runtime/installer.d.ts.map +1 -1
- package/runtime/installer.js +104 -47
- package/runtime/lifecycle.d.ts.map +1 -1
- package/runtime/lifecycle.js +121 -40
- package/runtime/pages.d.ts +3 -1
- package/runtime/pages.d.ts.map +1 -1
- package/runtime/pages.js +34 -10
- package/runtime/parts.d.ts +1 -0
- package/runtime/parts.d.ts.map +1 -1
- package/runtime/parts.js +6 -3
- package/runtime/programs.d.ts +1 -0
- package/runtime/programs.d.ts.map +1 -1
- package/runtime/programs.js +4 -1
- package/runtime/sessions.d.ts +2 -2
- package/runtime/sessions.d.ts.map +1 -1
- package/runtime/sessions.js +88 -58
- package/runtime/toaster.d.ts.map +1 -1
- package/runtime/toaster.js +23 -9
- package/runtime/ui.d.ts +21 -4
- package/runtime/ui.d.ts.map +1 -1
- package/runtime/ui.js +158 -58
- package/runtime/watches.d.ts.map +1 -1
- package/runtime/watches.js +18 -4
- package/runtime/widgets.d.ts +7 -5
- package/runtime/widgets.d.ts.map +1 -1
- package/runtime/widgets.js +29 -20
- package/session/context/turn/message/attached-file.d.ts +13 -0
- package/session/context/turn/message/attached-file.d.ts.map +1 -0
- package/session/context/turn/message/attached-file.js +21 -0
- package/session/context/turn/message/message.d.ts +3 -2
- package/session/context/turn/message/message.d.ts.map +1 -1
- package/session/context/turn/message/message.js +20 -6
- package/session/conversation.d.ts +14 -3
- package/session/conversation.d.ts.map +1 -1
- package/session/conversation.js +23 -4
- package/session/goal/task.d.ts +5 -0
- package/session/goal/task.d.ts.map +1 -1
- package/session/session.d.ts +35 -7
- package/session/session.d.ts.map +1 -1
- package/session/session.js +2 -1
- package/src/installer.ts +3 -2
- package/src/jobs/program.ts +41 -21
- package/src/mod.ts +3 -2
- package/src/records.ts +49 -1
- package/src/register.ts +9 -6
- package/src/runtime/before.ts +61 -22
- package/src/runtime/buttons.ts +22 -0
- package/src/runtime/conversations.ts +138 -32
- package/src/runtime/engine.ts +2 -0
- package/src/runtime/grants.ts +6 -2
- package/src/runtime/hotkeys.ts +7 -4
- package/src/runtime/installer.ts +144 -82
- package/src/runtime/lifecycle.ts +128 -43
- package/src/runtime/pages.ts +45 -8
- package/src/runtime/parts.ts +8 -4
- package/src/runtime/programs.ts +5 -1
- package/src/runtime/sessions.ts +83 -57
- package/src/runtime/toaster.ts +27 -9
- package/src/runtime/ui.ts +163 -61
- package/src/runtime/watches.ts +20 -5
- package/src/runtime/widgets.ts +34 -22
- package/src/session/context/turn/message/attached-file.ts +36 -0
- package/src/session/context/turn/message/message.ts +20 -7
- package/src/session/conversation.ts +30 -6
- package/src/session/goal/task.ts +6 -0
- package/src/session/session.ts +17 -7
- package/src/testing/fake-claude.ts +21 -6
- package/src/testing/fake-elements.ts +51 -8
- package/src/testing/fake-sessions.ts +60 -23
- package/src/testing.ts +86 -28
- package/src/ui/areas.ts +1 -0
- package/src/ui/components.ts +14 -8
- package/src/ui/elements.ts +6 -2
- package/src/ui/markdown.ts +3 -3
- package/src/ui/panes.ts +2 -2
- package/src/ui/styles.ts +6 -2
- package/testing/fake-claude.d.ts +3 -0
- package/testing/fake-claude.d.ts.map +1 -1
- package/testing/fake-claude.js +18 -5
- package/testing/fake-elements.d.ts.map +1 -1
- package/testing/fake-elements.js +46 -7
- package/testing/fake-sessions.d.ts +21 -10
- package/testing/fake-sessions.d.ts.map +1 -1
- package/testing/fake-sessions.js +58 -20
- package/testing.d.ts +8 -12
- package/testing.d.ts.map +1 -1
- package/testing.js +82 -21
- package/ui/areas.d.ts +4 -0
- package/ui/areas.d.ts.map +1 -1
- package/ui/components.d.ts +1 -0
- package/ui/components.d.ts.map +1 -1
- package/ui/components.js +11 -7
- package/ui/elements.d.ts +3 -0
- package/ui/elements.d.ts.map +1 -1
- package/ui/elements.js +6 -1
- package/ui/markdown.d.ts +2 -2
- package/ui/markdown.d.ts.map +1 -1
- package/ui/panes.d.ts +2 -1
- package/ui/panes.d.ts.map +1 -1
- package/ui/styles.d.ts +11 -2
- package/ui/styles.d.ts.map +1 -1
package/runtime/widgets.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
@@ -152,7 +157,10 @@ export function serveWidgets({ claude, router, store, report, turnClosedBy, part
|
|
|
152
157
|
};
|
|
153
158
|
const elementFor = (key, area, columns, turn) => {
|
|
154
159
|
const widget = widgetOf(key);
|
|
155
|
-
|
|
160
|
+
if (widget === undefined)
|
|
161
|
+
return undefined;
|
|
162
|
+
const element = parts.element(widget.mod, cacheKey(key, area, columns, turn), `${key}:`, nameOf(widget), `widget:${key}`);
|
|
163
|
+
return element === undefined ? undefined : Box({ ...widgetSizes[widget.place?.size ?? 'fit'], children: element });
|
|
156
164
|
};
|
|
157
165
|
const isHidden = (key) => layout.hidden.includes(key);
|
|
158
166
|
const shown = (keys) => keys.filter((key) => !isHidden(key));
|
|
@@ -160,37 +168,38 @@ export function serveWidgets({ claude, router, store, report, turnClosedBy, part
|
|
|
160
168
|
const side = (keys) => shown(keys).map((key) => elementFor(key, area, columns, turn)).filter((each) => each !== undefined);
|
|
161
169
|
const left = side(row.left);
|
|
162
170
|
const right = side(row.right);
|
|
163
|
-
|
|
171
|
+
const group = (keys, children) => Box({ flexShrink: shown(keys).some((key) => widgetOf(key)?.place?.size === 'fill') ? 1 : 0, minWidth: 0, columnGap: 2, children });
|
|
172
|
+
return left.length + right.length === 0 ? [] : [Box({ justifyContent: 'space-between', width: columns, columnGap: 2, children: [group(row.left, left), group(row.right, right)] })];
|
|
164
173
|
});
|
|
165
174
|
const keysIn = (area) => layout.areas[area].flatMap((row) => shown([...row.left, ...row.right]));
|
|
166
|
-
const draw = async (area, table,
|
|
167
|
-
await Promise.all(keysIn(area).map((key) => fill(key, area, columns, turn)));
|
|
168
|
-
return drawWith(table, () => rowsNow(area, columns, turn));
|
|
175
|
+
const draw = async (area, table, at, turn) => {
|
|
176
|
+
await Promise.all(keysIn(area).map((key) => fill(key, area, at.columns, turn)));
|
|
177
|
+
return drawWith(table, () => rowsNow(area, at.columns, turn), markdownIn(table, at));
|
|
169
178
|
};
|
|
170
179
|
const rows = (area, columns) => {
|
|
171
180
|
const started = keysIn(area).flatMap((key) => fill(key, area, columns, undefined) ?? []);
|
|
172
181
|
if (started.length > 0)
|
|
173
|
-
void Promise.all(started).then(
|
|
182
|
+
void Promise.all(started).then(redraw);
|
|
174
183
|
return rowsNow(area, columns, undefined);
|
|
175
184
|
};
|
|
176
185
|
const column = (table, children) => drawWith(table, () => Box({ flexDirection: 'column', children }));
|
|
177
186
|
const below = (table, above, added) => (added.length === 0 ? above : column(table, [above, ...added]));
|
|
178
187
|
router.add('ui.render', async (e, next) => {
|
|
179
188
|
const table = claude.ui.resolve(e);
|
|
180
|
-
const
|
|
189
|
+
const inTranscript = styledAt(e, viewportColumns(e) - transcriptIndent);
|
|
181
190
|
if (e.component === 'AbovePrompt')
|
|
182
|
-
return e.props.hasSurvey ? next(e) : below(table, await next(e), await draw(AbovePrompt, table, e.props.bodyColumns));
|
|
191
|
+
return e.props.hasSurvey ? next(e) : below(table, await next(e), await draw(AbovePrompt, table, styledAt(e, e.props.bodyColumns)));
|
|
183
192
|
if (e.component === 'PromptHint') {
|
|
184
|
-
const added = await draw(BelowPrompt, table, (e
|
|
193
|
+
const added = await draw(BelowPrompt, table, styledAt(e, viewportColumns(e) - promptIndent));
|
|
185
194
|
return isHidden(claudeHint) ? column(table, added) : below(table, await next(e), added);
|
|
186
195
|
}
|
|
187
196
|
if (e.component === 'SessionMode')
|
|
188
197
|
return isHidden(claudeModes) ? column(table, []) : next(e);
|
|
189
198
|
if (e.component === 'Spinner')
|
|
190
|
-
return below(table, await next(e), await draw(Working, table,
|
|
199
|
+
return below(table, await next(e), await draw(Working, table, inTranscript));
|
|
191
200
|
if (e.component === 'TurnDuration') {
|
|
192
201
|
const turn = turnClosedBy(e.requestId);
|
|
193
|
-
return below(table, await next(e), turn === undefined ? [] : await draw(TurnEnd, table,
|
|
202
|
+
return below(table, await next(e), turn === undefined ? [] : await draw(TurnEnd, table, inTranscript, turn));
|
|
194
203
|
}
|
|
195
204
|
return next(e);
|
|
196
205
|
});
|
|
@@ -204,7 +213,7 @@ export function serveWidgets({ claude, router, store, report, turnClosedBy, part
|
|
|
204
213
|
const isNewList = JSON.stringify(listed) !== JSON.stringify(declared.get(mod) ?? []);
|
|
205
214
|
declared.set(mod, listed);
|
|
206
215
|
if (isNewList)
|
|
207
|
-
place();
|
|
216
|
+
return place();
|
|
208
217
|
}
|
|
209
218
|
claude.ui.invalidate('ui.render');
|
|
210
219
|
},
|
|
@@ -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":"AAEA,OAAO,EAAE,eAAe,EAAc,MAAM,uBAAuB,CAAA;AACnE,OAAO,EAAqC,IAAI,EAAE,MAAM,WAAW,CAAA;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAElC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,eAAO,MAAM,OAAO,YAAY,CAAA;AAEhC,MAAM,MAAM,WAAW,GAAG,OAAO,MAAM,GAAG,OAAO,IAAI,GAAG,OAAO,KAAK,GAAG,OAAO,QAAQ,GAAG,OAAO,UAAU,GAAG,OAAO,KAAK,GAAG,OAAO,eAAe,GAAG,OAAO,MAAM,CAAA;
|
|
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
|
|
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
|
|
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,7 +3,7 @@ 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;
|
|
@@ -20,11 +20,21 @@ export type SessionData = {
|
|
|
20
20
|
export type ContextData = Pick<Context, 'number' | 'openedAt' | 'closedAt' | 'task'>;
|
|
21
21
|
export type TurnData = Pick<Turn, 'prompt' | 'context' | 'openedAt' | 'closedAt' | 'answer' | 'reason' | 'failure'>;
|
|
22
22
|
export type TurnEnding = Pick<Turn, 'answer' | 'reason' | 'failure'>;
|
|
23
|
-
export type TaskData = Pick<Task, 'id' | 'title' | 'openedBy' | 'openedAt' | 'closedAt'> & {
|
|
24
|
-
readonly agentType
|
|
23
|
+
export type TaskData = Pick<Task, 'id' | 'title' | 'openedBy' | 'openedAt' | 'closedAt' | 'status' | 'name' | 'spawnedBy' | 'isBackground'> & {
|
|
24
|
+
readonly agentType?: string;
|
|
25
25
|
readonly model?: string;
|
|
26
26
|
readonly parent?: string;
|
|
27
|
+
readonly forkedFrom?: string;
|
|
28
|
+
};
|
|
29
|
+
export declare const forkAgentType = "fork";
|
|
30
|
+
export declare function ownerOfSpawn(agentType: string | undefined, session: string): Pick<TaskData, 'agentType' | 'forkedFrom'>;
|
|
31
|
+
type Agent = {
|
|
32
|
+
readonly id: string;
|
|
33
|
+
readonly status: TaskStatus;
|
|
34
|
+
readonly name?: string;
|
|
35
|
+
readonly spawnedBy?: string;
|
|
27
36
|
};
|
|
37
|
+
export declare function tasksWithAgents(tasks: readonly TaskData[], agents: readonly Agent[]): TaskData[];
|
|
28
38
|
export type RunningTask = TaskData & {
|
|
29
39
|
readonly context: number;
|
|
30
40
|
readonly contextOpenedAt?: string;
|
|
@@ -68,6 +78,7 @@ type OpenCall = Pick<ToolCall, 'name' | 'input' | 'cwd'>;
|
|
|
68
78
|
export type Conversation = {
|
|
69
79
|
add(row: Row, task?: string): SessionChange[];
|
|
70
80
|
startTask(task: TaskData): SessionChange[];
|
|
81
|
+
endTask(task: TaskData, at: string): SessionChange[];
|
|
71
82
|
startContext(at: string): SessionChange[];
|
|
72
83
|
endTurn(at: string, ending: TurnEnding, task?: string): SessionChange[];
|
|
73
84
|
changeGoal(text: string): SessionChange[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../src/session/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,EAAE,OAAO,EAA6B,KAAK,GAAG,EAAE,MAAM,mCAAmC,CAAA;AAGhG,OAAO,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAA;AAE9D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,IAAI,EAAE,MAAM,wBAAwB,CAAA;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../src/session/conversation.ts"],"names":[],"mappings":"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"}
|
package/session/conversation.js
CHANGED
|
@@ -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
|
|
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(...
|
|
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(...
|
|
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(...
|
|
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,
|
package/session/goal/task.d.ts
CHANGED
|
@@ -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"}
|
package/session/session.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
76
|
-
|
|
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;
|
|
@@ -185,11 +207,13 @@ export type Session = RecordPart & {
|
|
|
185
207
|
}): Promise<Message[]>;
|
|
186
208
|
send(message: SessionSend): Promise<void>;
|
|
187
209
|
startTask(task: TaskStartArgs): Promise<Task>;
|
|
210
|
+
fork(task: Pick<TaskStartArgs, 'prompt' | 'title'>): Promise<Task>;
|
|
211
|
+
clone(task: Pick<TaskStartArgs, 'prompt' | 'title'>): Promise<Task>;
|
|
188
212
|
callTool(call: ToolCallArgs): Promise<ToolResult>;
|
|
189
213
|
usage(): Promise<Usage>;
|
|
190
214
|
surfaces(): Promise<Surface[]>;
|
|
191
215
|
};
|
|
192
|
-
export type TaskOwner = Omit<Session, 'startTask' | 'callTool'>;
|
|
216
|
+
export type TaskOwner = Omit<Session, 'startTask' | 'callTool' | 'fork' | 'clone'>;
|
|
193
217
|
export declare const processEvents: {
|
|
194
218
|
readonly ProjectSetup: {
|
|
195
219
|
readonly on: 'Setup';
|
|
@@ -429,7 +453,9 @@ export type ProcessAsked = Omit<ProcessPayload, 'SessionStart'> & {
|
|
|
429
453
|
readonly SessionStart: SessionStartAsked;
|
|
430
454
|
};
|
|
431
455
|
export type ProcessAnswer = {
|
|
432
|
-
readonly ProjectSetup:
|
|
456
|
+
readonly ProjectSetup: {
|
|
457
|
+
readonly note: string;
|
|
458
|
+
};
|
|
433
459
|
readonly SessionStart: {
|
|
434
460
|
readonly note?: string;
|
|
435
461
|
readonly title?: string;
|
|
@@ -438,6 +464,8 @@ export type ProcessAnswer = {
|
|
|
438
464
|
};
|
|
439
465
|
readonly ModelChange: {
|
|
440
466
|
readonly ask: string;
|
|
467
|
+
} | {
|
|
468
|
+
readonly note: string;
|
|
441
469
|
} | Refusal;
|
|
442
470
|
readonly WorktreeCreate: {
|
|
443
471
|
readonly result: string;
|