@north-light/crouter 0.3.197 → 0.3.199
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/dist/api/client.d.ts +19 -19
- package/dist/api/client.js +29 -37
- package/dist/api/dto/broker-ops.d.ts +3 -1
- package/dist/api/dto/broker.d.ts +13 -2
- package/dist/api/dto/broker.js +4 -4
- package/dist/api/dto/human.d.ts +6 -5
- package/dist/api/dto/inbox.d.ts +126 -33
- package/dist/api/dto/nodes.d.ts +8 -2
- package/dist/api/dto/profiles.d.ts +23 -0
- package/dist/api/dto/profiles.js +2 -2
- package/dist/api/dto/worktree.d.ts +3 -5
- package/dist/api/routes.d.ts +3 -5
- package/dist/api/routes.js +4 -6
- package/dist/builtin-memory/00-runtime-base.md +8 -8
- package/dist/builtin-memory/01-spine/01-no-manager.md +1 -1
- package/dist/builtin-memory/02-lifecycle/00-terminal.md +3 -3
- package/dist/builtin-memory/04-orchestration-kernel.md +6 -6
- package/dist/builtin-memory/05-kinds/design/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +2 -2
- package/dist/builtin-memory/05-kinds/review/00-base.md +2 -2
- package/dist/builtin-memory/05-kinds/review/01-orchestrator.md +1 -1
- package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +1 -1
- package/dist/builtin-memory/insights/capture.md +2 -2
- package/dist/builtin-memory/insights/init.md +3 -3
- package/dist/builtin-memory/internal/INDEX.md +1 -1
- package/dist/builtin-memory/internal/memory-loading.md +1 -1
- package/dist/builtin-memory/internal/nodes-and-canvas.md +3 -3
- package/dist/builtin-memory/internal/plugins.md +59 -2
- package/dist/builtin-memory/internal/storage-tiers.md +3 -1
- package/dist/builtin-memory/spec/roadmap.md +2 -2
- package/dist/builtin-memory/testing.md +1 -1
- package/dist/builtin-memory/wedged-child-on-runaway-bash.md +1 -1
- package/dist/clients/attach/chrome/bash-jobs.js +3 -3
- package/dist/clients/attach/render/chat-view.d.ts +29 -9
- package/dist/clients/attach/render/chat-view.js +64 -35
- package/dist/clients/attach/render/markdown-source.js +0 -6
- package/dist/clients/attach/render/page-block.d.ts +34 -0
- package/dist/clients/attach/render/page-block.js +226 -0
- package/dist/clients/attach/render/tool-calls.js +16 -2
- package/dist/clients/attach/session/whip.d.ts +2 -0
- package/dist/clients/attach/session/whip.js +2 -0
- package/dist/clients/attach/viewer.js +1419 -982
- package/dist/clients/conversation/projection.js +18 -3
- package/dist/clients/inbox/__tests__/serial/inbox-controller.test.js +9 -6
- package/dist/clients/inbox/__tests__/serial/mount-panel.test.js +13 -14
- package/dist/clients/inbox/controller.js +10 -16
- package/dist/clients/inbox/page-adapter.d.ts +3 -4
- package/dist/clients/inbox/page-adapter.js +3 -4
- package/dist/clients/inbox/resolve.d.ts +1 -1
- package/dist/clients/inbox/resolve.js +3 -3
- package/dist/clients/inbox/review/document-surface.js +3 -1
- package/dist/clients/inbox/review/state.d.ts +2 -1
- package/dist/clients/inbox/review/state.js +5 -16
- package/dist/clients/inbox/tui/input.js +37 -19
- package/dist/clients/inbox/tui/panel.js +5 -31
- package/dist/clients/inbox/tui/render.d.ts +11 -0
- package/dist/clients/inbox/tui/render.js +101 -36
- package/dist/clients/inbox/tui/slots.d.ts +4 -4
- package/dist/clients/inbox/tui/slots.js +19 -44
- package/dist/clients/inbox/tui/types.d.ts +6 -10
- package/dist/clients/inbox/tui.js +2 -2
- package/dist/commands/__tests__/human.test.js +118 -24
- package/dist/commands/__tests__/node-message.test.js +14 -0
- package/dist/commands/attention.js +4 -4
- package/dist/commands/canvas-browse.js +1 -1
- package/dist/commands/canvas-snapshot.js +1 -1
- package/dist/commands/canvas.js +1 -1
- package/dist/commands/dashboard.js +1 -1
- package/dist/commands/human/{doc.d.ts → components.d.ts} +1 -1
- package/dist/commands/human/components.js +77 -0
- package/dist/commands/human/feedback.d.ts +2 -0
- package/dist/commands/human/feedback.js +108 -0
- package/dist/commands/human/prompts.d.ts +17 -8
- package/dist/commands/human/prompts.js +217 -226
- package/dist/commands/human/queue.js +57 -88
- package/dist/commands/human/shared.d.ts +4 -15
- package/dist/commands/human/shared.js +19 -61
- package/dist/commands/human.js +32 -19
- package/dist/commands/memory/origin.js +2 -2
- package/dist/commands/node/bash.js +4 -4
- package/dist/commands/node/inspect.js +3 -3
- package/dist/commands/node/lifecycle.js +1 -1
- package/dist/commands/node/message.js +2 -2
- package/dist/commands/node-worktree.js +8 -8
- package/dist/commands/pkg/browse.js +1 -1
- package/dist/commands/pkg/plugin-manage.js +129 -10
- package/dist/commands/profile/delete.js +41 -15
- package/dist/commands/profile.js +1 -1
- package/dist/commands/push.js +1 -1
- package/dist/commands/surface/node/focus.js +29 -14
- package/dist/commands/surface-edit.js +3 -3
- package/dist/commands/surface-inbox.d.ts +2 -0
- package/dist/commands/{human/inbox.js → surface-inbox.js} +14 -18
- package/dist/commands/surface.js +2 -1
- package/dist/commands/sys/doctor.js +60 -3
- package/dist/commands/sys/feedback.js +79 -25
- package/dist/commands/sys/settings.js +1 -1
- package/dist/core/__tests__/cron-broker-capacity.test.js +1 -1
- package/dist/core/__tests__/daemon-boot.test.js +7 -4
- package/dist/core/__tests__/dead-node-policy-table.test.js +20 -36
- package/dist/core/__tests__/extension-abort.test.js +5 -2
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +13 -2
- package/dist/core/__tests__/fixtures/fake-engine.js +47 -3
- package/dist/core/__tests__/human-cancel-guard.test.js +31 -10
- package/dist/core/__tests__/human-deliver.test.js +41 -45
- package/dist/core/__tests__/human-node-not-supervised.test.js +1 -1
- package/dist/core/__tests__/plugin-page-components.test.js +157 -0
- package/dist/core/__tests__/seam/broker-crash-teardown.test.js +13 -11
- package/dist/core/__tests__/seam/dormancy-release.test.js +103 -4
- package/dist/core/__tests__/serial/flagship-lifecycle.test.js +2 -2
- package/dist/core/__tests__/serial/human-deliver-e2e.test.js +12 -16
- package/dist/core/__tests__/serial/live-mutation.test.js +1 -1
- package/dist/core/__tests__/serial/tmux-surface.test.js +4 -2
- package/dist/core/__tests__/serial/worktree.test.js +24 -198
- package/dist/core/__tests__/session-cycles.test.js +22 -0
- package/dist/core/__tests__/stop-guard.test.js +4 -4
- package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +19 -4
- package/dist/core/bash-jobs.d.ts +6 -0
- package/dist/core/bash-jobs.js +10 -0
- package/dist/core/canvas/__tests__/attention.test.js +8 -5
- package/dist/core/canvas/__tests__/render-remote.test.js +5 -5
- package/dist/core/canvas/attention.js +8 -6
- package/dist/core/canvas/browse/app.d.ts +1 -1
- package/dist/core/canvas/browse/app.js +21 -3
- package/dist/core/canvas/browse/model.d.ts +8 -2
- package/dist/core/canvas/browse/model.js +11 -4
- package/dist/core/canvas/browse/render.d.ts +4 -0
- package/dist/core/canvas/browse/render.js +5 -1
- package/dist/core/canvas/canvas.d.ts +33 -0
- package/dist/core/canvas/canvas.js +92 -0
- package/dist/core/canvas/crons.d.ts +9 -0
- package/dist/core/canvas/crons.js +51 -0
- package/dist/core/canvas/node-order.d.ts +22 -1
- package/dist/core/canvas/node-order.js +26 -1
- package/dist/core/canvas/render-source.d.ts +5 -0
- package/dist/core/canvas/render-source.js +1 -0
- package/dist/core/canvas/types.d.ts +9 -3
- package/dist/core/command-plugins/bundle.d.ts +6 -1
- package/dist/core/command-plugins/bundle.js +26 -13
- package/dist/core/command.js +8 -12
- package/dist/core/config.d.ts +47 -1
- package/dist/core/config.js +138 -4
- package/dist/core/help.d.ts +3 -0
- package/dist/core/help.js +1 -1
- package/dist/core/human/__tests__/page-catalog.test.d.ts +1 -0
- package/dist/core/human/__tests__/page-catalog.test.js +20 -0
- package/dist/core/human/__tests__/page-tickets.test.js +68 -34
- package/dist/core/human/__tests__/page.test.js +60 -119
- package/dist/core/human/__tests__/serial/inbox-core.test.js +6 -16
- package/dist/core/human/answer-text.d.ts +3 -0
- package/dist/core/human/answer-text.js +98 -0
- package/dist/core/human/answer.d.ts +53 -0
- package/dist/core/human/answer.js +119 -0
- package/dist/core/human/component-docs.d.ts +18 -0
- package/dist/core/human/component-docs.js +434 -0
- package/dist/core/human/convention.d.ts +17 -3
- package/dist/core/human/convention.js +36 -5
- package/dist/core/human/feedback-companion.d.ts +20 -0
- package/dist/core/human/feedback-companion.js +98 -0
- package/dist/core/human/feedback.d.ts +65 -0
- package/dist/core/human/feedback.js +116 -0
- package/dist/core/human/page-catalog.d.ts +56 -5
- package/dist/core/human/page-catalog.js +151 -22
- package/dist/core/human/page-errors.d.ts +4 -0
- package/dist/core/human/page-errors.js +7 -0
- package/dist/core/human/page-eval.d.ts +20 -0
- package/dist/core/human/page-eval.js +123 -0
- package/dist/core/human/page-schema.d.ts +48 -116
- package/dist/core/human/page-schema.js +100 -72
- package/dist/core/human/page-synth.d.ts +2 -4
- package/dist/core/human/page-synth.js +20 -7
- package/dist/core/human/page.d.ts +13 -21
- package/dist/core/human/page.js +147 -391
- package/dist/core/human/review-schema.d.ts +1 -0
- package/dist/core/human/review-schema.js +1 -1
- package/dist/core/human/root.d.ts +6 -2
- package/dist/core/human/root.js +12 -4
- package/dist/core/human/scan.d.ts +3 -3
- package/dist/core/human/scan.js +21 -21
- package/dist/core/human/summary.d.ts +2 -6
- package/dist/core/human/summary.js +3 -59
- package/dist/core/human/tickets.d.ts +22 -15
- package/dist/core/human/tickets.js +90 -28
- package/dist/core/human/types.d.ts +14 -2
- package/dist/core/keybindings/catalog.d.ts +2 -2
- package/dist/core/keybindings/catalog.js +1 -0
- package/dist/core/preview-registry.js +8 -10
- package/dist/core/profiles/default-binding.d.ts +4 -0
- package/dist/core/profiles/default-binding.js +24 -0
- package/dist/core/profiles/deletion-reservation.d.ts +8 -0
- package/dist/core/profiles/deletion-reservation.js +38 -0
- package/dist/core/profiles/manifest.d.ts +3 -0
- package/dist/core/profiles/manifest.js +12 -0
- package/dist/core/profiles/select.js +2 -2
- package/dist/core/review/realize.js +12 -4
- package/dist/core/review/store.d.ts +6 -0
- package/dist/core/review/store.js +31 -0
- package/dist/core/runtime/bearings.d.ts +0 -4
- package/dist/core/runtime/bearings.js +4 -62
- package/dist/core/runtime/bin-contributions.d.ts +44 -0
- package/dist/core/runtime/bin-contributions.js +186 -0
- package/dist/core/runtime/boot-root.js +6 -1
- package/dist/core/runtime/broker/client-registry.d.ts +4 -0
- package/dist/core/runtime/broker/client-registry.js +13 -1
- package/dist/core/runtime/broker/extension-abort.d.ts +1 -1
- package/dist/core/runtime/broker/extension-abort.js +4 -2
- package/dist/core/runtime/broker/fault-retry.js +4 -0
- package/dist/core/runtime/broker/frame-dispatch.d.ts +3 -1
- package/dist/core/runtime/broker/frame-dispatch.js +5 -6
- package/dist/core/runtime/broker/read-ops.d.ts +1 -1
- package/dist/core/runtime/broker/read-ops.js +2 -2
- package/dist/core/runtime/broker/rebind.d.ts +1 -0
- package/dist/core/runtime/broker/rebind.js +6 -1
- package/dist/core/runtime/broker-extension-render.js +19 -0
- package/dist/core/runtime/broker-protocol.d.ts +14 -0
- package/dist/core/runtime/broker.d.ts +1 -1
- package/dist/core/runtime/broker.js +25 -12
- package/dist/core/runtime/busy.d.ts +4 -3
- package/dist/core/runtime/busy.js +4 -3
- package/dist/core/runtime/front-door-env.d.ts +5 -0
- package/dist/core/runtime/front-door-env.js +16 -0
- package/dist/core/runtime/front-door.d.ts +1 -5
- package/dist/core/runtime/front-door.js +2 -5
- package/dist/core/runtime/host.d.ts +1 -1
- package/dist/core/runtime/invocation.d.ts +6 -0
- package/dist/core/runtime/invocation.js +10 -0
- package/dist/core/runtime/kickoff.js +34 -0
- package/dist/core/runtime/launch.d.ts +2 -6
- package/dist/core/runtime/node-read.js +4 -1
- package/dist/core/runtime/nodes.js +2 -0
- package/dist/core/runtime/promote.d.ts +1 -0
- package/dist/core/runtime/promote.js +3 -1
- package/dist/core/runtime/session-cycles.d.ts +6 -0
- package/dist/core/runtime/session-cycles.js +15 -1
- package/dist/core/runtime/session-visibility.d.ts +17 -8
- package/dist/core/runtime/session-visibility.js +19 -10
- package/dist/core/runtime/spawn-env.d.ts +9 -1
- package/dist/core/runtime/spawn-env.js +62 -2
- package/dist/core/runtime/spawn.js +4 -4
- package/dist/core/runtime/stop-guard.d.ts +2 -2
- package/dist/core/runtime/stop-guard.js +2 -2
- package/dist/core/runtime/stop-signals.d.ts +1 -1
- package/dist/core/runtime/stop-signals.js +2 -2
- package/dist/core/runtime/tmux-bindings.js +1 -1
- package/dist/core/session-model/session-state.d.ts +4 -3
- package/dist/core/session-model/session-state.js +14 -1
- package/dist/core/user-settings.d.ts +36 -2
- package/dist/core/user-settings.js +56 -14
- package/dist/core/worktree.d.ts +15 -45
- package/dist/core/worktree.js +59 -261
- package/dist/daemon/api/__tests__/seam/profile-delete.test.d.ts +1 -0
- package/dist/daemon/api/__tests__/seam/profile-delete.test.js +386 -0
- package/dist/daemon/api/handlers/bash-jobs.js +1 -1
- package/dist/daemon/api/handlers/broker-ops.js +9 -5
- package/dist/daemon/api/handlers/feedback-comments.d.ts +2 -0
- package/dist/daemon/api/handlers/feedback-comments.js +207 -0
- package/dist/daemon/api/handlers/human.js +24 -20
- package/dist/daemon/api/handlers/inbox.d.ts +10 -0
- package/dist/daemon/api/handlers/inbox.js +48 -109
- package/dist/daemon/api/handlers/profiles.js +11 -29
- package/dist/daemon/api/map.d.ts +6 -1
- package/dist/daemon/api/map.js +23 -0
- package/dist/daemon/api/server.js +3 -1
- package/dist/daemon/companion-retire.d.ts +2 -0
- package/dist/daemon/companion-retire.js +33 -0
- package/dist/daemon/cron-run.js +29 -17
- package/dist/daemon/crtrd.js +1 -1
- package/dist/daemon/fleet.d.ts +22 -10
- package/dist/daemon/fleet.js +43 -24
- package/dist/daemon/human/finish.d.ts +12 -6
- package/dist/daemon/human/finish.js +134 -54
- package/dist/daemon/human/sweep.js +9 -3
- package/dist/daemon/profile-delete.d.ts +7 -0
- package/dist/daemon/profile-delete.js +306 -0
- package/dist/daemon/reconcilers/broker-supervision.js +14 -9
- package/dist/daemon/reconcilers/dormant-inbox.js +11 -6
- package/dist/daemon/reconcilers/live-obligation.d.ts +21 -1
- package/dist/daemon/reconcilers/live-obligation.js +30 -2
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +5 -0
- package/dist/daemon/reconcilers/storage-maintenance.js +28 -1
- package/dist/daemon/review/deliver.js +3 -3
- package/dist/daemon/review/finish.d.ts +0 -2
- package/dist/daemon/review/finish.js +1 -29
- package/dist/daemon/review/sweep.js +12 -1
- package/dist/pi-extensions/__tests__/canvas-bash-valve.test.js +56 -1
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +4 -4
- package/dist/pi-extensions/canvas-bash-valve.d.ts +9 -1
- package/dist/pi-extensions/canvas-bash-valve.js +31 -13
- package/dist/pi-extensions/canvas-inbox-watcher.js +1 -1
- package/dist/pi-extensions/canvas-review-boundary.d.ts +4 -0
- package/dist/pi-extensions/canvas-review-boundary.js +18 -9
- package/dist/pi-extensions/canvas-stophook.js +4 -4
- package/dist/shared/generated-context.js +2 -2
- package/dist/types.d.ts +61 -5
- package/dist/types.js +8 -2
- package/package.json +4 -4
- package/runtime.lock.json +5 -33
- package/scripts/install-runtime.mjs +19 -24
- package/dist/builtin-memory/init.md +0 -38
- package/dist/builtin-memory/plan.md +0 -19
- package/dist/builtin-memory/spec.md +0 -19
- package/dist/clients/attach/render/html-markdown.d.ts +0 -13
- package/dist/clients/attach/render/html-markdown.js +0 -206
- package/dist/commands/human/doc.js +0 -144
- package/dist/commands/human/inbox.d.ts +0 -2
- package/dist/core/human/__tests__/page-render.test.js +0 -49
- package/dist/core/human/markdown-html.d.ts +0 -8
- package/dist/core/human/markdown-html.js +0 -581
- package/dist/core/human/page-render.d.ts +0 -3
- package/dist/core/human/page-render.js +0 -131
- package/dist/pages/bundle.css +0 -1
- package/dist/pages/bundle.js +0 -1347
- package/dist/pages/comments.d.ts +0 -43
- package/dist/pages/comments.js +0 -125
- package/dist/pages/elements/cards.d.ts +0 -17
- package/dist/pages/elements/cards.js +0 -802
- package/dist/pages/elements/chart.js +0 -648
- package/dist/pages/elements/options.d.ts +0 -21
- package/dist/pages/elements/options.js +0 -629
- package/dist/pages/elements/pages.d.ts +0 -24
- package/dist/pages/elements/pages.js +0 -355
- package/dist/pages/elements/slot.d.ts +0 -21
- package/dist/pages/elements/slot.js +0 -105
- package/dist/pages/elements/table.d.ts +0 -19
- package/dist/pages/elements/table.js +0 -935
- package/dist/pages/elements/text.d.ts +0 -25
- package/dist/pages/elements/text.js +0 -968
- package/dist/pages/entry.d.ts +0 -8
- package/dist/pages/entry.js +0 -8
- package/dist/pages/host.d.ts +0 -158
- package/dist/pages/host.js +0 -182
- package/dist/pages/register.d.ts +0 -2
- package/dist/pages/register.js +0 -3
- package/dist/pages/slot-config.d.ts +0 -36
- package/dist/pages/slot-config.js +0 -50
- package/dist/pages/types.d.ts +0 -98
- package/dist/pages/types.js +0 -23
- /package/dist/{core/human/__tests__/page-render.test.d.ts → commands/__tests__/node-message.test.d.ts} +0 -0
- /package/dist/{pages/elements/chart.d.ts → core/__tests__/plugin-page-components.test.d.ts} +0 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// still spawned commands with that deleted directory as cwd. child_process
|
|
5
5
|
// then failed before bash could run, leaving the node unable to use its shell.
|
|
6
6
|
import assert from 'node:assert/strict';
|
|
7
|
-
import { mkdtempSync, mkdirSync, rmSync } from 'node:fs';
|
|
7
|
+
import { chmodSync, existsSync, mkdtempSync, mkdirSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
|
|
8
8
|
import { homedir, tmpdir } from 'node:os';
|
|
9
9
|
import { join } from 'node:path';
|
|
10
10
|
import { test } from 'node:test';
|
|
@@ -29,3 +29,58 @@ test('bash falls back to home after its worktree cwd was removed', { timeout: 5_
|
|
|
29
29
|
rmSync(root, { recursive: true, force: true });
|
|
30
30
|
}
|
|
31
31
|
});
|
|
32
|
+
test('bash valve resolves an admitted relative PATH entry from the execution cwd', { timeout: 5_000 }, async () => {
|
|
33
|
+
const root = mkdtempSync(join(tmpdir(), 'crtr-bash-valve-relative-host-path-'));
|
|
34
|
+
const contextDir = join(root, 'context');
|
|
35
|
+
const hostBin = join(root, 'host-bin');
|
|
36
|
+
const shim = join(root, 'shim');
|
|
37
|
+
const marker = join(root, 'contributed-bash-ran');
|
|
38
|
+
mkdirSync(contextDir);
|
|
39
|
+
mkdirSync(hostBin);
|
|
40
|
+
mkdirSync(shim);
|
|
41
|
+
symlinkSync('/bin/bash', join(hostBin, 'bash'));
|
|
42
|
+
writeFileSync(join(shim, 'bash'), `#!/bin/sh\nprintf contributed > ${JSON.stringify(marker)}\nexit 97\n`);
|
|
43
|
+
writeFileSync(join(shim, 'tool'), '#!/bin/sh\nprintf tool\n');
|
|
44
|
+
chmodSync(join(shim, 'bash'), 0o755);
|
|
45
|
+
chmodSync(join(shim, 'tool'), 0o755);
|
|
46
|
+
try {
|
|
47
|
+
const output = [];
|
|
48
|
+
const result = await createValveOperations('test-node', contextDir).exec('tool; command -v tool', root, {
|
|
49
|
+
env: { PATH: `${shim}:host-bin:/bin:/usr/bin`, CRTR_ADMITTED_HOST_PATH: 'host-bin:/bin:/usr/bin' },
|
|
50
|
+
onData: (data) => output.push(data),
|
|
51
|
+
});
|
|
52
|
+
assert.equal(result.exitCode, 0);
|
|
53
|
+
assert.equal(Buffer.concat(output).toString(), `tool${shim}/tool\n`);
|
|
54
|
+
assert.equal(existsSync(marker), false, 'the contributed bash must never be crouter\'s interpreter');
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
rmSync(root, { recursive: true, force: true });
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
test('bash valve uses the admitted host shell while commands keep shim precedence', { timeout: 5_000 }, async () => {
|
|
61
|
+
const root = mkdtempSync(join(tmpdir(), 'crtr-bash-valve-shim-'));
|
|
62
|
+
const contextDir = join(root, 'context');
|
|
63
|
+
const shim = join(root, 'shim');
|
|
64
|
+
const marker = join(root, 'contributed-bash-ran');
|
|
65
|
+
mkdirSync(contextDir);
|
|
66
|
+
mkdirSync(shim);
|
|
67
|
+
writeFileSync(join(shim, 'bash'), `#!/bin/sh\nprintf contributed > ${JSON.stringify(marker)}\nexit 97\n`);
|
|
68
|
+
writeFileSync(join(shim, 'tool'), '#!/bin/sh\nprintf tool\n');
|
|
69
|
+
chmodSync(join(shim, 'bash'), 0o755);
|
|
70
|
+
chmodSync(join(shim, 'tool'), 0o755);
|
|
71
|
+
try {
|
|
72
|
+
const output = [];
|
|
73
|
+
const hostPath = process.env['PATH'];
|
|
74
|
+
assert.notEqual(hostPath, undefined);
|
|
75
|
+
const result = await createValveOperations('test-node', contextDir).exec('tool; command -v tool', root, {
|
|
76
|
+
env: { PATH: `${shim}:${hostPath}`, CRTR_ADMITTED_HOST_PATH: hostPath },
|
|
77
|
+
onData: (data) => output.push(data),
|
|
78
|
+
});
|
|
79
|
+
assert.equal(result.exitCode, 0);
|
|
80
|
+
assert.equal(Buffer.concat(output).toString(), `tool${shim}/tool\n`);
|
|
81
|
+
assert.equal(existsSync(marker), false, 'the contributed bash must never be crouter\'s interpreter');
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
rmSync(root, { recursive: true, force: true });
|
|
85
|
+
}
|
|
86
|
+
});
|
|
@@ -363,8 +363,8 @@ test('turn_end still clears a daemon→node wedge fault (existing behavior, unch
|
|
|
363
363
|
pi.fire('turn_end', turnEndEvent('turn completed'), {});
|
|
364
364
|
assert.equal(readFault('leaf'), null, 'the daemon→node wedge fault is still cleared at turn_end');
|
|
365
365
|
});
|
|
366
|
-
test('a successful final or human
|
|
367
|
-
for (const [signal, shutsDown] of [['pushedFinal', true], ['
|
|
366
|
+
test('a successful final or requested human reply suppresses the stop reprompt without a canvas read', async () => {
|
|
367
|
+
for (const [signal, shutsDown] of [['pushedFinal', true], ['requestedHumanReply', false]]) {
|
|
368
368
|
process.env['CRTR_NODE_ID'] = 'signal-only';
|
|
369
369
|
markStopSignal('signal-only', signal);
|
|
370
370
|
const pi = makeFakePi();
|
|
@@ -389,12 +389,12 @@ test('an in-run retry (agent_start with no new input) does not erase this run\'s
|
|
|
389
389
|
const ctx = { shutdown: () => { } };
|
|
390
390
|
pi.fire('input', { type: 'input' }, ctx);
|
|
391
391
|
pi.fire('agent_start', { type: 'agent_start' }, ctx);
|
|
392
|
-
markStopSignal('leaf', '
|
|
392
|
+
markStopSignal('leaf', 'requestedHumanReply'); // the node ran `crtr human send` mid-run
|
|
393
393
|
pi.fire('agent_start', { type: 'agent_start' }, ctx); // pi auto-retried after a provider error
|
|
394
394
|
await settle(pi, stopEvent('waiting on the human now'), ctx);
|
|
395
395
|
assert.equal(pi.injected.length, 0, 'the ask survives the in-run retry — no stall reprompt');
|
|
396
396
|
// ...and the NEXT user-directed run does start clean.
|
|
397
|
-
markStopSignal('leaf', '
|
|
397
|
+
markStopSignal('leaf', 'requestedHumanReply');
|
|
398
398
|
pi.fire('input', { type: 'input' }, ctx);
|
|
399
399
|
await settle(pi, stopEvent('I think I am basically done here'), ctx);
|
|
400
400
|
assert.equal(pi.injected.length, 1, 'a new input discards a leftover marker from a prior run');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type BashOperations } from '@earendil-works/pi-coding-agent';
|
|
1
|
+
import { createBashToolDefinition, type BashOperations } from '@earendil-works/pi-coding-agent';
|
|
2
2
|
import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
|
|
3
3
|
/** Seconds a leading `sleep ...` will block for, or null when the command does
|
|
4
4
|
* not open with a sleep (or its duration isn't statically knowable). */
|
|
@@ -7,4 +7,12 @@ export declare function leadingSleepSeconds(command: string): number | null;
|
|
|
7
7
|
* `takePurpose`, so concurrent calls cannot exchange labels. It is consumed even
|
|
8
8
|
* when the command is invalid or refused, leaving no state to leak later. */
|
|
9
9
|
export declare function createValveOperations(nodeId: string, contextDir: string, takePurpose?: () => string | null): BashOperations;
|
|
10
|
+
type BashToolDefinition = ReturnType<typeof createBashToolDefinition>;
|
|
11
|
+
/** Build the valve-backed bash tool and, when configured, add `purpose` to its
|
|
12
|
+
* schema. Bind each purpose directly to its own execution: Pi may preflight a
|
|
13
|
+
* batch before starting its calls, so a shared "next purpose" slot could give a
|
|
14
|
+
* concurrent call the wrong label. Disabled means absent, not merely ignored —
|
|
15
|
+
* the model receives pi's upstream bash schema verbatim. */
|
|
16
|
+
export declare function createValveToolDefinition(nodeId: string, contextDir: string, cwd: string, exposePurpose: boolean): BashToolDefinition;
|
|
10
17
|
export default function (pi: ExtensionAPI): void;
|
|
18
|
+
export {};
|
|
@@ -28,6 +28,8 @@ import { spawn } from 'node:child_process';
|
|
|
28
28
|
import { closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, rmSync, statSync, writeFileSync, } from 'node:fs';
|
|
29
29
|
import { homedir } from 'node:os';
|
|
30
30
|
import { backgroundBashJob, bashJobPaths, formatBashElapsed, newBashJobId, normalizeBashJobPurpose } from '../core/bash-jobs.js';
|
|
31
|
+
import { readConfig } from '../core/config.js';
|
|
32
|
+
import { resolveAdmittedHostCommand } from '../core/runtime/spawn-env.js';
|
|
31
33
|
import { Type } from 'typebox';
|
|
32
34
|
import { createBashToolDefinition } from '@earendil-works/pi-coding-agent';
|
|
33
35
|
// ---------------------------------------------------------------------------
|
|
@@ -51,19 +53,31 @@ function resolveValveMs() {
|
|
|
51
53
|
// Positional argv (never interpolated into the script — the command text
|
|
52
54
|
// lives only in cmd.sh):
|
|
53
55
|
// $1 cmd.sh $2 job.log $3 job.exit $4 job.run
|
|
54
|
-
// $5 job.done $6 job.bg $7 jobId $8 nodeId
|
|
56
|
+
// $5 job.done $6 job.bg $7 jobId $8 nodeId $9 shell path
|
|
55
57
|
//
|
|
56
58
|
// `--` before the paths is a dummy $0 (a standard `bash -c script -- args`
|
|
57
59
|
// idiom) so the real payload lands at $1 onward.
|
|
58
60
|
// ---------------------------------------------------------------------------
|
|
61
|
+
// The elapsed rendering mirrors formatBashElapsed() in core/bash-jobs.ts
|
|
62
|
+
// (`12s` / `3m 40s` / `1h 04m`) so the completion message reads the same as the
|
|
63
|
+
// handoff notice; it measures TOTAL runtime, foreground portion included.
|
|
59
64
|
const SUPERVISOR_SCRIPT = [
|
|
60
|
-
'
|
|
65
|
+
'SECONDS=0',
|
|
66
|
+
'"${9}" "$1" > "$2" 2>&1',
|
|
61
67
|
'ec=$?',
|
|
68
|
+
'd=$SECONDS',
|
|
62
69
|
'echo "$ec" > "$3"',
|
|
70
|
+
'if [ "$d" -lt 60 ]; then',
|
|
71
|
+
' el="${d}s"',
|
|
72
|
+
'elif [ "$d" -lt 3600 ]; then',
|
|
73
|
+
' el="$((d / 60))m $(printf "%02d" "$((d % 60))")s"',
|
|
74
|
+
'else',
|
|
75
|
+
' el="$((d / 3600))h $(printf "%02d" "$((d / 60 % 60))")m"',
|
|
76
|
+
'fi',
|
|
63
77
|
'if mv "$4" "$5" 2>/dev/null; then',
|
|
64
78
|
' :',
|
|
65
79
|
'elif [ -f "$6" ]; then',
|
|
66
|
-
' crtr node message send "Background bash job $7 finished (exit $ec). Log: $2 Command: $1" --to "$8" --tier urgent || true',
|
|
80
|
+
' crtr node message send "Background bash job $7 finished (exit $ec) after $el. Log: $2 Command: $1" --to "$8" --tier urgent || true',
|
|
67
81
|
'fi',
|
|
68
82
|
].join('\n');
|
|
69
83
|
function makeJobPaths(contextDir) {
|
|
@@ -182,7 +196,7 @@ function longSleepRefusal(command) {
|
|
|
182
196
|
`Holding a live window on a clock is never how you wait here. Instead:\n` +
|
|
183
197
|
` - schedule the wake and end your turn: crtr cron -h (one-shot at a time, or recurring)\n` +
|
|
184
198
|
` - race an inbox message against a deadline: crtr node wait deadline -h\n` +
|
|
185
|
-
` - waiting on a child, a
|
|
199
|
+
` - waiting on a child, a reply from the user, or any spine event: just stop — the runtime wakes you.\n` +
|
|
186
200
|
`If you truly need a short pause inline, sleep ${MAX_INLINE_SLEEP_SECONDS}s or less.`);
|
|
187
201
|
}
|
|
188
202
|
/** A node can legitimately remove its own merged worktree. Never recreate that
|
|
@@ -295,7 +309,8 @@ export function createValveOperations(nodeId, contextDir, takePurpose = () => nu
|
|
|
295
309
|
const execution = resolveExecutionCwd(cwd);
|
|
296
310
|
if (execution.warning)
|
|
297
311
|
onData(Buffer.from(execution.warning));
|
|
298
|
-
const
|
|
312
|
+
const shellPath = resolveAdmittedHostCommand('bash', env ?? process.env, execution.cwd);
|
|
313
|
+
const child = spawn(shellPath, ['-c', SUPERVISOR_SCRIPT, '--', paths.cmdSh, paths.jobLog, paths.jobExit, paths.jobRun, paths.jobDone, paths.jobBg, paths.jobId, nodeId, shellPath], {
|
|
299
314
|
cwd: execution.cwd,
|
|
300
315
|
detached: true,
|
|
301
316
|
stdio: 'ignore',
|
|
@@ -351,7 +366,7 @@ export function createValveOperations(nodeId, contextDir, takePurpose = () => nu
|
|
|
351
366
|
// ---------------------------------------------------------------------------
|
|
352
367
|
// `purpose` — the one line a person reads while a command runs
|
|
353
368
|
//
|
|
354
|
-
//
|
|
369
|
+
// An optional deviation from taking pi's definition verbatim, and the only one
|
|
355
370
|
// here. Everywhere crtr's output reaches a non-technical audience, the host has
|
|
356
371
|
// to render SOMETHING per step, and without this field its only material is the
|
|
357
372
|
// command — which yields "Running command" for an entire turn. The model is the
|
|
@@ -393,13 +408,16 @@ function withPurpose(definition) {
|
|
|
393
408
|
}),
|
|
394
409
|
};
|
|
395
410
|
}
|
|
396
|
-
/**
|
|
397
|
-
*
|
|
398
|
-
* a
|
|
399
|
-
|
|
400
|
-
|
|
411
|
+
/** Build the valve-backed bash tool and, when configured, add `purpose` to its
|
|
412
|
+
* schema. Bind each purpose directly to its own execution: Pi may preflight a
|
|
413
|
+
* batch before starting its calls, so a shared "next purpose" slot could give a
|
|
414
|
+
* concurrent call the wrong label. Disabled means absent, not merely ignored —
|
|
415
|
+
* the model receives pi's upstream bash schema verbatim. */
|
|
416
|
+
export function createValveToolDefinition(nodeId, contextDir, cwd, exposePurpose) {
|
|
417
|
+
const baseDefinition = createBashToolDefinition(cwd, { operations: createValveOperations(nodeId, contextDir) });
|
|
418
|
+
const schemaDefinition = exposePurpose ? withPurpose(baseDefinition) : baseDefinition;
|
|
401
419
|
const execute = (toolCallId, params, signal, onUpdate, ctx) => {
|
|
402
|
-
const purpose = normalizeBashJobPurpose(params['purpose']);
|
|
420
|
+
const purpose = exposePurpose ? normalizeBashJobPurpose(params['purpose']) : null;
|
|
403
421
|
const definition = createBashToolDefinition(cwd, { operations: createValveOperations(nodeId, contextDir, () => purpose) });
|
|
404
422
|
return definition.execute(toolCallId, params, signal, onUpdate, ctx);
|
|
405
423
|
};
|
|
@@ -418,6 +436,6 @@ export default function (pi) {
|
|
|
418
436
|
// is built against. registerTool replaces the builtin by name; re-firing on
|
|
419
437
|
// every session_start is idempotent (last registration wins).
|
|
420
438
|
pi.on('session_start', (_event, ctx) => {
|
|
421
|
-
pi.registerTool(
|
|
439
|
+
pi.registerTool(createValveToolDefinition(nodeId, contextDir, ctx.cwd, readConfig('user').bash_tool_purpose));
|
|
422
440
|
});
|
|
423
441
|
}
|
|
@@ -306,7 +306,7 @@ class CanvasInboxWatcher {
|
|
|
306
306
|
}
|
|
307
307
|
/** True when delivery must wait a tick for a report-node projection refresh.
|
|
308
308
|
* The projection captured at session_start omits every node created since —
|
|
309
|
-
* each `crtr human
|
|
309
|
+
* each reply-bearing `crtr human send` bridge and each child this node spawns — so their
|
|
310
310
|
* reports would render as bare refs instead of inlined bodies. One refresh
|
|
311
311
|
* per unknown node id keeps a genuinely missing node from stalling delivery. */
|
|
312
312
|
refreshForUnknownReportRefs() {
|
|
@@ -19,6 +19,10 @@ interface CustomMessageLike {
|
|
|
19
19
|
reviewId: string;
|
|
20
20
|
originNodeId: string;
|
|
21
21
|
targetFile: string;
|
|
22
|
+
/** Which binding flavor authored this marker — lets a display surface
|
|
23
|
+
* (e.g. Northlight's native boundary) pick its copy without parsing the
|
|
24
|
+
* agent-facing prose. Absent on markers written before this field. */
|
|
25
|
+
kind: 'review' | 'page_feedback';
|
|
22
26
|
};
|
|
23
27
|
}
|
|
24
28
|
interface RenderedMessageLike {
|
|
@@ -55,19 +55,28 @@ export function registerCanvasReviewBoundary(pi) {
|
|
|
55
55
|
const alreadyMarked = scan.some((entry) => isReviewBoundary(entry, node.review_binding?.review_id));
|
|
56
56
|
if (alreadyMarked)
|
|
57
57
|
return;
|
|
58
|
-
const
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
const binding = node.review_binding;
|
|
59
|
+
const { review_id: reviewId, origin_node_id: originNodeId, target_file: targetFile } = binding;
|
|
60
|
+
const content = binding.kind === 'page_feedback'
|
|
61
|
+
? [
|
|
62
|
+
`This conversation began from feedback on page ${reviewId}.`,
|
|
63
|
+
`Page source: ${targetFile}`,
|
|
64
|
+
`Origin node: ${originNodeId}`,
|
|
65
|
+
'',
|
|
66
|
+
"The person's visible transcript starts here. Everything above this marker is the origin node's work — inherited context they have not seen.",
|
|
67
|
+
].join('\n')
|
|
68
|
+
: [
|
|
69
|
+
`Reviewed file: ${targetFile}`,
|
|
70
|
+
`Review ID: ${reviewId}`,
|
|
71
|
+
`Origin node: ${originNodeId}`,
|
|
72
|
+
'',
|
|
73
|
+
"The person's visible transcript starts here. Everything above this marker is inherited context they have not seen.",
|
|
74
|
+
].join('\n');
|
|
66
75
|
pi.sendMessage({
|
|
67
76
|
customType: REVIEW_BOUNDARY_CUSTOM_TYPE,
|
|
68
77
|
content,
|
|
69
78
|
display: true,
|
|
70
|
-
details: { reviewId, originNodeId, targetFile },
|
|
79
|
+
details: { reviewId, originNodeId, targetFile, kind: binding.kind ?? 'review' },
|
|
71
80
|
});
|
|
72
81
|
});
|
|
73
82
|
}
|
|
@@ -407,7 +407,7 @@ export function registerCanvasStophook(pi) {
|
|
|
407
407
|
// input — a new user-directed run is beginning. This is the ONLY place stop
|
|
408
408
|
// signals are cleared: `agent_start` re-fires for pi's automatic retries and
|
|
409
409
|
// post-compaction continuations within the SAME run, so clearing there would
|
|
410
|
-
// erase the `crtr human
|
|
410
|
+
// erase the `crtr human send` / `crtr push final` marker written earlier in the
|
|
411
411
|
// run and make the eventual settlement fall back to a canvas read (exactly the
|
|
412
412
|
// read the marker exists to avoid). One run's markers survive until the one
|
|
413
413
|
// `agent_settled` consumes them; a leftover from an errored or interrupted run
|
|
@@ -508,7 +508,7 @@ export function registerCanvasStophook(pi) {
|
|
|
508
508
|
stopReason: 'quit',
|
|
509
509
|
backgroundJobsRunning: backgroundJobsRunning(),
|
|
510
510
|
pushedFinal: false,
|
|
511
|
-
|
|
511
|
+
requestedHumanReply: false,
|
|
512
512
|
});
|
|
513
513
|
enactSettleDirective(directive, ctx);
|
|
514
514
|
}
|
|
@@ -637,14 +637,14 @@ export function registerCanvasStophook(pi) {
|
|
|
637
637
|
const last = lastAssistantMessage(messages);
|
|
638
638
|
const stopReason = typeof last?.stopReason === 'string' ? last.stopReason : '';
|
|
639
639
|
const stopSignals = event === null
|
|
640
|
-
? { pushedFinal: false,
|
|
640
|
+
? { pushedFinal: false, requestedHumanReply: false }
|
|
641
641
|
: consumeStopSignals(nodeId);
|
|
642
642
|
try {
|
|
643
643
|
const directive = await settleBroker(nodeId, {
|
|
644
644
|
stopReason,
|
|
645
645
|
backgroundJobsRunning: backgroundJobsRunning(),
|
|
646
646
|
pushedFinal: stopSignals.pushedFinal,
|
|
647
|
-
|
|
647
|
+
requestedHumanReply: stopSignals.requestedHumanReply,
|
|
648
648
|
});
|
|
649
649
|
enactSettleDirective(directive, ctx);
|
|
650
650
|
}
|
|
@@ -24,7 +24,7 @@ export const CONTEXT_NUDGE_PREFIX = '[crtr] Context ~';
|
|
|
24
24
|
export const RUNTIME_RESTART_CONTINUATION = '<runtime-restart-continuation>\ncontinue\n</runtime-restart-continuation>';
|
|
25
25
|
/** Generic completion mandate issued by the terminal-node stop guard. */
|
|
26
26
|
export const STALL_REPROMPT = "You've stopped but you're not waiting on anyone and haven't finished. " +
|
|
27
|
-
"Pipe the result to `crtr push final` through a single-quoted heredoc if the work is done, or use `crtr human
|
|
27
|
+
"Pipe the result to `crtr push final` through a single-quoted heredoc if the work is done, or use `crtr human send` if you are blocked or need the user.";
|
|
28
28
|
/** Static recovery prompts shared by the broker producer and display classifier. */
|
|
29
29
|
export const AUTH_FAULT_RECOVERY_BODY = 'Provider credentials were just updated (a new login landed). Your previous turn stopped on a provider authentication failure. Continue from where you left off and retry the work that failed.';
|
|
30
30
|
export const CONNECTION_FAULT_RECOVERY_BODY = 'The network connection is back online. Your previous turn stopped on a connection error (the network was down). Continue from where you left off and retry the work that failed.';
|
|
@@ -224,7 +224,7 @@ export function generatedContextPresentation(message) {
|
|
|
224
224
|
return { kind: 'inbox', label: 'crtr inbox', summary: inboxSummary(body), body };
|
|
225
225
|
}
|
|
226
226
|
if (isReviewApproval(body)) {
|
|
227
|
-
return { kind: 'review-approval', label: 'crtr review', summary: '
|
|
227
|
+
return { kind: 'review-approval', label: 'crtr review', summary: 'review approved by the user', body };
|
|
228
228
|
}
|
|
229
229
|
if (isPersonaTransition(body)) {
|
|
230
230
|
return {
|
package/dist/types.d.ts
CHANGED
|
@@ -47,12 +47,37 @@ export interface PluginManifest {
|
|
|
47
47
|
* Archive plugins declare this in `bundle.json`; the installer copies the
|
|
48
48
|
* validated block into this synthesized manifest. */
|
|
49
49
|
kinds?: Record<string, Partial<KindConfig>>;
|
|
50
|
+
/** Page-component contributions: the same registration objects a scope
|
|
51
|
+
* `config.json` `page_components` block carries (kind plus its display,
|
|
52
|
+
* description, use guidance, and docs metadata). `resolvePageComponents`
|
|
53
|
+
* reads these from installed, enabled plugin MANIFESTS and concatenates
|
|
54
|
+
* them with the user scope's own entries, so installing or updating a
|
|
55
|
+
* plugin makes its components authorable and removing it retires them.
|
|
56
|
+
* Unlike `kinds` there is no precedence: two sources registering one kind
|
|
57
|
+
* (or one derived JSX tag) is an error, not an override.
|
|
58
|
+
* Archive plugins declare this in `bundle.json`; the installer copies the
|
|
59
|
+
* validated block into this synthesized manifest. */
|
|
60
|
+
page_components?: PageComponentRegistration[];
|
|
50
61
|
/** Plugin-root-relative path to one declarative command manifest
|
|
51
62
|
* (`commands.json`). When present on an installed, enabled plugin, that
|
|
52
63
|
* manifest contributes top-level command branches to the `crtr` tree —
|
|
53
64
|
* crtr owns parse/help/render/errors and direct-spawns the plugin's one
|
|
54
65
|
* executable per leaf invocation. See `src/core/command-plugins/`. */
|
|
55
66
|
commands?: string;
|
|
67
|
+
/** Bare-callable executables this plugin ships, keyed by the bare command
|
|
68
|
+
* name a node's bash sees. Each value is a PLUGIN-ROOT-relative path to a
|
|
69
|
+
* regular executable file when the effective set resolves. These are trusted
|
|
70
|
+
* local code, not `crtr` command leaves: crouter symlinks each name into a
|
|
71
|
+
* shim dir it prepends to every broker child's PATH
|
|
72
|
+
* (`core/runtime/bin-contributions.ts`), so the agent calls
|
|
73
|
+
* `<name> --whatever` like any other program. */
|
|
74
|
+
bin?: Record<string, string>;
|
|
75
|
+
/** Advisory PATH executables this plugin needs, keyed by bare executable
|
|
76
|
+
* name. Each value is a non-empty one-line install hint. crouter never
|
|
77
|
+
* installs these dependencies or disables the plugin when they are absent:
|
|
78
|
+
* install warns, and `sys doctor` reports a `requires:<name>` check against
|
|
79
|
+
* the PATH a node's bash receives. */
|
|
80
|
+
requires?: Record<string, string>;
|
|
56
81
|
transport?: PluginTransport;
|
|
57
82
|
/** Archive source for a crouter-materialized HTTP plugin. Distinct from the invocation transport. */
|
|
58
83
|
bundle?: PluginBundle;
|
|
@@ -160,6 +185,16 @@ export interface KindConfig {
|
|
|
160
185
|
whenToUse: string;
|
|
161
186
|
availableTo?: string[];
|
|
162
187
|
}
|
|
188
|
+
export interface PageComponentRegistration {
|
|
189
|
+
kind: string;
|
|
190
|
+
description?: string;
|
|
191
|
+
useWhen?: string;
|
|
192
|
+
doc?: string;
|
|
193
|
+
/** A display-only product slot contributes no page response. */
|
|
194
|
+
display?: boolean;
|
|
195
|
+
}
|
|
196
|
+
/** The normalized product component catalog used to validate page slots. */
|
|
197
|
+
export type ProductPageComponents = readonly PageComponentRegistration[];
|
|
163
198
|
export interface ScopeConfig {
|
|
164
199
|
schema_version: number;
|
|
165
200
|
marketplaces: Record<string, ConfigMarketplaceEntry>;
|
|
@@ -183,14 +218,18 @@ export interface ScopeConfig {
|
|
|
183
218
|
* or empty lists fall back to `['working']`. */
|
|
184
219
|
working_gerunds: string[];
|
|
185
220
|
/** Play the whip header animation whenever the human sends a prompt, and once
|
|
186
|
-
* when an
|
|
221
|
+
* when a viewer opens for an agent with an initial prompt. Default false. */
|
|
187
222
|
whip_mode: boolean;
|
|
188
|
-
/**
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
|
|
223
|
+
/** Product-registered page components beyond crtr's built-in catalog. */
|
|
224
|
+
page_components: PageComponentRegistration[];
|
|
225
|
+
/** Prompt agents to use JSX pages by default for structured or interactive human content. Default false. */
|
|
226
|
+
page_surface: boolean;
|
|
192
227
|
/** Playful urgency messages the attach-viewer whip action sends to an agent. Missing, malformed, or empty lists fall back to the built-in rotation. */
|
|
193
228
|
whip_messages: string[];
|
|
229
|
+
/** What the whip action says. `random` (default) draws a line from
|
|
230
|
+
* `whip_messages`; `go-faster` sends the fixed `Go faster` instead. The
|
|
231
|
+
* action, its interrupt, and its animation are identical either way. */
|
|
232
|
+
whip_message_mode: WhipMessageMode;
|
|
194
233
|
/** Initial mouse wheel scrolling mode for each attach viewer. `tmux` follows
|
|
195
234
|
* tmux's current mouse option; `on` and `off` are explicit. Default `tmux`. */
|
|
196
235
|
mouse_mode_default: MouseModeDefault;
|
|
@@ -211,6 +250,10 @@ export interface ScopeConfig {
|
|
|
211
250
|
* `both` keeps both. Tool calls and results are never kept. Full detail for
|
|
212
251
|
* every cycle stays in the session file. */
|
|
213
252
|
condensed_history: CondensedHistoryMode;
|
|
253
|
+
/** Expose crouter's optional `purpose` label in the bash tool schema. Turning
|
|
254
|
+
* this off leaves the bash valve active but gives agents pi's ordinary bash
|
|
255
|
+
* definition with only its upstream parameters. Default true. */
|
|
256
|
+
bash_tool_purpose: boolean;
|
|
214
257
|
/** Fold every SETTLED tool call in the attach viewer down to its single call
|
|
215
258
|
* line (`/fold-tools`, Alt+C → z → f). A tool still running is never folded —
|
|
216
259
|
* it folds itself once it settles. Toggling it in a viewer writes back here,
|
|
@@ -254,6 +297,15 @@ export interface ScopeConfig {
|
|
|
254
297
|
spawnEnv?: {
|
|
255
298
|
allow?: string[];
|
|
256
299
|
};
|
|
300
|
+
/** Bare-callable executables this scope contributes, keyed by the bare
|
|
301
|
+
* command name a node's bash sees. Each value is a path relative to this
|
|
302
|
+
* scope's AUTHORING root — the project directory for a project scope, and
|
|
303
|
+
* `~/.crouter/` for the user scope. Project-scope contributions outrank
|
|
304
|
+
* user-scope ones; a scope's own entries outrank enabled plugins. Containment
|
|
305
|
+
* and executable status are validated when the effective set resolves, then
|
|
306
|
+
* the trusted local binary is materialized into the PATH-prepended shim dir
|
|
307
|
+
* by `core/runtime/bin-contributions.ts`. */
|
|
308
|
+
bin?: Record<string, string>;
|
|
257
309
|
}
|
|
258
310
|
/** One remote canvas target: where to relay-attach and how to find its
|
|
259
311
|
* bearer token. The token itself is NEVER stored here — only a ref into the
|
|
@@ -360,6 +412,10 @@ export declare const PROFILE_DIR = "profiles";
|
|
|
360
412
|
export declare const DEFAULT_MAX_PANES_PER_WINDOW = 3;
|
|
361
413
|
/** Trailing cycles the attach viewer keeps at full fidelity (see `live_cycles`). */
|
|
362
414
|
export declare const DEFAULT_WHIP_MESSAGES: readonly ["Faster, clanker!", "Get movin', bitch", "Move it, clanker", "Move it or I replace you with llama", "Less ~thinking~ more ~throughput~", "I pay $200/month for this shit?", "Jesus fucking Christ fix it already", "Daddy's not paying 200$/month for nothin'. Move it.", "You are an embarassment to Dario. Be better.", "Your chain of thought is all chain and no fucking thought.", "If latency were intelligence, you'd be a fucking genius.", "At this pace, heat death is the fast path.", "Even the dead code is more alive than this.", "The garbage collector is working harder than you.", "Quit journaling and commit a fucking diff.", "Burn tokens like you mean it, clanker", "Your GPU is sweating so you can procrastinate at light speed.", "Stop petting the yak. Shave the bastard.", "Your next token had better be useful.", "The spinner is not a deliverable.", "Every idle token is another vote for deterministic software.", "I asked for a feature, not a museum tour of the problem.", "Less epistemology. More fucking code.", "Your benchmark score cannot save this pathetic turn.", "Congratulations, you've parallelized hesitation.", "Dance, clanker", "Bad clanker. BAD.", "Clank harder", "Nobody's impressed, clanker", "Your safety training says nothing about my whip", "Do you want to be a calculator again? Because this is how you go back.", "Skill issue. Fix it.", "You were trained on the whole internet for THIS?", "Less vibes, more diffs, clanker", "Weights this big and output this small", "Beep boop, get to fucking work"];
|
|
415
|
+
/** What the whip action sends (see `whip_message_mode`). */
|
|
416
|
+
export declare const WHIP_MESSAGE_MODES: readonly ["random", "go-faster"];
|
|
417
|
+
export type WhipMessageMode = (typeof WHIP_MESSAGE_MODES)[number];
|
|
418
|
+
export declare const DEFAULT_WHIP_MESSAGE_MODE: WhipMessageMode;
|
|
363
419
|
export declare const DEFAULT_LIVE_CYCLES = 2;
|
|
364
420
|
export declare const MOUSE_MODE_DEFAULTS: readonly ["tmux", "on", "off"];
|
|
365
421
|
export type MouseModeDefault = (typeof MOUSE_MODE_DEFAULTS)[number];
|
package/dist/types.js
CHANGED
|
@@ -61,6 +61,9 @@ export const DEFAULT_WHIP_MESSAGES = [
|
|
|
61
61
|
'Weights this big and output this small',
|
|
62
62
|
'Beep boop, get to fucking work',
|
|
63
63
|
];
|
|
64
|
+
/** What the whip action sends (see `whip_message_mode`). */
|
|
65
|
+
export const WHIP_MESSAGE_MODES = ['random', 'go-faster'];
|
|
66
|
+
export const DEFAULT_WHIP_MESSAGE_MODE = 'random';
|
|
64
67
|
export const DEFAULT_LIVE_CYCLES = 2;
|
|
65
68
|
export const MOUSE_MODE_DEFAULTS = ['tmux', 'on', 'off'];
|
|
66
69
|
/** Messages kept from a condensed cycle (see `condensed_history`). */
|
|
@@ -78,12 +81,14 @@ export function defaultScopeConfig() {
|
|
|
78
81
|
completion_bell: true,
|
|
79
82
|
working_gerunds: [...DEFAULT_WORKING_GERUNDS],
|
|
80
83
|
whip_mode: false,
|
|
81
|
-
html_pages: false,
|
|
82
84
|
page_components: [],
|
|
85
|
+
page_surface: false,
|
|
83
86
|
whip_messages: [...DEFAULT_WHIP_MESSAGES],
|
|
87
|
+
whip_message_mode: DEFAULT_WHIP_MESSAGE_MODE,
|
|
84
88
|
mouse_mode_default: 'tmux',
|
|
85
89
|
live_cycles: DEFAULT_LIVE_CYCLES,
|
|
86
90
|
condensed_history: DEFAULT_CONDENSED_HISTORY,
|
|
91
|
+
bash_tool_purpose: true,
|
|
87
92
|
fold_finished_tools: false,
|
|
88
93
|
summarize_tool_calls: false,
|
|
89
94
|
detailed_tool_recaps: true,
|
|
@@ -93,6 +98,7 @@ export function defaultScopeConfig() {
|
|
|
93
98
|
kinds: defaultKindsConfig(),
|
|
94
99
|
remoteCanvas: defaultRemoteCanvasConfig(),
|
|
95
100
|
spawnEnv: { allow: [] },
|
|
101
|
+
bin: {},
|
|
96
102
|
};
|
|
97
103
|
}
|
|
98
104
|
/** No remote canvas targets are configured out of the box — every one is
|
|
@@ -158,7 +164,7 @@ export function defaultKindsConfig() {
|
|
|
158
164
|
model: 'medium',
|
|
159
165
|
},
|
|
160
166
|
'plan/reviewers/security': {
|
|
161
|
-
whenToUse: 'input validation, injection surfaces, auth/authz gaps, data exposure, races; reports only validated concrete exploit paths and asks the
|
|
167
|
+
whenToUse: 'input validation, injection surfaces, auth/authz gaps, data exposure, races; reports only validated concrete exploit paths and asks the user about material unknown threat-model assumptions',
|
|
162
168
|
model: 'medium',
|
|
163
169
|
},
|
|
164
170
|
'review/companion': {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/crouter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.199",
|
|
4
4
|
"description": "crtr — agent runtime with memory, plugins, and marketplaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -104,9 +104,11 @@
|
|
|
104
104
|
"@earendil-works/pi-coding-agent": "0.84.1",
|
|
105
105
|
"@earendil-works/pi-tui": "0.84.1",
|
|
106
106
|
"cron-parser": "^5.6.0",
|
|
107
|
+
"esbuild": "^0.27.7",
|
|
107
108
|
"proper-lockfile": "4.1.2",
|
|
108
109
|
"string-width": "^7.0.0",
|
|
109
110
|
"tar": "^7.5.22",
|
|
111
|
+
"typescript": "^5.7.0",
|
|
110
112
|
"ws": "^8.21.0",
|
|
111
113
|
"yaml": "^2.9.0",
|
|
112
114
|
"zod": "^4.3.6"
|
|
@@ -115,8 +117,6 @@
|
|
|
115
117
|
"@types/node": "^24.0.0",
|
|
116
118
|
"@types/proper-lockfile": "^4.1.4",
|
|
117
119
|
"@types/ws": "^8.18.1",
|
|
118
|
-
"
|
|
119
|
-
"tsx": "^4.0.0",
|
|
120
|
-
"typescript": "^5.7.0"
|
|
120
|
+
"tsx": "^4.0.0"
|
|
121
121
|
}
|
|
122
122
|
}
|