@cmodjs/core 0.1.14 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/commands.md +32 -21
- package/docs/dependencies.md +8 -0
- package/docs/index.md +12 -4
- package/docs/install-steps.md +36 -4
- package/docs/jobs.md +25 -9
- package/docs/mod.md +103 -37
- package/docs/options.md +93 -0
- package/docs/permissions.md +88 -0
- package/docs/state.md +4 -31
- package/docs/testing.md +13 -2
- package/installer.d.ts +10 -0
- package/installer.d.ts.map +1 -0
- package/installer.js +8 -0
- package/jobs/context.d.ts +2 -2
- package/jobs/context.d.ts.map +1 -1
- package/jobs/context.js +5 -3
- package/jobs/permissions.js +1 -1
- package/jobs/program.d.ts.map +1 -1
- package/jobs/program.js +5 -1
- package/jobs/prompt.js +5 -5
- package/jobs/schedule.d.ts.map +1 -1
- package/jobs/schedule.js +2 -1
- package/jobs/slash-command.d.ts.map +1 -1
- package/jobs/slash-command.js +3 -2
- package/jobs/status-line.d.ts.map +1 -1
- package/jobs/status-line.js +3 -2
- package/jobs/tool.d.ts.map +1 -1
- package/jobs/tool.js +3 -2
- package/mod.d.ts +48 -10
- package/mod.d.ts.map +1 -1
- package/mod.js +3 -0
- package/options.d.ts +58 -0
- package/options.d.ts.map +1 -0
- package/options.js +66 -0
- package/package.json +1 -1
- package/records.d.ts +16 -1
- package/records.d.ts.map +1 -1
- package/records.js +119 -7
- package/register.d.ts +4 -2
- package/register.d.ts.map +1 -1
- package/register.js +8 -2
- package/runtime/claude.d.ts +5 -1
- package/runtime/claude.d.ts.map +1 -1
- package/runtime/grants.d.ts +28 -0
- package/runtime/grants.d.ts.map +1 -0
- package/runtime/grants.js +286 -0
- package/runtime/installer.d.ts +24 -0
- package/runtime/installer.d.ts.map +1 -0
- package/runtime/installer.js +118 -0
- package/runtime/lifecycle.d.ts +6 -3
- package/runtime/lifecycle.d.ts.map +1 -1
- package/runtime/lifecycle.js +226 -36
- package/runtime/metadata.d.ts +20 -0
- package/runtime/metadata.d.ts.map +1 -0
- package/runtime/metadata.js +143 -0
- package/runtime/options.d.ts +21 -0
- package/runtime/options.d.ts.map +1 -0
- package/runtime/options.js +100 -0
- package/runtime/state.d.ts +1 -0
- package/runtime/state.d.ts.map +1 -1
- package/runtime/state.js +5 -75
- package/src/installer.ts +17 -0
- package/src/jobs/context.ts +5 -3
- package/src/jobs/permissions.ts +1 -1
- package/src/jobs/program.ts +4 -1
- package/src/jobs/prompt.ts +5 -5
- package/src/jobs/schedule.ts +2 -1
- package/src/jobs/slash-command.ts +3 -2
- package/src/jobs/status-line.ts +3 -2
- package/src/jobs/tool.ts +3 -2
- package/src/mod.ts +46 -11
- package/src/options.ts +91 -0
- package/src/records.ts +131 -8
- package/src/register.ts +12 -3
- package/src/runtime/claude.ts +2 -0
- package/src/runtime/grants.ts +306 -0
- package/src/runtime/installer.ts +169 -0
- package/src/runtime/lifecycle.ts +227 -45
- package/src/runtime/metadata.ts +153 -0
- package/src/runtime/options.ts +102 -0
- package/src/runtime/state.ts +7 -70
- package/src/testing/fake-claude.ts +6 -1
- package/src/testing/fake-files.ts +9 -3
- package/src/testing.ts +40 -15
- package/src/utils/metadata.ts +242 -0
- package/testing/fake-claude.d.ts +4 -0
- package/testing/fake-claude.d.ts.map +1 -1
- package/testing/fake-claude.js +5 -1
- package/testing/fake-files.d.ts.map +1 -1
- package/testing/fake-files.js +9 -3
- package/testing.d.ts +6 -2
- package/testing.d.ts.map +1 -1
- package/testing.js +29 -13
- package/utils/metadata.d.ts +21 -0
- package/utils/metadata.d.ts.map +1 -0
- package/utils/metadata.js +250 -0
package/jobs/context.js
CHANGED
|
@@ -4,7 +4,7 @@ import { toolInputOf } from '../runtime/tool-calls.js';
|
|
|
4
4
|
import { listed } from '../utils/text.js';
|
|
5
5
|
import { findProjectScope } from './permissions/find-project-scope.js';
|
|
6
6
|
import { targetOf } from './permissions/match-target.js';
|
|
7
|
-
export function workspaceReader({ claude }) {
|
|
7
|
+
export function workspaceReader({ mod: { claude } }) {
|
|
8
8
|
let session;
|
|
9
9
|
return async () => {
|
|
10
10
|
session ??= readSession(claude);
|
|
@@ -25,7 +25,7 @@ async function readSession(claude) {
|
|
|
25
25
|
}
|
|
26
26
|
export function afterCall(job, contextAfter, failed) {
|
|
27
27
|
const readWorkspace = workspaceReader(job);
|
|
28
|
-
job.on('tool.call', async (e, next) => {
|
|
28
|
+
job.mod.claude.on('tool.call', async (e, next) => {
|
|
29
29
|
const before = Promise.all([useOf(job, e), readWorkspace()]);
|
|
30
30
|
await before.catch(() => undefined);
|
|
31
31
|
const result = await next(e);
|
|
@@ -41,7 +41,8 @@ async function useOf({ toolCalls }, e) {
|
|
|
41
41
|
export function modOf(job, { call, folder }, workspace, deadline) {
|
|
42
42
|
return modWithin(job, deadline, async () => workspace.scope?.workTreeOf(call !== undefined && 'path' in call ? call.path : folder));
|
|
43
43
|
}
|
|
44
|
-
export function modWithin({ mod
|
|
44
|
+
export function modWithin({ mod }, deadline, workTree = async () => undefined) {
|
|
45
|
+
const { claude } = mod;
|
|
45
46
|
const within = (call, task) => beforeDeadline(claude, deadline, call, task);
|
|
46
47
|
const folderOf = async (cwd) => {
|
|
47
48
|
const folder = cwd ?? (await workTree());
|
|
@@ -62,6 +63,7 @@ export function modWithin({ mod, claude }, deadline, workTree = async () => unde
|
|
|
62
63
|
list: (path) => within('mod.fs.list', mod.fs.list(path)),
|
|
63
64
|
exists: (path) => within('mod.fs.exists', mod.fs.exists(path)),
|
|
64
65
|
stat: (path, options) => within('mod.fs.stat', mod.fs.stat(path, options)),
|
|
66
|
+
find: (glob) => within('mod.fs.find', mod.fs.find(glob)),
|
|
65
67
|
},
|
|
66
68
|
http: { fetch: (url, init) => within('mod.http.fetch', mod.http.fetch(url, init)) },
|
|
67
69
|
dependencies: dependencyCalls(claude, within),
|
package/jobs/permissions.js
CHANGED
|
@@ -27,7 +27,7 @@ export function permissions(rules) {
|
|
|
27
27
|
return { decision: 'deny', reason: `The permissions job could not read the session, so it denies the call: ${messageOf(error)}` };
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
|
-
job.on('tool.check', async (e, next) => {
|
|
30
|
+
job.mod.claude.on('tool.check', async (e, next) => {
|
|
31
31
|
const [below, ours] = await Promise.all([next(e), verdictOf(e)]);
|
|
32
32
|
return ours === undefined ? below : stricterVerdict(below, ours);
|
|
33
33
|
});
|
package/jobs/program.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../src/jobs/program.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../src/jobs/program.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAIpC,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;IACxE,KAAK,IAAI,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACvD,CAAA;AAMD,wBAAgB,OAAO,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CA2ErI"}
|
package/jobs/program.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { PermissionRefused } from '../runtime/grants.js';
|
|
1
2
|
import { messageOf } from '../utils/text.js';
|
|
2
3
|
const backoffSeconds = [1, 2, 4, 8, 16];
|
|
3
4
|
export function program(options) {
|
|
4
5
|
const { command, environment } = options;
|
|
5
|
-
return ({ mod,
|
|
6
|
+
return ({ mod, announce }) => {
|
|
7
|
+
const { claude } = mod;
|
|
6
8
|
const [executable] = command;
|
|
7
9
|
if (executable === undefined)
|
|
8
10
|
throw new Error(`${mod.name}: the program has no command. Name the program on PATH and its arguments, such as ['preview-server', '--port', '0'].`);
|
|
@@ -47,6 +49,8 @@ export function program(options) {
|
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
51
|
catch (error) {
|
|
52
|
+
if (error instanceof PermissionRefused)
|
|
53
|
+
return stop(`${messageOf(error)} Add it, then run /reload-plugins.`);
|
|
50
54
|
lastError = messageOf(error);
|
|
51
55
|
}
|
|
52
56
|
address = undefined;
|
package/jobs/prompt.js
CHANGED
|
@@ -15,7 +15,7 @@ export function prompt({ name, prompt: text, when, after }) {
|
|
|
15
15
|
targetOf(target);
|
|
16
16
|
return (job) => {
|
|
17
17
|
job.reserveName('prompt', name, `prompt: ${job.mod.name} adds the name "${name}" two times. Give each prompt its own name.`);
|
|
18
|
-
const log = (reason) => job.claude.ui.log(`prompt "${name}" added nothing: ${reason}`, { to: 'debug' });
|
|
18
|
+
const log = (reason) => job.mod.claude.ui.log(`prompt "${name}" added nothing: ${reason}`, { to: 'debug' });
|
|
19
19
|
const textFor = async (input, mod) => {
|
|
20
20
|
try {
|
|
21
21
|
const value = typeof text === 'string' ? text : await text(input, mod);
|
|
@@ -49,13 +49,13 @@ function addKeptCurrent(job, name, textFor, log) {
|
|
|
49
49
|
let hasStarted = false;
|
|
50
50
|
let isQueued = false;
|
|
51
51
|
let updates = Promise.resolve();
|
|
52
|
-
job.on('classic.SessionStart', (e, next) => {
|
|
52
|
+
job.mod.claude.on('classic.SessionStart', (e, next) => {
|
|
53
53
|
hasStarted = e.source === 'resume' || e.source === 'compact';
|
|
54
54
|
if (!hasStarted)
|
|
55
55
|
given = undefined;
|
|
56
56
|
return next(e);
|
|
57
57
|
});
|
|
58
|
-
job.on('prompt.context', async (e, next) => {
|
|
58
|
+
job.mod.claude.on('prompt.context', async (e, next) => {
|
|
59
59
|
const below = await next(e);
|
|
60
60
|
hasStarted = true;
|
|
61
61
|
if (below.blocks.some((block) => block.name === name)) {
|
|
@@ -73,7 +73,7 @@ function addKeptCurrent(job, name, textFor, log) {
|
|
|
73
73
|
if (value === undefined || value === given)
|
|
74
74
|
return;
|
|
75
75
|
given = value;
|
|
76
|
-
await job.claude.session.append({ message: { type: 'user', content: [{ type: 'text', text: `# ${name}\n${value}` }] } }).then((added) => {
|
|
76
|
+
await job.mod.claude.session.append({ message: { type: 'user', content: [{ type: 'text', text: `# ${name}\n${value}` }] } }).then((added) => {
|
|
77
77
|
if (added.deny !== undefined)
|
|
78
78
|
log(`Claude Code refused the new text: ${added.deny}`);
|
|
79
79
|
});
|
|
@@ -86,7 +86,7 @@ function addKeptCurrent(job, name, textFor, log) {
|
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
88
|
function addAfterUserPrompts(job, when, textFor, log) {
|
|
89
|
-
job.on('prompt.submit', async (e, next) => {
|
|
89
|
+
job.mod.claude.on('prompt.submit', async (e, next) => {
|
|
90
90
|
let value;
|
|
91
91
|
try {
|
|
92
92
|
if (typeof when === 'function' ? when(e.text) : e.text.search(when) >= 0)
|
package/jobs/schedule.d.ts.map
CHANGED
|
@@ -1 +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,
|
|
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,CAoDlJ"}
|
package/jobs/schedule.js
CHANGED
|
@@ -5,7 +5,8 @@ export function schedule(entry) {
|
|
|
5
5
|
if (typeof entry !== 'function')
|
|
6
6
|
checked(entry);
|
|
7
7
|
return (job) => {
|
|
8
|
-
const { mod
|
|
8
|
+
const { mod } = job;
|
|
9
|
+
const { claude } = mod;
|
|
9
10
|
const order = scheduleCounts.get(mod) ?? 0;
|
|
10
11
|
scheduleCounts.set(mod, order + 1);
|
|
11
12
|
const storeKey = `cmod:schedule:${order}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slash-command.d.ts","sourceRoot":"","sources":["../src/jobs/slash-command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAMzC,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAA;AAM5E,wBAAgB,YAAY,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE;IACjF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAA;CAC1H,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"slash-command.d.ts","sourceRoot":"","sources":["../src/jobs/slash-command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAMzC,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAA;AAM5E,wBAAgB,YAAY,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE;IACjF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAA;CAC1H,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CA6BnB"}
|
package/jobs/slash-command.js
CHANGED
|
@@ -7,7 +7,8 @@ const commandName = /^[A-Za-z0-9_-]{1,64}$/;
|
|
|
7
7
|
export function slashCommand(options) {
|
|
8
8
|
const { name, description, argumentHint, immediate, reply } = options;
|
|
9
9
|
return (job) => {
|
|
10
|
-
const { mod,
|
|
10
|
+
const { mod, announce, reserveName } = job;
|
|
11
|
+
const { claude } = mod;
|
|
11
12
|
if (!commandName.test(name))
|
|
12
13
|
throw new Error(`${mod.name}: "${name}" is not a slash command name. Use 1 to 64 letters, digits, "_", or "-", without the slash.`);
|
|
13
14
|
reserveName('slashCommand', name, `${mod.name}: the slash command /${name} is already added. Give each slashCommand its own name.`);
|
|
@@ -19,7 +20,7 @@ export function slashCommand(options) {
|
|
|
19
20
|
});
|
|
20
21
|
announce(`/${name}`);
|
|
21
22
|
const replyMod = modWithin(job, deadline);
|
|
22
|
-
|
|
23
|
+
claude.on('command.run', async (e, next) => {
|
|
23
24
|
if (e.command !== registered)
|
|
24
25
|
return next(e);
|
|
25
26
|
try {
|
|
@@ -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,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,
|
|
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,CA0CnB"}
|
package/jobs/status-line.js
CHANGED
|
@@ -4,7 +4,8 @@ const deadline = { ms: 2000, job: 'statusLine' };
|
|
|
4
4
|
export function statusLine(options) {
|
|
5
5
|
const { text, interval = 10000 } = options;
|
|
6
6
|
return (job) => {
|
|
7
|
-
const { mod,
|
|
7
|
+
const { mod, announce, reserveName } = job;
|
|
8
|
+
const { claude } = mod;
|
|
8
9
|
if (!(interval >= 1))
|
|
9
10
|
throw new Error(`${mod.name}: the status line interval is ${interval}. Give it in milliseconds, 1 or more.`);
|
|
10
11
|
reserveName('statusLine', '', `${mod.name}: a status line is already added. A mod has one status line: join the texts in one statusLine.`);
|
|
@@ -33,7 +34,7 @@ export function statusLine(options) {
|
|
|
33
34
|
queue = queue.then(update);
|
|
34
35
|
};
|
|
35
36
|
announce('a status line');
|
|
36
|
-
|
|
37
|
+
claude.on('session.measure', (e, next) => {
|
|
37
38
|
refresh();
|
|
38
39
|
return next(e);
|
|
39
40
|
});
|
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,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,
|
|
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,CAqCxC"}
|
package/jobs/tool.js
CHANGED
|
@@ -7,7 +7,8 @@ const toolName = /^[A-Za-z0-9_-]{1,64}$/;
|
|
|
7
7
|
export function tool(options) {
|
|
8
8
|
const { name, description, inputSchema, execute } = options;
|
|
9
9
|
return (job) => {
|
|
10
|
-
const { mod,
|
|
10
|
+
const { mod, announce, reserveName } = job;
|
|
11
|
+
const { claude } = mod;
|
|
11
12
|
if (!toolName.test(name))
|
|
12
13
|
throw new Error(`${mod.name}: "${name}" is not a tool name. Use 1 to 64 letters, digits, "_", or "-".`);
|
|
13
14
|
const properties = inputSchema?.properties ?? {};
|
|
@@ -24,7 +25,7 @@ export function tool(options) {
|
|
|
24
25
|
});
|
|
25
26
|
announce(`the ${name} tool`);
|
|
26
27
|
const executeMod = modWithin(job, toolDeadline);
|
|
27
|
-
|
|
28
|
+
claude.on('tool.call', async (e, next) => {
|
|
28
29
|
if (e.tool !== registered)
|
|
29
30
|
return next(e);
|
|
30
31
|
const input = toolInputOf(e);
|
package/mod.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
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,
|
|
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, SessionMessage, Timer, ToastOptions, UiScrollArgs, UiScrollResult } from 'claude-code';
|
|
2
|
+
import type { Step } from './installer.js';
|
|
3
|
+
import { type Option, type Options, type OptionValues } from './options.js';
|
|
4
|
+
import type { FlagPermission, ListPermission } from './records.js';
|
|
2
5
|
import type { Claude } from './runtime/claude.js';
|
|
3
6
|
import type { RoutedEvent } from './runtime/hooks.js';
|
|
4
7
|
import type { RoutedHook } from './runtime/router.js';
|
|
@@ -74,9 +77,33 @@ export type ModHook<E extends ModEvent> = (input: HookInput<E>) => HookAnswer |
|
|
|
74
77
|
export type HookOptions = {
|
|
75
78
|
readonly timeoutMs?: number;
|
|
76
79
|
};
|
|
77
|
-
export type
|
|
80
|
+
export type ScrollArgs = Omit<UiScrollArgs, 'to'> & {
|
|
81
|
+
readonly to: Exclude<UiScrollArgs['to'], {
|
|
82
|
+
requestId: string;
|
|
83
|
+
}>;
|
|
84
|
+
};
|
|
85
|
+
export type ModClaude = Claude & {
|
|
86
|
+
on<N extends RoutedEvent>(event: N, hook: RoutedHook<N>): void;
|
|
87
|
+
};
|
|
88
|
+
export type Metadata = Readonly<Record<string, string>>;
|
|
89
|
+
export type FileMatch = {
|
|
90
|
+
readonly path: string;
|
|
91
|
+
readonly name?: string;
|
|
92
|
+
readonly metadata: Metadata;
|
|
93
|
+
readonly error?: string;
|
|
94
|
+
};
|
|
95
|
+
type SessionMessages = {
|
|
96
|
+
(): Promise<SessionMessage[]>;
|
|
97
|
+
(args: {
|
|
98
|
+
readonly agentId: string;
|
|
99
|
+
}): Promise<SessionMessage[] | {
|
|
100
|
+
readonly deny: string;
|
|
101
|
+
}>;
|
|
102
|
+
};
|
|
103
|
+
export type Mod<State extends object = Record<never, never>, Declared extends Options = Options> = {
|
|
78
104
|
readonly name: string;
|
|
79
105
|
readonly state: Readonly<State>;
|
|
106
|
+
readonly options: OptionValues<Declared>;
|
|
80
107
|
readonly dataFolder: string;
|
|
81
108
|
on<E extends ModEvent>(event: E, hook: ModHook<E>, options?: HookOptions): void;
|
|
82
109
|
use<Handle>(job: Job<Handle, State>): Handle;
|
|
@@ -87,7 +114,7 @@ export type Mod<State extends object = Record<never, never>> = {
|
|
|
87
114
|
toast(text: string, options?: ToastOptions): void;
|
|
88
115
|
progress<T>(title: string, task: (report: (step: ProgressStep) => void) => Promise<T>): Promise<T>;
|
|
89
116
|
ask(question: string, options?: readonly string[] | AskOptions): Promise<string>;
|
|
90
|
-
scroll(args:
|
|
117
|
+
scroll(args: ScrollArgs): Promise<UiScrollResult>;
|
|
91
118
|
};
|
|
92
119
|
readonly process: {
|
|
93
120
|
run(argv: readonly string[], init?: ProcessRunInit): Promise<ProcessRunResult>;
|
|
@@ -99,15 +126,21 @@ export type Mod<State extends object = Record<never, never>> = {
|
|
|
99
126
|
list(path?: string): Promise<FsEntry[]>;
|
|
100
127
|
exists(path: string): Promise<boolean>;
|
|
101
128
|
stat(path: string, options?: FsStatOptions): Promise<FsStat>;
|
|
129
|
+
find(glob: string | readonly string[]): Promise<readonly FileMatch[]>;
|
|
130
|
+
};
|
|
131
|
+
readonly metadata: {
|
|
132
|
+
read(path: string): Promise<Metadata>;
|
|
133
|
+
update(path: string, change: (metadata: Record<string, string>) => void): Promise<void>;
|
|
102
134
|
};
|
|
103
135
|
readonly http: {
|
|
104
136
|
fetch(url: string, init?: HttpInit): Promise<HttpResponse>;
|
|
105
137
|
};
|
|
106
138
|
readonly settings: {
|
|
107
|
-
|
|
139
|
+
page(page: Pane<State>): void;
|
|
140
|
+
open(pageId?: string): Promise<void>;
|
|
108
141
|
};
|
|
109
142
|
readonly session: {
|
|
110
|
-
messages:
|
|
143
|
+
messages: SessionMessages;
|
|
111
144
|
append(text: string): Promise<void>;
|
|
112
145
|
submit(text: string): Promise<void>;
|
|
113
146
|
};
|
|
@@ -117,9 +150,14 @@ export type Mod<State extends object = Record<never, never>> = {
|
|
|
117
150
|
readonly model: {
|
|
118
151
|
complete(request: ModelCompleteRequest, options?: ModelCompleteOptions): Promise<ModelCompleteResult>;
|
|
119
152
|
};
|
|
153
|
+
readonly permissions: {
|
|
154
|
+
has(name: ListPermission, value: string): boolean;
|
|
155
|
+
has(name: FlagPermission): boolean;
|
|
156
|
+
};
|
|
120
157
|
readonly projectRoot: string;
|
|
121
158
|
readonly cwd: string;
|
|
122
159
|
readonly dependencies: CmodDependencies;
|
|
160
|
+
readonly claude: ModClaude;
|
|
123
161
|
};
|
|
124
162
|
type StateGroups = {
|
|
125
163
|
readonly memory?: object;
|
|
@@ -130,22 +168,22 @@ type StateGroups = {
|
|
|
130
168
|
type Api<Contract, State extends object> = {
|
|
131
169
|
readonly [Method in keyof Contract]: Contract[Method] extends (input: infer Input) => infer Result ? (input: Input, mod: Mod<State>) => Result | Awaited<Result> : never;
|
|
132
170
|
};
|
|
133
|
-
export type ModDefinition<State extends StateGroups = Record<never, never>, Name extends string = string
|
|
171
|
+
export type ModDefinition<State extends StateGroups = Record<never, never>, Name extends string = string, Declared extends Options = Record<never, Option>> = {
|
|
134
172
|
readonly name: Name;
|
|
135
173
|
readonly state?: State;
|
|
174
|
+
readonly options?: Declared;
|
|
136
175
|
readonly api?: Name extends keyof CmodDependencies ? Api<CmodDependencies[Name], State> : {
|
|
137
176
|
readonly [method: string]: (input: never, mod: Mod<State>) => unknown;
|
|
138
177
|
};
|
|
139
|
-
|
|
178
|
+
readonly installer?: readonly Step<State>[];
|
|
179
|
+
setup(mod: Mod<State, Declared>): void | Promise<void>;
|
|
140
180
|
};
|
|
141
181
|
export type JobContext<State extends object = Record<never, never>> = {
|
|
142
182
|
readonly mod: Mod<State>;
|
|
143
|
-
readonly claude: Claude;
|
|
144
|
-
on<N extends RoutedEvent>(event: N, hook: RoutedHook<N>): void;
|
|
145
183
|
announce(feature: string): void;
|
|
146
184
|
reserveName(kind: string, name: string, taken: string): void;
|
|
147
185
|
readonly toolCalls: ToolCalls;
|
|
148
186
|
};
|
|
149
187
|
export type Job<Handle, State extends object = Record<never, never>> = (context: JobContext<State>) => Handle;
|
|
150
|
-
export declare function defineMod<State extends StateGroups = Record<never, never>, Name extends string = string
|
|
188
|
+
export declare function defineMod<State extends StateGroups = Record<never, never>, Name extends string = string, const Declared extends Options = Record<never, Option>>(definition: ModDefinition<State, Name, Declared>): ModDefinition<State, Name, Declared>;
|
|
151
189
|
//# 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":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,OAAO,EACP,MAAM,EACN,aAAa,EACb,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,EACZ,yBAAyB,EACzB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["src/mod.ts"],"names":[],"mappings":"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"}
|
package/mod.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { checkOptions } from './options.js';
|
|
1
2
|
export { longestMs } from './runtime/deadline.js';
|
|
2
3
|
export { notInstalled } from './runtime/dependencies.js';
|
|
3
4
|
export { messageOf } from './utils/text.js';
|
|
4
5
|
export function defineMod(definition) {
|
|
5
6
|
if (definition.name.trim() === '')
|
|
6
7
|
throw new Error('defineMod: the mod needs a name, such as the name in .claude-plugin/plugin.json.');
|
|
8
|
+
if (definition.options !== undefined)
|
|
9
|
+
checkOptions(definition.name, definition.options);
|
|
7
10
|
return definition;
|
|
8
11
|
}
|
package/options.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export type OptionKind = 'text' | 'secret' | 'number' | 'toggle' | 'choice' | 'folder' | 'file' | 'list';
|
|
2
|
+
export type OptionValue = string | number | boolean | readonly string[];
|
|
3
|
+
type Described = {
|
|
4
|
+
readonly title: string;
|
|
5
|
+
readonly description: string;
|
|
6
|
+
};
|
|
7
|
+
export type Option<Value extends OptionValue = OptionValue> = Described & {
|
|
8
|
+
readonly kind: OptionKind;
|
|
9
|
+
readonly default?: Value;
|
|
10
|
+
readonly min?: number;
|
|
11
|
+
readonly max?: number;
|
|
12
|
+
readonly choices?: readonly string[];
|
|
13
|
+
};
|
|
14
|
+
export type Options = Readonly<Record<string, Option>>;
|
|
15
|
+
export type OptionValues<Declared extends Options> = {
|
|
16
|
+
readonly [Key in keyof Declared]: Declared[Key] extends Option<infer Value> ? Value : never;
|
|
17
|
+
};
|
|
18
|
+
export type UserConfigField = Described & {
|
|
19
|
+
readonly type: 'string' | 'number' | 'boolean' | 'directory' | 'file';
|
|
20
|
+
readonly sensitive?: true;
|
|
21
|
+
readonly multiple?: true;
|
|
22
|
+
readonly default?: OptionValue;
|
|
23
|
+
readonly min?: number;
|
|
24
|
+
readonly max?: number;
|
|
25
|
+
readonly options?: readonly string[];
|
|
26
|
+
};
|
|
27
|
+
export declare const option: {
|
|
28
|
+
text: (field: Described & {
|
|
29
|
+
readonly default?: string;
|
|
30
|
+
}) => Option<string>;
|
|
31
|
+
secret: (field: Described) => Option<string>;
|
|
32
|
+
number: (field: Described & {
|
|
33
|
+
readonly default?: number;
|
|
34
|
+
readonly min?: number;
|
|
35
|
+
readonly max?: number;
|
|
36
|
+
}) => Option<number>;
|
|
37
|
+
toggle: (field: Described & {
|
|
38
|
+
readonly default?: boolean;
|
|
39
|
+
}) => Option<boolean>;
|
|
40
|
+
choice: <const Choice extends string>(choices: readonly Choice[], field: Described & {
|
|
41
|
+
readonly default?: Choice;
|
|
42
|
+
}) => Option<Choice>;
|
|
43
|
+
folder: (field: Described & {
|
|
44
|
+
readonly default?: string;
|
|
45
|
+
}) => Option<string>;
|
|
46
|
+
file: (field: Described & {
|
|
47
|
+
readonly default?: string;
|
|
48
|
+
}) => Option<string>;
|
|
49
|
+
list: (field: Described & {
|
|
50
|
+
readonly default?: readonly string[];
|
|
51
|
+
}) => Option<readonly string[]>;
|
|
52
|
+
};
|
|
53
|
+
export declare function checkOptions(name: string, options: Options): Options;
|
|
54
|
+
export declare function userConfigOf(options: Options): Record<string, UserConfigField>;
|
|
55
|
+
export declare function isUnset(value: unknown): boolean;
|
|
56
|
+
export declare function fitsOption(declared: Option, value: unknown): string | undefined;
|
|
57
|
+
export {};
|
|
58
|
+
//# sourceMappingURL=options.d.ts.map
|
package/options.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["src/options.ts"],"names":[],"mappings":"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"}
|
package/options.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export const option = {
|
|
2
|
+
text: (field) => ({ ...field, kind: 'text' }),
|
|
3
|
+
secret: (field) => ({ ...field, kind: 'secret' }),
|
|
4
|
+
number: (field) => ({ ...field, kind: 'number' }),
|
|
5
|
+
toggle: (field) => ({ ...field, kind: 'toggle', default: field.default ?? false }),
|
|
6
|
+
choice: (choices, field) => ({ ...field, kind: 'choice', choices }),
|
|
7
|
+
folder: (field) => ({ ...field, kind: 'folder' }),
|
|
8
|
+
file: (field) => ({ ...field, kind: 'file' }),
|
|
9
|
+
list: (field) => ({ ...field, kind: 'list' }),
|
|
10
|
+
};
|
|
11
|
+
const types = { text: 'string', secret: 'string', number: 'number', toggle: 'boolean', choice: 'string', folder: 'directory', file: 'file', list: 'string' };
|
|
12
|
+
const optionKey = /^[A-Za-z_]\w*$/;
|
|
13
|
+
export function checkOptions(name, options) {
|
|
14
|
+
for (const [key, declared] of Object.entries(options)) {
|
|
15
|
+
const at = `${name}: options.${key}`;
|
|
16
|
+
if (!optionKey.test(key))
|
|
17
|
+
throw new Error(`${at} is not an option name. Use letters, digits, and _, starting with a letter, as Claude Code passes each option on as CLAUDE_PLUGIN_OPTION_${key.toUpperCase()}.`);
|
|
18
|
+
if (declared.title.trim() === '')
|
|
19
|
+
throw new Error(`${at} needs a title, the label /config shows.`);
|
|
20
|
+
if (declared.kind === 'choice' && (declared.choices ?? []).length === 0)
|
|
21
|
+
throw new Error(`${at} is a choice with no choices. Give option.choice(['a', 'b'], { ... }).`);
|
|
22
|
+
if (declared.kind === 'choice' && declared.default !== undefined && !(declared.choices ?? []).includes(declared.default))
|
|
23
|
+
throw new Error(`${at} defaults to ${String(declared.default)}, which is not one of its choices: ${(declared.choices ?? []).join(', ')}.`);
|
|
24
|
+
}
|
|
25
|
+
return options;
|
|
26
|
+
}
|
|
27
|
+
export function userConfigOf(options) {
|
|
28
|
+
return Object.fromEntries(Object.entries(options).map(([key, declared]) => [
|
|
29
|
+
key,
|
|
30
|
+
{
|
|
31
|
+
type: types[declared.kind],
|
|
32
|
+
title: declared.title,
|
|
33
|
+
description: declared.description,
|
|
34
|
+
...(declared.kind === 'secret' ? { sensitive: true } : {}),
|
|
35
|
+
...(declared.kind === 'list' ? { multiple: true } : {}),
|
|
36
|
+
...(declared.kind === 'choice' ? { options: declared.choices } : {}),
|
|
37
|
+
...(declared.default === undefined ? {} : { default: declared.default }),
|
|
38
|
+
...(declared.min === undefined ? {} : { min: declared.min }),
|
|
39
|
+
...(declared.max === undefined ? {} : { max: declared.max }),
|
|
40
|
+
},
|
|
41
|
+
]));
|
|
42
|
+
}
|
|
43
|
+
export function isUnset(value) {
|
|
44
|
+
return value === undefined || value === '' || (Array.isArray(value) && value.length === 0);
|
|
45
|
+
}
|
|
46
|
+
export function fitsOption(declared, value) {
|
|
47
|
+
const kind = declared.kind;
|
|
48
|
+
if (kind === 'toggle')
|
|
49
|
+
return typeof value === 'boolean' ? undefined : 'takes true or false';
|
|
50
|
+
if (kind === 'number') {
|
|
51
|
+
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
52
|
+
return 'takes a number';
|
|
53
|
+
if (declared.min !== undefined && value < declared.min)
|
|
54
|
+
return `takes ${declared.min} or more`;
|
|
55
|
+
if (declared.max !== undefined && value > declared.max)
|
|
56
|
+
return `takes ${declared.max} or less`;
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
if (kind === 'list')
|
|
60
|
+
return Array.isArray(value) && value.every((item) => typeof item === 'string') ? undefined : 'takes a list of text';
|
|
61
|
+
if (typeof value !== 'string')
|
|
62
|
+
return 'takes text';
|
|
63
|
+
if (kind === 'choice' && !(declared.choices ?? []).includes(value))
|
|
64
|
+
return `takes one of: ${(declared.choices ?? []).join(', ')}`;
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
package/package.json
CHANGED
package/records.d.ts
CHANGED
|
@@ -13,7 +13,12 @@ export type Steps = {
|
|
|
13
13
|
uninstall?: string;
|
|
14
14
|
program?: string;
|
|
15
15
|
keys?: Readonly<Record<string, string>>;
|
|
16
|
+
permissions?: readonly string[];
|
|
16
17
|
};
|
|
18
|
+
export declare const listPermissions: readonly ['network', 'run', 'files'];
|
|
19
|
+
export declare const flagPermissions: readonly ['conversation', 'prompt', 'model', 'agents', 'tools', 'config', 'approve'];
|
|
20
|
+
export type ListPermission = (typeof listPermissions)[number];
|
|
21
|
+
export type FlagPermission = (typeof flagPermissions)[number];
|
|
17
22
|
export type ReadFile = (path: string) => Promise<string | undefined>;
|
|
18
23
|
export type RunnerEvent = {
|
|
19
24
|
kind: 'progress';
|
|
@@ -29,6 +34,7 @@ export type RunnerEvent = {
|
|
|
29
34
|
install: string;
|
|
30
35
|
uninstall: string;
|
|
31
36
|
keys: string;
|
|
37
|
+
permissions: readonly string[];
|
|
32
38
|
} | {
|
|
33
39
|
kind: 'done';
|
|
34
40
|
name: string;
|
|
@@ -53,7 +59,16 @@ export declare function configFolders(env: Record<string, string | undefined>, n
|
|
|
53
59
|
export declare function readRecord(read: ReadFile, store: string, name: string): Promise<InstallRecord | undefined>;
|
|
54
60
|
export declare function writeRecord(write: (path: string, text: string) => Promise<void>, store: string, record: InstallRecord): Promise<void>;
|
|
55
61
|
export declare function readSteps(pkg: unknown): Steps | undefined;
|
|
56
|
-
export declare function
|
|
62
|
+
export declare function permissionWords(item: string): string;
|
|
63
|
+
export declare const settingsPagesMethod = "cmod:settingsPages";
|
|
64
|
+
export declare const openPageMethod = "cmod:openPage";
|
|
65
|
+
export declare const pendingStepsMethod = "cmod:pendingSteps";
|
|
66
|
+
export declare const finishStepsMethod = "cmod:finishSteps";
|
|
67
|
+
export declare function marketplaceOf(root: string, name: string): string | undefined;
|
|
68
|
+
export declare function updatesToTurnOn(marketplace: string | undefined, settings: unknown, known: unknown): string | undefined;
|
|
69
|
+
export declare function consentPath(store: string): string;
|
|
70
|
+
export declare function parseConsent(value: unknown, path: string): Record<string, string[]>;
|
|
71
|
+
export declare function oldestCmodFor(steps: Steps): string;
|
|
57
72
|
export declare function keyWords(keys: Readonly<Record<string, string>> | undefined): string;
|
|
58
73
|
export declare function scriptPaths(command: string): string[];
|
|
59
74
|
export declare function scriptsSha256(steps: Steps, files: {
|
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;IACtB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CACvC,CAAA;AAED,MAAM,MAAM,KAAK,GAAG;
|
|
1
|
+
{"version":3,"file":"records.d.ts","sourceRoot":"","sources":["src/records.ts"],"names":[],"mappings":"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"}
|