@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/testing/fake-elements.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const boxInsides = new WeakMap();
|
|
2
|
+
const measuredProps = ['width', 'height', 'minWidth', 'minHeight'];
|
|
2
3
|
function element(type) {
|
|
3
4
|
return (props) => {
|
|
4
5
|
const { children, ...rest } = props;
|
|
@@ -7,6 +8,11 @@ function element(type) {
|
|
|
7
8
|
const drawn = { type, props: keyed, ...(flat.length === 0 ? {} : { children: flat }) };
|
|
8
9
|
if (type !== 'Box')
|
|
9
10
|
return drawn;
|
|
11
|
+
for (const size of measuredProps) {
|
|
12
|
+
const value = rest[size];
|
|
13
|
+
if (typeof value === 'number' && !(Number.isFinite(value) && value >= 0 && value <= 10000))
|
|
14
|
+
throw new Error(`Box prop "${size}" must be a finite number between 0 and 10000`);
|
|
15
|
+
}
|
|
10
16
|
const box = Object.freeze({});
|
|
11
17
|
boxInsides.set(box, drawn);
|
|
12
18
|
return box;
|
|
@@ -22,6 +28,9 @@ export const elements = {
|
|
|
22
28
|
Input: element('Input'),
|
|
23
29
|
Select: element('Select'),
|
|
24
30
|
Image: element('Image'),
|
|
31
|
+
Svg: element('Svg'),
|
|
32
|
+
Raster: element('Raster'),
|
|
33
|
+
Client: element('Client'),
|
|
25
34
|
};
|
|
26
35
|
export function findElement(node, type, key) {
|
|
27
36
|
if (typeof node === 'string')
|
|
@@ -37,12 +46,14 @@ export function findElement(node, type, key) {
|
|
|
37
46
|
return undefined;
|
|
38
47
|
}
|
|
39
48
|
export function rowsOf(node, width) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
49
|
+
const drawn = typeof node === 'string' ? undefined : insideOf(node);
|
|
50
|
+
if (drawn?.type === 'Box')
|
|
51
|
+
return boxRows(drawn, width);
|
|
52
|
+
if (drawn?.type === 'Svg')
|
|
53
|
+
return [];
|
|
43
54
|
return textOf(node)
|
|
44
55
|
.split('\n')
|
|
45
|
-
.flatMap((line) => fitted(line, width, wrap));
|
|
56
|
+
.flatMap((line) => fitted(line, width, drawn?.props['wrap']));
|
|
46
57
|
}
|
|
47
58
|
export function textOf(node) {
|
|
48
59
|
if (typeof node === 'string')
|
|
@@ -94,11 +105,45 @@ function boxRows({ props, children = [] }, width) {
|
|
|
94
105
|
const size = (key) => (typeof props[key] === 'number' ? props[key] : undefined);
|
|
95
106
|
const space = (side, axis) => (size(`padding${side}`) ?? size(`padding${axis}`) ?? size('padding') ?? 0) + (size(`margin${side}`) ?? size(`margin${axis}`) ?? size('margin') ?? 0);
|
|
96
107
|
const left = space('Left', 'X');
|
|
108
|
+
const right = space('Right', 'X');
|
|
109
|
+
const border = typeof props['borderStyle'] === 'string' ? 1 : 0;
|
|
97
110
|
const direction = String(props['flexDirection'] ?? 'row');
|
|
98
|
-
const
|
|
99
|
-
const
|
|
111
|
+
const flowing = children.filter((child) => !isPlaced(child));
|
|
112
|
+
const ordered = direction.endsWith('-reverse') ? [...flowing].reverse() : flowing;
|
|
113
|
+
const outer = Math.min(width, size('width') ?? width);
|
|
114
|
+
const inner = outer - left - right - border * 2;
|
|
100
115
|
const rows = direction.startsWith('column') ? stacked(ordered, inner, size('rowGap') ?? size('gap') ?? 0) : sideBySide(ordered, inner, size('columnGap') ?? size('gap') ?? 0, props['justifyContent'] === 'space-between');
|
|
101
|
-
|
|
116
|
+
const content = border === 1 && Number.isFinite(inner) ? inner : right === 0 && border === 0 ? 0 : Math.max(widthOf(rows), (size('minWidth') ?? 0) - left - right - border * 2);
|
|
117
|
+
const padded = [...blankRows(space('Top', 'Y')), ...rows.map((row) => `${' '.repeat(left)}${paddedTo(row, content)}${' '.repeat(right)}`), ...blankRows(space('Bottom', 'Y'))];
|
|
118
|
+
const framed = border === 0 ? padded : framedRows(padded, left + content + right, props['borderStyle']);
|
|
119
|
+
return placedOver(framed.map((row) => paddedTo(row, size('minWidth') ?? 0)), children.filter(isPlaced), outer);
|
|
120
|
+
}
|
|
121
|
+
function isPlaced(node) {
|
|
122
|
+
if (typeof node === 'string')
|
|
123
|
+
return false;
|
|
124
|
+
const { props } = insideOf(node);
|
|
125
|
+
return props['position'] === 'absolute' && typeof props['top'] === 'number';
|
|
126
|
+
}
|
|
127
|
+
function framedRows(rows, columns, style) {
|
|
128
|
+
const [topLeft, topRight, bottomLeft, bottomRight] = style === 'round' ? ['╭', '╮', '╰', '╯'] : ['┌', '┐', '└', '┘'];
|
|
129
|
+
return [`${topLeft}${'─'.repeat(columns)}${topRight}`, ...rows.map((row) => `│${paddedTo(row, columns)}│`), `${bottomLeft}${'─'.repeat(columns)}${bottomRight}`];
|
|
130
|
+
}
|
|
131
|
+
function placedOver(rows, placed, width) {
|
|
132
|
+
const drawn = [...rows];
|
|
133
|
+
for (const node of placed) {
|
|
134
|
+
const { props } = insideOf(node);
|
|
135
|
+
const top = Number(props['top']);
|
|
136
|
+
const left = typeof props['left'] === 'number' ? props['left'] : 0;
|
|
137
|
+
rowsOf(node, width - left).forEach((line, index) => {
|
|
138
|
+
const row = top + index;
|
|
139
|
+
if (row < 0 || row >= drawn.length)
|
|
140
|
+
return;
|
|
141
|
+
const cells = [...paddedTo(drawn[row] ?? '', left)];
|
|
142
|
+
cells.splice(left, [...line].length, ...line);
|
|
143
|
+
drawn[row] = cells.join('');
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return drawn;
|
|
102
147
|
}
|
|
103
148
|
function stacked(children, width, gap) {
|
|
104
149
|
const blocks = children.map((child) => rowsOf(child, width)).filter((block) => block.length > 0);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AttachedFile, type AttachmentType } from '../session/context/turn/message/attached-file.js';
|
|
1
2
|
import { InstructionFile } from '../session/context/turn/message/instruction-file.js';
|
|
2
3
|
import { Message } from '../session/context/turn/message/message.js';
|
|
3
4
|
import { Note } from '../session/context/turn/message/note.js';
|
|
@@ -9,8 +10,9 @@ import { Skill } from '../session/context/turn/message/skill.js';
|
|
|
9
10
|
import { ToolCall } from '../session/context/turn/message/tool-call.js';
|
|
10
11
|
import { ToolResult } from '../session/context/turn/message/tool-result.js';
|
|
11
12
|
import { type SessionChange, type SessionData, type TurnData, type TurnEnding } from '../session/conversation.js';
|
|
12
|
-
import type { Place } from '../runtime/before.js';
|
|
13
|
+
import type { Decide, Place } from '../runtime/before.js';
|
|
13
14
|
import type { Claude } from '../runtime/claude.js';
|
|
15
|
+
import { type SessionColor } from '../runtime/sessions.js';
|
|
14
16
|
export type MessageDraft = {
|
|
15
17
|
readonly type: typeof Prompt;
|
|
16
18
|
readonly text: string;
|
|
@@ -40,6 +42,11 @@ export type MessageDraft = {
|
|
|
40
42
|
readonly type: typeof InstructionFile;
|
|
41
43
|
readonly path: string;
|
|
42
44
|
readonly text: string;
|
|
45
|
+
} | {
|
|
46
|
+
readonly type: typeof AttachedFile;
|
|
47
|
+
readonly path: string;
|
|
48
|
+
readonly attachmentType: AttachmentType;
|
|
49
|
+
readonly text: string;
|
|
43
50
|
} | {
|
|
44
51
|
readonly type: typeof Notice;
|
|
45
52
|
readonly text: string;
|
|
@@ -49,22 +56,27 @@ export type FakeSession = Partial<Omit<SessionData, 'id'>> & {
|
|
|
49
56
|
readonly messages?: readonly MessageDraft[];
|
|
50
57
|
readonly goal?: string;
|
|
51
58
|
};
|
|
59
|
+
export type StartedTask = {
|
|
60
|
+
readonly title: string;
|
|
61
|
+
readonly agentType?: string;
|
|
62
|
+
readonly model?: string;
|
|
63
|
+
readonly openedBy?: string;
|
|
64
|
+
readonly parent?: string;
|
|
65
|
+
readonly isBackground?: true;
|
|
66
|
+
readonly forkedFrom?: string;
|
|
67
|
+
};
|
|
52
68
|
export type FakeSessions = {
|
|
53
69
|
answer(caller: string, method: string, input: unknown): unknown;
|
|
54
70
|
add(draft: MessageDraft, task?: string): Message[];
|
|
55
71
|
draft(draft: MessageDraft, task?: string): Message;
|
|
56
72
|
place(): Place;
|
|
57
73
|
wants(mod: string, event: string): boolean;
|
|
58
|
-
endTurn(ending?: TurnEnding): void;
|
|
74
|
+
endTurn(ending?: TurnEnding, task?: string): void;
|
|
59
75
|
compact(): void;
|
|
60
|
-
startTask(task:
|
|
61
|
-
readonly title: string;
|
|
62
|
-
readonly agentType?: string;
|
|
63
|
-
readonly model?: string;
|
|
64
|
-
readonly openedBy?: string;
|
|
65
|
-
readonly parent?: string;
|
|
66
|
-
}): string;
|
|
76
|
+
startTask(task: StartedTask): string;
|
|
67
77
|
start(id: string): void;
|
|
78
|
+
color(): SessionColor;
|
|
79
|
+
recolor(color: string | undefined): SessionColor;
|
|
68
80
|
lastTurn(): TurnData | undefined;
|
|
69
81
|
readonly sent: {
|
|
70
82
|
readonly session: string;
|
|
@@ -74,11 +86,13 @@ export type FakeSessions = {
|
|
|
74
86
|
readonly as?: string;
|
|
75
87
|
}[];
|
|
76
88
|
};
|
|
77
|
-
export declare function fakeSessions({ project, cwd, given, push, callTool }: {
|
|
89
|
+
export declare function fakeSessions({ project, cwd, given, push, callTool, listAgents, decide }: {
|
|
78
90
|
readonly project: () => string;
|
|
79
91
|
readonly cwd: () => string;
|
|
80
92
|
readonly given: readonly FakeSession[];
|
|
81
93
|
readonly push: (mod: string, session: string, change: SessionChange) => void;
|
|
82
94
|
readonly callTool: Claude['tool']['call'];
|
|
95
|
+
readonly listAgents: Claude['agent']['list'];
|
|
96
|
+
readonly decide: Decide;
|
|
83
97
|
}): FakeSessions;
|
|
84
98
|
//# sourceMappingURL=fake-sessions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fake-sessions.d.ts","sourceRoot":"","sources":["../src/testing/fake-sessions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,qDAAqD,CAAA;AACrF,OAAO,EAAE,OAAO,EAA0D,MAAM,4CAA4C,CAAA;AAC5H,OAAO,EAAE,IAAI,EAAE,MAAM,yCAAyC,CAAA;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAClE,OAAO,EAAE,KAAK,EAAE,MAAM,0CAA0C,CAAA;AAChE,OAAO,EAAyB,KAAK,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAG9F,OAAO,EAAE,KAAK,EAAE,MAAM,0CAA0C,CAAA;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,8CAA8C,CAAA;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,gDAAgD,CAAA;AAC3E,OAAO,
|
|
1
|
+
{"version":3,"file":"fake-sessions.d.ts","sourceRoot":"","sources":["../src/testing/fake-sessions.ts"],"names":[],"mappings":"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"}
|
package/testing/fake-sessions.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isObject } from '../records.js';
|
|
2
|
+
import { AttachedFile, attachmentNameOf } from '../session/context/turn/message/attached-file.js';
|
|
2
3
|
import { InstructionFile } from '../session/context/turn/message/instruction-file.js';
|
|
3
4
|
import { Message, messagesOf, noFiles, searchText, skillPrefix } from '../session/context/turn/message/message.js';
|
|
4
5
|
import { Note } from '../session/context/turn/message/note.js';
|
|
@@ -7,15 +8,15 @@ import { Prompt } from '../session/context/turn/message/prompt.js';
|
|
|
7
8
|
import { Reply } from '../session/context/turn/message/reply.js';
|
|
8
9
|
import { Mod, Person, Schedule } from '../session/context/turn/message/sender.js';
|
|
9
10
|
import { GoalChange } from '../session/goal/goal.js';
|
|
10
|
-
import { Task } from '../session/goal/task.js';
|
|
11
|
+
import { Task, TaskStart } from '../session/goal/task.js';
|
|
11
12
|
import { Skill } from '../session/context/turn/message/skill.js';
|
|
12
13
|
import { ToolCall } from '../session/context/turn/message/tool-call.js';
|
|
13
14
|
import { ToolResult } from '../session/context/turn/message/tool-result.js';
|
|
14
|
-
import { createConversation, emptyConversation, searchLimit } from '../session/conversation.js';
|
|
15
|
+
import { createConversation, emptyConversation, searchLimit, tasksWithAgents } from '../session/conversation.js';
|
|
15
16
|
import { conversationMethods, everySession, isHeardBy, resultOf } from '../runtime/sessions.js';
|
|
16
17
|
import { receivedMatcher } from '../utils/matcher.js';
|
|
17
18
|
import { firstLine, messageOf } from '../utils/text.js';
|
|
18
|
-
export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
19
|
+
export function fakeSessions({ project, cwd, given, push, callTool, listAgents, decide }) {
|
|
19
20
|
const kept = new Map();
|
|
20
21
|
const heard = new Map();
|
|
21
22
|
const watches = new Map();
|
|
@@ -52,6 +53,14 @@ export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
|
52
53
|
record(session, session.conversation.add(rowOf(draft, `message-${(ids += 1)}`, now(), cwd()), task));
|
|
53
54
|
return session.messages.slice(before);
|
|
54
55
|
};
|
|
56
|
+
const openTask = (session, { title, agentType, model, openedBy = '', parent, isBackground, forkedFrom }) => {
|
|
57
|
+
const owner = forkedFrom !== undefined ? { forkedFrom } : isBackground === true ? (agentType === undefined ? {} : { agentType }) : { agentType: agentType ?? 'general-purpose' };
|
|
58
|
+
const data = { id: `task-${(ids += 1)}`, title, ...owner, openedBy, openedAt: now(), ...(model === undefined ? {} : { model }), ...(parent === undefined ? {} : { parent }), ...(isBackground === true ? { isBackground } : {}) };
|
|
59
|
+
if (isBackground === true)
|
|
60
|
+
keep({ id: data.id, title, project: session.data.project, cwd: session.data.cwd, model: model ?? session.data.model, startedAt: data.openedAt, lastAt: data.openedAt, isRunning: true, ...owner });
|
|
61
|
+
record(session, session.conversation.startTask(data));
|
|
62
|
+
return data;
|
|
63
|
+
};
|
|
55
64
|
for (const each of given) {
|
|
56
65
|
const session = keep({ title: '', project: project(), cwd: project(), model: 'test-model', startedAt: now(), lastAt: '', isRunning: false, ...each });
|
|
57
66
|
for (const draft of each.messages ?? [])
|
|
@@ -66,10 +75,12 @@ export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
|
66
75
|
return session;
|
|
67
76
|
};
|
|
68
77
|
const currentSession = () => sessionOf(current);
|
|
78
|
+
const colorOf = ({ data: { id, color } }) => ({ session: id, ...(color === undefined ? {} : { color }) });
|
|
69
79
|
const place = () => {
|
|
70
80
|
const { session, context, contextOpenedAt, turn, tasks, taskTurns, openCalls } = currentSession().conversation.state;
|
|
71
81
|
return { session, context, contextOpenedAt, ...(turn === undefined ? {} : { turn }), tasks, taskTurns, ...(openCalls === undefined ? {} : { openCalls }) };
|
|
72
82
|
};
|
|
83
|
+
const wantsBefore = (mod, event) => [current, everySession].some((target) => (watches.get(mod)?.get(target) ?? []).includes(event));
|
|
73
84
|
const taskOf = (session, id) => {
|
|
74
85
|
const task = session.tasks.get(id);
|
|
75
86
|
if (task === undefined)
|
|
@@ -128,7 +139,11 @@ export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
|
128
139
|
const task = taskOf(session, request['task']);
|
|
129
140
|
return [{ number: session.conversation.state.tasks[task.id]?.context ?? 1, openedAt: task.openedAt, ...(task.closedAt === undefined ? {} : { closedAt: task.closedAt }) }];
|
|
130
141
|
},
|
|
131
|
-
[conversationMethods.tasks]
|
|
142
|
+
async [conversationMethods.tasks](request) {
|
|
143
|
+
const session = String(request['session']);
|
|
144
|
+
const tasks = [...sessionOf(session).tasks.values()].filter((task) => request['all'] === true || task.parent === request['task']);
|
|
145
|
+
return session === current ? tasksWithAgents(tasks, await listAgents()) : tasks;
|
|
146
|
+
},
|
|
132
147
|
[conversationMethods.goal](request) {
|
|
133
148
|
const session = sessionOf(String(request['session']));
|
|
134
149
|
const task = request['task'];
|
|
@@ -154,7 +169,7 @@ export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
|
154
169
|
watches.set(caller, targets);
|
|
155
170
|
return null;
|
|
156
171
|
},
|
|
157
|
-
async [conversationMethods.act](request) {
|
|
172
|
+
async [conversationMethods.act](request, caller) {
|
|
158
173
|
const session = sessionOf(String(request['session']));
|
|
159
174
|
const action = String(request['action']);
|
|
160
175
|
const input = isObject(request['input']) ? request['input'] : {};
|
|
@@ -176,11 +191,28 @@ export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
|
176
191
|
sent.push({ session: session.data.id, ...(task === undefined ? {} : { task }), type: String(input['type']), text: String(input['text']), ...(typeof input['as'] === 'string' ? { as: input['as'] } : {}) });
|
|
177
192
|
return null;
|
|
178
193
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
194
|
+
const text = (key) => (typeof input[key] === 'string' ? input[key] : undefined);
|
|
195
|
+
const title = text('title') ?? '';
|
|
196
|
+
if (action === 'startTask' || action === 'fork' || action === 'startBackgroundTask' || action === 'clone') {
|
|
197
|
+
if (title.trim() === '')
|
|
198
|
+
throw new Error('a task needs a title.');
|
|
199
|
+
const isClone = action === 'clone';
|
|
200
|
+
const isBackground = isClone || action === 'startBackgroundTask';
|
|
201
|
+
const forkedFrom = isClone || action === 'fork' ? session.data.id : undefined;
|
|
202
|
+
const agentType = forkedFrom === undefined ? text('agentType') : undefined;
|
|
203
|
+
const model = forkedFrom === undefined ? text('model') : undefined;
|
|
204
|
+
const fresh = { ...(agentType === undefined ? {} : { agentType }), ...(model === undefined ? {} : { model }), ...(forkedFrom === undefined ? {} : { forkedFrom }) };
|
|
205
|
+
if (!isBackground)
|
|
206
|
+
return openTask(session, { title, ...fresh });
|
|
207
|
+
if (input['name'] !== undefined)
|
|
208
|
+
throw new Error('a background task takes no name.');
|
|
209
|
+
const asked = { id: '', title, ...fresh, openedBy: '', openedAt: now(), isBackground: true };
|
|
210
|
+
const answer = wantsBefore(caller, TaskStart) ? await decide(TaskStart, { type: TaskStart, task: { ...asked, context: session.conversation.state.context } }) : undefined;
|
|
211
|
+
if (answer?.refuse !== undefined)
|
|
212
|
+
throw new Error(`a beforeTaskStart listener refused the task: ${answer.refuse}`);
|
|
213
|
+
const owner = forkedFrom === undefined ? (answer?.owner ?? {}) : {};
|
|
214
|
+
const chosen = { ...(owner.agentType === undefined ? {} : { agentType: owner.agentType }), ...(owner.model === undefined ? {} : { model: owner.model }) };
|
|
215
|
+
return openTask(session, { ...fresh, ...chosen, title: answer?.title ?? title, isBackground: true });
|
|
184
216
|
}
|
|
185
217
|
if (session.data.id === current)
|
|
186
218
|
return resultOf(place(), { name: String(input['name']), input: input['input'], cwd: project() }, await callTool({ ...input['input'], tool: String(input['name']) }));
|
|
@@ -206,7 +238,10 @@ export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
|
206
238
|
return { deny: messageOf(error) };
|
|
207
239
|
}
|
|
208
240
|
},
|
|
209
|
-
add
|
|
241
|
+
add(draft, task) {
|
|
242
|
+
const session = currentSession();
|
|
243
|
+
return task !== undefined && session.tasks.get(task)?.isBackground === true ? add(sessionOf(task), draft) : add(session, draft, task);
|
|
244
|
+
},
|
|
210
245
|
draft(draft, task) {
|
|
211
246
|
const where = place();
|
|
212
247
|
const [unplaced] = messagesOf(rowOf(draft, `message-${(ids += 1)}`, now(), cwd()), task !== undefined);
|
|
@@ -217,21 +252,23 @@ export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
|
217
252
|
return { ...unplaced, ...call, session: where.session, context: task === undefined ? where.context : (where.tasks[task]?.context ?? where.context), ...(turn === undefined ? {} : { turn: turn.prompt.id }), ...(task === undefined ? {} : { task }) };
|
|
218
253
|
},
|
|
219
254
|
place,
|
|
220
|
-
wants:
|
|
221
|
-
endTurn(ending = {}) {
|
|
255
|
+
wants: wantsBefore,
|
|
256
|
+
endTurn(ending = {}, task) {
|
|
222
257
|
const session = currentSession();
|
|
223
|
-
|
|
258
|
+
const background = task === undefined ? undefined : session.tasks.get(task);
|
|
259
|
+
if (background?.isBackground !== true) {
|
|
260
|
+
record(session, session.conversation.endTurn(now(), { reason: 'answer', ...ending }, task));
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const owner = sessionOf(background.id);
|
|
264
|
+
record(owner, owner.conversation.endTurn(now(), { reason: 'answer', ...ending }));
|
|
265
|
+
record(session, session.conversation.endTask(background, now()));
|
|
224
266
|
},
|
|
225
267
|
compact() {
|
|
226
268
|
const session = currentSession();
|
|
227
269
|
record(session, session.conversation.add({ id: `compact-${(ids += 1)}`, at: now(), type: 'system', name: 'compact_boundary', isMeta: false, isSummary: false, content: [] }));
|
|
228
270
|
},
|
|
229
|
-
startTask(
|
|
230
|
-
const session = currentSession();
|
|
231
|
-
const id = `task-${(ids += 1)}`;
|
|
232
|
-
record(session, session.conversation.startTask({ id, title, agentType, openedBy, openedAt: now(), ...(model === undefined ? {} : { model }), ...(parent === undefined ? {} : { parent }) }));
|
|
233
|
-
return id;
|
|
234
|
-
},
|
|
271
|
+
startTask: (task) => openTask(currentSession(), task).id,
|
|
235
272
|
start(id) {
|
|
236
273
|
current = id;
|
|
237
274
|
const session = kept.get(id) ?? keep({ id, title: '', project: project(), cwd: project(), model: 'test-model', startedAt: now(), lastAt: now(), isRunning: true });
|
|
@@ -239,6 +276,13 @@ export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
|
239
276
|
if (session.conversation.state.context === 0)
|
|
240
277
|
record(session, session.conversation.startContext(now()));
|
|
241
278
|
},
|
|
279
|
+
color: () => colorOf(currentSession()),
|
|
280
|
+
recolor(color) {
|
|
281
|
+
const session = currentSession();
|
|
282
|
+
const { color: _color, ...data } = session.data;
|
|
283
|
+
session.data = color === undefined ? data : { ...data, color };
|
|
284
|
+
return colorOf(session);
|
|
285
|
+
},
|
|
242
286
|
lastTurn: () => [...currentSession().turns.values()].filter((turn) => turn.prompt.task === undefined).at(-1),
|
|
243
287
|
sent,
|
|
244
288
|
};
|
|
@@ -261,5 +305,7 @@ function rowOf(draft, id, at, cwd) {
|
|
|
261
305
|
return { ...base, type: 'user', isMeta: true, content: text(`${skillPrefix} /skills/${draft.name}\n\n${draft.text}`) };
|
|
262
306
|
if (draft.type === InstructionFile)
|
|
263
307
|
return { ...base, type: 'attachment', name: 'nested_memory', content: text(draft.text), path: draft.path };
|
|
308
|
+
if (draft.type === AttachedFile)
|
|
309
|
+
return { ...base, type: 'attachment', name: attachmentNameOf(draft.attachmentType), content: text(draft.text), path: draft.path };
|
|
264
310
|
return { ...base, type: 'system', name: 'informational', content: text(draft.text) };
|
|
265
311
|
}
|
package/testing.d.ts
CHANGED
|
@@ -7,11 +7,11 @@ import { Message } from './session/context/turn/message/message.js';
|
|
|
7
7
|
import { type Turn } from './session/context/turn/turn.js';
|
|
8
8
|
import { sessionEvents, type AnswerOf, type BeforeName, type CommandRun, type CommandRunAnswer, type Placement, type ProcessAnswer, type ProcessAsked, type ProcessName, type ProcessPayload } from './session/session.js';
|
|
9
9
|
import { type Fakes, type Shown as ShownByClaude, type TestCall } from './testing/fake-claude.js';
|
|
10
|
-
import { type FakeSession, type FakeSessions, type MessageDraft } from './testing/fake-sessions.js';
|
|
11
|
-
import { type
|
|
10
|
+
import { type FakeSession, type FakeSessions, type MessageDraft, type StartedTask } from './testing/fake-sessions.js';
|
|
11
|
+
import { type KindProps, type Row } from './ui/styles.js';
|
|
12
12
|
import { type Area } from './ui/areas.js';
|
|
13
13
|
export type { Fakes, TestCall } from './testing/fake-claude.js';
|
|
14
|
-
export type { FakeSession, MessageDraft } from './testing/fake-sessions.js';
|
|
14
|
+
export type { FakeSession, MessageDraft, StartedTask } from './testing/fake-sessions.js';
|
|
15
15
|
export type { RoutedEvent } from './runtime/hooks.js';
|
|
16
16
|
export type { ShownToast } from './runtime/toaster.js';
|
|
17
17
|
export type ShownPart = {
|
|
@@ -85,23 +85,19 @@ export type TestedMod<State extends object> = {
|
|
|
85
85
|
add(message: MessageDraft, options?: {
|
|
86
86
|
readonly task?: string;
|
|
87
87
|
}): Promise<Message[]>;
|
|
88
|
-
endTurn(ending?: Pick<Turn, 'answer' | 'failure'
|
|
88
|
+
endTurn(ending?: Pick<Turn, 'answer' | 'failure'>, options?: {
|
|
89
|
+
readonly task?: string;
|
|
90
|
+
}): Promise<void>;
|
|
89
91
|
compact(): Promise<void>;
|
|
90
92
|
startSession(start: {
|
|
91
93
|
readonly source: 'startup' | 'resume' | 'clear' | 'fork';
|
|
92
94
|
readonly id?: string;
|
|
93
95
|
}): Promise<void>;
|
|
94
|
-
startTask(task:
|
|
95
|
-
readonly title: string;
|
|
96
|
-
readonly agentType?: string;
|
|
97
|
-
readonly model?: string;
|
|
98
|
-
readonly openedBy?: string;
|
|
99
|
-
readonly parent?: string;
|
|
100
|
-
}): Promise<string>;
|
|
96
|
+
startTask(task: StartedTask): Promise<string>;
|
|
101
97
|
lines(area: Area, props?: {
|
|
102
98
|
readonly columns?: number;
|
|
103
99
|
}): Promise<string[]>;
|
|
104
|
-
lines<K extends Row>(kind: K, props:
|
|
100
|
+
lines<K extends Row>(kind: K, props: KindProps<K>, requestId?: string): Promise<string[]>;
|
|
105
101
|
type(line: string): Promise<CommandReply>;
|
|
106
102
|
hotkey(name: string): Promise<void>;
|
|
107
103
|
callTool(name: string, input: Record<string, unknown>): Promise<EventResult<'tool.call'>>;
|
package/testing.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EAEJ,gBAAgB,
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["src/testing.ts"],"names":[],"mappings":"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"}
|