@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/src/ui/markdown.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Nodes, RootContent } from 'mdast'
|
|
2
2
|
import { fromMarkdown, gfm, gfmFromMarkdown, toString } from '../vendor-markdown.js'
|
|
3
|
-
import type {
|
|
3
|
+
import type { KindProps } from './styles.js'
|
|
4
4
|
|
|
5
5
|
type BlockText = { readonly text: string; readonly source: string }
|
|
6
6
|
|
|
@@ -163,7 +163,7 @@ function plainText(node: Nodes): string {
|
|
|
163
163
|
return node.children.map(plainText).join(node.type === 'tableRow' ? '\t' : '\n')
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
-
export function markdownBlocks<K extends Block>(text: string, kind: K):
|
|
166
|
+
export function markdownBlocks<K extends Block>(text: string, kind: K): KindProps<K>[] {
|
|
167
167
|
const blocks = parsed(text, 0).filter((block) => block.type === kind.markdown)
|
|
168
|
-
return blocks.map((block) => block.props) as unknown as
|
|
168
|
+
return blocks.map((block) => block.props) as unknown as KindProps<K>[]
|
|
169
169
|
}
|
package/src/ui/panes.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Frozen, PaneCloseInput, RenderElement, RenderPropsOf, UiScrollInput } from 'claude-code'
|
|
2
|
-
import type { Mod } from '../mod.js'
|
|
2
|
+
import type { Mod, Surface } from '../mod.js'
|
|
3
3
|
|
|
4
4
|
export type ScrollTarget = 'start' | 'end' | { readonly key: string }
|
|
5
5
|
|
|
@@ -7,7 +7,7 @@ export type ScrollOptions = { readonly block?: 'start' | 'center' | 'end' | 'nea
|
|
|
7
7
|
|
|
8
8
|
export type OpenOptions<Params> = { readonly focus?: true } & (undefined extends Params ? { readonly params?: Params } : { readonly params: Params })
|
|
9
9
|
|
|
10
|
-
export type PaneProps<Params> = Frozen<RenderPropsOf['Pane']> & { readonly params: Params }
|
|
10
|
+
export type PaneProps<Params> = Frozen<RenderPropsOf['Pane']> & { readonly surface: Surface; readonly params: Params }
|
|
11
11
|
|
|
12
12
|
export type PaneInit<State extends object = Record<never, never>, Params = undefined> = {
|
|
13
13
|
readonly id: string
|
package/src/ui/styles.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Frozen, RenderComponent, RenderElement, RenderPropsOf } from 'claude-code'
|
|
2
|
-
import type { Mod } from '../mod.js'
|
|
2
|
+
import type { Mod, Surface } from '../mod.js'
|
|
3
3
|
import { TurnEnd, Working } from './areas.js'
|
|
4
4
|
import type { Block, BlockProps } from './markdown.js'
|
|
5
5
|
|
|
@@ -32,7 +32,11 @@ type PropsOf<K extends Kind> = K extends Row ? RowProps[K] : K extends Block<inf
|
|
|
32
32
|
|
|
33
33
|
type DefaultOf<K extends Kind> = K extends Row ? Partial<Omit<RowProps[K], 'onScreen'>> : { readonly source?: string }
|
|
34
34
|
|
|
35
|
-
export type StyleProps<K extends Kind> = Frozen<PropsOf<K>> & { readonly Default: (props: Frozen<DefaultOf<K>>) => RenderElement }
|
|
35
|
+
export type StyleProps<K extends Kind> = Frozen<PropsOf<K>> & StyledAt & (K extends Row ? { readonly id: string } : { readonly id?: string }) & { readonly Default: (props: Frozen<DefaultOf<K>>) => RenderElement }
|
|
36
|
+
|
|
37
|
+
export type KindProps<K extends Kind> = Omit<StyleProps<K>, 'Default' | 'surface' | 'columns' | 'id'>
|
|
38
|
+
|
|
39
|
+
export type StyledAt = { readonly surface: Surface; readonly columns: number }
|
|
36
40
|
|
|
37
41
|
export type StyleInit<K extends Kind, State extends object = Record<never, never>> = {
|
|
38
42
|
readonly kind: K
|
package/testing/fake-claude.d.ts
CHANGED
|
@@ -40,6 +40,8 @@ export type Fakes = {
|
|
|
40
40
|
messages?: Claude['session']['messages'];
|
|
41
41
|
append?: Claude['session']['append'];
|
|
42
42
|
send?: Claude['session']['send'];
|
|
43
|
+
surfaces?: Claude['session']['surfaces'];
|
|
44
|
+
usage?: Claude['session']['usage'];
|
|
43
45
|
};
|
|
44
46
|
prompt: {
|
|
45
47
|
submit?: Claude['prompt']['submit'];
|
|
@@ -85,6 +87,7 @@ export type FakeClaude = {
|
|
|
85
87
|
readonly shown: Shown;
|
|
86
88
|
readonly store: Map<string, unknown>;
|
|
87
89
|
settle(): Promise<void>;
|
|
90
|
+
placePane(id: string): void;
|
|
88
91
|
};
|
|
89
92
|
export declare function calledAnswer(caller: string, answer: EventResult<'cmod.call'>): unknown;
|
|
90
93
|
export declare function fakeClaude(plugin: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fake-claude.d.ts","sourceRoot":"","sources":["../src/testing/fake-claude.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAS,MAAM,aAAa,CAAA;AAErD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAOlD,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;CAClC,CAAA;AAED,MAAM,MAAM,KAAK,GAAG;IAClB,OAAO,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;IAC/E,EAAE,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAA;KAAE,CAAA;IAC7J,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;IACzC,QAAQ,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAA;KAAE,CAAA;IAC/C,MAAM,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAA;KAAE,CAAA;IAC3C,OAAO,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAA;KAAE,CAAA;IAC7E,EAAE,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;IAC3J,OAAO,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAA;KAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"fake-claude.d.ts","sourceRoot":"","sources":["../src/testing/fake-claude.ts"],"names":[],"mappings":"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"}
|
package/testing/fake-claude.js
CHANGED
|
@@ -31,6 +31,15 @@ export function fakeClaude(plugin) {
|
|
|
31
31
|
const run = faked(call, answer);
|
|
32
32
|
return async (...args) => run(...args);
|
|
33
33
|
};
|
|
34
|
+
const cmodCall = rejected('cmod.call', () => fakes.cmod.call ?? cmodTakesParts);
|
|
35
|
+
const clonedAsClaudeCodeDoes = (args) => {
|
|
36
|
+
try {
|
|
37
|
+
return structuredClone(args);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
throw new Error(`interface.call: arguments are not plain data: ${error instanceof Error ? error.message : String(error)}`);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
34
43
|
const cmodTakesParts = async (input) => {
|
|
35
44
|
if (input.to === cmodPluginName && input.method === partMethods.changed)
|
|
36
45
|
return null;
|
|
@@ -70,7 +79,7 @@ export function fakeClaude(plugin) {
|
|
|
70
79
|
lines.push(text);
|
|
71
80
|
},
|
|
72
81
|
notice: () => undefined,
|
|
73
|
-
invalidate: () =>
|
|
82
|
+
invalidate: (event) => void calls.push({ call: 'ui.invalidate', args: [event] }),
|
|
74
83
|
ask: rejected('ui.ask', () => fakes.ui.ask),
|
|
75
84
|
open: async (pane) => {
|
|
76
85
|
calls.push({ call: 'ui.open', args: [pane] });
|
|
@@ -143,8 +152,8 @@ export function fakeClaude(plugin) {
|
|
|
143
152
|
root: async () => plugin.root,
|
|
144
153
|
cwd: async () => plugin.root,
|
|
145
154
|
model: async () => 'test-model',
|
|
146
|
-
usage:
|
|
147
|
-
surfaces:
|
|
155
|
+
usage: () => fakes.session.usage?.() ?? Promise.resolve({ startedAt: Date.parse('2026-01-01T00:00:00.000Z'), context: { window: 200000 }, rateLimits: [], cost: { usd: 0 } }),
|
|
156
|
+
surfaces: () => fakes.session.surfaces?.() ?? Promise.resolve(['terminal']),
|
|
148
157
|
messages: rejected('session.messages', () => fakes.session.messages),
|
|
149
158
|
append: rejected('session.append', () => fakes.session.append ?? appendNote),
|
|
150
159
|
send: rejected('session.send', () => fakes.session.send ?? (async () => ({ isDelivered: true }))),
|
|
@@ -172,7 +181,7 @@ export function fakeClaude(plugin) {
|
|
|
172
181
|
dataHome: async () => undefined,
|
|
173
182
|
configHome: async () => undefined,
|
|
174
183
|
},
|
|
175
|
-
cmod: { call:
|
|
184
|
+
cmod: { call: async (args) => cmodCall(clonedAsClaudeCodeDoes(args)) },
|
|
176
185
|
};
|
|
177
186
|
const settle = async () => {
|
|
178
187
|
let seen;
|
|
@@ -181,7 +190,11 @@ export function fakeClaude(plugin) {
|
|
|
181
190
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
182
191
|
} while (calls.length !== seen);
|
|
183
192
|
};
|
|
184
|
-
|
|
193
|
+
const placePane = (id) => {
|
|
194
|
+
if (unplacedPanes.delete(id))
|
|
195
|
+
shown.openPanes.add(id);
|
|
196
|
+
};
|
|
197
|
+
return { claude, calls, fakes, shown, store, settle, placePane };
|
|
185
198
|
}
|
|
186
199
|
function realTimer(ms, fn) {
|
|
187
200
|
const timeout = setTimeout(fn, ms);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fake-elements.d.ts","sourceRoot":"","sources":["../src/testing/fake-elements.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAiB,UAAU,EAAE,MAAM,aAAa,CAAA;AAE1E,KAAK,KAAK,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,UAAU,EAAE,CAAA;CAAE,CAAA;AAiB1H,eAAO,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"fake-elements.d.ts","sourceRoot":"","sources":["../src/testing/fake-elements.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAiB,UAAU,EAAE,MAAM,aAAa,CAAA;AAE1E,KAAK,KAAK,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,UAAU,EAAE,CAAA;CAAE,CAAA;AAiB1H,eAAO,MAAM,QAAQ,EAAE,YAatB,CAAA;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,SAAS,CASnG;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAOhE;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAiB/C"}
|
package/testing/fake-elements.js
CHANGED
|
@@ -22,6 +22,9 @@ export const elements = {
|
|
|
22
22
|
Input: element('Input'),
|
|
23
23
|
Select: element('Select'),
|
|
24
24
|
Image: element('Image'),
|
|
25
|
+
Svg: element('Svg'),
|
|
26
|
+
Raster: element('Raster'),
|
|
27
|
+
Client: element('Client'),
|
|
25
28
|
};
|
|
26
29
|
export function findElement(node, type, key) {
|
|
27
30
|
if (typeof node === 'string')
|
|
@@ -37,12 +40,14 @@ export function findElement(node, type, key) {
|
|
|
37
40
|
return undefined;
|
|
38
41
|
}
|
|
39
42
|
export function rowsOf(node, width) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
const drawn = typeof node === 'string' ? undefined : insideOf(node);
|
|
44
|
+
if (drawn?.type === 'Box')
|
|
45
|
+
return boxRows(drawn, width);
|
|
46
|
+
if (drawn?.type === 'Svg')
|
|
47
|
+
return [];
|
|
43
48
|
return textOf(node)
|
|
44
49
|
.split('\n')
|
|
45
|
-
.flatMap((line) => fitted(line, width, wrap));
|
|
50
|
+
.flatMap((line) => fitted(line, width, drawn?.props['wrap']));
|
|
46
51
|
}
|
|
47
52
|
export function textOf(node) {
|
|
48
53
|
if (typeof node === 'string')
|
|
@@ -94,11 +99,45 @@ function boxRows({ props, children = [] }, width) {
|
|
|
94
99
|
const size = (key) => (typeof props[key] === 'number' ? props[key] : undefined);
|
|
95
100
|
const space = (side, axis) => (size(`padding${side}`) ?? size(`padding${axis}`) ?? size('padding') ?? 0) + (size(`margin${side}`) ?? size(`margin${axis}`) ?? size('margin') ?? 0);
|
|
96
101
|
const left = space('Left', 'X');
|
|
102
|
+
const right = space('Right', 'X');
|
|
103
|
+
const border = typeof props['borderStyle'] === 'string' ? 1 : 0;
|
|
97
104
|
const direction = String(props['flexDirection'] ?? 'row');
|
|
98
|
-
const
|
|
99
|
-
const
|
|
105
|
+
const flowing = children.filter((child) => !isPlaced(child));
|
|
106
|
+
const ordered = direction.endsWith('-reverse') ? [...flowing].reverse() : flowing;
|
|
107
|
+
const outer = Math.min(width, size('width') ?? width);
|
|
108
|
+
const inner = outer - left - right - border * 2;
|
|
100
109
|
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
|
-
|
|
110
|
+
const content = border === 1 && Number.isFinite(inner) ? inner : right === 0 && border === 0 ? 0 : Math.max(widthOf(rows), (size('minWidth') ?? 0) - left - right - border * 2);
|
|
111
|
+
const padded = [...blankRows(space('Top', 'Y')), ...rows.map((row) => `${' '.repeat(left)}${paddedTo(row, content)}${' '.repeat(right)}`), ...blankRows(space('Bottom', 'Y'))];
|
|
112
|
+
const framed = border === 0 ? padded : framedRows(padded, left + content + right, props['borderStyle']);
|
|
113
|
+
return placedOver(framed.map((row) => paddedTo(row, size('minWidth') ?? 0)), children.filter(isPlaced), outer);
|
|
114
|
+
}
|
|
115
|
+
function isPlaced(node) {
|
|
116
|
+
if (typeof node === 'string')
|
|
117
|
+
return false;
|
|
118
|
+
const { props } = insideOf(node);
|
|
119
|
+
return props['position'] === 'absolute' && typeof props['top'] === 'number';
|
|
120
|
+
}
|
|
121
|
+
function framedRows(rows, columns, style) {
|
|
122
|
+
const [topLeft, topRight, bottomLeft, bottomRight] = style === 'round' ? ['╭', '╮', '╰', '╯'] : ['┌', '┐', '└', '┘'];
|
|
123
|
+
return [`${topLeft}${'─'.repeat(columns)}${topRight}`, ...rows.map((row) => `│${paddedTo(row, columns)}│`), `${bottomLeft}${'─'.repeat(columns)}${bottomRight}`];
|
|
124
|
+
}
|
|
125
|
+
function placedOver(rows, placed, width) {
|
|
126
|
+
const drawn = [...rows];
|
|
127
|
+
for (const node of placed) {
|
|
128
|
+
const { props } = insideOf(node);
|
|
129
|
+
const top = Number(props['top']);
|
|
130
|
+
const left = typeof props['left'] === 'number' ? props['left'] : 0;
|
|
131
|
+
rowsOf(node, width - left).forEach((line, index) => {
|
|
132
|
+
const row = top + index;
|
|
133
|
+
if (row < 0 || row >= drawn.length)
|
|
134
|
+
return;
|
|
135
|
+
const cells = [...paddedTo(drawn[row] ?? '', left)];
|
|
136
|
+
cells.splice(left, [...line].length, ...line);
|
|
137
|
+
drawn[row] = cells.join('');
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return drawn;
|
|
102
141
|
}
|
|
103
142
|
function stacked(children, width, gap) {
|
|
104
143
|
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,7 +10,7 @@ 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';
|
|
14
15
|
export type MessageDraft = {
|
|
15
16
|
readonly type: typeof Prompt;
|
|
@@ -40,6 +41,11 @@ export type MessageDraft = {
|
|
|
40
41
|
readonly type: typeof InstructionFile;
|
|
41
42
|
readonly path: string;
|
|
42
43
|
readonly text: string;
|
|
44
|
+
} | {
|
|
45
|
+
readonly type: typeof AttachedFile;
|
|
46
|
+
readonly path: string;
|
|
47
|
+
readonly attachmentType: AttachmentType;
|
|
48
|
+
readonly text: string;
|
|
43
49
|
} | {
|
|
44
50
|
readonly type: typeof Notice;
|
|
45
51
|
readonly text: string;
|
|
@@ -49,21 +55,24 @@ export type FakeSession = Partial<Omit<SessionData, 'id'>> & {
|
|
|
49
55
|
readonly messages?: readonly MessageDraft[];
|
|
50
56
|
readonly goal?: string;
|
|
51
57
|
};
|
|
58
|
+
export type StartedTask = {
|
|
59
|
+
readonly title: string;
|
|
60
|
+
readonly agentType?: string;
|
|
61
|
+
readonly model?: string;
|
|
62
|
+
readonly openedBy?: string;
|
|
63
|
+
readonly parent?: string;
|
|
64
|
+
readonly isBackground?: true;
|
|
65
|
+
readonly forkedFrom?: string;
|
|
66
|
+
};
|
|
52
67
|
export type FakeSessions = {
|
|
53
68
|
answer(caller: string, method: string, input: unknown): unknown;
|
|
54
69
|
add(draft: MessageDraft, task?: string): Message[];
|
|
55
70
|
draft(draft: MessageDraft, task?: string): Message;
|
|
56
71
|
place(): Place;
|
|
57
72
|
wants(mod: string, event: string): boolean;
|
|
58
|
-
endTurn(ending?: TurnEnding): void;
|
|
73
|
+
endTurn(ending?: TurnEnding, task?: string): void;
|
|
59
74
|
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;
|
|
75
|
+
startTask(task: StartedTask): string;
|
|
67
76
|
start(id: string): void;
|
|
68
77
|
lastTurn(): TurnData | undefined;
|
|
69
78
|
readonly sent: {
|
|
@@ -74,11 +83,13 @@ export type FakeSessions = {
|
|
|
74
83
|
readonly as?: string;
|
|
75
84
|
}[];
|
|
76
85
|
};
|
|
77
|
-
export declare function fakeSessions({ project, cwd, given, push, callTool }: {
|
|
86
|
+
export declare function fakeSessions({ project, cwd, given, push, callTool, listAgents, decide }: {
|
|
78
87
|
readonly project: () => string;
|
|
79
88
|
readonly cwd: () => string;
|
|
80
89
|
readonly given: readonly FakeSession[];
|
|
81
90
|
readonly push: (mod: string, session: string, change: SessionChange) => void;
|
|
82
91
|
readonly callTool: Claude['tool']['call'];
|
|
92
|
+
readonly listAgents: Claude['agent']['list'];
|
|
93
|
+
readonly decide: Decide;
|
|
83
94
|
}): FakeSessions;
|
|
84
95
|
//# 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 ?? [])
|
|
@@ -70,6 +79,7 @@ export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
|
70
79
|
const { session, context, contextOpenedAt, turn, tasks, taskTurns, openCalls } = currentSession().conversation.state;
|
|
71
80
|
return { session, context, contextOpenedAt, ...(turn === undefined ? {} : { turn }), tasks, taskTurns, ...(openCalls === undefined ? {} : { openCalls }) };
|
|
72
81
|
};
|
|
82
|
+
const wantsBefore = (mod, event) => [current, everySession].some((target) => (watches.get(mod)?.get(target) ?? []).includes(event));
|
|
73
83
|
const taskOf = (session, id) => {
|
|
74
84
|
const task = session.tasks.get(id);
|
|
75
85
|
if (task === undefined)
|
|
@@ -128,7 +138,11 @@ export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
|
128
138
|
const task = taskOf(session, request['task']);
|
|
129
139
|
return [{ number: session.conversation.state.tasks[task.id]?.context ?? 1, openedAt: task.openedAt, ...(task.closedAt === undefined ? {} : { closedAt: task.closedAt }) }];
|
|
130
140
|
},
|
|
131
|
-
[conversationMethods.tasks]
|
|
141
|
+
async [conversationMethods.tasks](request) {
|
|
142
|
+
const session = String(request['session']);
|
|
143
|
+
const tasks = [...sessionOf(session).tasks.values()].filter((task) => request['all'] === true || task.parent === request['task']);
|
|
144
|
+
return session === current ? tasksWithAgents(tasks, await listAgents()) : tasks;
|
|
145
|
+
},
|
|
132
146
|
[conversationMethods.goal](request) {
|
|
133
147
|
const session = sessionOf(String(request['session']));
|
|
134
148
|
const task = request['task'];
|
|
@@ -154,7 +168,7 @@ export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
|
154
168
|
watches.set(caller, targets);
|
|
155
169
|
return null;
|
|
156
170
|
},
|
|
157
|
-
async [conversationMethods.act](request) {
|
|
171
|
+
async [conversationMethods.act](request, caller) {
|
|
158
172
|
const session = sessionOf(String(request['session']));
|
|
159
173
|
const action = String(request['action']);
|
|
160
174
|
const input = isObject(request['input']) ? request['input'] : {};
|
|
@@ -176,11 +190,28 @@ export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
|
176
190
|
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
191
|
return null;
|
|
178
192
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
193
|
+
const text = (key) => (typeof input[key] === 'string' ? input[key] : undefined);
|
|
194
|
+
const title = text('title') ?? '';
|
|
195
|
+
if (action === 'startTask' || action === 'fork' || action === 'startBackgroundTask' || action === 'clone') {
|
|
196
|
+
if (title.trim() === '')
|
|
197
|
+
throw new Error('a task needs a title.');
|
|
198
|
+
const isClone = action === 'clone';
|
|
199
|
+
const isBackground = isClone || action === 'startBackgroundTask';
|
|
200
|
+
const forkedFrom = isClone || action === 'fork' ? session.data.id : undefined;
|
|
201
|
+
const agentType = forkedFrom === undefined ? text('agentType') : undefined;
|
|
202
|
+
const model = forkedFrom === undefined ? text('model') : undefined;
|
|
203
|
+
const fresh = { ...(agentType === undefined ? {} : { agentType }), ...(model === undefined ? {} : { model }), ...(forkedFrom === undefined ? {} : { forkedFrom }) };
|
|
204
|
+
if (!isBackground)
|
|
205
|
+
return openTask(session, { title, ...fresh });
|
|
206
|
+
if (input['name'] !== undefined)
|
|
207
|
+
throw new Error('a background task takes no name.');
|
|
208
|
+
const asked = { id: '', title, ...fresh, openedBy: '', openedAt: now(), isBackground: true };
|
|
209
|
+
const answer = wantsBefore(caller, TaskStart) ? await decide(TaskStart, { type: TaskStart, task: { ...asked, context: session.conversation.state.context } }) : undefined;
|
|
210
|
+
if (answer?.refuse !== undefined)
|
|
211
|
+
throw new Error(`a beforeTaskStart listener refused the task: ${answer.refuse}`);
|
|
212
|
+
const owner = forkedFrom === undefined ? (answer?.owner ?? {}) : {};
|
|
213
|
+
const chosen = { ...(owner.agentType === undefined ? {} : { agentType: owner.agentType }), ...(owner.model === undefined ? {} : { model: owner.model }) };
|
|
214
|
+
return openTask(session, { ...fresh, ...chosen, title: answer?.title ?? title, isBackground: true });
|
|
184
215
|
}
|
|
185
216
|
if (session.data.id === current)
|
|
186
217
|
return resultOf(place(), { name: String(input['name']), input: input['input'], cwd: project() }, await callTool({ ...input['input'], tool: String(input['name']) }));
|
|
@@ -206,7 +237,10 @@ export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
|
206
237
|
return { deny: messageOf(error) };
|
|
207
238
|
}
|
|
208
239
|
},
|
|
209
|
-
add
|
|
240
|
+
add(draft, task) {
|
|
241
|
+
const session = currentSession();
|
|
242
|
+
return task !== undefined && session.tasks.get(task)?.isBackground === true ? add(sessionOf(task), draft) : add(session, draft, task);
|
|
243
|
+
},
|
|
210
244
|
draft(draft, task) {
|
|
211
245
|
const where = place();
|
|
212
246
|
const [unplaced] = messagesOf(rowOf(draft, `message-${(ids += 1)}`, now(), cwd()), task !== undefined);
|
|
@@ -217,21 +251,23 @@ export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
|
217
251
|
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
252
|
},
|
|
219
253
|
place,
|
|
220
|
-
wants:
|
|
221
|
-
endTurn(ending = {}) {
|
|
254
|
+
wants: wantsBefore,
|
|
255
|
+
endTurn(ending = {}, task) {
|
|
222
256
|
const session = currentSession();
|
|
223
|
-
|
|
257
|
+
const background = task === undefined ? undefined : session.tasks.get(task);
|
|
258
|
+
if (background?.isBackground !== true) {
|
|
259
|
+
record(session, session.conversation.endTurn(now(), { reason: 'answer', ...ending }, task));
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const owner = sessionOf(background.id);
|
|
263
|
+
record(owner, owner.conversation.endTurn(now(), { reason: 'answer', ...ending }));
|
|
264
|
+
record(session, session.conversation.endTask(background, now()));
|
|
224
265
|
},
|
|
225
266
|
compact() {
|
|
226
267
|
const session = currentSession();
|
|
227
268
|
record(session, session.conversation.add({ id: `compact-${(ids += 1)}`, at: now(), type: 'system', name: 'compact_boundary', isMeta: false, isSummary: false, content: [] }));
|
|
228
269
|
},
|
|
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
|
-
},
|
|
270
|
+
startTask: (task) => openTask(currentSession(), task).id,
|
|
235
271
|
start(id) {
|
|
236
272
|
current = id;
|
|
237
273
|
const session = kept.get(id) ?? keep({ id, title: '', project: project(), cwd: project(), model: 'test-model', startedAt: now(), lastAt: now(), isRunning: true });
|
|
@@ -261,5 +297,7 @@ function rowOf(draft, id, at, cwd) {
|
|
|
261
297
|
return { ...base, type: 'user', isMeta: true, content: text(`${skillPrefix} /skills/${draft.name}\n\n${draft.text}`) };
|
|
262
298
|
if (draft.type === InstructionFile)
|
|
263
299
|
return { ...base, type: 'attachment', name: 'nested_memory', content: text(draft.text), path: draft.path };
|
|
300
|
+
if (draft.type === AttachedFile)
|
|
301
|
+
return { ...base, type: 'attachment', name: attachmentNameOf(draft.attachmentType), content: text(draft.text), path: draft.path };
|
|
264
302
|
return { ...base, type: 'system', name: 'informational', content: text(draft.text) };
|
|
265
303
|
}
|
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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"}
|