@cmodjs/core 1.6.0 → 2.0.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 +7 -7
- package/docs/dependencies.md +1 -1
- package/docs/index.md +12 -11
- package/docs/jobs.md +12 -16
- package/docs/mod.md +111 -36
- package/docs/permissions.md +14 -18
- package/docs/session.md +171 -82
- package/docs/state.md +5 -5
- package/docs/testing.md +57 -41
- package/docs/ui.md +9 -9
- package/jobs/permissions/decide-permission.d.ts.map +1 -1
- package/jobs/permissions/decide-permission.js +1 -1
- package/jobs/prompt.d.ts +1 -3
- package/jobs/prompt.d.ts.map +1 -1
- package/jobs/prompt.js +2 -21
- package/jobs/slash-command.d.ts +1 -1
- package/jobs/slash-command.d.ts.map +1 -1
- package/jobs/slash-command.js +1 -1
- package/jobs/status-line.d.ts +0 -1
- package/jobs/status-line.d.ts.map +1 -1
- package/jobs/status-line.js +3 -4
- package/mod.d.ts +53 -105
- package/mod.d.ts.map +1 -1
- package/mod.js +18 -80
- package/package.json +1 -1
- package/records.d.ts +1 -1
- package/records.js +1 -1
- package/register.d.ts.map +1 -1
- package/register.js +8 -5
- package/runtime/before.d.ts +11 -4
- package/runtime/before.d.ts.map +1 -1
- package/runtime/before.js +131 -67
- package/runtime/claude.d.ts +6 -1
- package/runtime/claude.d.ts.map +1 -1
- package/runtime/conversations.d.ts.map +1 -1
- package/runtime/conversations.js +82 -38
- package/runtime/deadline.d.ts +17 -0
- package/runtime/deadline.d.ts.map +1 -1
- package/runtime/deadline.js +34 -0
- package/runtime/dependencies.d.ts +2 -0
- package/runtime/dependencies.d.ts.map +1 -1
- package/runtime/dependencies.js +12 -0
- package/runtime/grants.d.ts.map +1 -1
- package/runtime/grants.js +13 -8
- package/runtime/hooks.d.ts +15 -11
- package/runtime/hooks.d.ts.map +1 -1
- package/runtime/hooks.js +8 -165
- package/runtime/lifecycle.d.ts +4 -2
- package/runtime/lifecycle.d.ts.map +1 -1
- package/runtime/lifecycle.js +96 -62
- package/runtime/permission-check.d.ts +15 -0
- package/runtime/permission-check.d.ts.map +1 -0
- package/runtime/permission-check.js +37 -0
- package/runtime/sessions.d.ts +35 -5
- package/runtime/sessions.d.ts.map +1 -1
- package/runtime/sessions.js +304 -82
- package/runtime/state.d.ts.map +1 -1
- package/runtime/state.js +14 -11
- package/runtime/tool-calls.d.ts +0 -1
- package/runtime/tool-calls.d.ts.map +1 -1
- package/runtime/tool-calls.js +0 -19
- package/session/context/turn/message/instruction-file.d.ts +9 -0
- package/session/context/turn/message/instruction-file.d.ts.map +1 -0
- package/session/context/turn/message/instruction-file.js +4 -0
- package/session/context/turn/message/message.d.ts +6 -4
- package/session/context/turn/message/message.d.ts.map +1 -1
- package/session/context/turn/message/message.js +12 -8
- package/session/context/turn/message/sender.d.ts +2 -1
- package/session/context/turn/message/sender.d.ts.map +1 -1
- package/session/context/turn/message/sender.js +4 -1
- package/session/context/turn/message/tool-call.d.ts +5 -0
- package/session/context/turn/message/tool-call.d.ts.map +1 -1
- package/session/context/turn/message/tool-result.d.ts +6 -1
- package/session/context/turn/message/tool-result.d.ts.map +1 -1
- package/session/context/turn/turn.d.ts +7 -0
- package/session/context/turn/turn.d.ts.map +1 -1
- package/session/conversation.d.ts +10 -3
- package/session/conversation.d.ts.map +1 -1
- package/session/conversation.js +14 -5
- package/session/goal/goal.d.ts +1 -1
- package/session/goal/goal.d.ts.map +1 -1
- package/session/goal/task.d.ts +2 -2
- package/session/goal/task.d.ts.map +1 -1
- package/session/session.d.ts +361 -26
- package/session/session.d.ts.map +1 -1
- package/session/session.js +40 -0
- package/src/jobs/permissions/decide-permission.ts +2 -1
- package/src/jobs/prompt.ts +3 -20
- package/src/jobs/slash-command.ts +2 -2
- package/src/jobs/status-line.ts +4 -7
- package/src/mod.ts +52 -147
- package/src/records.ts +1 -1
- package/src/register.ts +8 -5
- package/src/runtime/before.ts +140 -66
- package/src/runtime/claude.ts +5 -1
- package/src/runtime/conversations.ts +75 -37
- package/src/runtime/deadline.ts +38 -0
- package/src/runtime/dependencies.ts +12 -0
- package/src/runtime/grants.ts +11 -7
- package/src/runtime/hooks.ts +24 -163
- package/src/runtime/lifecycle.ts +110 -77
- package/src/runtime/permission-check.ts +47 -0
- package/src/runtime/sessions.ts +334 -91
- package/src/runtime/state.ts +15 -8
- package/src/runtime/tool-calls.ts +0 -19
- package/src/session/context/turn/message/instruction-file.ts +13 -0
- package/src/session/context/turn/message/message.ts +17 -11
- package/src/session/context/turn/message/sender.ts +5 -2
- package/src/session/context/turn/message/tool-call.ts +3 -0
- package/src/session/context/turn/message/tool-result.ts +6 -1
- package/src/session/context/turn/turn.ts +4 -0
- package/src/session/conversation.ts +21 -8
- package/src/session/goal/goal.ts +1 -1
- package/src/session/goal/task.ts +2 -2
- package/src/session/session.ts +227 -24
- package/src/testing/claude-code.ts +23 -0
- package/src/testing/fake-claude.ts +5 -1
- package/src/testing/fake-sessions.ts +38 -24
- package/src/testing.ts +88 -19
- package/testing/claude-code.d.ts +12 -0
- package/testing/claude-code.d.ts.map +1 -0
- package/testing/claude-code.js +10 -0
- package/testing/fake-claude.d.ts +4 -0
- package/testing/fake-claude.d.ts.map +1 -1
- package/testing/fake-claude.js +4 -1
- package/testing/fake-sessions.d.ts +8 -6
- package/testing/fake-sessions.d.ts.map +1 -1
- package/testing/fake-sessions.js +35 -20
- package/testing.d.ts +38 -9
- package/testing.d.ts.map +1 -1
- package/testing.js +58 -8
- package/docs/hooks.md +0 -259
- package/session/context/turn/message/document.d.ts +0 -7
- package/session/context/turn/message/document.d.ts.map +0 -1
- package/session/context/turn/message/document.js +0 -1
- package/src/session/context/turn/message/document.ts +0 -8
package/src/testing.ts
CHANGED
|
@@ -18,25 +18,30 @@ import type {
|
|
|
18
18
|
UiSelectArgument,
|
|
19
19
|
} from 'claude-code'
|
|
20
20
|
import type { CommandReply } from './jobs/slash-command.js'
|
|
21
|
-
import type {
|
|
21
|
+
import type { ModDefinition } from './mod.js'
|
|
22
22
|
import type { Options, OptionValues } from './options.js'
|
|
23
23
|
import { readSteps, storeFolder, type Steps } from './records.js'
|
|
24
24
|
import type { Claude } from './runtime/claude.js'
|
|
25
25
|
import { answerCall, cmodPluginName, notInstalled } from './runtime/dependencies.js'
|
|
26
|
-
import {
|
|
26
|
+
import { foldBefore, installBefore } from './runtime/before.js'
|
|
27
|
+
import { permissionRoutes } from './runtime/permission-check.js'
|
|
27
28
|
import type { RoutedEvent } from './runtime/hooks.js'
|
|
29
|
+
import { keepClaudeCode, type ClaudeCode } from './testing/claude-code.js'
|
|
28
30
|
import { createRouter } from './runtime/router.js'
|
|
29
31
|
import { toolInputOf } from './runtime/tool-calls.js'
|
|
30
32
|
import { createLifecycle } from './runtime/lifecycle.js'
|
|
31
33
|
import { MissingOptions } from './runtime/options.js'
|
|
32
34
|
import { conversationMethods } from './runtime/sessions.js'
|
|
33
35
|
import type { ShownToast } from './runtime/toaster.js'
|
|
34
|
-
import
|
|
36
|
+
import { Message } from './session/context/turn/message/message.js'
|
|
35
37
|
import { Note } from './session/context/turn/message/note.js'
|
|
36
38
|
import { Prompt } from './session/context/turn/message/prompt.js'
|
|
37
39
|
import { Mod, Person } from './session/context/turn/message/sender.js'
|
|
38
40
|
import type { SessionChange } from './session/conversation.js'
|
|
39
|
-
import type
|
|
41
|
+
import { TurnEnd, type Turn } from './session/context/turn/turn.js'
|
|
42
|
+
import { beforeEvents, processEvents, sessionEvents, type AnswerOf, type BeforeEvent, type BeforeName, type CommandRun, type CommandRunAnswer, type Placement, type ProcessAnswer, type ProcessAsked, type ProcessName, type ProcessPayload } from './session/session.js'
|
|
43
|
+
import { ContextEnd } from './session/context/context.js'
|
|
44
|
+
import { TaskStart } from './session/goal/task.js'
|
|
40
45
|
import { calledAnswer, fakeClaude, type Fakes, type Shown as ShownByClaude, type TestCall } from './testing/fake-claude.js'
|
|
41
46
|
import { elements, findElement, rowsOf } from './testing/fake-elements.js'
|
|
42
47
|
import { fakeFiles } from './testing/fake-files.js'
|
|
@@ -64,18 +69,38 @@ export type TestOptions<State extends object, Declared extends Options = Options
|
|
|
64
69
|
readonly sessions?: readonly FakeSession[]
|
|
65
70
|
}
|
|
66
71
|
|
|
67
|
-
type
|
|
72
|
+
type Placed<Payload> = Omit<Payload, keyof Placement> & Partial<Placement>
|
|
68
73
|
|
|
69
|
-
|
|
74
|
+
type MessageBefore = Exclude<BeforeName, 'TaskStart' | 'TurnEnd' | 'ContextEnd'>
|
|
75
|
+
|
|
76
|
+
type DraftOf<Name extends MessageBefore> = Omit<Extract<MessageDraft, { readonly type: (typeof sessionEvents)[Name] }>, 'type'>
|
|
77
|
+
|
|
78
|
+
export type Raise = {
|
|
79
|
+
readonly [Name in MessageBefore as `before${Name}`]: (message: DraftOf<Name>, options?: { readonly task?: string }) => Promise<AnswerOf<Name> | undefined>
|
|
80
|
+
} & {
|
|
81
|
+
beforeTaskStart(task: { readonly title: string; readonly agentType?: string; readonly model?: string }): Promise<AnswerOf<'TaskStart'> | undefined>
|
|
82
|
+
beforeTurnEnd(ending?: Pick<Turn, 'answer' | 'failure'>): Promise<AnswerOf<'TurnEnd'> | undefined>
|
|
83
|
+
beforeContextEnd(): Promise<AnswerOf<'ContextEnd'> | undefined>
|
|
84
|
+
} & {
|
|
85
|
+
readonly [Name in ProcessName as `on${Name}`]: (payload: Placed<ProcessPayload[Name]>) => Promise<void>
|
|
86
|
+
} & {
|
|
87
|
+
readonly [Name in keyof ProcessAnswer as `before${Name}`]: (payload: Placed<ProcessAsked[Name]>) => Promise<ProcessAnswer[Name] | undefined>
|
|
88
|
+
} & {
|
|
89
|
+
onRun(run: Placed<CommandRun>): Promise<void>
|
|
90
|
+
beforeRun(run: Placed<CommandRun>): Promise<CommandRunAnswer | undefined>
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
type FiredEvent = 'ui.render' | 'ui.scroll' | 'ui.close' | 'cmod.call' | 'tool.check' | 'prompt.context'
|
|
70
94
|
|
|
71
95
|
export type TestedMod<State extends object> = {
|
|
72
96
|
start(): Promise<void>
|
|
73
|
-
|
|
74
|
-
fire<N extends
|
|
97
|
+
readonly raise: Raise
|
|
98
|
+
fire<N extends FiredEvent>(event: N, input: Args<N>, below?: EventResult<N>): Promise<EventResult<N>>
|
|
75
99
|
settle(): Promise<void>
|
|
76
100
|
add(message: MessageDraft, options?: { readonly task?: string }): Promise<Message[]>
|
|
77
|
-
endTurn(): Promise<void>
|
|
101
|
+
endTurn(ending?: Pick<Turn, 'answer' | 'failure'>): Promise<void>
|
|
78
102
|
compact(): Promise<void>
|
|
103
|
+
startSession(start: { readonly source: 'startup' | 'resume' | 'clear' | 'fork'; readonly id?: string }): Promise<void>
|
|
79
104
|
startTask(task: { readonly title: string; readonly agentType?: string; readonly model?: string; readonly openedBy?: string; readonly parent?: string }): Promise<string>
|
|
80
105
|
lines(paneId: string): Promise<string[]>
|
|
81
106
|
lines<P extends ComponentPlace>(place: P, props: Omit<PlaceProps<P>, 'Default'>, requestId?: string): Promise<string[]>
|
|
@@ -97,7 +122,7 @@ const defaultRows = 24
|
|
|
97
122
|
|
|
98
123
|
const presentation: CommandPresentation = { isFullscreen: false, columns: defaultColumns }
|
|
99
124
|
|
|
100
|
-
const toolUseEvents: readonly string[] = ['PreToolUse', 'PostToolUse', 'PostToolUseFailure', 'PermissionDenied']
|
|
125
|
+
const toolUseEvents: readonly string[] = ['PreToolUse', 'PostToolUse', 'PostToolUseFailure', 'PermissionDenied']
|
|
101
126
|
|
|
102
127
|
export function testMod<State extends object, Declared extends Options = Options>(definition: ModDefinition<State, string, Declared>, options: TestOptions<State, Declared> = {}): TestedMod<State> {
|
|
103
128
|
installJsx()
|
|
@@ -117,6 +142,7 @@ export function testMod<State extends object, Declared extends Options = Options
|
|
|
117
142
|
const conversations = fakeSessions({
|
|
118
143
|
callTool: (args: Parameters<Claude["tool"]["call"]>[0]) => fake.claude.tool.call(args),
|
|
119
144
|
project: () => projectRoot,
|
|
145
|
+
cwd: () => cwd,
|
|
120
146
|
given: options.sessions ?? [],
|
|
121
147
|
push: (mod, session, change) => {
|
|
122
148
|
if (mod !== name) return
|
|
@@ -149,7 +175,7 @@ export function testMod<State extends object, Declared extends Options = Options
|
|
|
149
175
|
const starting = options.state as Record<string, object> | undefined
|
|
150
176
|
const declared = Object.entries(definition.state ?? {}) as [string, object][]
|
|
151
177
|
const state = Object.fromEntries(declared.map(([lifetime, values]) => [lifetime, { ...values, ...starting?.[lifetime] }])) as State
|
|
152
|
-
const lifecycle = createLifecycle<State, Declared>({ ...definition, state }, () =>
|
|
178
|
+
const lifecycle = createLifecycle<State, Declared>({ ...definition, state }, () => permissionRoutes,(options.options ?? {}) as PluginOptions, false)
|
|
153
179
|
let started: Promise<void> | undefined
|
|
154
180
|
|
|
155
181
|
const start = async () => {
|
|
@@ -187,7 +213,7 @@ export function testMod<State extends object, Declared extends Options = Options
|
|
|
187
213
|
hooks: {
|
|
188
214
|
place: async () => conversations.place(),
|
|
189
215
|
wants: async (event) => conversations.wants(name, event),
|
|
190
|
-
decide: (event, change) =>
|
|
216
|
+
decide: (event, change) => foldBefore(event, change, [(latest) => askMod(event, latest)], (error) => fake.claude.ui.log(`cmod: passed the ${event} on without ${name}'s answer: ${messageOf(error)}`, { to: 'debug' })),
|
|
191
217
|
},
|
|
192
218
|
})
|
|
193
219
|
|
|
@@ -239,9 +265,44 @@ export function testMod<State extends object, Declared extends Options = Options
|
|
|
239
265
|
const transcript = `/test/transcripts/${sessionId}.jsonl`
|
|
240
266
|
const filled = { session_id: sessionId, transcript_path: transcript, cwd, hook_event_name: event, ...toolUse, ...input }
|
|
241
267
|
if (event === 'SessionStart' && !('transcript_path' in input)) return files.write(transcript, '').then(() => route('classic.SessionStart', filled, below))
|
|
242
|
-
if (event !== 'PreToolUse') return route(`classic.${event as
|
|
268
|
+
if (event !== 'PreToolUse') return route(`classic.${event}` as RoutedEvent, filled, below)
|
|
243
269
|
return firePreToolUse(filled as ClassicHookInputs['PreToolUse'], below as { deny?: string } | undefined)
|
|
244
|
-
}) as
|
|
270
|
+
}) as ClaudeCode['fire']
|
|
271
|
+
|
|
272
|
+
const asked = async (event: BeforeEvent, change: SessionChange) => {
|
|
273
|
+
await start()
|
|
274
|
+
return (await askMod(event, change)) ?? undefined
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const raise = Object.fromEntries([
|
|
278
|
+
...beforeEvents
|
|
279
|
+
.filter((named) => named !== 'TaskStart' && named !== 'TurnEnd' && named !== 'ContextEnd')
|
|
280
|
+
.map((named) => [`before${named}`, async (draft: object, placed?: { readonly task?: string }) => {
|
|
281
|
+
await start()
|
|
282
|
+
return asked(sessionEvents[named], { type: Message, message: conversations.draft({ ...draft, type: sessionEvents[named] } as MessageDraft, placed?.task) })
|
|
283
|
+
}]),
|
|
284
|
+
['beforeTaskStart', async ({ title, agentType = 'general-purpose', model }: { readonly title: string; readonly agentType?: string; readonly model?: string }) => {
|
|
285
|
+
await start()
|
|
286
|
+
return asked(TaskStart, { type: TaskStart, task: { id: '', title, agentType, openedBy: '', openedAt: new Date().toISOString(), context: conversations.place().context, ...(model === undefined ? {} : { model }) } })
|
|
287
|
+
}],
|
|
288
|
+
['beforeTurnEnd', async (ending: Pick<Turn, 'answer' | 'failure'> = {}) => {
|
|
289
|
+
await start()
|
|
290
|
+
const { turn } = conversations.place()
|
|
291
|
+
if (turn === undefined) throw new Error(`${name} has no turn open to end. Open one with tested.add({ type: Prompt, text: '…' }).`)
|
|
292
|
+
return asked(TurnEnd, { type: TurnEnd, turn: { ...turn, ...ending, closedAt: new Date().toISOString() } })
|
|
293
|
+
}],
|
|
294
|
+
['beforeContextEnd', async () => {
|
|
295
|
+
await start()
|
|
296
|
+
const { context, contextOpenedAt } = conversations.place()
|
|
297
|
+
return asked(ContextEnd, { type: ContextEnd, context: { number: context, openedAt: contextOpenedAt, closedAt: new Date().toISOString() } })
|
|
298
|
+
}],
|
|
299
|
+
...[...Object.entries(processEvents).flatMap(([named, event]) => [`on${named}`, ...('before' in event ? [`before${named}`] : [])]), 'onRun', 'beforeRun'].map((method) => [method, async (payload: object) => {
|
|
300
|
+
await start()
|
|
301
|
+
const answer = await lifecycle.raise(method, { session: sessionId, cwd, ...payload })
|
|
302
|
+
await fake.settle()
|
|
303
|
+
return answer
|
|
304
|
+
}]),
|
|
305
|
+
]) as Raise
|
|
245
306
|
|
|
246
307
|
const firePreToolUse = async ({ tool_name, tool_input, tool_use_id, agent_id, agent_type }: ClassicHookInputs['PreToolUse'], below: { deny?: string } | undefined) => {
|
|
247
308
|
await start()
|
|
@@ -269,22 +330,28 @@ export function testMod<State extends object, Declared extends Options = Options
|
|
|
269
330
|
return value
|
|
270
331
|
}
|
|
271
332
|
|
|
272
|
-
|
|
333
|
+
const tested: TestedMod<State> = {
|
|
273
334
|
start,
|
|
335
|
+
raise,
|
|
274
336
|
fire,
|
|
275
337
|
settle: fake.settle,
|
|
276
338
|
add: async (message, added) => {
|
|
277
339
|
await start()
|
|
278
340
|
return settled(conversations.add(message, added?.task))
|
|
279
341
|
},
|
|
280
|
-
endTurn: async () => {
|
|
342
|
+
endTurn: async (ending) => {
|
|
281
343
|
await start()
|
|
282
|
-
await settled(conversations.endTurn())
|
|
344
|
+
await settled(conversations.endTurn(ending === undefined ? undefined : { ...ending, ...(ending.failure === undefined ? {} : { reason: 'error' as const }) }))
|
|
283
345
|
},
|
|
284
346
|
compact: async () => {
|
|
285
347
|
await start()
|
|
286
348
|
await settled(conversations.compact())
|
|
287
349
|
},
|
|
350
|
+
startSession: async ({ source, id }) => {
|
|
351
|
+
await start()
|
|
352
|
+
await fire('SessionStart', { source, ...(id === undefined ? {} : { session_id: id }) })
|
|
353
|
+
await fake.settle()
|
|
354
|
+
},
|
|
288
355
|
startTask: async (task) => {
|
|
289
356
|
await start()
|
|
290
357
|
return settled(conversations.startTask(task))
|
|
@@ -353,7 +420,7 @@ export function testMod<State extends object, Declared extends Options = Options
|
|
|
353
420
|
},
|
|
354
421
|
get state() {
|
|
355
422
|
const mod = lifecycle.mod
|
|
356
|
-
if (mod === undefined) throw new Error(`${name} has not started. Await tested.start()
|
|
423
|
+
if (mod === undefined) throw new Error(`${name} has not started. Await tested.start() first.`)
|
|
357
424
|
return mod.state
|
|
358
425
|
},
|
|
359
426
|
calls: fake.calls,
|
|
@@ -366,6 +433,8 @@ export function testMod<State extends object, Declared extends Options = Options
|
|
|
366
433
|
sent: conversations.sent,
|
|
367
434
|
},
|
|
368
435
|
}
|
|
436
|
+
keepClaudeCode(tested, { fire })
|
|
437
|
+
return tested
|
|
369
438
|
}
|
|
370
439
|
|
|
371
440
|
function fakeDependencies(caller: string, dependencies: NonNullable<TestOptions<object>['dependencies']>, conversations: FakeSessions): Claude['cmod']['call'] {
|
|
@@ -395,7 +464,7 @@ function plainOutput({ component, props }: Args<'ui.render'>): RenderElement {
|
|
|
395
464
|
}
|
|
396
465
|
|
|
397
466
|
function replyOf({ text, context }: CommandRunResult): CommandReply {
|
|
398
|
-
return { ...(text === undefined ? {} : { text }), ...(context === undefined ? {} : {
|
|
467
|
+
return { ...(text === undefined ? {} : { text }), ...(context === undefined ? {} : { note: context.join('\n') }) }
|
|
399
468
|
}
|
|
400
469
|
|
|
401
470
|
async function modSteps(): Promise<Steps> {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Args, ClassicHookInputs, EventResult } from 'claude-code';
|
|
2
|
+
import type { Hook, RoutedEvent } from '../runtime/hooks.js';
|
|
3
|
+
type FilledField = 'session_id' | 'transcript_path' | 'cwd' | 'hook_event_name' | 'tool_use_id';
|
|
4
|
+
export type HookInputOf<H extends Hook | 'PreToolUse'> = Omit<ClassicHookInputs[H], FilledField> & Partial<Pick<ClassicHookInputs[H], FilledField & keyof ClassicHookInputs[H]>>;
|
|
5
|
+
export type ClaudeCode = {
|
|
6
|
+
fire<H extends Hook | 'PreToolUse'>(hook: H, input: HookInputOf<H>, below?: EventResult<`classic.${H}`>): Promise<EventResult<`classic.${H}`>>;
|
|
7
|
+
fire<N extends RoutedEvent>(event: N, input: Args<N>, below?: EventResult<N>): Promise<EventResult<N>>;
|
|
8
|
+
};
|
|
9
|
+
export declare function keepClaudeCode(tested: object, driver: ClaudeCode): void;
|
|
10
|
+
export declare function claudeCodeOf(tested: object): ClaudeCode;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=claude-code.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../src/testing/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACvE,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAE5D,KAAK,WAAW,GAAG,YAAY,GAAG,iBAAiB,GAAG,KAAK,GAAG,iBAAiB,GAAG,aAAa,CAAA;AAE/F,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,IAAI,GAAG,YAAY,IAAI,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAEhL,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,CAAC,CAAC,SAAS,IAAI,GAAG,YAAY,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAA;IAC9I,IAAI,CAAC,CAAC,SAAS,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;CACvG,CAAA;AAID,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAEvE;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAIvD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const drivers = new WeakMap();
|
|
2
|
+
export function keepClaudeCode(tested, driver) {
|
|
3
|
+
drivers.set(tested, driver);
|
|
4
|
+
}
|
|
5
|
+
export function claudeCodeOf(tested) {
|
|
6
|
+
const driver = drivers.get(tested);
|
|
7
|
+
if (driver === undefined)
|
|
8
|
+
throw new Error('claudeCodeOf takes a mod testMod returned.');
|
|
9
|
+
return driver;
|
|
10
|
+
}
|
package/testing/fake-claude.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fake-claude.d.ts","sourceRoot":"","sources":["../src/testing/fake-claude.ts"],"names":[],"mappings":"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
|
|
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
|
@@ -8,7 +8,7 @@ export function calledAnswer(caller, answer) {
|
|
|
8
8
|
}
|
|
9
9
|
export function fakeClaude(plugin) {
|
|
10
10
|
const calls = [];
|
|
11
|
-
const fakes = { process: {}, fs: {}, http: {}, settings: {}, config: {}, ui: {}, session: {}, prompt: {}, model: {}, agent: {}, clock: {}, cmod: {}, tool: {} };
|
|
11
|
+
const fakes = { process: {}, fs: {}, http: {}, settings: {}, config: {}, command: {}, ui: {}, session: {}, prompt: {}, model: {}, agent: {}, clock: {}, cmod: {}, tool: {} };
|
|
12
12
|
const emptyDisk = fakeFiles({});
|
|
13
13
|
const shown = { notes: [], prompts: [], logs: [], debug: [], statuses: [], openPanes: new Set(), commands: [], tools: [], schedules: [] };
|
|
14
14
|
const unplacedPanes = new Set();
|
|
@@ -145,12 +145,15 @@ export function fakeClaude(plugin) {
|
|
|
145
145
|
send: rejected('session.send', () => fakes.session.send ?? (async () => ({ isDelivered: true }))),
|
|
146
146
|
},
|
|
147
147
|
prompt: { submit: rejected('prompt.submit', () => fakes.prompt.submit ?? submitPrompt) },
|
|
148
|
+
turn: { abort: rejected('turn.abort', () => async () => undefined) },
|
|
148
149
|
model: { complete: rejected('model.complete', () => fakes.model.complete) },
|
|
149
150
|
command: {
|
|
150
151
|
register: async (command) => {
|
|
151
152
|
shown.commands.push(command.name);
|
|
152
153
|
return { command: command.name };
|
|
153
154
|
},
|
|
155
|
+
list: rejected('command.list', () => fakes.command.list ?? (async () => shown.commands.map((name) => ({ name, description: '', source: 'plugin', plugin: plugin.name })))),
|
|
156
|
+
run: rejected('command.run', () => fakes.command.run ?? (async () => ({}))),
|
|
154
157
|
},
|
|
155
158
|
tool: {
|
|
156
159
|
register: async (tool) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { InstructionFile } from '../session/context/turn/message/instruction-file.js';
|
|
2
2
|
import { Message } from '../session/context/turn/message/message.js';
|
|
3
3
|
import { Note } from '../session/context/turn/message/note.js';
|
|
4
4
|
import { Notice } from '../session/context/turn/message/notice.js';
|
|
@@ -8,7 +8,7 @@ import { type Sender } from '../session/context/turn/message/sender.js';
|
|
|
8
8
|
import { Skill } from '../session/context/turn/message/skill.js';
|
|
9
9
|
import { ToolCall } from '../session/context/turn/message/tool-call.js';
|
|
10
10
|
import { ToolResult } from '../session/context/turn/message/tool-result.js';
|
|
11
|
-
import { type SessionChange, type SessionData } from '../session/conversation.js';
|
|
11
|
+
import { type SessionChange, type SessionData, type TurnEnding } from '../session/conversation.js';
|
|
12
12
|
import type { Place } from '../runtime/before.js';
|
|
13
13
|
import type { Claude } from '../runtime/claude.js';
|
|
14
14
|
export type MessageDraft = {
|
|
@@ -30,14 +30,14 @@ export type MessageDraft = {
|
|
|
30
30
|
} | {
|
|
31
31
|
readonly type: typeof ToolResult;
|
|
32
32
|
readonly callId: string;
|
|
33
|
-
readonly
|
|
33
|
+
readonly output: string;
|
|
34
34
|
readonly isError?: boolean;
|
|
35
35
|
} | {
|
|
36
36
|
readonly type: typeof Skill;
|
|
37
37
|
readonly name: string;
|
|
38
38
|
readonly text: string;
|
|
39
39
|
} | {
|
|
40
|
-
readonly type: typeof
|
|
40
|
+
readonly type: typeof InstructionFile;
|
|
41
41
|
readonly path: string;
|
|
42
42
|
readonly text: string;
|
|
43
43
|
} | {
|
|
@@ -52,9 +52,10 @@ export type FakeSession = Partial<Omit<SessionData, 'id'>> & {
|
|
|
52
52
|
export type FakeSessions = {
|
|
53
53
|
answer(caller: string, method: string, input: unknown): unknown;
|
|
54
54
|
add(draft: MessageDraft, task?: string): Message[];
|
|
55
|
+
draft(draft: MessageDraft, task?: string): Message;
|
|
55
56
|
place(): Place;
|
|
56
57
|
wants(mod: string, event: string): boolean;
|
|
57
|
-
endTurn(): void;
|
|
58
|
+
endTurn(ending?: TurnEnding): void;
|
|
58
59
|
compact(): void;
|
|
59
60
|
startTask(task: {
|
|
60
61
|
readonly title: string;
|
|
@@ -72,8 +73,9 @@ export type FakeSessions = {
|
|
|
72
73
|
readonly as?: string;
|
|
73
74
|
}[];
|
|
74
75
|
};
|
|
75
|
-
export declare function fakeSessions({ project, given, push, callTool }: {
|
|
76
|
+
export declare function fakeSessions({ project, cwd, given, push, callTool }: {
|
|
76
77
|
readonly project: () => string;
|
|
78
|
+
readonly cwd: () => string;
|
|
77
79
|
readonly given: readonly FakeSession[];
|
|
78
80
|
readonly push: (mod: string, session: string, change: SessionChange) => void;
|
|
79
81
|
readonly callTool: Claude['tool']['call'];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fake-sessions.d.ts","sourceRoot":"","sources":["../src/testing/fake-sessions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
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,6 +1,6 @@
|
|
|
1
1
|
import { isObject } from '../records.js';
|
|
2
|
-
import {
|
|
3
|
-
import { Message, searchText, skillPrefix } from '../session/context/turn/message/message.js';
|
|
2
|
+
import { InstructionFile } from '../session/context/turn/message/instruction-file.js';
|
|
3
|
+
import { Message, messagesOf, noFiles, searchText, skillPrefix } from '../session/context/turn/message/message.js';
|
|
4
4
|
import { Note } from '../session/context/turn/message/note.js';
|
|
5
5
|
import { Notice } from '../session/context/turn/message/notice.js';
|
|
6
6
|
import { Prompt } from '../session/context/turn/message/prompt.js';
|
|
@@ -15,7 +15,7 @@ import { createConversation, emptyConversation, searchLimit } from '../session/c
|
|
|
15
15
|
import { conversationMethods, everySession, isHeardBy, resultOf } from '../runtime/sessions.js';
|
|
16
16
|
import { receivedMatcher } from '../utils/matcher.js';
|
|
17
17
|
import { firstLine, messageOf } from '../utils/text.js';
|
|
18
|
-
export function fakeSessions({ project, given, push, callTool }) {
|
|
18
|
+
export function fakeSessions({ project, cwd, given, push, callTool }) {
|
|
19
19
|
const kept = new Map();
|
|
20
20
|
const heard = new Map();
|
|
21
21
|
const watches = new Map();
|
|
@@ -49,7 +49,7 @@ export function fakeSessions({ project, given, push, callTool }) {
|
|
|
49
49
|
};
|
|
50
50
|
const add = (session, draft, task) => {
|
|
51
51
|
const before = session.messages.length;
|
|
52
|
-
record(session, session.conversation.add(rowOf(draft, `message-${(ids += 1)}`, now()), task));
|
|
52
|
+
record(session, session.conversation.add(rowOf(draft, `message-${(ids += 1)}`, now(), cwd()), task));
|
|
53
53
|
return session.messages.slice(before);
|
|
54
54
|
};
|
|
55
55
|
for (const each of given) {
|
|
@@ -67,8 +67,8 @@ export function fakeSessions({ project, given, push, callTool }) {
|
|
|
67
67
|
};
|
|
68
68
|
const currentSession = () => sessionOf(current);
|
|
69
69
|
const place = () => {
|
|
70
|
-
const { session, context, contextOpenedAt, turn, tasks, taskTurns } = currentSession().conversation.state;
|
|
71
|
-
return { session, context, contextOpenedAt, ...(turn === undefined ? {} : { turn }), tasks, taskTurns };
|
|
70
|
+
const { session, context, contextOpenedAt, turn, tasks, taskTurns, openCalls } = currentSession().conversation.state;
|
|
71
|
+
return { session, context, contextOpenedAt, ...(turn === undefined ? {} : { turn }), tasks, taskTurns, ...(openCalls === undefined ? {} : { openCalls }) };
|
|
72
72
|
};
|
|
73
73
|
const taskOf = (session, id) => {
|
|
74
74
|
const task = session.tasks.get(id);
|
|
@@ -99,9 +99,9 @@ export function fakeSessions({ project, given, push, callTool }) {
|
|
|
99
99
|
const task = request['task'];
|
|
100
100
|
if (request['session'] !== undefined && message.session !== request['session'])
|
|
101
101
|
return false;
|
|
102
|
-
if (
|
|
102
|
+
if (request['isAgent'] === true && message.task !== task)
|
|
103
103
|
return false;
|
|
104
|
-
if (task ===
|
|
104
|
+
if (typeof task === 'string' && (message.task === undefined || !isUnder(session, message.task, task)))
|
|
105
105
|
return false;
|
|
106
106
|
return (request['turn'] === undefined || message.turn === request['turn']) && (request['context'] === undefined || message.context === request['context']);
|
|
107
107
|
};
|
|
@@ -112,7 +112,7 @@ export function fakeSessions({ project, given, push, callTool }) {
|
|
|
112
112
|
.toSorted((first, second) => second.at.localeCompare(first.at));
|
|
113
113
|
const before = isObject(request['before']) ? request['before'] : undefined;
|
|
114
114
|
const start = before === undefined ? 0 : found.findIndex((message) => message.session === before['session'] && message.id === before['id']) + 1;
|
|
115
|
-
return found.slice(start, start +
|
|
115
|
+
return found.slice(start, start + searchLimit);
|
|
116
116
|
},
|
|
117
117
|
[conversationMethods.messages](request) {
|
|
118
118
|
const session = sessionOf(String(request['session']));
|
|
@@ -161,24 +161,30 @@ export function fakeSessions({ project, given, push, callTool }) {
|
|
|
161
161
|
const task = typeof request['task'] === 'string' ? request['task'] : undefined;
|
|
162
162
|
const isLive = task === undefined ? session.data.isRunning : session.data.isRunning && taskOf(session, task).closedAt === undefined;
|
|
163
163
|
if (action === 'usage')
|
|
164
|
-
return { model: task === undefined ? session.data.model : (taskOf(session, task).model ?? session.data.model),
|
|
165
|
-
if (action === '
|
|
164
|
+
return { model: task === undefined ? session.data.model : (taskOf(session, task).model ?? session.data.model), contextWindow: {} };
|
|
165
|
+
if (action === 'surfaces')
|
|
166
166
|
return isLive ? ['terminal'] : [];
|
|
167
167
|
if (!isLive)
|
|
168
168
|
throw new Error(`session ${task ?? session.data.id} has ended`);
|
|
169
|
+
if (action === 'abort') {
|
|
170
|
+
const open = task === undefined ? session.conversation.state.turn : session.conversation.state.taskTurns[task];
|
|
171
|
+
if (open?.prompt.id !== input['turn'])
|
|
172
|
+
throw new Error(`turn ${String(input['turn'])} has ended, so there is nothing to abort.`);
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
169
175
|
if (action === 'send') {
|
|
170
176
|
sent.push({ session: session.data.id, ...(task === undefined ? {} : { task }), type: String(input['type']), text: String(input['text']), ...(typeof input['as'] === 'string' ? { as: input['as'] } : {}) });
|
|
171
177
|
return null;
|
|
172
178
|
}
|
|
173
179
|
if (action === 'startTask') {
|
|
174
180
|
const id = `task-${(ids += 1)}`;
|
|
175
|
-
const data = { id, title: typeof input['
|
|
181
|
+
const data = { id, title: typeof input['title'] === 'string' ? input['title'] : '', agentType: typeof input['agentType'] === 'string' ? input['agentType'] : 'general-purpose', openedBy: '', openedAt: now(), ...(typeof input['model'] === 'string' ? { model: input['model'] } : {}) };
|
|
176
182
|
record(session, session.conversation.startTask(data));
|
|
177
183
|
return data;
|
|
178
184
|
}
|
|
179
185
|
if (session.data.id === current)
|
|
180
|
-
return resultOf(place(), await callTool({ ...input['input'], tool: String(input['name']) }));
|
|
181
|
-
return { id: '', type: ToolResult, at: now(), session: session.data.id, context: session.conversation.state.context, callId: '',
|
|
186
|
+
return resultOf(place(), { name: String(input['name']), input: input['input'], cwd: project() }, await callTool({ ...input['input'], tool: String(input['name']) }));
|
|
187
|
+
return { id: '', type: ToolResult, at: now(), session: session.data.id, context: session.conversation.state.context, callId: '', name: '', input: {}, cwd: project(), files: noFiles, output: '', isError: false };
|
|
182
188
|
},
|
|
183
189
|
[conversationMethods.subscribe](request, caller) {
|
|
184
190
|
const list = Array.isArray(request['subscriptions']) ? request['subscriptions'] : [];
|
|
@@ -201,11 +207,20 @@ export function fakeSessions({ project, given, push, callTool }) {
|
|
|
201
207
|
}
|
|
202
208
|
},
|
|
203
209
|
add: (draft, task) => add(currentSession(), draft, task),
|
|
210
|
+
draft(draft, task) {
|
|
211
|
+
const where = place();
|
|
212
|
+
const [unplaced] = messagesOf(rowOf(draft, `message-${(ids += 1)}`, now(), cwd()), task !== undefined);
|
|
213
|
+
if (unplaced === undefined)
|
|
214
|
+
throw new Error(`A ${draft.type} draft makes no message.`);
|
|
215
|
+
const call = unplaced.type === ToolResult ? where.openCalls?.[unplaced.callId] : undefined;
|
|
216
|
+
const turn = task === undefined ? where.turn : where.taskTurns[task];
|
|
217
|
+
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
|
+
},
|
|
204
219
|
place,
|
|
205
220
|
wants: (mod, event) => [current, everySession].some((target) => (watches.get(mod)?.get(target) ?? []).includes(event)),
|
|
206
|
-
endTurn() {
|
|
221
|
+
endTurn(ending = {}) {
|
|
207
222
|
const session = currentSession();
|
|
208
|
-
record(session, session.conversation.
|
|
223
|
+
record(session, session.conversation.endTurn(now(), { reason: 'answer', ...ending }));
|
|
209
224
|
},
|
|
210
225
|
compact() {
|
|
211
226
|
const session = currentSession();
|
|
@@ -227,7 +242,7 @@ export function fakeSessions({ project, given, push, callTool }) {
|
|
|
227
242
|
sent,
|
|
228
243
|
};
|
|
229
244
|
}
|
|
230
|
-
function rowOf(draft, id, at) {
|
|
245
|
+
function rowOf(draft, id, at, cwd) {
|
|
231
246
|
const base = { id, at, isMeta: false, isSummary: false };
|
|
232
247
|
const text = (value) => [{ type: 'text', text: value }];
|
|
233
248
|
const origin = (from) => (from === undefined || from.type === Person ? { kind: 'human' } : from.type === Mod ? { kind: 'plugin', name: from.name, ...(from.as === Person ? { asUser: true } : {}) } : from.type === 'session' ? { kind: 'peer' } : from.type === Task ? { kind: 'task-notification' } : { kind: from.type === Schedule ? 'scheduled-trigger' : from.type, ...(from.name === undefined ? {} : { server: from.name }) });
|
|
@@ -238,12 +253,12 @@ function rowOf(draft, id, at) {
|
|
|
238
253
|
if (draft.type === Reply)
|
|
239
254
|
return { ...base, type: 'assistant', content: text(draft.text) };
|
|
240
255
|
if (draft.type === ToolCall)
|
|
241
|
-
return { ...base, type: 'assistant', content: [{ type: 'tool_use', id: draft.callId ?? `toolu_${id}`, name: draft.name, input: draft.input ?? {} }], cwd
|
|
256
|
+
return { ...base, type: 'assistant', content: [{ type: 'tool_use', id: draft.callId ?? `toolu_${id}`, name: draft.name, input: draft.input ?? {} }], cwd };
|
|
242
257
|
if (draft.type === ToolResult)
|
|
243
|
-
return { ...base, type: 'user', content: [{ type: 'tool_result', tool_use_id: draft.callId, content: draft.
|
|
258
|
+
return { ...base, type: 'user', content: [{ type: 'tool_result', tool_use_id: draft.callId, content: draft.output, ...(draft.isError === true ? { is_error: true } : {}) }] };
|
|
244
259
|
if (draft.type === Skill)
|
|
245
260
|
return { ...base, type: 'user', isMeta: true, content: text(`${skillPrefix} /skills/${draft.name}\n\n${draft.text}`) };
|
|
246
|
-
if (draft.type ===
|
|
261
|
+
if (draft.type === InstructionFile)
|
|
247
262
|
return { ...base, type: 'attachment', name: 'nested_memory', content: text(draft.text), path: draft.path };
|
|
248
263
|
return { ...base, type: 'system', name: 'informational', content: text(draft.text) };
|
|
249
264
|
}
|
package/testing.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { Args,
|
|
1
|
+
import type { Args, CmodDependencies, EventResult, UiInputArgument } from 'claude-code';
|
|
2
2
|
import type { CommandReply } from './jobs/slash-command.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { ModDefinition } from './mod.js';
|
|
4
4
|
import type { Options, OptionValues } from './options.js';
|
|
5
|
-
import type { RoutedEvent } from './runtime/hooks.js';
|
|
6
5
|
import type { ShownToast } from './runtime/toaster.js';
|
|
7
|
-
import
|
|
6
|
+
import { Message } from './session/context/turn/message/message.js';
|
|
7
|
+
import { type Turn } from './session/context/turn/turn.js';
|
|
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';
|
|
8
9
|
import { type Fakes, type Shown as ShownByClaude, type TestCall } from './testing/fake-claude.js';
|
|
9
10
|
import { type FakeSession, type FakeSessions, type MessageDraft } from './testing/fake-sessions.js';
|
|
10
11
|
import { type ComponentPlace, type PlaceProps } from './ui/places.js';
|
|
@@ -32,18 +33,46 @@ export type TestOptions<State extends object, Declared extends Options = Options
|
|
|
32
33
|
readonly links?: Readonly<Record<string, string>>;
|
|
33
34
|
readonly sessions?: readonly FakeSession[];
|
|
34
35
|
};
|
|
35
|
-
type
|
|
36
|
-
|
|
36
|
+
type Placed<Payload> = Omit<Payload, keyof Placement> & Partial<Placement>;
|
|
37
|
+
type MessageBefore = Exclude<BeforeName, 'TaskStart' | 'TurnEnd' | 'ContextEnd'>;
|
|
38
|
+
type DraftOf<Name extends MessageBefore> = Omit<Extract<MessageDraft, {
|
|
39
|
+
readonly type: (typeof sessionEvents)[Name];
|
|
40
|
+
}>, 'type'>;
|
|
41
|
+
export type Raise = {
|
|
42
|
+
readonly [Name in MessageBefore as `before${Name}`]: (message: DraftOf<Name>, options?: {
|
|
43
|
+
readonly task?: string;
|
|
44
|
+
}) => Promise<AnswerOf<Name> | undefined>;
|
|
45
|
+
} & {
|
|
46
|
+
beforeTaskStart(task: {
|
|
47
|
+
readonly title: string;
|
|
48
|
+
readonly agentType?: string;
|
|
49
|
+
readonly model?: string;
|
|
50
|
+
}): Promise<AnswerOf<'TaskStart'> | undefined>;
|
|
51
|
+
beforeTurnEnd(ending?: Pick<Turn, 'answer' | 'failure'>): Promise<AnswerOf<'TurnEnd'> | undefined>;
|
|
52
|
+
beforeContextEnd(): Promise<AnswerOf<'ContextEnd'> | undefined>;
|
|
53
|
+
} & {
|
|
54
|
+
readonly [Name in ProcessName as `on${Name}`]: (payload: Placed<ProcessPayload[Name]>) => Promise<void>;
|
|
55
|
+
} & {
|
|
56
|
+
readonly [Name in keyof ProcessAnswer as `before${Name}`]: (payload: Placed<ProcessAsked[Name]>) => Promise<ProcessAnswer[Name] | undefined>;
|
|
57
|
+
} & {
|
|
58
|
+
onRun(run: Placed<CommandRun>): Promise<void>;
|
|
59
|
+
beforeRun(run: Placed<CommandRun>): Promise<CommandRunAnswer | undefined>;
|
|
60
|
+
};
|
|
61
|
+
type FiredEvent = 'ui.render' | 'ui.scroll' | 'ui.close' | 'cmod.call' | 'tool.check' | 'prompt.context';
|
|
37
62
|
export type TestedMod<State extends object> = {
|
|
38
63
|
start(): Promise<void>;
|
|
39
|
-
|
|
40
|
-
fire<N extends
|
|
64
|
+
readonly raise: Raise;
|
|
65
|
+
fire<N extends FiredEvent>(event: N, input: Args<N>, below?: EventResult<N>): Promise<EventResult<N>>;
|
|
41
66
|
settle(): Promise<void>;
|
|
42
67
|
add(message: MessageDraft, options?: {
|
|
43
68
|
readonly task?: string;
|
|
44
69
|
}): Promise<Message[]>;
|
|
45
|
-
endTurn(): Promise<void>;
|
|
70
|
+
endTurn(ending?: Pick<Turn, 'answer' | 'failure'>): Promise<void>;
|
|
46
71
|
compact(): Promise<void>;
|
|
72
|
+
startSession(start: {
|
|
73
|
+
readonly source: 'startup' | 'resume' | 'clear' | 'fork';
|
|
74
|
+
readonly id?: string;
|
|
75
|
+
}): Promise<void>;
|
|
47
76
|
startTask(task: {
|
|
48
77
|
readonly title: string;
|
|
49
78
|
readonly agentType?: string;
|
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,
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["src/testing.ts"],"names":[],"mappings":"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"}
|