@cmodjs/core 0.1.11 → 0.1.13
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 +21 -14
- package/docs/dependencies.md +8 -0
- package/docs/hooks.md +10 -1
- package/docs/index.md +7 -4
- package/docs/install-steps.md +22 -4
- package/docs/jobs.md +55 -8
- package/docs/mod.md +58 -3
- package/docs/testing.md +29 -3
- package/jobs/context.d.ts +2 -2
- package/jobs/context.d.ts.map +1 -1
- package/jobs/context.js +2 -2
- package/jobs/permissions/decide-permission.d.ts +2 -2
- package/jobs/permissions/decide-permission.d.ts.map +1 -1
- package/jobs/permissions/match-target.d.ts +3 -2
- package/jobs/permissions/match-target.d.ts.map +1 -1
- package/jobs/permissions/match-target.js +24 -15
- package/jobs/permissions.d.ts +1 -1
- package/jobs/permissions.d.ts.map +1 -1
- package/jobs/permissions.js +18 -6
- package/jobs/prompt.d.ts.map +1 -1
- package/jobs/prompt.js +34 -3
- package/jobs/schedule.d.ts +7 -0
- package/jobs/schedule.d.ts.map +1 -0
- package/jobs/schedule.js +66 -0
- package/mod.d.ts +11 -2
- package/mod.d.ts.map +1 -1
- package/package.json +1 -1
- package/records.d.ts +5 -0
- package/records.d.ts.map +1 -1
- package/records.js +30 -6
- package/register.d.ts.map +1 -1
- package/register.js +4 -1
- package/runtime/claude.d.ts +8 -0
- package/runtime/claude.d.ts.map +1 -1
- package/runtime/hooks.js +4 -4
- package/runtime/lifecycle.d.ts +1 -0
- package/runtime/lifecycle.d.ts.map +1 -1
- package/runtime/lifecycle.js +92 -16
- package/runtime/state.d.ts +2 -1
- package/runtime/state.d.ts.map +1 -1
- package/runtime/state.js +12 -1
- package/src/jobs/check.ts +2 -2
- package/src/jobs/context.ts +5 -5
- package/src/jobs/permissions/decide-permission.ts +4 -4
- package/src/jobs/permissions/match-target.ts +24 -16
- package/src/jobs/permissions.ts +18 -7
- package/src/jobs/prompt.ts +31 -3
- package/src/jobs/schedule.ts +65 -0
- package/src/mod.ts +15 -1
- package/src/records.ts +32 -8
- package/src/register.ts +5 -2
- package/src/runtime/claude.ts +4 -1
- package/src/runtime/hooks.ts +5 -5
- package/src/runtime/lifecycle.ts +101 -15
- package/src/runtime/state.ts +13 -1
- package/src/testing/fake-claude.ts +40 -3
- package/src/testing.ts +1 -0
- package/src/utils/call-effects.ts +13 -11
- package/testing/fake-claude.d.ts +18 -0
- package/testing/fake-claude.d.ts.map +1 -1
- package/testing/fake-claude.js +32 -2
- package/testing.d.ts.map +1 -1
- package/testing.js +1 -0
- package/utils/call-effects.d.ts +4 -8
- package/utils/call-effects.d.ts.map +1 -1
- package/utils/call-effects.js +6 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type CallBase, type CallEffects, type CommandCall, type FetchCall, type FileAccess, type FileCall, type ToolCall
|
|
1
|
+
import { type CallBase, type CallEffects, type CommandCall, type FetchCall, type FileAccess, type FileCall, type ToolCall } from '../../utils/call-effects.js';
|
|
2
2
|
import type { Workspace } from './find-project-scope.js';
|
|
3
3
|
export type TargetCalls = {
|
|
4
4
|
command: CommandCall;
|
|
@@ -21,7 +21,8 @@ export type MatchedCall = {
|
|
|
21
21
|
export declare function targetOf(target: Target): {
|
|
22
22
|
key: TargetKey;
|
|
23
23
|
patterns: string[];
|
|
24
|
+
exclusions: string[];
|
|
24
25
|
};
|
|
25
|
-
export declare function matchTarget(target: Target,
|
|
26
|
+
export declare function matchTarget(target: Target, call: CallBase, effects: CallEffects, workspace: Workspace): Promise<MatchedCall[]>;
|
|
26
27
|
export declare function folderInScope(shell: NonNullable<CallEffects['shell']>, workspace: Workspace): Promise<string | undefined>;
|
|
27
28
|
//# sourceMappingURL=match-target.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"match-target.d.ts","sourceRoot":"","sources":["../../src/jobs/permissions/match-target.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"match-target.d.ts","sourceRoot":"","sources":["../../src/jobs/permissions/match-target.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AAC1K,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAIxD,MAAM,MAAM,WAAW,GAAG;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAA;AACzI,MAAM,MAAM,SAAS,GAAG,MAAM,WAAW,CAAA;AACzC,MAAM,MAAM,QAAQ,CAAC,GAAG,SAAS,SAAS,IAAI,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAA;AAC9H,MAAM,MAAM,MAAM,GAAG;KAAG,GAAG,IAAI,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC;CAAE,CAAC,SAAS,CAAC,CAAA;AACrE,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAI5F,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAWrG;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAkCpI;AA4BD,wBAAsB,aAAa,CAAC,KAAK,EAAE,WAAW,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAI/H"}
|
|
@@ -11,17 +11,23 @@ export function targetOf(target) {
|
|
|
11
11
|
if (key === undefined || keys.length > 1 || !(typeof value === 'string' || (Array.isArray(value) && value.every((pattern) => typeof pattern === 'string')))) {
|
|
12
12
|
throw new Error(`A rule names exactly one of ${targetKeys.join(', ')} with a pattern or a list of patterns; this one names ${keys.join(' and ') || 'none'}.`);
|
|
13
13
|
}
|
|
14
|
-
|
|
14
|
+
const all = typeof value === 'string' ? [value] : value;
|
|
15
|
+
const patterns = all.filter((pattern) => !pattern.startsWith('!'));
|
|
16
|
+
if (patterns.length === 0)
|
|
17
|
+
throw new Error(`A ${key} target needs a pattern without "!" for its "!" patterns to leave calls out of, such as ['**', ${all.map((pattern) => `'${pattern}'`).join(', ')}].`);
|
|
18
|
+
return { key, patterns, exclusions: all.filter((pattern) => pattern.startsWith('!')).map((pattern) => pattern.slice(1)) };
|
|
15
19
|
}
|
|
16
|
-
export async function matchTarget(target,
|
|
17
|
-
const { key, patterns } = targetOf(target);
|
|
18
|
-
const base = callBaseOf(
|
|
19
|
-
const only = (
|
|
20
|
+
export async function matchTarget(target, call, effects, workspace) {
|
|
21
|
+
const { key, patterns, exclusions } = targetOf(target);
|
|
22
|
+
const base = callBaseOf(call);
|
|
23
|
+
const only = (matched, folder = workspace.cwd) => [{ call: matched, access: undefined, folder }];
|
|
24
|
+
const isNamed = (value) => matchesAny(value, patterns) && !matchesAny(value, exclusions);
|
|
20
25
|
if (key === 'read' || key === 'write') {
|
|
21
26
|
const matched = [];
|
|
22
27
|
for (const access of key === 'read' ? effects.reads : effects.writes) {
|
|
23
28
|
const path = await matchedPath(patterns, access.path, workspace);
|
|
24
|
-
|
|
29
|
+
const isExcluded = path !== undefined && exclusions.length > 0 && (await matchedPath(exclusions, access.path, workspace)) !== undefined;
|
|
30
|
+
if (path !== undefined && !isExcluded)
|
|
25
31
|
matched.push({ call: { ...base, path }, access, folder: workspace.cwd });
|
|
26
32
|
}
|
|
27
33
|
return matched;
|
|
@@ -30,23 +36,26 @@ export async function matchTarget(target, use, effects, workspace) {
|
|
|
30
36
|
const shell = effects.shell;
|
|
31
37
|
if (shell === undefined)
|
|
32
38
|
return [];
|
|
33
|
-
const
|
|
34
|
-
|
|
39
|
+
const commandCall = { ...base, commands: shell.commands.map((command) => command.argv), isFullyParsed: shell.isFullyParsed };
|
|
40
|
+
const isEvery = patterns.includes('*');
|
|
41
|
+
if (isEvery && exclusions.length === 0) {
|
|
35
42
|
const folder = await folderInScope(shell, workspace);
|
|
36
|
-
return folder === undefined ? [] : only(
|
|
43
|
+
return folder === undefined ? [] : only(commandCall, folder);
|
|
37
44
|
}
|
|
38
|
-
const wanted = patterns.map(commandPattern);
|
|
45
|
+
const wanted = patterns.filter((pattern) => pattern !== '*').map(commandPattern);
|
|
46
|
+
const unwanted = exclusions.map(commandPattern);
|
|
39
47
|
for (const command of shell.commands) {
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
const isWanted = isEvery || wanted.some((pattern) => commandMatches(pattern, command.argv));
|
|
49
|
+
if (isWanted && !unwanted.some((pattern) => commandMatches(pattern, command.argv)) && (await isInScope(command.folder, workspace)))
|
|
50
|
+
return only(commandCall, command.folder);
|
|
42
51
|
}
|
|
43
52
|
return [];
|
|
44
53
|
}
|
|
45
54
|
if (key === 'fetch')
|
|
46
|
-
return effects.urls.filter(
|
|
55
|
+
return effects.urls.filter(isNamed).map((url) => ({ call: { ...base, url }, access: undefined, folder: workspace.cwd }));
|
|
47
56
|
if (key === 'subagent')
|
|
48
|
-
return effects.subagent !== undefined &&
|
|
49
|
-
return
|
|
57
|
+
return effects.subagent !== undefined && isNamed(effects.subagent) ? only(base) : [];
|
|
58
|
+
return isNamed(call.tool) ? only(base) : [];
|
|
50
59
|
}
|
|
51
60
|
function commandPattern(pattern) {
|
|
52
61
|
const command = parseShell(pattern).commands[0];
|
package/jobs/permissions.d.ts
CHANGED
|
@@ -4,5 +4,5 @@ export type { CommandCall, FetchCall, FileCall, ToolCall } from '../utils/call-e
|
|
|
4
4
|
export type { Target } from './permissions/match-target.js';
|
|
5
5
|
export type Rule<State extends object = Record<never, never>> = RuleFor<Mod<State>>;
|
|
6
6
|
export type PermissionRules<State extends object = Record<never, never>> = RulesFor<Mod<State>>;
|
|
7
|
-
export declare function permissions<State extends object = Record<never, never>>(rules: PermissionRules<State>): Job<void, State>;
|
|
7
|
+
export declare function permissions<State extends object = Record<never, never>>(rules: PermissionRules<State> | ((state: State) => PermissionRules<State>)): Job<void, State>;
|
|
8
8
|
//# sourceMappingURL=permissions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/jobs/permissions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAGzC,OAAO,EAAqC,KAAK,eAAe,IAAI,QAAQ,EAAE,KAAK,IAAI,IAAI,OAAO,EAAgB,MAAM,oCAAoC,CAAA;AAK5J,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAC1F,YAAY,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAA;AAC3D,MAAM,MAAM,IAAI,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;AACnF,MAAM,MAAM,eAAe,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;AAI/F,wBAAgB,WAAW,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/jobs/permissions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAGzC,OAAO,EAAqC,KAAK,eAAe,IAAI,QAAQ,EAAE,KAAK,IAAI,IAAI,OAAO,EAAgB,MAAM,oCAAoC,CAAA;AAK5J,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAC1F,YAAY,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAA;AAC3D,MAAM,MAAM,IAAI,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;AACnF,MAAM,MAAM,eAAe,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;AAI/F,wBAAgB,WAAW,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,eAAe,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CA6BrK"}
|
package/jobs/permissions.js
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
|
+
import { inputOf } from '../utils/call-effects.js';
|
|
1
2
|
import { decidePermission, stricterVerdict } from './permissions/decide-permission.js';
|
|
2
3
|
import { targetOf } from './permissions/match-target.js';
|
|
3
4
|
import { messageOf } from '../utils/text.js';
|
|
4
5
|
import { modOf, workspaceReader } from './context.js';
|
|
5
6
|
const deadline = { ms: 2000, job: 'permissions' };
|
|
6
7
|
export function permissions(rules) {
|
|
7
|
-
const count =
|
|
8
|
+
const count = typeof rules === 'function' ? undefined : checkedCount(rules);
|
|
8
9
|
if (count === 0)
|
|
9
10
|
throw new Error('permissions: give it a deny or an ask rule, or remove it from setup.');
|
|
10
|
-
for (const rule of [...(rules.deny ?? []), ...(rules.ask ?? [])])
|
|
11
|
-
targetOf(rule);
|
|
12
11
|
return (job) => {
|
|
13
12
|
const readWorkspace = workspaceReader(job);
|
|
14
13
|
const verdictOf = async (e) => {
|
|
14
|
+
let current;
|
|
15
|
+
try {
|
|
16
|
+
current = typeof rules === 'function' ? rules(job.mod.state) : rules;
|
|
17
|
+
checkedCount(current);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return { decision: 'deny', reason: `The permission rules of ${job.mod.name} failed, so it denies the call: ${messageOf(error)}` };
|
|
21
|
+
}
|
|
15
22
|
try {
|
|
16
23
|
const [agent, workspace] = await Promise.all([job.toolCalls.agentOf(e.tool_use_id), readWorkspace()]);
|
|
17
|
-
|
|
18
|
-
return await decidePermission(rules, use, workspace, (call, folder) => modOf(job, { call, folder }, workspace, deadline));
|
|
24
|
+
return await decidePermission(current, { tool: e.tool, input: inputOf(e.input), ...agent }, workspace, (call, folder) => modOf(job, { call, folder }, workspace, deadline));
|
|
19
25
|
}
|
|
20
26
|
catch (error) {
|
|
21
27
|
return { decision: 'deny', reason: `The permissions job could not read the session, so it denies the call: ${messageOf(error)}` };
|
|
@@ -25,6 +31,12 @@ export function permissions(rules) {
|
|
|
25
31
|
const [below, ours] = await Promise.all([next(e), verdictOf(e)]);
|
|
26
32
|
return ours === undefined ? below : stricterVerdict(below, ours);
|
|
27
33
|
});
|
|
28
|
-
job.announce(`${count} permission rule${count === 1 ? '' : 's'}`);
|
|
34
|
+
job.announce(count === undefined ? 'permission rules from its state' : `${count} permission rule${count === 1 ? '' : 's'}`);
|
|
29
35
|
};
|
|
30
36
|
}
|
|
37
|
+
function checkedCount(rules) {
|
|
38
|
+
const all = [...(rules.deny ?? []), ...(rules.ask ?? [])];
|
|
39
|
+
for (const rule of all)
|
|
40
|
+
targetOf(rule);
|
|
41
|
+
return all.length;
|
|
42
|
+
}
|
package/jobs/prompt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/jobs/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAc,GAAG,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/jobs/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAc,GAAG,EAAE,MAAM,WAAW,CAAA;AAIrD,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACrE,OAAO,EAAyB,KAAK,MAAM,EAAE,MAAM,+BAA+B,CAAA;AAGlF,KAAK,WAAW,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,QAAQ,CAAA;CAAE,CAAA;AAE3D,KAAK,aAAa,CAAC,KAAK,SAAS,MAAM,IAAI;IACzC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAA;IAC5G,IAAI,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,CAAA;IACjD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAC1B,CAAA;AAID,wBAAgB,MAAM,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAoC/I"}
|
package/jobs/prompt.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { longestMs } from '../runtime/deadline.js';
|
|
2
|
+
import { onStateChange } from '../runtime/state.js';
|
|
2
3
|
import { listed, messageOf } from '../utils/text.js';
|
|
3
4
|
import { callEffects } from '../utils/call-effects.js';
|
|
4
5
|
import { matchTarget, targetOf } from './permissions/match-target.js';
|
|
@@ -38,20 +39,50 @@ export function prompt({ name, prompt: text, when, after }) {
|
|
|
38
39
|
job.announce(`the ${name} prompt after ${listed(targets.map(targetWords))}`);
|
|
39
40
|
}
|
|
40
41
|
else {
|
|
41
|
-
|
|
42
|
+
addKeptCurrent(job, name, () => textFor({}, modWithin(job, deadline)), log);
|
|
42
43
|
job.announce(`the ${name} prompt`);
|
|
43
44
|
}
|
|
44
45
|
};
|
|
45
46
|
}
|
|
46
|
-
function
|
|
47
|
+
function addKeptCurrent(job, name, textFor, log) {
|
|
48
|
+
let given;
|
|
49
|
+
let hasStarted = false;
|
|
50
|
+
let isQueued = false;
|
|
51
|
+
let updates = Promise.resolve();
|
|
52
|
+
job.on('classic.SessionStart', (e, next) => {
|
|
53
|
+
hasStarted = e.source === 'resume' || e.source === 'compact';
|
|
54
|
+
if (!hasStarted)
|
|
55
|
+
given = undefined;
|
|
56
|
+
return next(e);
|
|
57
|
+
});
|
|
47
58
|
job.on('prompt.context', async (e, next) => {
|
|
48
59
|
const below = await next(e);
|
|
60
|
+
hasStarted = true;
|
|
49
61
|
if (below.blocks.some((block) => block.name === name)) {
|
|
50
62
|
log(`a block named "${name}" is already in the context`);
|
|
51
63
|
return below;
|
|
52
64
|
}
|
|
65
|
+
given = await textFor();
|
|
66
|
+
return given === undefined ? below : { ...below, blocks: [...below.blocks, { name, text: given }] };
|
|
67
|
+
});
|
|
68
|
+
const update = async () => {
|
|
69
|
+
isQueued = false;
|
|
70
|
+
if (!hasStarted)
|
|
71
|
+
return;
|
|
53
72
|
const value = await textFor();
|
|
54
|
-
|
|
73
|
+
if (value === undefined || value === given)
|
|
74
|
+
return;
|
|
75
|
+
given = value;
|
|
76
|
+
await job.claude.session.append({ message: { type: 'user', content: [{ type: 'text', text: `# ${name}\n${value}` }] } }).then((added) => {
|
|
77
|
+
if (added.deny !== undefined)
|
|
78
|
+
log(`Claude Code refused the new text: ${added.deny}`);
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
onStateChange(job.mod.state, () => {
|
|
82
|
+
if (isQueued)
|
|
83
|
+
return;
|
|
84
|
+
isQueued = true;
|
|
85
|
+
updates = updates.then(update).catch((error) => log(messageOf(error)));
|
|
55
86
|
});
|
|
56
87
|
}
|
|
57
88
|
function addAfterUserPrompts(job, when, textFor, log) {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Job } from '../mod.js';
|
|
2
|
+
export type Schedule = {
|
|
3
|
+
readonly cron: string;
|
|
4
|
+
readonly prompt: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function schedule<State extends object = Record<never, never>>(entry: Schedule | ((state: State) => Schedule | undefined)): Job<void, State>;
|
|
7
|
+
//# sourceMappingURL=schedule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../src/jobs/schedule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAIpC,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAIzE,wBAAgB,QAAQ,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,QAAQ,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAmDlJ"}
|
package/jobs/schedule.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { onStateChange } from '../runtime/state.js';
|
|
2
|
+
import { messageOf } from '../utils/text.js';
|
|
3
|
+
const scheduleCounts = new WeakMap();
|
|
4
|
+
export function schedule(entry) {
|
|
5
|
+
if (typeof entry !== 'function')
|
|
6
|
+
checked(entry);
|
|
7
|
+
return (job) => {
|
|
8
|
+
const { mod, claude } = job;
|
|
9
|
+
const order = scheduleCounts.get(mod) ?? 0;
|
|
10
|
+
scheduleCounts.set(mod, order + 1);
|
|
11
|
+
const storeKey = `cmod:schedule:${order}`;
|
|
12
|
+
const log = (reason) => claude.ui.log(`${mod.name}: the schedule ${reason}`);
|
|
13
|
+
let current;
|
|
14
|
+
let isQueued = false;
|
|
15
|
+
const remove = async (id) => {
|
|
16
|
+
await claude.tool.call({ tool: 'CronDelete', id }).catch(() => undefined);
|
|
17
|
+
await claude.store.delete(storeKey);
|
|
18
|
+
};
|
|
19
|
+
const update = async () => {
|
|
20
|
+
isQueued = false;
|
|
21
|
+
let next;
|
|
22
|
+
try {
|
|
23
|
+
next = typeof entry === 'function' ? entry(mod.state) : entry;
|
|
24
|
+
if (next !== undefined)
|
|
25
|
+
checked(next);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
log(`kept its last cron: ${messageOf(error)}`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const wanted = next === undefined ? undefined : JSON.stringify([next.cron, next.prompt]);
|
|
32
|
+
if (wanted === current?.wanted)
|
|
33
|
+
return;
|
|
34
|
+
if (current !== undefined)
|
|
35
|
+
await remove(current.id);
|
|
36
|
+
current = undefined;
|
|
37
|
+
if (next === undefined)
|
|
38
|
+
return;
|
|
39
|
+
const answer = await claude.tool.call({ tool: 'CronCreate', cron: next.cron, prompt: next.prompt, recurring: true });
|
|
40
|
+
if (answer.deny !== undefined)
|
|
41
|
+
return log(`was refused: ${answer.deny}`);
|
|
42
|
+
if (answer.isError === true)
|
|
43
|
+
return log(`failed: ${answer.text ?? 'CronCreate answered an error'}`);
|
|
44
|
+
current = { id: answer.result.id, wanted: wanted };
|
|
45
|
+
await claude.store.set(storeKey, current.id);
|
|
46
|
+
};
|
|
47
|
+
let updates = claude.store
|
|
48
|
+
.get(storeKey)
|
|
49
|
+
.then((left) => (typeof left === 'string' ? remove(left) : undefined))
|
|
50
|
+
.then(update)
|
|
51
|
+
.catch((error) => log(`failed: ${messageOf(error)}`));
|
|
52
|
+
onStateChange(mod.state, () => {
|
|
53
|
+
if (isQueued)
|
|
54
|
+
return;
|
|
55
|
+
isQueued = true;
|
|
56
|
+
updates = updates.then(update).catch((error) => log(`failed: ${messageOf(error)}`));
|
|
57
|
+
});
|
|
58
|
+
job.announce(typeof entry === 'function' ? 'a schedule from its state' : `a schedule at ${entry.cron}`);
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function checked(entry) {
|
|
62
|
+
if (entry.cron.trim() === '')
|
|
63
|
+
throw new Error('schedule: give it a cron, such as "*/10 * * * *" for every 10 minutes.');
|
|
64
|
+
if (entry.prompt.trim() === '')
|
|
65
|
+
throw new Error('schedule: give it the prompt Claude gets at each fire.');
|
|
66
|
+
}
|
package/mod.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentSpawnArgs, AgentSpawnResult, AskOptions, ClassicHookInputs, CmodDependencies, FsEntry, FsStat, FsStatOptions, HookStream, HttpInit, HttpResponse, PaneOpenArgs, PermissionRequestDecision, ProcessRunInit, ProcessRunResult, ProcessSpawnChunk, ProcessSpawnRequest, ProcessSpawnResult, RenderElement, Settings, SettingsReadArgs, ToastOptions, UiScrollArgs, UiScrollResult } from 'claude-code';
|
|
1
|
+
import type { AgentSpawnArgs, AgentSpawnResult, AskOptions, ClassicHookInputs, CmodDependencies, FsEntry, FsStat, FsStatOptions, HookStream, HttpInit, HttpResponse, ModelCompleteOptions, ModelCompleteRequest, ModelCompleteResult, PaneOpenArgs, PermissionRequestDecision, ProcessRunInit, ProcessRunResult, ProcessSpawnChunk, ProcessSpawnRequest, ProcessSpawnResult, RenderElement, Settings, SettingsReadArgs, Timer, ToastOptions, UiScrollArgs, UiScrollResult } from 'claude-code';
|
|
2
2
|
import type { Claude } from './runtime/claude.js';
|
|
3
3
|
import type { RoutedEvent } from './runtime/hooks.js';
|
|
4
4
|
import type { RoutedHook } from './runtime/router.js';
|
|
@@ -71,12 +71,16 @@ type HookInputs = Omit<ClassicHookInputs, 'PreToolUse' | 'PostToolUse' | 'PostTo
|
|
|
71
71
|
};
|
|
72
72
|
export type HookInput<E extends ModEvent> = HookInputs[E];
|
|
73
73
|
export type ModHook<E extends ModEvent> = (input: HookInput<E>) => HookAnswer | void | Promise<HookAnswer | void>;
|
|
74
|
+
export type HookOptions = {
|
|
75
|
+
readonly timeoutMs?: number;
|
|
76
|
+
};
|
|
74
77
|
export type Mod<State extends object = Record<never, never>> = {
|
|
75
78
|
readonly name: string;
|
|
76
79
|
readonly state: Readonly<State>;
|
|
77
80
|
readonly dataFolder: string;
|
|
78
|
-
on<E extends ModEvent>(event: E, hook: ModHook<E
|
|
81
|
+
on<E extends ModEvent>(event: E, hook: ModHook<E>, options?: HookOptions): void;
|
|
79
82
|
use<Handle>(job: Job<Handle, State>): Handle;
|
|
83
|
+
every(ms: number, hook: () => unknown): Timer;
|
|
80
84
|
readonly ui: {
|
|
81
85
|
pane(pane: Pane<State>): PaneHandle;
|
|
82
86
|
render<S extends Slot>(slot: S, Component: (props: SlotProps<S>) => RenderElement): void;
|
|
@@ -104,10 +108,15 @@ export type Mod<State extends object = Record<never, never>> = {
|
|
|
104
108
|
};
|
|
105
109
|
readonly session: {
|
|
106
110
|
messages: Claude['session']['messages'];
|
|
111
|
+
append(text: string): Promise<void>;
|
|
112
|
+
submit(text: string): Promise<void>;
|
|
107
113
|
};
|
|
108
114
|
readonly agent: {
|
|
109
115
|
spawn(args: AgentSpawnArgs): Promise<AgentSpawnResult>;
|
|
110
116
|
};
|
|
117
|
+
readonly model: {
|
|
118
|
+
complete(request: ModelCompleteRequest, options?: ModelCompleteOptions): Promise<ModelCompleteResult>;
|
|
119
|
+
};
|
|
111
120
|
readonly projectRoot: string;
|
|
112
121
|
readonly cwd: string;
|
|
113
122
|
readonly dependencies: CmodDependencies;
|
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":"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"}
|
package/package.json
CHANGED
package/records.d.ts
CHANGED
|
@@ -6,11 +6,13 @@ export type InstallRecord = {
|
|
|
6
6
|
scriptsSha256: string;
|
|
7
7
|
uninstall: string | null;
|
|
8
8
|
program: string | null;
|
|
9
|
+
keys: Readonly<Record<string, string>>;
|
|
9
10
|
};
|
|
10
11
|
export type Steps = {
|
|
11
12
|
install?: string;
|
|
12
13
|
uninstall?: string;
|
|
13
14
|
program?: string;
|
|
15
|
+
keys?: Readonly<Record<string, string>>;
|
|
14
16
|
};
|
|
15
17
|
export type ReadFile = (path: string) => Promise<string | undefined>;
|
|
16
18
|
export type RunnerEvent = {
|
|
@@ -26,6 +28,7 @@ export type RunnerEvent = {
|
|
|
26
28
|
sha256: string;
|
|
27
29
|
install: string;
|
|
28
30
|
uninstall: string;
|
|
31
|
+
keys: string;
|
|
29
32
|
} | {
|
|
30
33
|
kind: 'done';
|
|
31
34
|
name: string;
|
|
@@ -50,6 +53,8 @@ export declare function configFolders(env: Record<string, string | undefined>, n
|
|
|
50
53
|
export declare function readRecord(read: ReadFile, store: string, name: string): Promise<InstallRecord | undefined>;
|
|
51
54
|
export declare function writeRecord(write: (path: string, text: string) => Promise<void>, store: string, record: InstallRecord): Promise<void>;
|
|
52
55
|
export declare function readSteps(pkg: unknown): Steps | undefined;
|
|
56
|
+
export declare function oldestCmodFor(keys: Readonly<Record<string, string>>): string;
|
|
57
|
+
export declare function keyWords(keys: Readonly<Record<string, string>> | undefined): string;
|
|
53
58
|
export declare function scriptPaths(command: string): string[];
|
|
54
59
|
export declare function scriptsSha256(steps: Steps, files: {
|
|
55
60
|
read: ReadFile;
|
package/records.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"records.d.ts","sourceRoot":"","sources":["src/records.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"records.d.ts","sourceRoot":"","sources":["src/records.ts"],"names":[],"mappings":"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"}
|
package/records.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { messageOf } from './utils/text.js';
|
|
1
|
+
import { listed, messageOf } from './utils/text.js';
|
|
2
2
|
export const pluginName = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
3
3
|
export function storeFolder(env) {
|
|
4
4
|
const dataHome = env['XDG_DATA_HOME'];
|
|
@@ -67,6 +67,9 @@ function parseRecord(text, path) {
|
|
|
67
67
|
const program = value['program'];
|
|
68
68
|
if (program !== null && typeof program !== 'string')
|
|
69
69
|
throw new Error(`${path} has a "program" that is neither a command name nor null. ${fix}`);
|
|
70
|
+
const keys = value['keys'] ?? {};
|
|
71
|
+
if (!isObject(keys) || Object.values(keys).some((command) => typeof command !== 'string'))
|
|
72
|
+
throw new Error(`${path} has "keys" that are not key bindings. ${fix}`);
|
|
70
73
|
return {
|
|
71
74
|
name: value['name'],
|
|
72
75
|
version: value['version'],
|
|
@@ -75,6 +78,7 @@ function parseRecord(text, path) {
|
|
|
75
78
|
scriptsSha256: value['scriptsSha256'],
|
|
76
79
|
uninstall,
|
|
77
80
|
program,
|
|
81
|
+
keys: keys,
|
|
78
82
|
};
|
|
79
83
|
}
|
|
80
84
|
export function readSteps(pkg) {
|
|
@@ -90,7 +94,27 @@ export function readSteps(pkg) {
|
|
|
90
94
|
const program = steps['program'];
|
|
91
95
|
if (program !== undefined && (typeof program !== 'string' || !pluginName.test(program)))
|
|
92
96
|
throw new Error('package.json "cmod.program" must be the program\'s command, such as "hello".');
|
|
93
|
-
return { ...readCommand(steps, 'install'), ...readCommand(steps, 'uninstall'), ...(program === undefined ? {} : { program }) };
|
|
97
|
+
return { ...readCommand(steps, 'install'), ...readCommand(steps, 'uninstall'), ...(program === undefined ? {} : { program }), ...readKeys(steps['keys']) };
|
|
98
|
+
}
|
|
99
|
+
function readKeys(keys) {
|
|
100
|
+
if (keys === undefined)
|
|
101
|
+
return {};
|
|
102
|
+
if (!isObject(keys) || Object.keys(keys).length === 0)
|
|
103
|
+
throw new Error('package.json "cmod.keys" must bind each key to a command, such as "keys": { "shift+tab": "/mode" }.');
|
|
104
|
+
const commands = {};
|
|
105
|
+
for (const [key, value] of Object.entries(keys)) {
|
|
106
|
+
const command = typeof value === 'string' ? /^\/([A-Za-z0-9][A-Za-z0-9._:-]*)$/.exec(value)?.[1] : undefined;
|
|
107
|
+
if (key.trim() === '' || command === undefined)
|
|
108
|
+
throw new Error(`package.json "cmod.keys" binds "${key}" to ${JSON.stringify(value)}. Bind each key to one of the mod's commands, such as "shift+tab": "/mode".`);
|
|
109
|
+
commands[key] = command;
|
|
110
|
+
}
|
|
111
|
+
return { keys: commands };
|
|
112
|
+
}
|
|
113
|
+
export function oldestCmodFor(keys) {
|
|
114
|
+
return Object.keys(keys).length > 0 ? '0.1.12' : '0.0.0';
|
|
115
|
+
}
|
|
116
|
+
export function keyWords(keys) {
|
|
117
|
+
return listed(Object.entries(keys ?? {}).map(([key, command]) => `${key} to /${command}`));
|
|
94
118
|
}
|
|
95
119
|
function readCommand(steps, key) {
|
|
96
120
|
const command = steps[key];
|
|
@@ -131,7 +155,7 @@ export async function scriptsSha256(steps, files) {
|
|
|
131
155
|
for (const folder of scriptFolders)
|
|
132
156
|
folders.add(folder);
|
|
133
157
|
}
|
|
134
|
-
let text = [steps.install ?? '', steps.uninstall ?? '', steps.program ?? ''].join('\0');
|
|
158
|
+
let text = [steps.install ?? '', steps.uninstall ?? '', steps.program ?? '', ...(steps.keys === undefined ? [] : [JSON.stringify(Object.entries(steps.keys).sort())])].join('\0');
|
|
135
159
|
for (const folder of [...folders].sort()) {
|
|
136
160
|
for (const name of (await files.list(folder)).sort()) {
|
|
137
161
|
const path = `${folder}/${name}`;
|
|
@@ -151,7 +175,7 @@ export function formatEvent(event) {
|
|
|
151
175
|
case 'log':
|
|
152
176
|
return `log ${event.text}`;
|
|
153
177
|
case 'needs-consent':
|
|
154
|
-
return `needs-consent ${event.sha256}\t${event.install}\t${event.uninstall}`;
|
|
178
|
+
return `needs-consent ${event.sha256}\t${event.install}\t${event.uninstall}\t${event.keys}`;
|
|
155
179
|
case 'done':
|
|
156
180
|
return event.version === undefined ? `done ${event.name}` : `done ${event.name} ${event.version}`;
|
|
157
181
|
case 'missing':
|
|
@@ -164,9 +188,9 @@ export function parseEvent(line) {
|
|
|
164
188
|
const progress = /^progress (\d+) (\d+)(?: (.*))?$/.exec(line);
|
|
165
189
|
if (progress !== null)
|
|
166
190
|
return { kind: 'progress', done: Number(progress[1]), total: Number(progress[2]), label: progress[3] ?? '' };
|
|
167
|
-
const consent = /^needs-consent (\S+)\t([^\t]*)\t(.*)
|
|
191
|
+
const consent = /^needs-consent (\S+)\t([^\t]*)\t([^\t]*)(?:\t(.*))?$/.exec(line);
|
|
168
192
|
if (consent !== null)
|
|
169
|
-
return { kind: 'needs-consent', sha256: consent[1], install: consent[2], uninstall: consent[3] };
|
|
193
|
+
return { kind: 'needs-consent', sha256: consent[1], install: consent[2], uninstall: consent[3], keys: consent[4] ?? '' };
|
|
170
194
|
const done = /^done (\S+)(?: (\S+))?$/.exec(line);
|
|
171
195
|
if (done !== null)
|
|
172
196
|
return { kind: 'done', name: done[1], ...(done[2] === undefined ? {} : { version: done[2] }) };
|
package/register.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["src/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoD,EAAE,
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["src/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoD,EAAE,EAAgB,MAAM,aAAa,CAAA;AACrG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAkF7C,wBAAgB,WAAW,CAAC,KAAK,SAAS,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,IAAI,CA8BrG;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,EAAE,GAAG,IAAI,CAIzD"}
|
package/register.js
CHANGED
|
@@ -49,9 +49,12 @@ async function startMod($, eventInput, passOn) {
|
|
|
49
49
|
usage: () => $.session.usage(),
|
|
50
50
|
surfaces: () => $.session.surfaces(),
|
|
51
51
|
messages: ((args) => (args === undefined ? $.session.messages() : $.session.messages(args))),
|
|
52
|
+
append: (args) => $.session.append(args),
|
|
52
53
|
},
|
|
54
|
+
prompt: { submit: (args) => $.prompt.submit(args) },
|
|
55
|
+
model: { complete: (request, options) => $.model.complete(request, options) },
|
|
53
56
|
command: { register: (command) => $.command.register(command) },
|
|
54
|
-
tool: { register: (tool) => $.tool.register(tool) },
|
|
57
|
+
tool: { register: (tool) => $.tool.register(tool), call: ((input) => $.tool.call(input)) },
|
|
55
58
|
agent: {
|
|
56
59
|
list: () => $.agent.list(),
|
|
57
60
|
spawn: (args) => $.agent.spawn(args),
|
package/runtime/claude.d.ts
CHANGED
|
@@ -53,6 +53,13 @@ export type Claude = {
|
|
|
53
53
|
usage(): Promise<SessionUsage>;
|
|
54
54
|
surfaces(): Promise<readonly RenderSurface[]>;
|
|
55
55
|
messages: EngineInterface['session']['messages'];
|
|
56
|
+
append: EngineInterface['session']['append'];
|
|
57
|
+
};
|
|
58
|
+
readonly prompt: {
|
|
59
|
+
submit: EngineInterface['prompt']['submit'];
|
|
60
|
+
};
|
|
61
|
+
readonly model: {
|
|
62
|
+
complete: EngineInterface['model']['complete'];
|
|
56
63
|
};
|
|
57
64
|
readonly command: {
|
|
58
65
|
register(command: CommandSpec): Promise<{
|
|
@@ -63,6 +70,7 @@ export type Claude = {
|
|
|
63
70
|
register(tool: ToolSpec): Promise<{
|
|
64
71
|
tool: string;
|
|
65
72
|
}>;
|
|
73
|
+
call: EngineInterface['tool']['call'];
|
|
66
74
|
};
|
|
67
75
|
readonly agent: {
|
|
68
76
|
list(): Promise<AgentInfo[]>;
|
package/runtime/claude.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/runtime/claude.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/runtime/claude.ts"],"names":[],"mappings":"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"}
|
package/runtime/hooks.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { configFolders } from '../records.js';
|
|
2
2
|
import { reservedKeys, toolInputOf } from './tool-calls.js';
|
|
3
|
-
import { callEffects } from '../utils/call-effects.js';
|
|
3
|
+
import { callEffects, inputOf } from '../utils/call-effects.js';
|
|
4
4
|
import { dynamicPattern } from '../utils/parse-shell.js';
|
|
5
5
|
import { messageOf } from '../utils/text.js';
|
|
6
6
|
export const permissionEvents = ['tool.check', 'classic.PermissionRequest'];
|
|
@@ -26,15 +26,15 @@ const readFields = {
|
|
|
26
26
|
FileChanged: [],
|
|
27
27
|
};
|
|
28
28
|
export function classicHook(name, event, hook, claude, calls) {
|
|
29
|
-
const
|
|
29
|
+
const hookInputOf = async (e) => {
|
|
30
30
|
if (event !== 'PostToolUse' && event !== 'PostToolUseFailure')
|
|
31
31
|
return e;
|
|
32
32
|
const input = e;
|
|
33
33
|
const cwd = calls.cwdOf(input.tool_use_id) ?? input.cwd;
|
|
34
|
-
return { ...input, files: await callFiles(name, claude, { tool: input.tool_name, input: input.tool_input }, cwd) };
|
|
34
|
+
return { ...input, files: await callFiles(name, claude, { tool: input.tool_name, input: inputOf(input.tool_input) }, cwd) };
|
|
35
35
|
};
|
|
36
36
|
const resultOf = async (e) => {
|
|
37
|
-
const answer = await hook((await
|
|
37
|
+
const answer = await hook((await hookInputOf(e)));
|
|
38
38
|
if (answer === undefined)
|
|
39
39
|
return undefined;
|
|
40
40
|
if (answer.systemMessage !== undefined)
|
package/runtime/lifecycle.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export type Plugin = {
|
|
|
10
10
|
readonly store: string;
|
|
11
11
|
readonly isInstalled: boolean;
|
|
12
12
|
readonly shouldRecord: boolean;
|
|
13
|
+
readonly keys: Readonly<Record<string, string>>;
|
|
13
14
|
};
|
|
14
15
|
export type Phase = 'starting' | 'installing' | 'waiting' | 'declined' | 'failed' | 'ready' | 'active';
|
|
15
16
|
export type Lifecycle<State extends object> = {
|