@cmodjs/core 2.1.0 → 3.1.0
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 +2 -2
- package/docs/mod.md +3 -1
- package/docs/permissions.md +3 -1
- package/docs/session.md +9 -1
- package/docs/testing.md +4 -2
- package/jobs/context.d.ts.map +1 -1
- package/jobs/context.js +2 -1
- package/jobs/permissions.d.ts.map +1 -1
- package/jobs/permissions.js +1 -1
- package/jobs/prompt.d.ts.map +1 -1
- package/jobs/prompt.js +2 -1
- package/jobs/slash-command.d.ts.map +1 -1
- package/jobs/slash-command.js +4 -3
- package/package.json +1 -1
- package/records.d.ts +2 -1
- package/records.d.ts.map +1 -1
- package/records.js +4 -1
- package/register.d.ts.map +1 -1
- package/register.js +58 -51
- package/runtime/before.d.ts +1 -1
- package/runtime/before.d.ts.map +1 -1
- package/runtime/before.js +6 -5
- package/runtime/conversations.d.ts.map +1 -1
- package/runtime/conversations.js +46 -19
- package/runtime/hooks.d.ts +2 -1
- package/runtime/hooks.d.ts.map +1 -1
- package/runtime/hooks.js +7 -0
- package/runtime/lifecycle.d.ts +2 -1
- package/runtime/lifecycle.d.ts.map +1 -1
- package/runtime/lifecycle.js +31 -9
- package/runtime/permission-check.d.ts +3 -0
- package/runtime/permission-check.d.ts.map +1 -1
- package/runtime/permission-check.js +31 -10
- package/runtime/router.d.ts +3 -1
- package/runtime/router.d.ts.map +1 -1
- package/runtime/router.js +19 -11
- package/runtime/sessions.d.ts +13 -4
- package/runtime/sessions.d.ts.map +1 -1
- package/runtime/sessions.js +67 -26
- package/runtime/toaster.d.ts.map +1 -1
- package/runtime/toaster.js +3 -0
- package/session/context/turn/message/message.d.ts.map +1 -1
- package/session/context/turn/message/message.js +30 -2
- package/session/context/turn/message/note.d.ts +7 -0
- package/session/context/turn/message/note.d.ts.map +1 -1
- package/session/context/turn/message/note.js +12 -0
- package/session/session.d.ts +3 -1
- package/session/session.d.ts.map +1 -1
- package/src/jobs/context.ts +2 -1
- package/src/jobs/permissions.ts +8 -4
- package/src/jobs/prompt.ts +2 -1
- package/src/jobs/slash-command.ts +4 -3
- package/src/records.ts +5 -1
- package/src/register.ts +63 -52
- package/src/runtime/before.ts +7 -6
- package/src/runtime/conversations.ts +54 -27
- package/src/runtime/hooks.ts +9 -1
- package/src/runtime/lifecycle.ts +37 -13
- package/src/runtime/permission-check.ts +51 -21
- package/src/runtime/router.ts +23 -13
- package/src/runtime/sessions.ts +91 -37
- package/src/runtime/toaster.ts +2 -0
- package/src/session/context/turn/message/message.ts +27 -2
- package/src/session/context/turn/message/note.ts +16 -0
- package/src/session/session.ts +1 -2
- package/src/testing/fake-claude.ts +4 -3
- package/src/testing.ts +6 -5
- package/testing/fake-claude.d.ts +1 -0
- package/testing/fake-claude.d.ts.map +1 -1
- package/testing/fake-claude.js +3 -2
- package/testing.d.ts.map +1 -1
- package/testing.js +5 -4
package/docs/commands.md
CHANGED
|
@@ -93,7 +93,7 @@ cmod publish [path] [--dry-run]
|
|
|
93
93
|
Releases the mod at `path` (default: the current folder) at the version in its `plugin.json`. It refuses a `plugin.json` whose `userConfig` differs from the options `defineMod` declares, and says to run `cmod check` and commit `.claude-plugin/plugin.json`.
|
|
94
94
|
|
|
95
95
|
1. Builds the release from the committed files, leaving out `cli/`, `.github/`, and `.claude/`. A `"files"` list in `package.json` limits the release to the paths it lists, plus the folders of the install and uninstall steps, `.claude-plugin/`, `package.json`, `tsconfig.json`, the README, the license, and `CHANGELOG.md`, the way `npm publish` reads it. `tsconfig.json` holds the JSX settings the bundle in step 2 needs. List every folder the hooks module imports from, such as `"files": ["hooks", "src", "skills"]`, because the bundle in step 2 is built from the release.
|
|
96
|
-
2. Bundles the hooks module that `hooks/hooks.json` names, with the mod's source and packages, into one readable `.js` file, writes each control character in it as a `\u` escape, and points `hooks/hooks.json` at it. Anthropic's plugin directory reads a repository without installing its packages, so it can follow a mod only when all its code is in one file.
|
|
96
|
+
2. Bundles the hooks module that `hooks/hooks.json` names, with the mod's source and packages, into one readable `.js` file, writes each control character in it as a `\u` escape, and points `hooks/hooks.json` at it. Anthropic's plugin directory reads a repository without installing its packages, so it can follow a mod only when all its code is in one file. Without `"approve": true` in `package.json` `"cmod".permissions`, the bundle leaves out the code that allows and asks on Claude Code's permission check ([permissions.md](permissions.md)).
|
|
97
97
|
3. Checks the release with `claude plugin validate --strict`, and stops with the validator's message when it fails.
|
|
98
98
|
4. Commits the release as the `release` branch, and builds the release archive from that commit.
|
|
99
99
|
5. Builds the program `cli/` declares, and writes `SHA256SUMS` for every file of the release.
|
|
@@ -205,7 +205,7 @@ Reads every conversation Claude Code saved, as the sessions, contexts, turns, ta
|
|
|
205
205
|
- `state` prints what a running conversation resumes from.
|
|
206
206
|
- `follow` prints each message, turn, context, task, and goal change of the sessions named as Claude Code saves it, until stopped with Ctrl+C. `--running` follows every running session of the project too, and each one that starts later. The cmod plugin runs it to hear other running sessions.
|
|
207
207
|
- `--json` prints JSON instead of one line each.
|
|
208
|
-
- `index` reads every saved conversation into the index at `~/.local/share/cmod/history-
|
|
208
|
+
- `index` reads every saved conversation into the index at `~/.local/share/cmod/history-7.sqlite`, which holds where each message is in its transcript, not a copy of it, and each conversation's turns, contexts, and tasks. While a mod other than cmod holds the `conversation` permission, the cmod plugin runs it in the background at each session's start, and a second run while one is running exits at once. The index forgets a conversation whose transcript is deleted.
|
|
209
209
|
|
|
210
210
|
## Run in an install script
|
|
211
211
|
|
package/docs/mod.md
CHANGED
|
@@ -133,7 +133,9 @@ export function register(addHook: On, options: PluginOptions): void {
|
|
|
133
133
|
}
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
-
A mod that
|
|
136
|
+
A mod that allows or asks, with a `before` method or an `ask` rule of the `permissions` job, also declares `"approve": true` in its `package.json` `"cmod".permissions`, so the person grants it at install. `cmod check` adds the line when it is missing, and without the grant cmod drops every allow or ask the mod answers, so Claude Code decides those calls itself. A mod that only refuses needs no `approve`, and its bundle holds no code that allows, so Anthropic's plugin directory can list it ([permissions.md](permissions.md)). A mod without `registerPermissionCheck` has no part in Claude Code's permission check, so the plugin directory reads it as one that never answers a permission. Without it, each of those methods and `mod.use(permissions(…))` throws `<mod>: <method> hears Claude Code's permission check, so hooks/register.ts must call registerPermissionCheck(addHook) after registerMod.` where it is called, so a mod that calls one in `setup` does not start. `cmod check` fails a mod whose `src/` uses one while `register.ts` does not call `registerPermissionCheck`.
|
|
137
|
+
|
|
138
|
+
Where an organization manages Claude Code, Claude Code passes a mod the person installed over on its classic hooks, the notes it adds to a prompt, its Skill and instruction-file text, and compactions, and runs those only for a plugin the organization lists in managed settings. There, the `on` and `before` methods built on them hear nothing until the organization lists the mod and the cmod plugin. `claude plugin validate` names each such hook.
|
|
137
139
|
|
|
138
140
|
Keep `register.ts` this small. Claude Code checks a hooks module before it loads it, and refuses some shapes, such as a `$` passed to a function in another module. The plugin directory reads the bundled module too, and flags it when the name of `register`'s first parameter is declared anywhere else in the bundle. `@cmodjs/core` declares `on` as a key, so name that parameter `addHook`. Declare `register` as a function, as here: `cmod publish` bundles the hooks module into one file, and Claude Code refuses a bundled `register` that is not one.
|
|
139
141
|
|
package/docs/permissions.md
CHANGED
|
@@ -29,7 +29,9 @@ They sit in the `package.json` `cmod` key, beside `install` and `keys`, because
|
|
|
29
29
|
|
|
30
30
|
Reading files, drawing panes and renders, toasts, slash commands, tools of the mod's own, listeners on the mod's own session, and a `refuse` answer need no permission. Writing a Claude Code settings file with `fs.write` is refused with every permission, and names the `settings` call to use instead ([mod.md](mod.md#settings-claude-code-s-settings-files)).
|
|
31
31
|
|
|
32
|
-
`cmod check` adds `"approve": true` to `package.json` when the mod
|
|
32
|
+
`cmod check` adds `"approve": true` to `package.json` when the mod allows or asks, with a `beforePermissionCheck` or `beforePermissionRequest` answer or an `ask` rule of the `permissions` job, and the line is missing, and says so. A mod that only refuses, or only listens with `onPermissionCheck` or `onPermissionRequest`, needs no `approve`.
|
|
33
|
+
|
|
34
|
+
Anthropic's plugin directory does not list a mod that can approve Claude's tool calls. So `cmod publish` leaves the code that allows and asks out of the bundle of a mod that does not declare `"approve": true`, and that mod can be listed. A mod that declares it installs through cmod and the [Mods page](https://claudemodmanager.com/mods), and `cmod check` says the directory does not list it.
|
|
33
35
|
|
|
34
36
|
## What the person sees
|
|
35
37
|
|
package/docs/session.md
CHANGED
|
@@ -165,7 +165,7 @@ sessions.current.onTurnEnd(async (turn, { signal }) => {
|
|
|
165
165
|
}, { timeoutMs: 30_000 })
|
|
166
166
|
```
|
|
167
167
|
|
|
168
|
-
An `on` listener that passes its time stops quietly. A `before` listener that passes its time shows the error toast, and what was about to happen goes on as it was. With `onFailure: 'refuse'`, a `before` listener that throws or passes its time refuses instead, with the error as the reason, for a gate that must hold even when it breaks.
|
|
168
|
+
An `on` listener that passes its time stops quietly. A `before` listener that passes its time shows the error toast, and what was about to happen goes on as it was. With `onFailure: 'refuse'`, a `before` listener that throws or passes its time refuses instead, with the error as the reason, for a gate that must hold even when it breaks. The gate holds when Claude Code stops the mod's hook too, as it does when the listener's own code runs past 10 seconds without waiting on a call, and the toast `Claude Code stopped its <hook> hook` says so. On another session, it holds when that session does not answer within 5 seconds, or within what is left of the 8 seconds cmod waits on other sessions for one event, for what the listener's matcher and part cover. A `beforePermissionRequest` listener always refuses when it fails.
|
|
169
169
|
|
|
170
170
|
### Change what happens
|
|
171
171
|
|
|
@@ -197,6 +197,8 @@ sessions.current.beforeTurnEnd(async () => ((await testsPass()) ? undefined : {
|
|
|
197
197
|
|
|
198
198
|
An answer that changes text needs the `prompt` permission, a `beforeToolCall` answer needs `tools`, and a `beforeTaskStart` answer needs `tasks`. Without it the answer changes nothing, and the toast `The <method> listener failed` names the permission. When several listeners answer, each sees what the one before it changed, and the first `refuse` or `result` decides.
|
|
199
199
|
|
|
200
|
+
Claude reads each mod's `note` inside the mod's own tag, such as `<tracer_mod>…</tracer_mod>` for the mod `tracer`. Every note Claude received becomes a `Note` whose `from` is `{ type: 'mod', name }`, so `onNote({ from: { type: 'mod', name: 'tracer' } })` hears each note of tracer's that Claude got, and never one Claude Code dropped.
|
|
201
|
+
|
|
200
202
|
### The session's own events
|
|
201
203
|
|
|
202
204
|
`sessions.current` is a `CurrentSession`, which also hears what happens to the session itself. Each event has an `on` method, and one a mod can change also has a `before` method. A `before` method's answer reaches Claude Code, and an `on` listener never makes Claude Code wait. These methods hear the main agent, never a subagent.
|
|
@@ -222,6 +224,12 @@ An answer that changes text needs the `prompt` permission, a `beforeToolCall` an
|
|
|
222
224
|
|
|
223
225
|
The four `PermissionCheck` and `PermissionRequest` methods work only in a mod whose `hooks/register.ts` calls `registerPermissionCheck` ([mod.md](mod.md#register-the-mod-with-claude-code)). Without it they throw where they are called.
|
|
224
226
|
|
|
227
|
+
At a compaction, Claude reads the `note` at the start of the window the compaction opens, and `title`, `reloadSkills`, and `firstPrompt` apply to the whole session. The payload carries `model` for the main agent and `contextTokenCount` as the compaction left it. `sessions.current.beforeSessionStart` hears the main agent's compactions. `sessions.current.goal.beforeSessionStart` also hears every subagent's, with the subagent in `task`, and its note reaches that subagent's window:
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
sessions.current.goal.beforeSessionStart({ source: 'compact' }, ({ task }) => ({ note: primerFor(task) }))
|
|
231
|
+
```
|
|
232
|
+
|
|
225
233
|
Every payload also carries where it happened: `session`, `cwd`, and `agentType?` and `permissionMode?` when Claude Code reports them. A matcher keeps the payloads it matches:
|
|
226
234
|
|
|
227
235
|
```ts
|
package/docs/testing.md
CHANGED
|
@@ -97,6 +97,8 @@ Starts the mod: loads its state, runs `setup`, and adds its listeners, panes, an
|
|
|
97
97
|
- `raise.beforeTaskStart({ title, agentType?, model? })` asks about a task about to start.
|
|
98
98
|
- `raise.beforeTurnEnd({ answer?, failure? })` asks about the open turn ending. It rejects when no turn is open: add a `Prompt` first.
|
|
99
99
|
- `raise.beforeContextEnd()` asks about a compaction of the open context. `{ task }` asks about the compaction of a task's context, a task `tested.startTask` started.
|
|
100
|
+
- `raise.beforeSessionStart({ source: 'compact' })` asks about the main agent's compaction. `{ source: 'compact', task }` asks about a subagent's, which only `sessions.current.goal.beforeSessionStart` hears.
|
|
101
|
+
- A `note` that `raise` returns is the mod's own text. What Claude Code receives, as `claudeCodeOf(tested).fire` shows it, holds the note inside the mod's tag, such as `<guard_mod>…</guard_mod>`.
|
|
100
102
|
|
|
101
103
|
```ts
|
|
102
104
|
test('a force push is refused', async () => {
|
|
@@ -279,7 +281,7 @@ type Fakes = {
|
|
|
279
281
|
prompt: { submit? }
|
|
280
282
|
model: { complete? }
|
|
281
283
|
agent: { list?, spawn? }
|
|
282
|
-
clock: { after?, every? }
|
|
284
|
+
clock: { now?, after?, every? }
|
|
283
285
|
cmod: { call? }
|
|
284
286
|
tool: { call? }
|
|
285
287
|
}
|
|
@@ -292,7 +294,7 @@ Set a fake to answer a call:
|
|
|
292
294
|
- `files` already fills the `fs` fakes: a write is read back, and `list` lists the given files. The fake file system resolves a relative path against `/`, not against the session's working folder, so a mod under test reads `${sessions.current.project}/<file>` rather than a relative path. `fs.list()` with no path rejects.
|
|
293
295
|
- `ui.open` places every pane by default. A fake that answers `{ isPlaced: false }` holds a pane back.
|
|
294
296
|
- `ui.scroll` answers `{}` by default, as when the window moved. A fake that answers `{ deny }` refuses the scroll.
|
|
295
|
-
- `clock.after(ms, fn)` and `clock.every(ms, fn)` each return `{ cancel() }`, and so must a fake of either. `clock.after` runs a real timer by default. `clock.every` never fires unless a fake keeps `fn` for the test to call, so a test of `mod.every` keeps it and calls it once per tick.
|
|
297
|
+
- `clock.now()` answers the real time unless a fake gives its own, so a test of a deadline can move time. `clock.after(ms, fn)` and `clock.every(ms, fn)` each return `{ cancel() }`, and so must a fake of either. `clock.after` runs a real timer by default. `clock.every` never fires unless a fake keeps `fn` for the test to call, so a test of `mod.every` keeps it and calls it once per tick.
|
|
296
298
|
- `session.append` and `prompt.submit` take every note and prompt by default, into `shown.notes` and `shown.prompts`. A fake that answers `{ deny }` or `{ drop }` refuses one.
|
|
297
299
|
- `model.complete` has no default: set it to the answer the model gives, such as `async () => ({ isAnswered: true, text: 'no', usage })`.
|
|
298
300
|
- `settings.read` answers `{}` by default, as Claude Code does with no `settings.json` files.
|
package/jobs/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/jobs/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAC3C,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/jobs/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAC3C,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAKtE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAA;AACpD,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,qCAAqC,CAAA;AACtF,OAAO,EAAY,KAAK,MAAM,EAAE,MAAM,+BAA+B,CAAA;AAKrE,wBAAgB,eAAe,CAAC,EAAE,GAAG,EAAE,EAAE,UAAU,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAmB7E;AAED,wBAAgB,SAAS,CAAC,KAAK,SAAS,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,SAAS,MAAM,EAAE,GAAG,IAAI,CAW3M;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAE5H;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAEzI;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CASlD"}
|
package/jobs/context.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { beforeDeadline } from '../runtime/deadline.js';
|
|
2
2
|
import { engineOf } from '../runtime/engine.js';
|
|
3
3
|
import { toolInputOf } from '../runtime/tool-calls.js';
|
|
4
|
+
import { modNote } from '../session/context/turn/message/note.js';
|
|
4
5
|
import { listed } from '../utils/text.js';
|
|
5
6
|
import { findProjectScope } from './permissions/find-project-scope.js';
|
|
6
7
|
import { targetOf } from './permissions/match-target.js';
|
|
@@ -34,7 +35,7 @@ export function afterCall(job, contextAfter, failed) {
|
|
|
34
35
|
if (result.deny !== undefined || result.isError === true)
|
|
35
36
|
return result;
|
|
36
37
|
const added = await before.then(([use, workspace]) => contextAfter(use, workspace)).catch(failed);
|
|
37
|
-
return added.length === 0 ? result : { ...result, context: [...(result.context ?? []), ...added] };
|
|
38
|
+
return added.length === 0 ? result : { ...result, context: [...(result.context ?? []), ...added.map((note) => modNote(job.mod.name, note))] };
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
41
|
export async function inFolder(call, folder, workspace) {
|
|
@@ -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;AAKzC,OAAO,EAAqC,KAAK,eAAe,IAAI,QAAQ,EAAE,KAAK,IAAI,IAAI,OAAO,EAAgB,MAAM,oCAAoC,CAAA;AAK5J,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAA;AACtF,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,
|
|
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;AAKzC,OAAO,EAAqC,KAAK,eAAe,IAAI,QAAQ,EAAE,KAAK,IAAI,IAAI,OAAO,EAAgB,MAAM,oCAAoC,CAAA;AAK5J,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAA;AACtF,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,CAmCrK"}
|
package/jobs/permissions.js
CHANGED
|
@@ -35,7 +35,7 @@ export function permissions(rules) {
|
|
|
35
35
|
router.add('tool.check', async (e, next) => {
|
|
36
36
|
const [below, ours] = await Promise.all([next(e), verdictOf(e)]);
|
|
37
37
|
return ours === undefined ? below : stricterVerdict(below, ours);
|
|
38
|
-
});
|
|
38
|
+
}, (_e, error) => ({ decision: 'deny', reason: `Claude Code stopped the permissions job of ${job.mod.name}, so it denies the call: ${error.message}` }));
|
|
39
39
|
job.announce(count === undefined ? 'permission rules from its state' : `${count} permission rule${count === 1 ? '' : 's'}`);
|
|
40
40
|
};
|
|
41
41
|
}
|
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;AAMrD,OAAO,EAAe,KAAK,IAAI,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAyB,KAAK,MAAM,EAAE,MAAM,+BAA+B,CAAA;AAGlF,KAAK,WAAW,GAAG;IAAE,IAAI,CAAC,EAAE,IAAI,GAAG;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAA;AAEhE,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,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,KAAK,EAAE,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAgCzI"}
|
package/jobs/prompt.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { engineOf } from '../runtime/engine.js';
|
|
2
2
|
import { onStateChange } from '../runtime/state.js';
|
|
3
|
+
import { modNote } from '../session/context/turn/message/note.js';
|
|
3
4
|
import { listed, messageOf } from '../utils/text.js';
|
|
4
5
|
import { callEffects } from '../utils/call-effects.js';
|
|
5
6
|
import { matchTarget, targetOf } from './permissions/match-target.js';
|
|
@@ -68,7 +69,7 @@ function addKeptCurrent(job, name, textFor, log) {
|
|
|
68
69
|
if (value === undefined || value === given)
|
|
69
70
|
return;
|
|
70
71
|
given = value;
|
|
71
|
-
await claude.session.append({ message: { type: 'user', content: [{ type: 'text', text: `# ${name}\n${value}` }] } }).then((added) => {
|
|
72
|
+
await claude.session.append({ message: { type: 'user', content: [{ type: 'text', text: modNote(job.mod.name, `# ${name}\n${value}`) }] } }).then((added) => {
|
|
72
73
|
if (added.deny !== undefined)
|
|
73
74
|
log(`Claude Code refused the new text: ${added.deny}`);
|
|
74
75
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slash-command.d.ts","sourceRoot":"","sources":["../src/jobs/slash-command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"slash-command.d.ts","sourceRoot":"","sources":["../src/jobs/slash-command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAQrD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAA;AAMhF,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,YAAY,GAAG,IAAI,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAA;CACxI,GAAG,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAkCzB"}
|
package/jobs/slash-command.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { parse } from '../vendor.js';
|
|
2
2
|
import { engineOf } from '../runtime/engine.js';
|
|
3
|
+
import { modNote } from '../session/context/turn/message/note.js';
|
|
3
4
|
import { messageOf } from '../utils/text.js';
|
|
4
5
|
import { withinDeadline } from './context.js';
|
|
5
6
|
const deadline = { ms: 30000, job: 'slashCommand' };
|
|
@@ -23,7 +24,7 @@ export function slashCommand(options) {
|
|
|
23
24
|
if (e.command !== registered)
|
|
24
25
|
return next(e);
|
|
25
26
|
try {
|
|
26
|
-
return answerOf(await withinDeadline(mod, deadline, `/${name}`, () => reply({ args: e.args, positionals: splitWords(e.args) }, mod)));
|
|
27
|
+
return answerOf(mod.name, await withinDeadline(mod, deadline, `/${name}`, () => reply({ args: e.args, positionals: splitWords(e.args) }, mod)));
|
|
27
28
|
}
|
|
28
29
|
catch (error) {
|
|
29
30
|
return { text: `/${name} failed: ${oneLine(error)}` };
|
|
@@ -37,12 +38,12 @@ export function slashCommand(options) {
|
|
|
37
38
|
};
|
|
38
39
|
};
|
|
39
40
|
}
|
|
40
|
-
function answerOf(reply) {
|
|
41
|
+
function answerOf(name, reply) {
|
|
41
42
|
if (reply === undefined)
|
|
42
43
|
return {};
|
|
43
44
|
if (typeof reply === 'string')
|
|
44
45
|
return { text: reply };
|
|
45
|
-
return { ...(reply.text === undefined ? {} : { text: reply.text }), ...(reply.note === undefined ? {} : { context: [reply.note] }) };
|
|
46
|
+
return { ...(reply.text === undefined ? {} : { text: reply.text }), ...(reply.note === undefined ? {} : { context: [modNote(name, reply.note)] }) };
|
|
46
47
|
}
|
|
47
48
|
function splitWords(args) {
|
|
48
49
|
return parse(args, (key) => `$${key}`).flatMap((entry) => {
|
package/package.json
CHANGED
package/records.d.ts
CHANGED
|
@@ -74,9 +74,10 @@ export declare function marketplaceOf(root: string, name: string): string | unde
|
|
|
74
74
|
export declare function updatesToTurnOn(marketplace: string | undefined, settings: unknown, known: unknown): string | undefined;
|
|
75
75
|
export declare function consentPath(store: string): string;
|
|
76
76
|
export declare function parseConsent(value: unknown, path: string): Record<string, string[]>;
|
|
77
|
-
export declare const coreVersion = "
|
|
77
|
+
export declare const coreVersion = "3.1.0";
|
|
78
78
|
export declare function oldestCmodFor(steps: Steps): string;
|
|
79
79
|
export declare function keyWords(keys: Readonly<Record<string, string>> | undefined): string;
|
|
80
|
+
export declare function bundleDefines(permissions: readonly string[]): Record<string, string>;
|
|
80
81
|
export declare function scriptPaths(command: string): string[];
|
|
81
82
|
export declare function scriptsSha256(steps: Steps, files: {
|
|
82
83
|
read: ReadFile;
|
package/records.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"records.d.ts","sourceRoot":"","sources":["src/records.ts"],"names":[],"mappings":"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"}
|
|
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;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACvC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAChC,CAAA;AAED,eAAO,MAAM,eAAe,YAAI,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAU,CAAA;AAC7E,eAAO,MAAM,eAAe,YAAI,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,CAAU,CAAA;AACxG,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAA;AAC7D,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAA;AAY7D,MAAM,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;AAEpE,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC3H;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAErD,eAAO,MAAM,UAAU,QAAiC,CAAA;AAExD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,CAM3E;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAM1F;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,CAKrK;AASD,wBAAsB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAKhH;AAED,wBAAsB,WAAW,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3I;AAgCD,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,GAAG,SAAS,CAgBzD;AA+BD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA2BpD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,EAAE,EAAE,CAElF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAGjF;AAED,eAAO,MAAM,mBAAmB,uBAAuB,CAAA;AAEvD,eAAO,MAAM,aAAa,cAAc,CAAA;AAExC,eAAO,MAAM,cAAc,kBAAkB,CAAA;AAE7C,eAAO,MAAM,kBAAkB,sBAAsB,CAAA;AAErD,eAAO,MAAM,iBAAiB,qBAAqB,CAAA;AAEnD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG5E;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAOtH;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAMnF;AAcD,eAAO,MAAM,WAAW,UAAU,CAAA;AAElC,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAKlD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,MAAM,CAEnF;AAYD,wBAAgB,aAAa,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAEpF;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAMrD;AAMD,wBAAsB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BzI;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAiBtD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAiBpD;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAQnE;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE"}
|
package/records.js
CHANGED
|
@@ -227,7 +227,7 @@ function readKeys(keys) {
|
|
|
227
227
|
}
|
|
228
228
|
return { keys: commands };
|
|
229
229
|
}
|
|
230
|
-
export const coreVersion = '
|
|
230
|
+
export const coreVersion = '3.1.0';
|
|
231
231
|
export function oldestCmodFor(steps) {
|
|
232
232
|
if (steps.permissions?.some((item) => item.startsWith('config:')) === true)
|
|
233
233
|
return '1.6.0';
|
|
@@ -253,6 +253,9 @@ function readCommand(steps, key) {
|
|
|
253
253
|
throw new Error(`package.json "cmod.${key}" names ${atRoot}, a script at the plugin root. Move it into a folder, such as ./setup/${key}.sh: cmod asks consent for the whole folder of each script.`);
|
|
254
254
|
return { [key]: command };
|
|
255
255
|
}
|
|
256
|
+
export function bundleDefines(permissions) {
|
|
257
|
+
return permissions.includes('approve') ? {} : { 'globalThis.cmodWithoutApprove': 'true' };
|
|
258
|
+
}
|
|
256
259
|
export function scriptPaths(command) {
|
|
257
260
|
const words = command
|
|
258
261
|
.split(/[\s;&|()<>]+/)
|
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,
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["src/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA4D,EAAE,EAAE,aAAa,EAAgB,MAAM,aAAa,CAAA;AAC5H,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAa3C,wBAAgB,aAAa,IAAI,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAEjE;AA+FD,wBAAgB,WAAW,CAAC,KAAK,SAAS,MAAM,EAAE,QAAQ,SAAS,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAqDzK;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,EAAE,GAAG,IAAI,CAIzD"}
|
package/register.js
CHANGED
|
@@ -82,67 +82,74 @@ async function startMod($, eventInput, passOn) {
|
|
|
82
82
|
function routeToMod(_$, eventInput, passOn) {
|
|
83
83
|
return lifecycle.route(passOn.event, eventInput, (passed) => passOn(passed));
|
|
84
84
|
}
|
|
85
|
+
function routeFailure(_$, eventInput, passOn) {
|
|
86
|
+
return lifecycle.caught(passOn.event, eventInput, (passed) => passOn(passed), passOn.error);
|
|
87
|
+
}
|
|
88
|
+
const withCaller = (eventInput, passOn) => ({ ...eventInput, caller: passOn.origin.plugin });
|
|
89
|
+
const withoutCaller = (passOn) => (passed) => passOn(Object.fromEntries(Object.entries(passed).filter(([key]) => key !== 'caller')));
|
|
85
90
|
function routeCallToMod(_$, eventInput, passOn) {
|
|
86
|
-
|
|
87
|
-
|
|
91
|
+
return lifecycle.route('cmod.call', withCaller(eventInput, passOn), withoutCaller(passOn));
|
|
92
|
+
}
|
|
93
|
+
function routeCallFailure(_$, eventInput, passOn) {
|
|
94
|
+
return lifecycle.caught('cmod.call', withCaller(eventInput, passOn), withoutCaller(passOn), passOn.error);
|
|
88
95
|
}
|
|
89
96
|
export function registerMod(addHook, definition, options) {
|
|
90
97
|
permissionCheck = undefined;
|
|
91
98
|
registered = definition;
|
|
92
99
|
lifecycle = createLifecycle(definition, () => permissionCheck, options);
|
|
93
100
|
addHook('session.start', startMod);
|
|
94
|
-
addHook('classic.Setup', routeToMod);
|
|
95
|
-
addHook('classic.SessionStart', routeToMod);
|
|
96
|
-
addHook('classic.SessionEnd', routeToMod);
|
|
97
|
-
addHook('classic.UserPromptSubmit', routeToMod);
|
|
98
|
-
addHook('classic.UserPromptExpansion', routeToMod);
|
|
99
|
-
addHook('classic.InstructionsLoaded', routeToMod);
|
|
100
|
-
addHook('classic.ConfigChange', routeToMod);
|
|
101
|
-
addHook('classic.DirectoryAdded', routeToMod);
|
|
102
|
-
addHook('classic.PreModelSwitch', routeToMod);
|
|
103
|
-
addHook('classic.PostModelSwitch', routeToMod);
|
|
104
|
-
addHook('classic.PermissionDenied', routeToMod);
|
|
105
|
-
addHook('classic.PostToolUse', routeToMod);
|
|
106
|
-
addHook('classic.PostToolUseFailure', routeToMod);
|
|
107
|
-
addHook('classic.PostToolBatch', routeToMod);
|
|
108
|
-
addHook('classic.MessageDisplay', routeToMod);
|
|
109
|
-
addHook('classic.SubagentStart', routeToMod);
|
|
110
|
-
addHook('classic.SubagentStop', routeToMod);
|
|
111
|
-
addHook('classic.TaskCreated', routeToMod);
|
|
112
|
-
addHook('classic.TaskCompleted', routeToMod);
|
|
113
|
-
addHook('classic.TeammateIdle', routeToMod);
|
|
114
|
-
addHook('classic.Elicitation', routeToMod);
|
|
115
|
-
addHook('classic.ElicitationResult', routeToMod);
|
|
116
|
-
addHook('classic.Notification', routeToMod);
|
|
117
|
-
addHook('classic.PreCompact', routeToMod);
|
|
118
|
-
addHook('classic.PostCompact', routeToMod);
|
|
119
|
-
addHook('classic.Stop', routeToMod);
|
|
120
|
-
addHook('classic.StopFailure', routeToMod);
|
|
121
|
-
addHook('classic.FileChanged', routeToMod);
|
|
122
|
-
addHook('classic.WorktreeCreate', routeToMod);
|
|
123
|
-
addHook('classic.WorktreeRemove', routeToMod);
|
|
124
|
-
addHook('tool.call', routeToMod);
|
|
125
|
-
addHook('prompt.submit', routeToMod);
|
|
126
|
-
addHook('prompt.context', routeToMod);
|
|
127
|
-
addHook('command.run', routeToMod);
|
|
128
|
-
addHook('session.measure', routeToMod);
|
|
129
|
-
addHook('skill.prompt', routeToMod);
|
|
130
|
-
addHook('ui.render', routeToMod);
|
|
131
|
-
addHook('ui.press', routeToMod);
|
|
132
|
-
addHook('ui.scroll', routeToMod);
|
|
133
|
-
addHook('ui.close', routeToMod);
|
|
134
|
-
addHook('cmod.call', routeCallToMod);
|
|
101
|
+
addHook('classic.Setup', routeToMod).catch(routeFailure);
|
|
102
|
+
addHook('classic.SessionStart', routeToMod).catch(routeFailure);
|
|
103
|
+
addHook('classic.SessionEnd', routeToMod).catch(routeFailure);
|
|
104
|
+
addHook('classic.UserPromptSubmit', routeToMod).catch(routeFailure);
|
|
105
|
+
addHook('classic.UserPromptExpansion', routeToMod).catch(routeFailure);
|
|
106
|
+
addHook('classic.InstructionsLoaded', routeToMod).catch(routeFailure);
|
|
107
|
+
addHook('classic.ConfigChange', routeToMod).catch(routeFailure);
|
|
108
|
+
addHook('classic.DirectoryAdded', routeToMod).catch(routeFailure);
|
|
109
|
+
addHook('classic.PreModelSwitch', routeToMod).catch(routeFailure);
|
|
110
|
+
addHook('classic.PostModelSwitch', routeToMod).catch(routeFailure);
|
|
111
|
+
addHook('classic.PermissionDenied', routeToMod).catch(routeFailure);
|
|
112
|
+
addHook('classic.PostToolUse', routeToMod).catch(routeFailure);
|
|
113
|
+
addHook('classic.PostToolUseFailure', routeToMod).catch(routeFailure);
|
|
114
|
+
addHook('classic.PostToolBatch', routeToMod).catch(routeFailure);
|
|
115
|
+
addHook('classic.MessageDisplay', routeToMod).catch(routeFailure);
|
|
116
|
+
addHook('classic.SubagentStart', routeToMod).catch(routeFailure);
|
|
117
|
+
addHook('classic.SubagentStop', routeToMod).catch(routeFailure);
|
|
118
|
+
addHook('classic.TaskCreated', routeToMod).catch(routeFailure);
|
|
119
|
+
addHook('classic.TaskCompleted', routeToMod).catch(routeFailure);
|
|
120
|
+
addHook('classic.TeammateIdle', routeToMod).catch(routeFailure);
|
|
121
|
+
addHook('classic.Elicitation', routeToMod).catch(routeFailure);
|
|
122
|
+
addHook('classic.ElicitationResult', routeToMod).catch(routeFailure);
|
|
123
|
+
addHook('classic.Notification', routeToMod).catch(routeFailure);
|
|
124
|
+
addHook('classic.PreCompact', routeToMod).catch(routeFailure);
|
|
125
|
+
addHook('classic.PostCompact', routeToMod).catch(routeFailure);
|
|
126
|
+
addHook('classic.Stop', routeToMod).catch(routeFailure);
|
|
127
|
+
addHook('classic.StopFailure', routeToMod).catch(routeFailure);
|
|
128
|
+
addHook('classic.FileChanged', routeToMod).catch(routeFailure);
|
|
129
|
+
addHook('classic.WorktreeCreate', routeToMod).catch(routeFailure);
|
|
130
|
+
addHook('classic.WorktreeRemove', routeToMod).catch(routeFailure);
|
|
131
|
+
addHook('tool.call', routeToMod).catch(routeFailure);
|
|
132
|
+
addHook('prompt.submit', routeToMod).catch(routeFailure);
|
|
133
|
+
addHook('prompt.context', routeToMod).catch(routeFailure);
|
|
134
|
+
addHook('command.run', routeToMod).catch(routeFailure);
|
|
135
|
+
addHook('session.measure', routeToMod).catch(routeFailure);
|
|
136
|
+
addHook('skill.prompt', routeToMod).catch(routeFailure);
|
|
137
|
+
addHook('ui.render', routeToMod).catch(routeFailure);
|
|
138
|
+
addHook('ui.press', routeToMod).catch(routeFailure);
|
|
139
|
+
addHook('ui.scroll', routeToMod).catch(routeFailure);
|
|
140
|
+
addHook('ui.close', routeToMod).catch(routeFailure);
|
|
141
|
+
addHook('cmod.call', routeCallToMod).catch(routeCallFailure);
|
|
142
|
+
addHook('session.compact', routeToMod).catch(routeFailure);
|
|
135
143
|
if (definition.name !== cmodPluginName)
|
|
136
144
|
return;
|
|
137
|
-
addHook('session.append', routeToMod);
|
|
138
|
-
addHook('session.
|
|
139
|
-
addHook('
|
|
140
|
-
addHook('
|
|
141
|
-
addHook('
|
|
142
|
-
addHook('turn.start', routeToMod);
|
|
145
|
+
addHook('session.append', routeToMod).catch(routeFailure);
|
|
146
|
+
addHook('session.receive', routeToMod).catch(routeFailure);
|
|
147
|
+
addHook('agent.spawn', routeToMod).catch(routeFailure);
|
|
148
|
+
addHook('prompt.attachment', routeToMod).catch(routeFailure);
|
|
149
|
+
addHook('turn.start', routeToMod).catch(routeFailure);
|
|
143
150
|
}
|
|
144
151
|
export function registerPermissionCheck(addHook) {
|
|
145
152
|
permissionCheck = permissionRoutes;
|
|
146
|
-
addHook('tool.check', routeToMod);
|
|
147
|
-
addHook('classic.PermissionRequest', routeToMod);
|
|
153
|
+
addHook('tool.check', routeToMod).catch(routeFailure);
|
|
154
|
+
addHook('classic.PermissionRequest', routeToMod).catch(routeFailure);
|
|
148
155
|
}
|
package/runtime/before.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export type Answers = {
|
|
|
22
22
|
export type BeforeHooks = {
|
|
23
23
|
readonly place: () => Promise<Place>;
|
|
24
24
|
readonly wants: (event: BeforeEvent) => Promise<boolean>;
|
|
25
|
-
readonly
|
|
25
|
+
readonly fold: () => Decide;
|
|
26
26
|
};
|
|
27
27
|
export declare function relayOf(e: Frozen<Args<'session.receive'>>): string | undefined;
|
|
28
28
|
export declare function installBefore({ claude, router, hooks }: {
|
package/runtime/before.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"before.d.ts","sourceRoot":"","sources":["../src/runtime/before.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAa3C,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAY,MAAM,4BAA4B,CAAA;AAEtH,OAAO,EAAiB,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAC1F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAIzC,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,SAAS,GAAG,iBAAiB,GAAG,MAAM,GAAG,OAAO,GAAG,WAAW,GAAG,WAAW,CAAC,CAAA;AAErI,MAAM,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,CAAA;AAEzG,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CAC3C,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"before.d.ts","sourceRoot":"","sources":["../src/runtime/before.ts"],"names":[],"mappings":"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"}
|
package/runtime/before.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ContextEnd } from '../session/context/context.js';
|
|
2
2
|
import { InstructionFile, isRulePath } from '../session/context/turn/message/instruction-file.js';
|
|
3
3
|
import { instructionPathOf, Message, messagesOf, noFiles, rowOfAppend, withTexts } from '../session/context/turn/message/message.js';
|
|
4
|
-
import { Note } from '../session/context/turn/message/note.js';
|
|
4
|
+
import { Note, untagged } from '../session/context/turn/message/note.js';
|
|
5
5
|
import { Notice } from '../session/context/turn/message/notice.js';
|
|
6
6
|
import { Prompt } from '../session/context/turn/message/prompt.js';
|
|
7
7
|
import { Reply } from '../session/context/turn/message/reply.js';
|
|
@@ -26,9 +26,9 @@ export function relayOf(e) {
|
|
|
26
26
|
return isFromCmod ? relayTag.exec(e.text)?.[1] : undefined;
|
|
27
27
|
}
|
|
28
28
|
export function installBefore({ claude, router, hooks }) {
|
|
29
|
-
const { place, wants,
|
|
29
|
+
const { place, wants, fold } = hooks;
|
|
30
30
|
const now = () => new Date().toISOString();
|
|
31
|
-
const asked = async (event, change) => (await decide(event, change)) ?? {};
|
|
31
|
+
const asked = async (event, change, decide = fold()) => (await decide(event, change)) ?? {};
|
|
32
32
|
const message = (where, unplaced, task, isInTurn = true) => {
|
|
33
33
|
const turn = isInTurn ? (task === undefined ? where.turn : where.taskTurns[task]) : undefined;
|
|
34
34
|
const context = task === undefined ? where.context : (where.tasks[task]?.context ?? where.context);
|
|
@@ -50,7 +50,7 @@ export function installBefore({ claude, router, hooks }) {
|
|
|
50
50
|
const answer = await asked(ToolResult, message(where, result, task));
|
|
51
51
|
const below = await next(e);
|
|
52
52
|
const rewritten = answer.output === undefined || isFailure ? {} : name.startsWith('mcp__') ? { updatedMCPToolOutput: answer.output } : { updatedToolOutput: answer.output };
|
|
53
|
-
const failed = answer.isError === true && !isFailure ? { block: answer.note
|
|
53
|
+
const failed = answer.isError === true && !isFailure ? { block: answer.note === undefined ? `${name} failed.` : untagged(answer.note) } : {};
|
|
54
54
|
return { ...withNote(below, answer.isError === true ? undefined : answer.note), ...rewritten, ...failed };
|
|
55
55
|
};
|
|
56
56
|
const added = [
|
|
@@ -118,10 +118,11 @@ export function installBefore({ claude, router, hooks }) {
|
|
|
118
118
|
return next(e);
|
|
119
119
|
const where = await place();
|
|
120
120
|
const texts = new Map();
|
|
121
|
+
const decide = fold();
|
|
121
122
|
for (const [part, unplaced] of found.entries()) {
|
|
122
123
|
if (!wanted.has(unplaced.type))
|
|
123
124
|
continue;
|
|
124
|
-
const answer = await asked(unplaced.type, message(where, unplaced, e.agentId));
|
|
125
|
+
const answer = await asked(unplaced.type, message(where, unplaced, e.agentId), decide);
|
|
125
126
|
if (answer.text !== undefined)
|
|
126
127
|
texts.set(part, answer.text);
|
|
127
128
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversations.d.ts","sourceRoot":"","sources":["../src/runtime/conversations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAY5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGzC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"conversations.d.ts","sourceRoot":"","sources":["../src/runtime/conversations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAY5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGzC,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,aAAa,CAAA;AA8BrD,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC,CAAA;IAClH,KAAK,IAAI,IAAI,CAAA;CACd,CAAA;AAED,wBAAgB,kBAAkB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,GAAG,aAAa,CAqkBlR"}
|