@cmodjs/core 0.1.4 → 0.1.6
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/README.md +4 -0
- package/connect.d.ts.map +1 -1
- package/connect.js +35 -37
- package/docs/commands.md +15 -6
- package/docs/index.md +3 -3
- package/docs/jobs.md +20 -20
- package/docs/mod.md +4 -4
- package/docs/testing.md +1 -1
- package/jobs/check.d.ts +2 -2
- package/jobs/check.d.ts.map +1 -1
- package/jobs/check.js +5 -5
- package/jobs/context.d.ts +14 -0
- package/jobs/context.d.ts.map +1 -0
- package/jobs/{part-context.js → context.js} +6 -6
- package/jobs/permissions.d.ts +2 -2
- package/jobs/permissions.d.ts.map +1 -1
- package/jobs/permissions.js +7 -7
- package/jobs/program.d.ts +2 -2
- package/jobs/program.d.ts.map +1 -1
- package/jobs/prompt.d.ts +2 -2
- package/jobs/prompt.d.ts.map +1 -1
- package/jobs/prompt.js +17 -17
- package/jobs/slash-command.d.ts +2 -2
- package/jobs/slash-command.d.ts.map +1 -1
- package/jobs/slash-command.js +5 -5
- package/jobs/status-line.d.ts +2 -2
- package/jobs/status-line.d.ts.map +1 -1
- package/jobs/status-line.js +5 -5
- package/jobs/tool.d.ts +2 -2
- package/jobs/tool.d.ts.map +1 -1
- package/jobs/tool.js +5 -5
- package/mod.d.ts +3 -3
- package/mod.d.ts.map +1 -1
- package/package.json +1 -1
- package/runtime/lifecycle.d.ts.map +1 -1
- package/runtime/lifecycle.js +8 -9
- package/runtime/tool-calls.d.ts +3 -2
- package/runtime/tool-calls.d.ts.map +1 -1
- package/runtime/tool-calls.js +6 -6
- package/src/connect.ts +36 -39
- package/src/jobs/check.ts +7 -7
- package/src/jobs/{part-context.ts → context.ts} +10 -10
- package/src/jobs/permissions.ts +9 -9
- package/src/jobs/program.ts +2 -2
- package/src/jobs/prompt.ts +19 -19
- package/src/jobs/slash-command.ts +7 -7
- package/src/jobs/status-line.ts +7 -7
- package/src/jobs/tool.ts +7 -7
- package/src/mod.ts +3 -3
- package/src/runtime/lifecycle.ts +9 -10
- package/src/runtime/tool-calls.ts +8 -7
- package/jobs/part-context.d.ts +0 -14
- package/jobs/part-context.d.ts.map +0 -1
package/src/jobs/prompt.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Job, JobContext, Mod } from '../mod.js'
|
|
2
2
|
import { longestMs, type Deadline } from '../runtime/deadline.js'
|
|
3
3
|
import { listed, messageOf } from '../utils/text.js'
|
|
4
4
|
import { callEffects, type ToolCall } from '../utils/call-effects.js'
|
|
5
5
|
import { matchTarget, targetOf, type Target } from './permissions/match-target.js'
|
|
6
|
-
import { afterCall, modOf, modWithin, targetWords } from './
|
|
6
|
+
import { afterCall, modOf, modWithin, targetWords } from './context.js'
|
|
7
7
|
|
|
8
8
|
type PromptInput = { userPrompt?: string; call?: ToolCall }
|
|
9
9
|
|
|
@@ -16,16 +16,16 @@ type PromptOptions<State extends object> = {
|
|
|
16
16
|
|
|
17
17
|
const deadline: Deadline = { ms: 5000, longestMs, job: 'prompt' }
|
|
18
18
|
|
|
19
|
-
export function prompt<State extends object = Record<never, never>>({ name, prompt: text, when, after }: PromptOptions<State>):
|
|
19
|
+
export function prompt<State extends object = Record<never, never>>({ name, prompt: text, when, after }: PromptOptions<State>): Job<void, State> {
|
|
20
20
|
if (name.trim() === '') throw new Error('prompt: give the block a name. Claude reads the text under it.')
|
|
21
21
|
if (when !== undefined && after !== undefined) throw new Error(`prompt "${name}": use when or after, not both. Add a second prompt for the other trigger.`)
|
|
22
22
|
const targets = after === undefined ? [] : Array.isArray(after) ? after : [after]
|
|
23
23
|
for (const target of targets) targetOf(target)
|
|
24
24
|
|
|
25
|
-
return (
|
|
26
|
-
|
|
25
|
+
return (job) => {
|
|
26
|
+
job.reserveName('prompt', name, `prompt: ${job.mod.name} adds the name "${name}" two times. Give each prompt its own name.`)
|
|
27
27
|
|
|
28
|
-
const log = (reason: string) =>
|
|
28
|
+
const log = (reason: string) => job.claude.ui.log(`prompt "${name}" added nothing: ${reason}`, { to: 'debug' })
|
|
29
29
|
const textFor = async (input: PromptInput, mod: Mod<State>) => {
|
|
30
30
|
try {
|
|
31
31
|
const value = typeof text === 'string' ? text : await text(input, mod)
|
|
@@ -42,20 +42,20 @@ export function prompt<State extends object = Record<never, never>>({ name, prom
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
if (when !== undefined) {
|
|
45
|
-
addAfterUserPrompts(
|
|
46
|
-
|
|
45
|
+
addAfterUserPrompts(job, when, (userPrompt) => headedText({ userPrompt }, modWithin(job, deadline)), log)
|
|
46
|
+
job.announce(`the ${name} prompt after matching user prompts`)
|
|
47
47
|
} else if (targets.length > 0) {
|
|
48
|
-
addAfterCalls(
|
|
49
|
-
|
|
48
|
+
addAfterCalls(job, targets, headedText, log)
|
|
49
|
+
job.announce(`the ${name} prompt after ${listed(targets.map(targetWords))}`)
|
|
50
50
|
} else {
|
|
51
|
-
addOncePerConversation(
|
|
52
|
-
|
|
51
|
+
addOncePerConversation(job, name, () => textFor({}, modWithin(job, deadline)), log)
|
|
52
|
+
job.announce(`the ${name} prompt`)
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
function addOncePerConversation(
|
|
58
|
-
|
|
57
|
+
function addOncePerConversation(job: JobContext, name: string, textFor: () => Promise<string | undefined>, log: (reason: string) => void): void {
|
|
58
|
+
job.on('prompt.context', async (e, next) => {
|
|
59
59
|
const below = await next(e)
|
|
60
60
|
if (below.blocks.some((block) => block.name === name)) {
|
|
61
61
|
log(`a block named "${name}" is already in the context`)
|
|
@@ -66,8 +66,8 @@ function addOncePerConversation(part: PartContext, name: string, textFor: () =>
|
|
|
66
66
|
})
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
function addAfterUserPrompts(
|
|
70
|
-
|
|
69
|
+
function addAfterUserPrompts(job: JobContext, when: RegExp | ((userPrompt: string) => boolean), textFor: (userPrompt: string) => Promise<string | undefined>, log: (reason: string) => void): void {
|
|
70
|
+
job.on('prompt.submit', async (e, next) => {
|
|
71
71
|
let value: string | undefined
|
|
72
72
|
try {
|
|
73
73
|
if (typeof when === 'function' ? when(e.text) : e.text.search(when) >= 0) value = await textFor(e.text)
|
|
@@ -79,19 +79,19 @@ function addAfterUserPrompts(part: PartContext, when: RegExp | ((userPrompt: str
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
function addAfterCalls<State extends object>(
|
|
82
|
-
|
|
82
|
+
job: JobContext<State>,
|
|
83
83
|
targets: Target[],
|
|
84
84
|
textFor: (input: PromptInput, mod: Mod<State>) => Promise<string | undefined>,
|
|
85
85
|
log: (reason: string) => void,
|
|
86
86
|
): void {
|
|
87
87
|
afterCall(
|
|
88
|
-
|
|
88
|
+
job,
|
|
89
89
|
async (use, workspace) => {
|
|
90
90
|
const effects = callEffects(use, workspace)
|
|
91
91
|
for (const target of targets) {
|
|
92
92
|
const [matched] = await matchTarget(target, use, effects, workspace)
|
|
93
93
|
if (matched === undefined) continue
|
|
94
|
-
const value = await textFor({ call: matched.call }, modOf(
|
|
94
|
+
const value = await textFor({ call: matched.call }, modOf(job, matched, workspace, deadline))
|
|
95
95
|
return value === undefined ? [] : [value]
|
|
96
96
|
}
|
|
97
97
|
return []
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { CommandRunResult } from 'claude-code'
|
|
2
|
-
import type {
|
|
2
|
+
import type { Job, Mod } from '../mod.js'
|
|
3
3
|
import { parse } from '../vendor.js'
|
|
4
4
|
import { longestMs, type Deadline } from '../runtime/deadline.js'
|
|
5
5
|
import { messageOf } from '../utils/text.js'
|
|
6
|
-
import { modWithin } from './
|
|
6
|
+
import { modWithin } from './context.js'
|
|
7
7
|
|
|
8
8
|
export type Reply = string | { text?: string; context?: string } | undefined
|
|
9
9
|
|
|
@@ -17,10 +17,10 @@ export function slashCommand<State extends object = Record<never, never>>(option
|
|
|
17
17
|
readonly argumentHint?: string
|
|
18
18
|
readonly immediate?: true
|
|
19
19
|
readonly reply: (input: { args: string; positionals: string[] }, mod: Mod<State>) => Reply | void | Promise<Reply | void>
|
|
20
|
-
}):
|
|
20
|
+
}): Job<void, State> {
|
|
21
21
|
const { name, description, argumentHint, immediate, reply } = options
|
|
22
|
-
return (
|
|
23
|
-
const { mod, claude,
|
|
22
|
+
return (job) => {
|
|
23
|
+
const { mod, claude, announce, reserveName } = job
|
|
24
24
|
if (!commandName.test(name)) throw new Error(`${mod.name}: "${name}" is not a slash command name. Use 1 to 64 letters, digits, "_", or "-", without the slash.`)
|
|
25
25
|
reserveName('slashCommand', name, `${mod.name}: the slash command /${name} is already added. Give each slashCommand its own name.`)
|
|
26
26
|
|
|
@@ -35,8 +35,8 @@ export function slashCommand<State extends object = Record<never, never>>(option
|
|
|
35
35
|
)
|
|
36
36
|
announce(`/${name}`)
|
|
37
37
|
|
|
38
|
-
const replyMod = modWithin(
|
|
39
|
-
on('command.run', async (e, next) => {
|
|
38
|
+
const replyMod = modWithin(job, deadline)
|
|
39
|
+
job.on('command.run', async (e, next) => {
|
|
40
40
|
if (e.command !== registered) return next(e)
|
|
41
41
|
try {
|
|
42
42
|
return answerOf(await reply({ args: e.args, positionals: splitWords(e.args) }, replyMod))
|
package/src/jobs/status-line.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Job, Mod } from '../mod.js'
|
|
2
2
|
import type { Deadline } from '../runtime/deadline.js'
|
|
3
3
|
import { messageOf } from '../utils/text.js'
|
|
4
|
-
import { modWithin } from './
|
|
4
|
+
import { modWithin } from './context.js'
|
|
5
5
|
|
|
6
6
|
export type Usage = {
|
|
7
7
|
model: string
|
|
@@ -14,14 +14,14 @@ const deadline: Deadline = { ms: 2000, job: 'statusLine' }
|
|
|
14
14
|
export function statusLine<State extends object = Record<never, never>>(options: {
|
|
15
15
|
readonly text: (usage: Usage, mod: Mod<State>) => string | undefined | Promise<string | undefined>
|
|
16
16
|
readonly interval?: number
|
|
17
|
-
}):
|
|
17
|
+
}): Job<void, State> {
|
|
18
18
|
const { text, interval = 10000 } = options
|
|
19
|
-
return (
|
|
20
|
-
const { mod, claude,
|
|
19
|
+
return (job) => {
|
|
20
|
+
const { mod, claude, announce, reserveName } = job
|
|
21
21
|
if (!(interval >= 1)) throw new Error(`${mod.name}: the status line interval is ${interval}. Give it in milliseconds, 1 or more.`)
|
|
22
22
|
reserveName('statusLine', '', `${mod.name}: a status line is already added. A mod has one status line: join the texts in one statusLine.`)
|
|
23
23
|
|
|
24
|
-
const textMod = modWithin(
|
|
24
|
+
const textMod = modWithin(job, deadline)
|
|
25
25
|
let shown: string | undefined
|
|
26
26
|
let queue = Promise.resolve()
|
|
27
27
|
const update = async () => {
|
|
@@ -48,7 +48,7 @@ export function statusLine<State extends object = Record<never, never>>(options:
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
announce('a status line')
|
|
51
|
-
on('session.measure', (e, next) => {
|
|
51
|
+
job.on('session.measure', (e, next) => {
|
|
52
52
|
refresh()
|
|
53
53
|
return next(e)
|
|
54
54
|
})
|
package/src/jobs/tool.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { FromSchema, JSONSchema } from 'json-schema-to-ts'
|
|
2
|
-
import type {
|
|
2
|
+
import type { Job, Mod } from '../mod.js'
|
|
3
3
|
import { Validator } from '../vendor.js'
|
|
4
4
|
import { toolDeadline } from '../runtime/deadline.js'
|
|
5
5
|
import { reservedKeys, toolInputOf } from '../runtime/tool-calls.js'
|
|
6
6
|
import { messageOf } from '../utils/text.js'
|
|
7
|
-
import { modWithin } from './
|
|
7
|
+
import { modWithin } from './context.js'
|
|
8
8
|
|
|
9
9
|
const toolName = /^[A-Za-z0-9_-]{1,64}$/
|
|
10
10
|
|
|
@@ -13,10 +13,10 @@ export function tool<const Schema extends object = { type: 'object' }, State ext
|
|
|
13
13
|
readonly description: string
|
|
14
14
|
readonly inputSchema?: Schema
|
|
15
15
|
readonly execute: (input: Schema extends JSONSchema ? FromSchema<Schema> : never, mod: Mod<State>) => unknown
|
|
16
|
-
}):
|
|
16
|
+
}): Job<{ readonly name: string }, State> {
|
|
17
17
|
const { name, description, inputSchema, execute } = options
|
|
18
|
-
return (
|
|
19
|
-
const { mod, claude,
|
|
18
|
+
return (job) => {
|
|
19
|
+
const { mod, claude, announce, reserveName } = job
|
|
20
20
|
if (!toolName.test(name)) throw new Error(`${mod.name}: "${name}" is not a tool name. Use 1 to 64 letters, digits, "_", or "-".`)
|
|
21
21
|
const properties = (inputSchema as { properties?: object } | undefined)?.properties ?? {}
|
|
22
22
|
const reserved = reservedKeys.filter((key) => Object.hasOwn(properties, key))
|
|
@@ -35,8 +35,8 @@ export function tool<const Schema extends object = { type: 'object' }, State ext
|
|
|
35
35
|
)
|
|
36
36
|
announce(`the ${name} tool`)
|
|
37
37
|
|
|
38
|
-
const executeMod = modWithin(
|
|
39
|
-
on('tool.call', async (e, next) => {
|
|
38
|
+
const executeMod = modWithin(job, toolDeadline)
|
|
39
|
+
job.on('tool.call', async (e, next) => {
|
|
40
40
|
if (e.tool !== registered) return next(e)
|
|
41
41
|
const input = toolInputOf(e)
|
|
42
42
|
const { valid, errors } = validator.validate(input)
|
package/src/mod.ts
CHANGED
|
@@ -111,7 +111,7 @@ export type Mod<State extends object = Record<never, never>> = {
|
|
|
111
111
|
readonly state: Readonly<State>
|
|
112
112
|
readonly dataFolder: string
|
|
113
113
|
on<E extends ModEvent>(event: E, hook: ModHook<E>): void
|
|
114
|
-
use<Handle>(
|
|
114
|
+
use<Handle>(job: Job<Handle, State>): Handle
|
|
115
115
|
readonly ui: {
|
|
116
116
|
pane(pane: Pane<State>): PaneHandle
|
|
117
117
|
render<S extends Slot>(slot: S, Component: (props: SlotProps<S>) => RenderElement): void
|
|
@@ -157,7 +157,7 @@ export type ModDefinition<State extends StateGroups = Record<never, never>, Name
|
|
|
157
157
|
setup(mod: Mod<State>): void | Promise<void>
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
export type
|
|
160
|
+
export type JobContext<State extends object = Record<never, never>> = {
|
|
161
161
|
readonly mod: Mod<State>
|
|
162
162
|
readonly claude: Claude
|
|
163
163
|
on<N extends RoutedEvent>(event: N, hook: RoutedHook<N>): void
|
|
@@ -166,7 +166,7 @@ export type PartContext<State extends object = Record<never, never>> = {
|
|
|
166
166
|
readonly toolCalls: ToolCalls
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
export type
|
|
169
|
+
export type Job<Handle, State extends object = Record<never, never>> = (context: JobContext<State>) => Handle
|
|
170
170
|
|
|
171
171
|
export function defineMod<State extends StateGroups = Record<never, never>, Name extends string = string>(definition: ModDefinition<State, Name>): ModDefinition<State, Name> {
|
|
172
172
|
if (definition.name.trim() === '') throw new Error('defineMod: the mod needs a name, such as the name in .claude-plugin/plugin.json.')
|
package/src/runtime/lifecycle.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Args, EventResult, Frozen, HookBudget, HookStream, ProcessSpawnChunk, ProcessSpawnResult } from 'claude-code'
|
|
2
|
-
import type { Mod, ModDefinition, ModEvent, ModHook
|
|
2
|
+
import type { Mod, ModDefinition, ModEvent, ModHook } from '../mod.js'
|
|
3
3
|
import { dataFolder, isAtLeast, parseEvent, readRecord, readSteps, scriptsSha256, storeFolder, type ReadFile, type RunnerEvent } from '../records.js'
|
|
4
4
|
import { relativePath } from '../utils/paths.js'
|
|
5
5
|
import { formatExit, listed, messageOf } from '../utils/text.js'
|
|
@@ -355,7 +355,6 @@ async function createMod<State extends object>(definition: ModDefinition<State>,
|
|
|
355
355
|
const announce = (feature: string) => {
|
|
356
356
|
added.push(feature)
|
|
357
357
|
}
|
|
358
|
-
const on: PartContext<State>['on'] = (event, hook) => router.add(event, hook)
|
|
359
358
|
const [session, root, startCwd] = await Promise.all([claude.session.id(), claude.session.root(), claude.session.cwd()])
|
|
360
359
|
let cwd = startCwd
|
|
361
360
|
let loadedCwd = startCwd
|
|
@@ -370,7 +369,7 @@ async function createMod<State extends object>(definition: ModDefinition<State>,
|
|
|
370
369
|
if (!hookEvents.includes(event)) hookEvents.push(event)
|
|
371
370
|
router.add(`classic.${event}`, classicHook(definition.name, event, hook, claude, agents))
|
|
372
371
|
},
|
|
373
|
-
use: (
|
|
372
|
+
use: (job) => job({ mod, claude, on: (event, hook) => router.add(event, hook), announce, reserveName, toolCalls: agents }),
|
|
374
373
|
ui: area.ui,
|
|
375
374
|
process: {
|
|
376
375
|
run: (argv, init) => claude.process.run(argv, init),
|
|
@@ -414,32 +413,32 @@ async function createMod<State extends object>(definition: ModDefinition<State>,
|
|
|
414
413
|
claude.ui.log(`${definition.name} keeps the state of ${modState.root} until the next prompt or folder move: ${messageOf(error)}`)
|
|
415
414
|
}
|
|
416
415
|
}
|
|
417
|
-
|
|
416
|
+
router.add('classic.SessionStart', async (e, next) => {
|
|
418
417
|
await modState.switchSession(e.session_id, e.source).catch((error: unknown) => {
|
|
419
418
|
claude.ui.log(`${definition.name} kept its session values from before the ${e.source}: ${messageOf(error)}`)
|
|
420
419
|
})
|
|
421
420
|
return next(e)
|
|
422
421
|
})
|
|
423
|
-
|
|
422
|
+
router.add('classic.UserPromptSubmit', async (e, next) => {
|
|
424
423
|
staleCwd = undefined
|
|
425
424
|
await followSession()
|
|
426
425
|
return next(e)
|
|
427
426
|
})
|
|
428
427
|
for (const event of ['classic.PostToolUse', 'classic.PostToolUseFailure'] as const) {
|
|
429
|
-
|
|
428
|
+
router.add(event, async (e, next) => {
|
|
430
429
|
if (shellTools.includes(e.tool_name)) await followSession()
|
|
431
430
|
return next(e)
|
|
432
431
|
})
|
|
433
432
|
}
|
|
434
|
-
|
|
433
|
+
router.add('command.run', async (e, next) => {
|
|
435
434
|
const answer = await next(e)
|
|
436
435
|
if (e.command === 'cd') await followSession(true)
|
|
437
436
|
return answer
|
|
438
437
|
})
|
|
439
|
-
|
|
438
|
+
router.add('skill.prompt', userSkillHook(claude))
|
|
440
439
|
const api = Object.fromEntries(Object.entries(definition.api ?? {}).map(([method, run]) => [method, (input: never) => run(input, mod)]))
|
|
441
|
-
|
|
442
|
-
const agents = toolCalls(
|
|
440
|
+
router.add('cmod.call', (e, next) => (e.to === definition.name ? answerCall(definition.name, api, e) : next(e)))
|
|
441
|
+
const agents = toolCalls(claude, router)
|
|
443
442
|
const names = new Set<string>()
|
|
444
443
|
const reserveName = (kind: string, name: string, taken: string) => {
|
|
445
444
|
const key = `${kind}:${name}`
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Claude } from './claude.js'
|
|
2
|
+
import type { Router } from './router.js'
|
|
2
3
|
|
|
3
4
|
export type Agent = { agentId?: string; agentType?: string }
|
|
4
5
|
|
|
@@ -17,22 +18,22 @@ type AgentFields = { readonly agent_id?: string; readonly agent_type?: string }
|
|
|
17
18
|
|
|
18
19
|
const keptCalls = 100
|
|
19
20
|
|
|
20
|
-
export function toolCalls(
|
|
21
|
+
export function toolCalls(claude: Claude, router: Router): ToolCalls {
|
|
21
22
|
let mainAgentType: string | undefined
|
|
22
23
|
const agentIds = new Map<string, string>()
|
|
23
24
|
const cwds = new Map<string, string>()
|
|
24
25
|
const noteAgent = (e: AgentFields) => {
|
|
25
26
|
if (e.agent_id === undefined) mainAgentType = e.agent_type
|
|
26
27
|
}
|
|
27
|
-
|
|
28
|
+
router.add('classic.SessionStart', (e, next) => {
|
|
28
29
|
noteAgent(e)
|
|
29
30
|
return next(e)
|
|
30
31
|
})
|
|
31
|
-
|
|
32
|
+
router.add('classic.UserPromptSubmit', (e, next) => {
|
|
32
33
|
noteAgent(e)
|
|
33
34
|
return next(e)
|
|
34
35
|
})
|
|
35
|
-
|
|
36
|
+
router.add('tool.call', async (e, next) => {
|
|
36
37
|
if (e.agentId === undefined) return next(e)
|
|
37
38
|
agentIds.set(e.tool_use_id, e.agentId)
|
|
38
39
|
try {
|
|
@@ -41,7 +42,7 @@ export function toolCalls({ claude, on }: Pick<PartContext, 'claude' | 'on'>): T
|
|
|
41
42
|
agentIds.delete(e.tool_use_id)
|
|
42
43
|
}
|
|
43
44
|
})
|
|
44
|
-
|
|
45
|
+
router.add('classic.PreToolUse', async (e, next) => {
|
|
45
46
|
cwds.set(e.tool_use_id, await claude.session.cwd())
|
|
46
47
|
for (const oldest of cwds.keys()) {
|
|
47
48
|
if (cwds.size <= keptCalls) break
|
|
@@ -50,7 +51,7 @@ export function toolCalls({ claude, on }: Pick<PartContext, 'claude' | 'on'>): T
|
|
|
50
51
|
return next(e)
|
|
51
52
|
})
|
|
52
53
|
for (const event of ['classic.PostToolUse', 'classic.PostToolUseFailure'] as const) {
|
|
53
|
-
|
|
54
|
+
router.add(event, async (e, next) => {
|
|
54
55
|
try {
|
|
55
56
|
return await next(e)
|
|
56
57
|
} finally {
|
package/jobs/part-context.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { Mod, PartContext } from '../mod.js';
|
|
2
|
-
import { type Deadline } from '../runtime/deadline.js';
|
|
3
|
-
import type { ToolCall, ToolUse } from '../utils/call-effects.js';
|
|
4
|
-
import { type Workspace } from './permissions/find-project-scope.js';
|
|
5
|
-
import { type Target } from './permissions/match-target.js';
|
|
6
|
-
export declare function workspaceReader({ claude }: PartContext): () => Promise<Workspace>;
|
|
7
|
-
export declare function afterCall<State extends object>(part: PartContext<State>, contextAfter: (use: ToolUse, workspace: Workspace) => Promise<readonly string[]>, failed: (error: unknown) => readonly string[]): void;
|
|
8
|
-
export declare function modOf<State extends object>(context: PartContext<State>, { call, folder }: {
|
|
9
|
-
readonly call?: ToolCall;
|
|
10
|
-
readonly folder: string;
|
|
11
|
-
}, workspace: Workspace, deadline: Deadline): Mod<State>;
|
|
12
|
-
export declare function modWithin<State extends object>({ mod, claude }: PartContext<State>, deadline: Deadline, workTree?: () => Promise<string | undefined>): Mod<State>;
|
|
13
|
-
export declare function targetWords(target: Target): string;
|
|
14
|
-
//# sourceMappingURL=part-context.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"part-context.d.ts","sourceRoot":"","sources":["../src/jobs/part-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEjD,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAItE,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,qCAAqC,CAAA;AACtF,OAAO,EAAY,KAAK,MAAM,EAAE,MAAM,+BAA+B,CAAA;AAOrE,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,EAAE,WAAW,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAOjF;AAaD,wBAAgB,SAAS,CAAC,KAAK,SAAS,MAAM,EAC5C,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,EACxB,YAAY,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,EAChF,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,SAAS,MAAM,EAAE,GAC5C,IAAI,CAUN;AAMD,wBAAgB,KAAK,CAAC,KAAK,SAAS,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,CAEtM;AAED,wBAAgB,SAAS,CAAC,KAAK,SAAS,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,GAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAyB,GAAG,GAAG,CAAC,KAAK,CAAC,CAwBxL;AAwBD,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CASlD"}
|