@cmodjs/core 0.1.6 → 0.1.8
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 +2 -2
- package/docs/commands.md +14 -14
- package/docs/dependencies.md +1 -1
- package/docs/hooks.md +9 -7
- package/docs/index.md +3 -3
- package/docs/install-steps.md +17 -17
- package/docs/jobs.md +19 -18
- package/docs/mod.md +28 -13
- package/docs/state.md +8 -8
- package/docs/ui.md +6 -6
- package/package.json +2 -2
- package/records.js +3 -3
- package/register.d.ts +5 -0
- package/register.d.ts.map +1 -0
- package/{connect.js → register.js} +35 -30
- package/runtime/hooks.d.ts +1 -0
- package/runtime/hooks.d.ts.map +1 -1
- package/runtime/hooks.js +1 -0
- package/runtime/lifecycle.d.ts +1 -1
- package/runtime/lifecycle.d.ts.map +1 -1
- package/runtime/lifecycle.js +13 -9
- package/runtime/router.d.ts +1 -0
- package/runtime/router.d.ts.map +1 -1
- package/runtime/router.js +1 -0
- package/runtime/tool-calls.d.ts.map +1 -1
- package/runtime/tool-calls.js +6 -9
- package/src/records.ts +3 -3
- package/src/{connect.ts → register.ts} +37 -30
- package/src/runtime/hooks.ts +2 -0
- package/src/runtime/lifecycle.ts +14 -9
- package/src/runtime/router.ts +2 -0
- package/src/runtime/tool-calls.ts +5 -8
- package/vendor.js +1 -3
- package/connect.d.ts +0 -4
- package/connect.d.ts.map +0 -1
package/src/runtime/lifecycle.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { formatExit, listed, messageOf } from '../utils/text.js'
|
|
|
6
6
|
import type { Claude } from './claude.js'
|
|
7
7
|
import { beforeDeadline } from './deadline.js'
|
|
8
8
|
import { answerCall, dependencyCalls, notInstalled } from './dependencies.js'
|
|
9
|
-
import { classicHook, userSkillHook, type RoutedEvent } from './hooks.js'
|
|
9
|
+
import { classicHook, permissionEvents, userSkillHook, type RoutedEvent } from './hooks.js'
|
|
10
10
|
import { createRouter, type Router, type RouterNext } from './router.js'
|
|
11
11
|
import { createState } from './state.js'
|
|
12
12
|
import { toolCalls } from './tool-calls.js'
|
|
@@ -36,6 +36,7 @@ type ModRuntime = {
|
|
|
36
36
|
readonly router: Router
|
|
37
37
|
readonly progress: Progress
|
|
38
38
|
readonly dataFolder: string
|
|
39
|
+
readonly checksPermissions: () => boolean
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
type ActiveMod<State extends object> = {
|
|
@@ -120,7 +121,7 @@ async function cmodVersion(claude: Claude): Promise<string | undefined> {
|
|
|
120
121
|
return result.stdout.trim().split(/\s+/).at(-1)
|
|
121
122
|
}
|
|
122
123
|
|
|
123
|
-
export function createLifecycle<State extends object>(definition: ModDefinition<State
|
|
124
|
+
export function createLifecycle<State extends object>(definition: ModDefinition<State>, checksPermissions: () => boolean = () => true): Lifecycle<State> {
|
|
124
125
|
let router: Router = createRouter()
|
|
125
126
|
let phase: Phase = 'starting'
|
|
126
127
|
let runtime: Pick<ModRuntime, 'claude' | 'progress'> | undefined
|
|
@@ -136,7 +137,7 @@ export function createLifecycle<State extends object>(definition: ModDefinition<
|
|
|
136
137
|
const startSettled = new Promise<void>((resolve) => (settleStart = resolve))
|
|
137
138
|
|
|
138
139
|
const claude = () => {
|
|
139
|
-
if (runtime === undefined) throw new Error(`${definition.name}: the lifecycle has not started.
|
|
140
|
+
if (runtime === undefined) throw new Error(`${definition.name}: the lifecycle has not started. registerMod(addHook, mod) starts it at session.start.`)
|
|
140
141
|
return runtime.claude
|
|
141
142
|
}
|
|
142
143
|
|
|
@@ -171,7 +172,7 @@ export function createLifecycle<State extends object>(definition: ModDefinition<
|
|
|
171
172
|
|
|
172
173
|
const record = () => {
|
|
173
174
|
recording ??= recordThroughCmod()
|
|
174
|
-
.catch((error: unknown) => claude().ui.log(`${definition.name} has no
|
|
175
|
+
.catch((error: unknown) => claude().ui.log(`${definition.name} has no cmod record yet: ${messageOf(error)}`, { to: 'debug' }))
|
|
175
176
|
.finally(() => {
|
|
176
177
|
recording = undefined
|
|
177
178
|
})
|
|
@@ -180,7 +181,7 @@ export function createLifecycle<State extends object>(definition: ModDefinition<
|
|
|
180
181
|
const activate = async () => {
|
|
181
182
|
if (runtime === undefined || plugin === undefined) return
|
|
182
183
|
const activeRouter = createRouter()
|
|
183
|
-
const active = await createMod(definition, { ...runtime, router: activeRouter, dataFolder: dataFolder(plugin.store, plugin.name) }).catch((error: unknown) => {
|
|
184
|
+
const active = await createMod(definition, { ...runtime, router: activeRouter, dataFolder: dataFolder(plugin.store, plugin.name), checksPermissions }).catch((error: unknown) => {
|
|
184
185
|
fail(messageOf(error), 'Fix it, then run /reload-plugins.')
|
|
185
186
|
throw error
|
|
186
187
|
})
|
|
@@ -226,7 +227,7 @@ export function createLifecycle<State extends object>(definition: ModDefinition<
|
|
|
226
227
|
if (plugin === undefined) return
|
|
227
228
|
if (plugin.name === cmodPluginName) return bootstrap(plugin.root)
|
|
228
229
|
phase = 'installing'
|
|
229
|
-
if ((await cmodVersion(claude())) === undefined) return
|
|
230
|
+
if ((await cmodVersion(claude())) === undefined) return waitForcmod()
|
|
230
231
|
endLine()
|
|
231
232
|
const progress = showLine()
|
|
232
233
|
let outcome: RunnerEvent | undefined
|
|
@@ -242,9 +243,9 @@ export function createLifecycle<State extends object>(definition: ModDefinition<
|
|
|
242
243
|
fail(reason, `Fix the cause, then run: cmod install ${definition.name}`)
|
|
243
244
|
}
|
|
244
245
|
|
|
245
|
-
const
|
|
246
|
+
const waitForcmod = () => {
|
|
246
247
|
phase = 'waiting'
|
|
247
|
-
showLine().wait('Waiting for
|
|
248
|
+
showLine().wait('Waiting for cmod')
|
|
248
249
|
let check: Promise<void> | undefined
|
|
249
250
|
const stop = () => {
|
|
250
251
|
timer.cancel()
|
|
@@ -263,7 +264,7 @@ export function createLifecycle<State extends object>(definition: ModDefinition<
|
|
|
263
264
|
report(error)
|
|
264
265
|
})
|
|
265
266
|
})
|
|
266
|
-
const longWait = claude().clock.after(cmodWaitMs, () => showLine().wait("Still waiting for
|
|
267
|
+
const longWait = claude().clock.after(cmodWaitMs, () => showLine().wait("Still waiting for cmod to download cmod. See cmod's own line."))
|
|
267
268
|
}
|
|
268
269
|
|
|
269
270
|
const bootstrap = async (root: string) => {
|
|
@@ -447,6 +448,10 @@ async function createMod<State extends object>(definition: ModDefinition<State>,
|
|
|
447
448
|
}
|
|
448
449
|
await failsAs('its state did not load', () => modState.load())
|
|
449
450
|
await failsAs('its setup function threw', () => definition.setup(mod))
|
|
451
|
+
const permissionHooks = permissionEvents.filter((event) => router.has(event))
|
|
452
|
+
if (permissionHooks.length > 0 && !runtime.checksPermissions()) {
|
|
453
|
+
throw new Error(`it decides permissions on ${listed(permissionHooks)}, so hooks/register.ts must call registerPermissionCheck(addHook) after registerMod`)
|
|
454
|
+
}
|
|
450
455
|
await failsAs('its open panes did not load', () => area.restorePanes())
|
|
451
456
|
if (hookEvents.length > 0) added.push(`${hookEvents.length === 1 ? 'a hook' : 'hooks'} on ${listed(hookEvents)}`)
|
|
452
457
|
return { mod, added }
|
package/src/runtime/router.ts
CHANGED
|
@@ -7,6 +7,7 @@ export type RoutedHook<N extends RoutedEvent> = (e: Frozen<Args<N>>, next: Route
|
|
|
7
7
|
|
|
8
8
|
export type Router = {
|
|
9
9
|
add<N extends RoutedEvent>(event: N, hook: RoutedHook<N>): void
|
|
10
|
+
has(event: RoutedEvent): boolean
|
|
10
11
|
dispatch<N extends RoutedEvent>(event: N, e: Frozen<Args<N>>, next: RouterNext<N>): Promise<EventResult<N>>
|
|
11
12
|
}
|
|
12
13
|
|
|
@@ -21,6 +22,7 @@ export function createRouter(): Router {
|
|
|
21
22
|
chain.push(hook as unknown as ErasedHook)
|
|
22
23
|
hooks.set(event, chain)
|
|
23
24
|
},
|
|
25
|
+
has: (event) => hooks.has(event),
|
|
24
26
|
dispatch<N extends RoutedEvent>(event: N, e: Frozen<Args<N>>, next: RouterNext<N>): Promise<EventResult<N>> {
|
|
25
27
|
const chain = hooks.get(event)
|
|
26
28
|
const call = async (index: number, current: unknown): Promise<unknown> => {
|
|
@@ -34,6 +34,11 @@ export function toolCalls(claude: Claude, router: Router): ToolCalls {
|
|
|
34
34
|
return next(e)
|
|
35
35
|
})
|
|
36
36
|
router.add('tool.call', async (e, next) => {
|
|
37
|
+
cwds.set(e.tool_use_id, await claude.session.cwd())
|
|
38
|
+
for (const oldest of cwds.keys()) {
|
|
39
|
+
if (cwds.size <= keptCalls) break
|
|
40
|
+
cwds.delete(oldest)
|
|
41
|
+
}
|
|
37
42
|
if (e.agentId === undefined) return next(e)
|
|
38
43
|
agentIds.set(e.tool_use_id, e.agentId)
|
|
39
44
|
try {
|
|
@@ -42,14 +47,6 @@ export function toolCalls(claude: Claude, router: Router): ToolCalls {
|
|
|
42
47
|
agentIds.delete(e.tool_use_id)
|
|
43
48
|
}
|
|
44
49
|
})
|
|
45
|
-
router.add('classic.PreToolUse', async (e, next) => {
|
|
46
|
-
cwds.set(e.tool_use_id, await claude.session.cwd())
|
|
47
|
-
for (const oldest of cwds.keys()) {
|
|
48
|
-
if (cwds.size <= keptCalls) break
|
|
49
|
-
cwds.delete(oldest)
|
|
50
|
-
}
|
|
51
|
-
return next(e)
|
|
52
|
-
})
|
|
53
50
|
for (const event of ['classic.PostToolUse', 'classic.PostToolUseFailure'] as const) {
|
|
54
51
|
router.add(event, async (e, next) => {
|
|
55
52
|
try {
|
package/vendor.js
CHANGED
|
@@ -179,9 +179,7 @@ var require_utils = __commonJS((exports) => {
|
|
|
179
179
|
const platform = navigator.platform.toLowerCase();
|
|
180
180
|
return platform === "win32" || platform === "windows";
|
|
181
181
|
}
|
|
182
|
-
if (
|
|
183
|
-
return process.platform === "win32";
|
|
184
|
-
}
|
|
182
|
+
if (false) {}
|
|
185
183
|
return false;
|
|
186
184
|
};
|
|
187
185
|
exports.removeBackslashes = (str) => {
|
package/connect.d.ts
DELETED
package/connect.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["src/connect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoD,EAAE,EAAE,MAAM,aAAa,CAAA;AACvF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAwE7C,wBAAgB,OAAO,CAAC,KAAK,SAAS,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,IAAI,CA8B5F"}
|