@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.
- package/docs/commands.md +44 -9
- package/docs/index.md +3 -3
- package/docs/install-steps.md +8 -8
- 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 +46 -13
- package/docs/testing.md +15 -11
- 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 +8 -5
- 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 +3 -0
- package/runtime/conversations.d.ts.map +1 -1
- package/runtime/conversations.js +164 -27
- 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 +10 -6
- package/runtime/installer.d.ts.map +1 -1
- package/runtime/installer.js +106 -48
- package/runtime/lifecycle.d.ts +2 -2
- package/runtime/lifecycle.d.ts.map +1 -1
- package/runtime/lifecycle.js +144 -42
- package/runtime/pages.d.ts +3 -1
- package/runtime/pages.d.ts.map +1 -1
- package/runtime/pages.js +48 -14
- 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 +10 -3
- package/runtime/sessions.d.ts.map +1 -1
- package/runtime/sessions.js +104 -59
- package/runtime/toaster.d.ts.map +1 -1
- package/runtime/toaster.js +23 -9
- package/runtime/ui.d.ts +22 -4
- package/runtime/ui.d.ts.map +1 -1
- package/runtime/ui.js +161 -59
- 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 +31 -21
- 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 +15 -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 +36 -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 +11 -8
- package/src/runtime/before.ts +61 -22
- package/src/runtime/buttons.ts +22 -0
- package/src/runtime/conversations.ts +170 -34
- 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 +147 -83
- package/src/runtime/lifecycle.ts +149 -48
- package/src/runtime/pages.ts +56 -12
- package/src/runtime/parts.ts +8 -4
- package/src/runtime/programs.ts +5 -1
- package/src/runtime/sessions.ts +106 -59
- package/src/runtime/toaster.ts +27 -9
- package/src/runtime/ui.ts +166 -62
- package/src/runtime/watches.ts +20 -5
- package/src/runtime/widgets.ts +35 -23
- 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 +31 -6
- package/src/session/goal/task.ts +6 -0
- package/src/session/session.ts +18 -7
- package/src/testing/fake-claude.ts +21 -6
- package/src/testing/fake-elements.ts +57 -8
- package/src/testing/fake-sessions.ts +72 -24
- package/src/testing.ts +114 -33
- 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 +52 -7
- package/testing/fake-sessions.d.ts +24 -10
- package/testing/fake-sessions.d.ts.map +1 -1
- package/testing/fake-sessions.js +66 -20
- package/testing.d.ts +8 -12
- package/testing.d.ts.map +1 -1
- package/testing.js +113 -27
- 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 {
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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(
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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":"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,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
|
|
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":"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;
|
|
@@ -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:
|
|
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;
|