@cmodjs/core 0.1.5 → 0.1.7
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 +4 -3
- package/docs/hooks.md +2 -0
- package/docs/index.md +4 -4
- package/docs/jobs.md +23 -22
- package/docs/mod.md +24 -9
- 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 +2 -2
- package/register.d.ts +5 -0
- package/register.d.ts.map +1 -0
- package/{connect.js → register.js} +42 -39
- 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 +16 -13
- 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 +3 -2
- package/runtime/tool-calls.d.ts.map +1 -1
- package/runtime/tool-calls.js +11 -14
- 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/{connect.ts → register.ts} +44 -40
- package/src/runtime/hooks.ts +2 -0
- package/src/runtime/lifecycle.ts +18 -14
- package/src/runtime/router.ts +2 -0
- package/src/runtime/tool-calls.ts +12 -14
- package/vendor.js +1 -3
- package/connect.d.ts +0 -4
- package/connect.d.ts.map +0 -1
- package/jobs/part-context.d.ts +0 -14
- package/jobs/part-context.d.ts.map +0 -1
package/jobs/slash-command.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { parse } from '../vendor.js';
|
|
2
2
|
import { longestMs } from '../runtime/deadline.js';
|
|
3
3
|
import { messageOf } from '../utils/text.js';
|
|
4
|
-
import { modWithin } from './
|
|
4
|
+
import { modWithin } from './context.js';
|
|
5
5
|
const deadline = { ms: 30000, longestMs, job: 'slashCommand' };
|
|
6
6
|
const commandName = /^[A-Za-z0-9_-]{1,64}$/;
|
|
7
7
|
export function slashCommand(options) {
|
|
8
8
|
const { name, description, argumentHint, immediate, reply } = options;
|
|
9
|
-
return (
|
|
10
|
-
const { mod, claude,
|
|
9
|
+
return (job) => {
|
|
10
|
+
const { mod, claude, announce, reserveName } = job;
|
|
11
11
|
if (!commandName.test(name))
|
|
12
12
|
throw new Error(`${mod.name}: "${name}" is not a slash command name. Use 1 to 64 letters, digits, "_", or "-", without the slash.`);
|
|
13
13
|
reserveName('slashCommand', name, `${mod.name}: the slash command /${name} is already added. Give each slashCommand its own name.`);
|
|
@@ -18,8 +18,8 @@ export function slashCommand(options) {
|
|
|
18
18
|
claude.ui.log(`${mod.name}: /${name} is not added: ${oneLine(error)}`);
|
|
19
19
|
});
|
|
20
20
|
announce(`/${name}`);
|
|
21
|
-
const replyMod = modWithin(
|
|
22
|
-
on('command.run', async (e, next) => {
|
|
21
|
+
const replyMod = modWithin(job, deadline);
|
|
22
|
+
job.on('command.run', async (e, next) => {
|
|
23
23
|
if (e.command !== registered)
|
|
24
24
|
return next(e);
|
|
25
25
|
try {
|
package/jobs/status-line.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Job, Mod } from '../mod.js';
|
|
2
2
|
export type Usage = {
|
|
3
3
|
model: string;
|
|
4
4
|
context: {
|
|
@@ -13,5 +13,5 @@ export type Usage = {
|
|
|
13
13
|
export declare function statusLine<State extends object = Record<never, never>>(options: {
|
|
14
14
|
readonly text: (usage: Usage, mod: Mod<State>) => string | undefined | Promise<string | undefined>;
|
|
15
15
|
readonly interval?: number;
|
|
16
|
-
}):
|
|
16
|
+
}): Job<void, State>;
|
|
17
17
|
//# sourceMappingURL=status-line.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status-line.d.ts","sourceRoot":"","sources":["../src/jobs/status-line.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,
|
|
1
|
+
{"version":3,"file":"status-line.d.ts","sourceRoot":"","sources":["../src/jobs/status-line.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAKzC,MAAM,MAAM,KAAK,GAAG;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9D,IAAI,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CACvB,CAAA;AAID,wBAAgB,UAAU,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE;IAC/E,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAClG,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAyCnB"}
|
package/jobs/status-line.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { messageOf } from '../utils/text.js';
|
|
2
|
-
import { modWithin } from './
|
|
2
|
+
import { modWithin } from './context.js';
|
|
3
3
|
const deadline = { ms: 2000, job: 'statusLine' };
|
|
4
4
|
export function statusLine(options) {
|
|
5
5
|
const { text, interval = 10000 } = options;
|
|
6
|
-
return (
|
|
7
|
-
const { mod, claude,
|
|
6
|
+
return (job) => {
|
|
7
|
+
const { mod, claude, announce, reserveName } = job;
|
|
8
8
|
if (!(interval >= 1))
|
|
9
9
|
throw new Error(`${mod.name}: the status line interval is ${interval}. Give it in milliseconds, 1 or more.`);
|
|
10
10
|
reserveName('statusLine', '', `${mod.name}: a status line is already added. A mod has one status line: join the texts in one statusLine.`);
|
|
11
|
-
const textMod = modWithin(
|
|
11
|
+
const textMod = modWithin(job, deadline);
|
|
12
12
|
let shown;
|
|
13
13
|
let queue = Promise.resolve();
|
|
14
14
|
const update = async () => {
|
|
@@ -33,7 +33,7 @@ export function statusLine(options) {
|
|
|
33
33
|
queue = queue.then(update);
|
|
34
34
|
};
|
|
35
35
|
announce('a status line');
|
|
36
|
-
on('session.measure', (e, next) => {
|
|
36
|
+
job.on('session.measure', (e, next) => {
|
|
37
37
|
refresh();
|
|
38
38
|
return next(e);
|
|
39
39
|
});
|
package/jobs/tool.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Job, Mod } from '../mod.js';
|
|
3
3
|
export declare function tool<const Schema extends object = {
|
|
4
4
|
type: 'object';
|
|
5
5
|
}, State extends object = Record<never, never>>(options: {
|
|
@@ -7,7 +7,7 @@ export declare function tool<const Schema extends object = {
|
|
|
7
7
|
readonly description: string;
|
|
8
8
|
readonly inputSchema?: Schema;
|
|
9
9
|
readonly execute: (input: Schema extends JSONSchema ? FromSchema<Schema> : never, mod: Mod<State>) => unknown;
|
|
10
|
-
}):
|
|
10
|
+
}): Job<{
|
|
11
11
|
readonly name: string;
|
|
12
12
|
}, State>;
|
|
13
13
|
//# sourceMappingURL=tool.d.ts.map
|
package/jobs/tool.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../src/jobs/tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,KAAK,EAAE,GAAG,EAAE,
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../src/jobs/tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AASzC,wBAAgB,IAAI,CAAC,KAAK,CAAC,MAAM,SAAS,MAAM,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,EAAE,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE;IAC3H,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,SAAS,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,OAAO,CAAA;CAC9G,GAAG,GAAG,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,KAAK,CAAC,CAoCxC"}
|
package/jobs/tool.js
CHANGED
|
@@ -2,12 +2,12 @@ import { Validator } from '../vendor.js';
|
|
|
2
2
|
import { toolDeadline } from '../runtime/deadline.js';
|
|
3
3
|
import { reservedKeys, toolInputOf } from '../runtime/tool-calls.js';
|
|
4
4
|
import { messageOf } from '../utils/text.js';
|
|
5
|
-
import { modWithin } from './
|
|
5
|
+
import { modWithin } from './context.js';
|
|
6
6
|
const toolName = /^[A-Za-z0-9_-]{1,64}$/;
|
|
7
7
|
export function tool(options) {
|
|
8
8
|
const { name, description, inputSchema, execute } = options;
|
|
9
|
-
return (
|
|
10
|
-
const { mod, claude,
|
|
9
|
+
return (job) => {
|
|
10
|
+
const { mod, claude, announce, reserveName } = job;
|
|
11
11
|
if (!toolName.test(name))
|
|
12
12
|
throw new Error(`${mod.name}: "${name}" is not a tool name. Use 1 to 64 letters, digits, "_", or "-".`);
|
|
13
13
|
const properties = inputSchema?.properties ?? {};
|
|
@@ -23,8 +23,8 @@ export function tool(options) {
|
|
|
23
23
|
claude.ui.log(`${mod.name}: the ${name} tool is not added: ${messageOf(error)}`);
|
|
24
24
|
});
|
|
25
25
|
announce(`the ${name} tool`);
|
|
26
|
-
const executeMod = modWithin(
|
|
27
|
-
on('tool.call', async (e, next) => {
|
|
26
|
+
const executeMod = modWithin(job, toolDeadline);
|
|
27
|
+
job.on('tool.call', async (e, next) => {
|
|
28
28
|
if (e.tool !== registered)
|
|
29
29
|
return next(e);
|
|
30
30
|
const input = toolInputOf(e);
|
package/mod.d.ts
CHANGED
|
@@ -75,7 +75,7 @@ export type Mod<State extends object = Record<never, never>> = {
|
|
|
75
75
|
readonly state: Readonly<State>;
|
|
76
76
|
readonly dataFolder: string;
|
|
77
77
|
on<E extends ModEvent>(event: E, hook: ModHook<E>): void;
|
|
78
|
-
use<Handle>(
|
|
78
|
+
use<Handle>(job: Job<Handle, State>): Handle;
|
|
79
79
|
readonly ui: {
|
|
80
80
|
pane(pane: Pane<State>): PaneHandle;
|
|
81
81
|
render<S extends Slot>(slot: S, Component: (props: SlotProps<S>) => RenderElement): void;
|
|
@@ -119,7 +119,7 @@ export type ModDefinition<State extends StateGroups = Record<never, never>, Name
|
|
|
119
119
|
};
|
|
120
120
|
setup(mod: Mod<State>): void | Promise<void>;
|
|
121
121
|
};
|
|
122
|
-
export type
|
|
122
|
+
export type JobContext<State extends object = Record<never, never>> = {
|
|
123
123
|
readonly mod: Mod<State>;
|
|
124
124
|
readonly claude: Claude;
|
|
125
125
|
on<N extends RoutedEvent>(event: N, hook: RoutedHook<N>): void;
|
|
@@ -127,6 +127,6 @@ export type PartContext<State extends object = Record<never, never>> = {
|
|
|
127
127
|
reserveName(kind: string, name: string, taken: string): void;
|
|
128
128
|
readonly toolCalls: ToolCalls;
|
|
129
129
|
};
|
|
130
|
-
export type
|
|
130
|
+
export type Job<Handle, State extends object = Record<never, never>> = (context: JobContext<State>) => Handle;
|
|
131
131
|
export declare function defineMod<State extends StateGroups = Record<never, never>, Name extends string = string>(definition: ModDefinition<State, Name>): ModDefinition<State, Name>;
|
|
132
132
|
//# sourceMappingURL=mod.d.ts.map
|
package/mod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["src/mod.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,OAAO,EACP,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,yBAAyB,EACzB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,QAAQ,EACR,gBAAgB,EACjB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAEpD,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACzB,CAAA;AAED,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,MAAM,MAAM,QAAQ,GAChB,cAAc,GACd,YAAY,GACZ,kBAAkB,GAClB,oBAAoB,GACpB,YAAY,GACZ,mBAAmB,GACnB,kBAAkB,GAClB,aAAa,GACb,oBAAoB,GACpB,eAAe,GACf,eAAe,GACf,cAAc,GACd,cAAc,GACd,YAAY,GACZ,MAAM,GACN,aAAa,GACb,YAAY,CAAA;AAEhB,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,kBAAkB,CAAC,EAAE;QACnB,aAAa,CAAC,EAAE,QAAQ,CAAA;QACxB,iBAAiB,CAAC,EAAE,MAAM,CAAA;QAC1B,kBAAkB,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAA;QAC7C,wBAAwB,CAAC,EAAE,MAAM,CAAA;QACjC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACtC,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,sBAAsB,CAAC,EAAE,OAAO,CAAA;QAChC,kBAAkB,CAAC,EAAE,MAAM,CAAA;QAC3B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;QACrB,YAAY,CAAC,EAAE,OAAO,CAAA;QACtB,QAAQ,CAAC,EAAE,yBAAyB,CAAA;QACpC,iBAAiB,CAAC,EAAE,OAAO,CAAA;QAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAA;QAC9B,KAAK,CAAC,EAAE,OAAO,CAAA;KAChB,CAAA;CACF,CAAA;AAED,KAAK,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAEtD,KAAK,UAAU,GAAG,IAAI,CAAC,iBAAiB,EAAE,YAAY,GAAG,aAAa,GAAG,oBAAoB,GAAG,YAAY,CAAC,GAAG;IAC9G,UAAU,EAAE;QACV,UAAU,EAAE,MAAM,CAAA;QAClB,GAAG,EAAE,MAAM,CAAA;QACX,eAAe,EAAE,YAAY,CAAA;QAC7B,SAAS,EAAE,MAAM,CAAA;QACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACnC,WAAW,EAAE,MAAM,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,KAAK,EAAE,SAAS,CAAA;KACjB,CAAA;IACD,WAAW,EAAE,iBAAiB,CAAC,aAAa,CAAC,GAAG;QAAE,KAAK,EAAE,SAAS,CAAA;KAAE,CAAA;IACpE,kBAAkB,EAAE,iBAAiB,CAAC,oBAAoB,CAAC,GAAG;QAAE,KAAK,EAAE,SAAS,CAAA;KAAE,CAAA;IAClF,UAAU,EAAE,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAC,CAAA;CACrE,CAAA;AAED,MAAM,MAAM,OAAO,CAAC,CAAC,SAAS,QAAQ,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,GAAG,IAAI,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;AAElH,MAAM,MAAM,GAAG,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,EAAE,CAAC,CAAC,SAAS,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;IACxD,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,CAAA;IAC5C,QAAQ,CAAC,EAAE,EAAE;QACX,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,UAAU,CAAA;QACnC,MAAM,CAAC,CAAC,SAAS,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,aAAa,GAAG,IAAI,CAAA;QACxF,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;QAClG,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;KACjF,CAAA;IACD,QAAQ,CAAC,OAAO,EAAE;QAChB,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;QAC9E,KAAK,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,GAAG,UAAU,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,CAAA;KAC5H,CAAA;IACD,QAAQ,CAAC,EAAE,EAAE;QACX,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;QACnC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;QAChD,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;KACxC,CAAA;IACD,QAAQ,CAAC,IAAI,EAAE;QACb,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;KAC3D,CAAA;IACD,QAAQ,CAAC,QAAQ,EAAE;QACjB,IAAI,CAAC,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;KACjD,CAAA;IACD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAA;CACxC,CAAA;AAED,KAAK,WAAW,GAAG;IACjB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,KAAK,GAAG,CAAC,QAAQ,EAAE,KAAK,SAAS,MAAM,IAAI;IACzC,QAAQ,EAAE,MAAM,IAAI,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK;CACzK,CAAA;AAED,MAAM,MAAM,aAAa,CAAC,KAAK,SAAS,WAAW,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,IAAI,SAAS,MAAM,GAAG,MAAM,IAAI;IAC1G,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAA;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,SAAS,MAAM,gBAAgB,GAAG,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,GAAG;QAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,OAAO,CAAA;KAAE,CAAA;IACnK,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7C,CAAA;AAED,MAAM,MAAM,UAAU,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI;IACpE,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,EAAE,CAAC,CAAC,SAAS,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;IAC9D,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5D,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,MAAM,CAAA;AAE7G,wBAAgB,SAAS,CAAC,KAAK,SAAS,WAAW,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,IAAI,SAAS,MAAM,GAAG,MAAM,EAAE,UAAU,EAAE,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAG5K"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cmodjs/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Build Claude Code mods: hooks, panes, permissions, checks, and an install that just works.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"docs/"
|
|
26
26
|
],
|
|
27
27
|
"scripts": {
|
|
28
|
-
"build": "tsc -p tsconfig.build.json && bun build src/vendor.ts --outfile vendor.js --format esm --target browser && NODE_ENV=production bun build src/vendor-markdown.ts --outfile vendor-markdown.js --format esm --target browser --conditions worker",
|
|
28
|
+
"build": "tsc -p tsconfig.build.json && bun build src/vendor.ts --outfile vendor.js --format esm --target browser --define process=undefined && NODE_ENV=production bun build src/vendor-markdown.ts --outfile vendor-markdown.js --format esm --target browser --conditions worker",
|
|
29
29
|
"check": "tsc -p tsconfig.json --noEmit && oxlint --deny-warnings",
|
|
30
30
|
"test": "bun test"
|
|
31
31
|
},
|
package/register.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { On } from 'claude-code';
|
|
2
|
+
import type { ModDefinition } from './mod.js';
|
|
3
|
+
export declare function registerMod<State extends object>(addHook: On, definition: ModDefinition<State>): void;
|
|
4
|
+
export declare function registerPermissionCheck(addHook: On): void;
|
|
5
|
+
//# sourceMappingURL=register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["src/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoD,EAAE,EAAE,MAAM,aAAa,CAAA;AACvF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AA0E7C,wBAAgB,WAAW,CAAC,KAAK,SAAS,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,IAAI,CA4BrG;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,EAAE,GAAG,IAAI,CAKzD"}
|
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
import { createLifecycle, readPlugin } from './runtime/lifecycle.js';
|
|
2
2
|
let lifecycle;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
function routeToMod(_$, e, next) {
|
|
8
|
-
return lifecycle.route(next.event, e, (passed) => next(passed));
|
|
9
|
-
}
|
|
10
|
-
function claudeOf($) {
|
|
11
|
-
return {
|
|
3
|
+
let checksPermissions = false;
|
|
4
|
+
async function startMod($, eventInput, passOn) {
|
|
5
|
+
const claude = {
|
|
12
6
|
plugin: { name: $.plugin.name, root: $.plugin.root },
|
|
13
7
|
ui: {
|
|
14
8
|
toast: (text, options) => $.ui.toast(text, options),
|
|
@@ -64,35 +58,44 @@ function claudeOf($) {
|
|
|
64
58
|
},
|
|
65
59
|
cmod: { call: (input) => $.cmod.call(input) },
|
|
66
60
|
};
|
|
61
|
+
await lifecycle.start(claude, readPlugin);
|
|
62
|
+
return passOn(eventInput);
|
|
63
|
+
}
|
|
64
|
+
function routeToMod(_$, eventInput, passOn) {
|
|
65
|
+
return lifecycle.route(passOn.event, eventInput, (passed) => passOn(passed));
|
|
66
|
+
}
|
|
67
|
+
export function registerMod(addHook, definition) {
|
|
68
|
+
checksPermissions = false;
|
|
69
|
+
lifecycle = createLifecycle(definition, () => checksPermissions);
|
|
70
|
+
addHook('session.start', startMod);
|
|
71
|
+
addHook('classic.SessionStart', routeToMod);
|
|
72
|
+
addHook('classic.SessionEnd', routeToMod);
|
|
73
|
+
addHook('classic.UserPromptSubmit', routeToMod);
|
|
74
|
+
addHook('classic.InstructionsLoaded', routeToMod);
|
|
75
|
+
addHook('classic.PermissionDenied', routeToMod);
|
|
76
|
+
addHook('classic.PostToolUse', routeToMod);
|
|
77
|
+
addHook('classic.PostToolUseFailure', routeToMod);
|
|
78
|
+
addHook('classic.PostToolBatch', routeToMod);
|
|
79
|
+
addHook('classic.SubagentStart', routeToMod);
|
|
80
|
+
addHook('classic.SubagentStop', routeToMod);
|
|
81
|
+
addHook('classic.Notification', routeToMod);
|
|
82
|
+
addHook('classic.PreCompact', routeToMod);
|
|
83
|
+
addHook('classic.Stop', routeToMod);
|
|
84
|
+
addHook('classic.StopFailure', routeToMod);
|
|
85
|
+
addHook('tool.call', routeToMod);
|
|
86
|
+
addHook('prompt.submit', routeToMod);
|
|
87
|
+
addHook('prompt.context', routeToMod);
|
|
88
|
+
addHook('command.run', routeToMod);
|
|
89
|
+
addHook('session.measure', routeToMod);
|
|
90
|
+
addHook('skill.prompt', routeToMod);
|
|
91
|
+
addHook('ui.render', routeToMod);
|
|
92
|
+
addHook('ui.press', routeToMod);
|
|
93
|
+
addHook('ui.close', routeToMod);
|
|
94
|
+
addHook('cmod.call', routeToMod);
|
|
67
95
|
}
|
|
68
|
-
export function
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
on('classic.UserPromptSubmit', routeToMod);
|
|
74
|
-
on('classic.InstructionsLoaded', routeToMod);
|
|
75
|
-
on('classic.PreToolUse', routeToMod);
|
|
76
|
-
on('classic.PermissionRequest', routeToMod);
|
|
77
|
-
on('classic.PermissionDenied', routeToMod);
|
|
78
|
-
on('classic.PostToolUse', routeToMod);
|
|
79
|
-
on('classic.PostToolUseFailure', routeToMod);
|
|
80
|
-
on('classic.PostToolBatch', routeToMod);
|
|
81
|
-
on('classic.SubagentStart', routeToMod);
|
|
82
|
-
on('classic.SubagentStop', routeToMod);
|
|
83
|
-
on('classic.Notification', routeToMod);
|
|
84
|
-
on('classic.PreCompact', routeToMod);
|
|
85
|
-
on('classic.Stop', routeToMod);
|
|
86
|
-
on('classic.StopFailure', routeToMod);
|
|
87
|
-
on('tool.check', routeToMod);
|
|
88
|
-
on('tool.call', routeToMod);
|
|
89
|
-
on('prompt.submit', routeToMod);
|
|
90
|
-
on('prompt.context', routeToMod);
|
|
91
|
-
on('command.run', routeToMod);
|
|
92
|
-
on('session.measure', routeToMod);
|
|
93
|
-
on('skill.prompt', routeToMod);
|
|
94
|
-
on('ui.render', routeToMod);
|
|
95
|
-
on('ui.press', routeToMod);
|
|
96
|
-
on('ui.close', routeToMod);
|
|
97
|
-
on('cmod.call', routeToMod);
|
|
96
|
+
export function registerPermissionCheck(addHook) {
|
|
97
|
+
checksPermissions = true;
|
|
98
|
+
addHook('tool.check', routeToMod);
|
|
99
|
+
addHook('classic.PreToolUse', routeToMod);
|
|
100
|
+
addHook('classic.PermissionRequest', routeToMod);
|
|
98
101
|
}
|
package/runtime/hooks.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { Claude } from './claude.js';
|
|
|
3
3
|
import type { RoutedHook } from './router.js';
|
|
4
4
|
import { type ToolCalls } from './tool-calls.js';
|
|
5
5
|
export type RoutedEvent = `classic.${ModEvent}` | 'tool.check' | 'tool.call' | 'prompt.submit' | 'prompt.context' | 'command.run' | 'session.measure' | 'skill.prompt' | 'ui.render' | 'ui.press' | 'ui.close' | 'cmod.call';
|
|
6
|
+
export declare const permissionEvents: readonly RoutedEvent[];
|
|
6
7
|
export declare function classicHook<E extends ModEvent>(name: string, event: E, hook: ModHook<E>, claude: Claude, calls: ToolCalls): RoutedHook<RoutedEvent>;
|
|
7
8
|
export declare function userSkillHook(claude: Claude): RoutedHook<'skill.prompt'>;
|
|
8
9
|
export declare const strictness: readonly ['allow', 'ask', 'deny'];
|
package/runtime/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/runtime/hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAE9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAK7D,MAAM,MAAM,WAAW,GACnB,WAAW,QAAQ,EAAE,GACrB,YAAY,GACZ,WAAW,GACX,eAAe,GACf,gBAAgB,GAChB,aAAa,GACb,iBAAiB,GACjB,cAAc,GACd,WAAW,GACX,UAAU,GACV,UAAU,GACV,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/runtime/hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAE9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAK7D,MAAM,MAAM,WAAW,GACnB,WAAW,QAAQ,EAAE,GACrB,YAAY,GACZ,WAAW,GACX,eAAe,GACf,gBAAgB,GAChB,aAAa,GACb,iBAAiB,GACjB,cAAc,GACd,WAAW,GACX,UAAU,GACV,UAAU,GACV,WAAW,CAAA;AAEf,eAAO,MAAM,gBAAgB,EAAE,SAAS,WAAW,EAAsE,CAAA;AA8BzH,wBAAgB,WAAW,CAAC,CAAC,SAAS,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,CA0BnJ;AAMD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC,cAAc,CAAC,CAexE;AA4DD,eAAO,MAAM,UAAU,YAAI,OAAO,EAAE,KAAK,EAAE,MAAM,CAAU,CAAA"}
|
package/runtime/hooks.js
CHANGED
|
@@ -3,6 +3,7 @@ import { toolInputOf } from './tool-calls.js';
|
|
|
3
3
|
import { callEffects } from '../utils/call-effects.js';
|
|
4
4
|
import { dynamicPattern } from '../utils/parse-shell.js';
|
|
5
5
|
import { messageOf } from '../utils/text.js';
|
|
6
|
+
export const permissionEvents = ['tool.check', 'classic.PreToolUse', 'classic.PermissionRequest'];
|
|
6
7
|
const flags = ['suppressOriginalPrompt', 'reloadSkills', 'retry'];
|
|
7
8
|
const readFields = {
|
|
8
9
|
SessionStart: ['additionalContext', 'initialUserMessage', 'sessionTitle', 'watchPaths', 'reloadSkills'],
|
package/runtime/lifecycle.d.ts
CHANGED
|
@@ -20,5 +20,5 @@ export type Lifecycle<State extends object> = {
|
|
|
20
20
|
route<N extends RoutedEvent>(event: N, e: Frozen<Args<N>>, next: RouterNext<N>): Promise<EventResult<N>>;
|
|
21
21
|
};
|
|
22
22
|
export declare function readPlugin(claude: Claude): Promise<Plugin>;
|
|
23
|
-
export declare function createLifecycle<State extends object>(definition: ModDefinition<State
|
|
23
|
+
export declare function createLifecycle<State extends object>(definition: ModDefinition<State>, checksPermissions?: () => boolean): Lifecycle<State>;
|
|
24
24
|
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/runtime/lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAiE,MAAM,aAAa,CAAA;AAC3H,OAAO,KAAK,EAAE,GAAG,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/runtime/lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAiE,MAAM,aAAa,CAAA;AAC3H,OAAO,KAAK,EAAE,GAAG,EAAE,aAAa,EAAqB,MAAM,WAAW,CAAA;AAItE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGzC,OAAO,EAAgD,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAC3F,OAAO,EAA6B,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAKxE,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;CAC/B,CAAA;AAED,MAAM,MAAM,KAAK,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAA;AAEtG,MAAM,MAAM,SAAS,CAAC,KAAK,SAAS,MAAM,IAAI;IAC5C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/E,KAAK,CAAC,CAAC,SAAS,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;CACzG,CAAA;AAiCD,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBhE;AAkCD,wBAAgB,eAAe,CAAC,KAAK,SAAS,MAAM,EAAE,UAAU,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,iBAAiB,GAAE,MAAM,OAAoB,GAAG,SAAS,CAAC,KAAK,CAAC,CAkOvJ"}
|
package/runtime/lifecycle.js
CHANGED
|
@@ -3,7 +3,7 @@ import { relativePath } from '../utils/paths.js';
|
|
|
3
3
|
import { formatExit, listed, messageOf } from '../utils/text.js';
|
|
4
4
|
import { beforeDeadline } from './deadline.js';
|
|
5
5
|
import { answerCall, dependencyCalls, notInstalled } from './dependencies.js';
|
|
6
|
-
import { classicHook, userSkillHook } from './hooks.js';
|
|
6
|
+
import { classicHook, permissionEvents, userSkillHook } from './hooks.js';
|
|
7
7
|
import { createRouter } from './router.js';
|
|
8
8
|
import { createState } from './state.js';
|
|
9
9
|
import { toolCalls } from './tool-calls.js';
|
|
@@ -79,7 +79,7 @@ async function cmodVersion(claude) {
|
|
|
79
79
|
throw new Error(`cmod --version ${formatExit(result.exitCode, lastLineOf(result.stderr) ?? '')}`);
|
|
80
80
|
return result.stdout.trim().split(/\s+/).at(-1);
|
|
81
81
|
}
|
|
82
|
-
export function createLifecycle(definition) {
|
|
82
|
+
export function createLifecycle(definition, checksPermissions = () => true) {
|
|
83
83
|
let router = createRouter();
|
|
84
84
|
let phase = 'starting';
|
|
85
85
|
let runtime;
|
|
@@ -95,7 +95,7 @@ export function createLifecycle(definition) {
|
|
|
95
95
|
const startSettled = new Promise((resolve) => (settleStart = resolve));
|
|
96
96
|
const claude = () => {
|
|
97
97
|
if (runtime === undefined)
|
|
98
|
-
throw new Error(`${definition.name}: the lifecycle has not started.
|
|
98
|
+
throw new Error(`${definition.name}: the lifecycle has not started. registerMod(addHook, mod) starts it at session.start.`);
|
|
99
99
|
return runtime.claude;
|
|
100
100
|
};
|
|
101
101
|
const showLine = () => {
|
|
@@ -136,7 +136,7 @@ export function createLifecycle(definition) {
|
|
|
136
136
|
if (runtime === undefined || plugin === undefined)
|
|
137
137
|
return;
|
|
138
138
|
const activeRouter = createRouter();
|
|
139
|
-
const active = await createMod(definition, { ...runtime, router: activeRouter, dataFolder: dataFolder(plugin.store, plugin.name) }).catch((error) => {
|
|
139
|
+
const active = await createMod(definition, { ...runtime, router: activeRouter, dataFolder: dataFolder(plugin.store, plugin.name), checksPermissions }).catch((error) => {
|
|
140
140
|
fail(messageOf(error), 'Fix it, then run /reload-plugins.');
|
|
141
141
|
throw error;
|
|
142
142
|
});
|
|
@@ -326,7 +326,6 @@ async function createMod(definition, runtime) {
|
|
|
326
326
|
const announce = (feature) => {
|
|
327
327
|
added.push(feature);
|
|
328
328
|
};
|
|
329
|
-
const on = (event, hook) => router.add(event, hook);
|
|
330
329
|
const [session, root, startCwd] = await Promise.all([claude.session.id(), claude.session.root(), claude.session.cwd()]);
|
|
331
330
|
let cwd = startCwd;
|
|
332
331
|
let loadedCwd = startCwd;
|
|
@@ -342,7 +341,7 @@ async function createMod(definition, runtime) {
|
|
|
342
341
|
hookEvents.push(event);
|
|
343
342
|
router.add(`classic.${event}`, classicHook(definition.name, event, hook, claude, agents));
|
|
344
343
|
},
|
|
345
|
-
use: (
|
|
344
|
+
use: (job) => job({ mod, claude, on: (event, hook) => router.add(event, hook), announce, reserveName, toolCalls: agents }),
|
|
346
345
|
ui: area.ui,
|
|
347
346
|
process: {
|
|
348
347
|
run: (argv, init) => claude.process.run(argv, init),
|
|
@@ -393,34 +392,34 @@ async function createMod(definition, runtime) {
|
|
|
393
392
|
claude.ui.log(`${definition.name} keeps the state of ${modState.root} until the next prompt or folder move: ${messageOf(error)}`);
|
|
394
393
|
}
|
|
395
394
|
};
|
|
396
|
-
|
|
395
|
+
router.add('classic.SessionStart', async (e, next) => {
|
|
397
396
|
await modState.switchSession(e.session_id, e.source).catch((error) => {
|
|
398
397
|
claude.ui.log(`${definition.name} kept its session values from before the ${e.source}: ${messageOf(error)}`);
|
|
399
398
|
});
|
|
400
399
|
return next(e);
|
|
401
400
|
});
|
|
402
|
-
|
|
401
|
+
router.add('classic.UserPromptSubmit', async (e, next) => {
|
|
403
402
|
staleCwd = undefined;
|
|
404
403
|
await followSession();
|
|
405
404
|
return next(e);
|
|
406
405
|
});
|
|
407
406
|
for (const event of ['classic.PostToolUse', 'classic.PostToolUseFailure']) {
|
|
408
|
-
|
|
407
|
+
router.add(event, async (e, next) => {
|
|
409
408
|
if (shellTools.includes(e.tool_name))
|
|
410
409
|
await followSession();
|
|
411
410
|
return next(e);
|
|
412
411
|
});
|
|
413
412
|
}
|
|
414
|
-
|
|
413
|
+
router.add('command.run', async (e, next) => {
|
|
415
414
|
const answer = await next(e);
|
|
416
415
|
if (e.command === 'cd')
|
|
417
416
|
await followSession(true);
|
|
418
417
|
return answer;
|
|
419
418
|
});
|
|
420
|
-
|
|
419
|
+
router.add('skill.prompt', userSkillHook(claude));
|
|
421
420
|
const api = Object.fromEntries(Object.entries(definition.api ?? {}).map(([method, run]) => [method, (input) => run(input, mod)]));
|
|
422
|
-
|
|
423
|
-
const agents = toolCalls(
|
|
421
|
+
router.add('cmod.call', (e, next) => (e.to === definition.name ? answerCall(definition.name, api, e) : next(e)));
|
|
422
|
+
const agents = toolCalls(claude, router);
|
|
424
423
|
const names = new Set();
|
|
425
424
|
const reserveName = (kind, name, taken) => {
|
|
426
425
|
const key = `${kind}:${name}`;
|
|
@@ -430,6 +429,10 @@ async function createMod(definition, runtime) {
|
|
|
430
429
|
};
|
|
431
430
|
await failsAs('its state did not load', () => modState.load());
|
|
432
431
|
await failsAs('its setup function threw', () => definition.setup(mod));
|
|
432
|
+
const permissionHooks = permissionEvents.filter((event) => router.has(event));
|
|
433
|
+
if (permissionHooks.length > 0 && !runtime.checksPermissions()) {
|
|
434
|
+
throw new Error(`it decides permissions on ${listed(permissionHooks)}, so hooks/register.ts must call registerPermissionCheck(addHook) after registerMod`);
|
|
435
|
+
}
|
|
433
436
|
await failsAs('its open panes did not load', () => area.restorePanes());
|
|
434
437
|
if (hookEvents.length > 0)
|
|
435
438
|
added.push(`${hookEvents.length === 1 ? 'a hook' : 'hooks'} on ${listed(hookEvents)}`);
|
package/runtime/router.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export type RouterNext<N extends RoutedEvent> = (e: Frozen<Args<N>>) => Promise<
|
|
|
4
4
|
export type RoutedHook<N extends RoutedEvent> = (e: Frozen<Args<N>>, next: RouterNext<N>) => EventResult<N> | Promise<EventResult<N>>;
|
|
5
5
|
export type Router = {
|
|
6
6
|
add<N extends RoutedEvent>(event: N, hook: RoutedHook<N>): void;
|
|
7
|
+
has(event: RoutedEvent): boolean;
|
|
7
8
|
dispatch<N extends RoutedEvent>(event: N, e: Frozen<Args<N>>, next: RouterNext<N>): Promise<EventResult<N>>;
|
|
8
9
|
};
|
|
9
10
|
export declare function createRouter(): Router;
|
package/runtime/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/runtime/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAE/F,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAErI,MAAM,MAAM,MAAM,GAAG;IACnB,GAAG,CAAC,CAAC,SAAS,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;IAC/D,QAAQ,CAAC,CAAC,SAAS,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;CAC5G,CAAA;AAID,wBAAgB,YAAY,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/runtime/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAE/F,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAErI,MAAM,MAAM,MAAM,GAAG;IACnB,GAAG,CAAC,CAAC,SAAS,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;IAC/D,GAAG,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAA;IAChC,QAAQ,CAAC,CAAC,SAAS,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;CAC5G,CAAA;AAID,wBAAgB,YAAY,IAAI,MAAM,CAoBrC"}
|
package/runtime/router.js
CHANGED
package/runtime/tool-calls.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Claude } from './claude.js';
|
|
2
|
+
import type { Router } from './router.js';
|
|
2
3
|
export type Agent = {
|
|
3
4
|
agentId?: string;
|
|
4
5
|
agentType?: string;
|
|
@@ -9,5 +10,5 @@ export type ToolCalls = {
|
|
|
9
10
|
};
|
|
10
11
|
export declare const reservedKeys: readonly string[];
|
|
11
12
|
export declare function toolInputOf(envelope: object): Record<string, unknown>;
|
|
12
|
-
export declare function toolCalls(
|
|
13
|
+
export declare function toolCalls(claude: Claude, router: Router): ToolCalls;
|
|
13
14
|
//# sourceMappingURL=tool-calls.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-calls.d.ts","sourceRoot":"","sources":["../src/runtime/tool-calls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"tool-calls.d.ts","sourceRoot":"","sources":["../src/runtime/tool-calls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,MAAM,MAAM,KAAK,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAE5D,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;IACtD,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAC7C,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAAkD,CAAA;AAE5F,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAErE;AAMD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CA8CnE"}
|
package/runtime/tool-calls.js
CHANGED
|
@@ -3,7 +3,7 @@ export function toolInputOf(envelope) {
|
|
|
3
3
|
return Object.fromEntries(Object.entries(envelope).filter(([key]) => !reservedKeys.includes(key)));
|
|
4
4
|
}
|
|
5
5
|
const keptCalls = 100;
|
|
6
|
-
export function toolCalls(
|
|
6
|
+
export function toolCalls(claude, router) {
|
|
7
7
|
let mainAgentType;
|
|
8
8
|
const agentIds = new Map();
|
|
9
9
|
const cwds = new Map();
|
|
@@ -11,15 +11,21 @@ export function toolCalls({ claude, on }) {
|
|
|
11
11
|
if (e.agent_id === undefined)
|
|
12
12
|
mainAgentType = e.agent_type;
|
|
13
13
|
};
|
|
14
|
-
|
|
14
|
+
router.add('classic.SessionStart', (e, next) => {
|
|
15
15
|
noteAgent(e);
|
|
16
16
|
return next(e);
|
|
17
17
|
});
|
|
18
|
-
|
|
18
|
+
router.add('classic.UserPromptSubmit', (e, next) => {
|
|
19
19
|
noteAgent(e);
|
|
20
20
|
return next(e);
|
|
21
21
|
});
|
|
22
|
-
|
|
22
|
+
router.add('tool.call', async (e, next) => {
|
|
23
|
+
cwds.set(e.tool_use_id, await claude.session.cwd());
|
|
24
|
+
for (const oldest of cwds.keys()) {
|
|
25
|
+
if (cwds.size <= keptCalls)
|
|
26
|
+
break;
|
|
27
|
+
cwds.delete(oldest);
|
|
28
|
+
}
|
|
23
29
|
if (e.agentId === undefined)
|
|
24
30
|
return next(e);
|
|
25
31
|
agentIds.set(e.tool_use_id, e.agentId);
|
|
@@ -30,17 +36,8 @@ export function toolCalls({ claude, on }) {
|
|
|
30
36
|
agentIds.delete(e.tool_use_id);
|
|
31
37
|
}
|
|
32
38
|
});
|
|
33
|
-
on('classic.PreToolUse', async (e, next) => {
|
|
34
|
-
cwds.set(e.tool_use_id, await claude.session.cwd());
|
|
35
|
-
for (const oldest of cwds.keys()) {
|
|
36
|
-
if (cwds.size <= keptCalls)
|
|
37
|
-
break;
|
|
38
|
-
cwds.delete(oldest);
|
|
39
|
-
}
|
|
40
|
-
return next(e);
|
|
41
|
-
});
|
|
42
39
|
for (const event of ['classic.PostToolUse', 'classic.PostToolUseFailure']) {
|
|
43
|
-
|
|
40
|
+
router.add(event, async (e, next) => {
|
|
44
41
|
try {
|
|
45
42
|
return await next(e);
|
|
46
43
|
}
|
package/src/jobs/check.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Job } from '../mod.js'
|
|
2
2
|
import { longestMs, type Deadline } from '../runtime/deadline.js'
|
|
3
3
|
import { callEffects, type ToolUse } from '../utils/call-effects.js'
|
|
4
4
|
import { parentOf } from '../utils/paths.js'
|
|
5
5
|
import { listed, messageOf } from '../utils/text.js'
|
|
6
|
-
import { afterCall, modOf, targetWords } from './
|
|
6
|
+
import { afterCall, modOf, targetWords } from './context.js'
|
|
7
7
|
import type { Workspace } from './permissions/find-project-scope.js'
|
|
8
8
|
import { matchTarget, targetOf, type Target } from './permissions/match-target.js'
|
|
9
9
|
|
|
10
10
|
const defaultMs = 60_000
|
|
11
11
|
|
|
12
|
-
export function check<State extends object = Record<never, never>>(options: { readonly after: Target | Target[]; readonly run: readonly string[]; readonly timeoutMs?: number }):
|
|
12
|
+
export function check<State extends object = Record<never, never>>(options: { readonly after: Target | Target[]; readonly run: readonly string[]; readonly timeoutMs?: number }): Job<void, State> {
|
|
13
13
|
const { after, run, timeoutMs = defaultMs } = options
|
|
14
14
|
const targets = Array.isArray(after) ? after : [after]
|
|
15
15
|
if (targets.length === 0) throw new Error("check: give after a target, such as { write: '**/*.ts' }.")
|
|
@@ -19,15 +19,15 @@ export function check<State extends object = Record<never, never>>(options: { re
|
|
|
19
19
|
if (!(timeoutMs > 0 && timeoutMs <= longestMs)) throw new Error(`check: the ${named} has timeoutMs ${timeoutMs}. Set it above 0 and at most ${longestMs} (${longestMs / 60_000} minutes).`)
|
|
20
20
|
const deadline: Deadline = { ms: timeoutMs, job: 'check' }
|
|
21
21
|
|
|
22
|
-
return (
|
|
22
|
+
return (job) => {
|
|
23
23
|
afterCall(
|
|
24
|
-
|
|
24
|
+
job,
|
|
25
25
|
async (use, workspace) => {
|
|
26
26
|
const triggered = await triggeredRun(targets, run, use, workspace)
|
|
27
27
|
if (triggered === undefined) return []
|
|
28
28
|
try {
|
|
29
29
|
const { command, folder } = triggered
|
|
30
|
-
const { exitCode, stdout, stderr } = await modOf(
|
|
30
|
+
const { exitCode, stdout, stderr } = await modOf(job, { folder }, workspace, deadline).process.run(command)
|
|
31
31
|
return exitCode === 0 ? [] : [`${command.join(' ')} exited with ${exitCode}:\n${`${stdout}${stderr}`.trim()}`]
|
|
32
32
|
} catch (error) {
|
|
33
33
|
return [`The ${named} failed: ${messageOf(error)}`]
|
|
@@ -35,7 +35,7 @@ export function check<State extends object = Record<never, never>>(options: { re
|
|
|
35
35
|
},
|
|
36
36
|
(error) => [`The check job failed, so the ${named} did not run: ${messageOf(error)}`],
|
|
37
37
|
)
|
|
38
|
-
|
|
38
|
+
job.announce(`a ${named}`)
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|