harnery 0.30.0 → 0.31.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/README.md +4 -4
- package/dist/commander.d.ts +8 -0
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +14 -13
- package/dist/commands/adapter.d.ts +12 -0
- package/dist/commands/adapter.d.ts.map +1 -0
- package/dist/commands/{harness.js → adapter.js} +35 -35
- package/dist/commands/agents.d.ts +3 -2
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +61 -60
- package/dist/commands/artifacts.d.ts +4 -0
- package/dist/commands/artifacts.d.ts.map +1 -0
- package/dist/commands/artifacts.js +143 -0
- package/dist/commands/backup.d.ts +1 -1
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +5 -2
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +310 -7
- package/dist/commands/checkpoint.d.ts +12 -0
- package/dist/commands/checkpoint.d.ts.map +1 -0
- package/dist/commands/checkpoint.js +162 -0
- package/dist/commands/context.d.ts +2 -2
- package/dist/commands/context.d.ts.map +1 -1
- package/dist/commands/context.js +3 -151
- package/dist/commands/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +31 -7
- package/dist/commands/deinit.d.ts +2 -2
- package/dist/commands/deinit.js +15 -15
- package/dist/commands/doctor.js +23 -23
- package/dist/commands/governor.d.ts +4 -0
- package/dist/commands/governor.d.ts.map +1 -0
- package/dist/commands/{supervisor.js → governor.js} +133 -108
- package/dist/commands/init.d.ts +12 -12
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +44 -30
- package/dist/commands/{session.d.ts → journal.d.ts} +2 -2
- package/dist/commands/journal.d.ts.map +1 -0
- package/dist/commands/{scratch.js → journal.js} +47 -47
- package/dist/commands/policy.js +1 -1
- package/dist/commands/presence.js +2 -2
- package/dist/commands/sync.d.ts +1 -1
- package/dist/commands/sync.js +3 -3
- package/dist/commands/tunnel.d.ts +16 -0
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +193 -23
- package/dist/commands/web-fetch.js +1 -1
- package/dist/commands/web.d.ts +19 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +51 -0
- package/dist/commands/work.d.ts.map +1 -1
- package/dist/commands/work.js +38 -22
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +35 -28
- package/dist/core/{harnesses → adapters}/attest-projection.d.ts +2 -2
- package/dist/core/adapters/attest-projection.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/attest.d.ts +16 -16
- package/dist/core/adapters/attest.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/attest.js +9 -9
- package/dist/core/{harnesses → adapters}/attestation.d.ts +16 -16
- package/dist/core/adapters/attestation.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/attestation.js +20 -20
- package/dist/core/{harnesses → adapters}/bench.d.ts +12 -12
- package/dist/core/adapters/bench.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/bench.js +12 -12
- package/dist/core/adapters/index.d.ts +13 -0
- package/dist/core/adapters/index.d.ts.map +1 -0
- package/dist/core/adapters/index.js +6 -0
- package/dist/core/{harnesses → adapters}/profiles.d.ts +11 -11
- package/dist/core/adapters/profiles.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/profiles.js +11 -11
- package/dist/core/adapters/registry.d.ts +15 -0
- package/dist/core/adapters/registry.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/registry.js +11 -11
- package/dist/core/{harnesses → adapters}/types.d.ts +23 -23
- package/dist/core/adapters/types.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/types.js +1 -1
- package/dist/core/agents/canonical-emit.d.ts +4 -4
- package/dist/core/agents/canonical-emit.js +5 -5
- package/dist/core/agents/cli-emit.js +1 -1
- package/dist/core/agents/cli.js +30 -26
- package/dist/core/agents/codex-replay.d.ts +1 -1
- package/dist/core/agents/codex-replay.js +6 -6
- package/dist/core/agents/coord-client.d.ts +21 -2
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +122 -27
- package/dist/core/agents/events/consume.d.ts +1 -1
- package/dist/core/agents/events/emit.d.ts +5 -6
- package/dist/core/agents/events/emit.d.ts.map +1 -1
- package/dist/core/agents/events/emit.js +2 -2
- package/dist/core/agents/render/prompt-context.d.ts +21 -9
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +82 -30
- package/dist/core/agents/render/session-context.d.ts +1 -1
- package/dist/core/agents/render/session-context.js +5 -5
- package/dist/core/agents/rules/claim-conflict.d.ts +2 -6
- package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/claim-conflict.js +1 -1
- package/dist/core/agents/rules/commit-conflict.js +98 -22
- package/dist/core/agents/rules/stop-hook.d.ts +9 -9
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +23 -5
- package/dist/core/agents/rules/verdict.d.ts +14 -0
- package/dist/core/agents/rules/verdict.d.ts.map +1 -0
- package/dist/core/agents/rules/verdict.js +1 -0
- package/dist/core/agents/session-events.js +3 -3
- package/dist/core/agents/state/council.d.ts +1 -1
- package/dist/core/agents/state/council.js +1 -1
- package/dist/core/agents/state/heartbeat-projector.d.ts +3 -2
- package/dist/core/agents/state/heartbeat-projector.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-projector.js +14 -10
- package/dist/core/agents/state/heartbeat-writer.d.ts +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +12 -12
- package/dist/core/agents/state/{scratch.d.ts → journal.d.ts} +7 -7
- package/dist/core/agents/state/{scratch.d.ts.map → journal.d.ts.map} +1 -1
- package/dist/core/agents/state/{scratch.js → journal.js} +12 -12
- package/dist/core/agents/state/pidmap.d.ts +28 -4
- package/dist/core/agents/state/pidmap.d.ts.map +1 -1
- package/dist/core/agents/state/pidmap.js +130 -15
- package/dist/core/agents/state/proc-start.d.ts +95 -0
- package/dist/core/agents/state/proc-start.d.ts.map +1 -0
- package/dist/core/agents/state/proc-start.js +199 -0
- package/dist/core/agents/state/shell-mutation.d.ts +1 -1
- package/dist/core/agents/state/shell-mutation.js +1 -1
- package/dist/core/agents/state/stale-sweep.js +7 -7
- package/dist/core/artifacts/index.d.ts +86 -0
- package/dist/core/artifacts/index.d.ts.map +1 -0
- package/dist/core/artifacts/index.js +421 -0
- package/dist/core/config.d.ts +9 -2
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +26 -2
- package/dist/core/context/index.d.ts +12 -12
- package/dist/core/context/index.js +10 -10
- package/dist/core/governor/adapter-spread.d.ts +52 -0
- package/dist/core/governor/adapter-spread.d.ts.map +1 -0
- package/dist/core/governor/adapter-spread.js +52 -0
- package/dist/core/governor/index.d.ts +7 -0
- package/dist/core/governor/index.d.ts.map +1 -0
- package/dist/core/governor/index.js +6 -0
- package/dist/core/governor/plan-api.d.ts +38 -0
- package/dist/core/governor/plan-api.d.ts.map +1 -0
- package/dist/core/governor/plan-api.js +83 -0
- package/dist/core/governor/plan-read.d.ts +5 -0
- package/dist/core/governor/plan-read.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/plan-read.js +66 -52
- package/dist/core/{supervisor → governor}/plan-types.d.ts +57 -56
- package/dist/core/governor/plan-types.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/plan-types.js +4 -4
- package/dist/core/governor/planning.d.ts +48 -0
- package/dist/core/governor/planning.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/planning.js +125 -94
- package/dist/core/governor/read.d.ts +6 -0
- package/dist/core/governor/read.d.ts.map +1 -0
- package/dist/core/governor/read.js +4 -0
- package/dist/core/governor/runner.d.ts +37 -0
- package/dist/core/governor/runner.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/runner.js +15 -15
- package/dist/core/governor/service-read.d.ts +6 -0
- package/dist/core/governor/service-read.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/service-read.js +12 -12
- package/dist/core/governor/service.d.ts +114 -0
- package/dist/core/governor/service.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/service.js +57 -57
- package/dist/core/governor/state.d.ts +116 -0
- package/dist/core/governor/state.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/state.js +228 -108
- package/dist/core/hooks/adapter/detect.d.ts +9 -0
- package/dist/core/hooks/{harness → adapter}/detect.d.ts.map +1 -1
- package/dist/core/hooks/{harness → adapter}/detect.js +8 -8
- package/dist/core/hooks/{harness → adapter}/events.d.ts +15 -14
- package/dist/core/hooks/adapter/events.d.ts.map +1 -0
- package/dist/core/hooks/{harness → adapter}/events.js +5 -5
- package/dist/core/hooks/{harness → adapter}/output.d.ts +20 -14
- package/dist/core/hooks/adapter/output.d.ts.map +1 -0
- package/dist/core/hooks/{harness → adapter}/output.js +30 -22
- package/dist/core/hooks/{harness → adapter}/parse.d.ts +5 -5
- package/dist/core/hooks/{harness → adapter}/parse.d.ts.map +1 -1
- package/dist/core/hooks/{harness → adapter}/parse.js +4 -4
- package/dist/core/hooks/{harness → adapter}/wiring.d.ts +15 -15
- package/dist/core/hooks/{harness → adapter}/wiring.d.ts.map +1 -1
- package/dist/core/hooks/{harness → adapter}/wiring.js +13 -13
- package/dist/core/hooks/cli.d.ts +3 -3
- package/dist/core/hooks/cli.js +175 -151
- package/dist/core/hooks/effects/image-capture.d.ts +5 -5
- package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
- package/dist/core/hooks/effects/image-capture.js +3 -3
- package/dist/core/hooks/effects/index.d.ts +12 -12
- package/dist/core/hooks/effects/index.d.ts.map +1 -1
- package/dist/core/hooks/effects/index.js +17 -17
- package/dist/core/hooks/events/emit.d.ts +2 -2
- package/dist/core/hooks/events/emit.d.ts.map +1 -1
- package/dist/core/hooks/events/emit.js +1 -1
- package/dist/core/hooks/events/rotate.js +1 -1
- package/dist/core/hooks/events/schema.d.ts +13 -5
- package/dist/core/hooks/events/schema.d.ts.map +1 -1
- package/dist/core/hooks/guard-path.d.ts +2 -2
- package/dist/core/hooks/guard-path.js +2 -2
- package/dist/core/hooks/index.d.ts +1 -1
- package/dist/core/hooks/index.d.ts.map +1 -1
- package/dist/core/hooks/resolve/anchor.d.ts +14 -5
- package/dist/core/hooks/resolve/anchor.d.ts.map +1 -1
- package/dist/core/hooks/resolve/anchor.js +64 -7
- package/dist/core/hooks/resolve/coord-root.d.ts +3 -3
- package/dist/core/hooks/resolve/coord-root.js +4 -4
- package/dist/core/hooks/resolve/intent.js +1 -1
- package/dist/core/hooks/resolve/owner.d.ts +1 -1
- package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
- package/dist/core/hooks/resolve/owner.js +11 -5
- package/dist/core/{scratch → journal}/index.d.ts +25 -25
- package/dist/core/{scratch → journal}/index.d.ts.map +1 -1
- package/dist/core/{scratch → journal}/index.js +38 -38
- package/dist/core/policy/evaluate.d.ts +1 -1
- package/dist/core/policy/evaluate.d.ts.map +1 -1
- package/dist/core/policy/evaluate.js +7 -7
- package/dist/core/policy/types.d.ts +3 -3
- package/dist/core/policy/types.d.ts.map +1 -1
- package/dist/core/work/state.d.ts +12 -4
- package/dist/core/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +50 -17
- package/dist/core/workflow/adapters.d.ts +17 -0
- package/dist/core/workflow/adapters.d.ts.map +1 -0
- package/dist/core/workflow/adapters.js +21 -0
- package/dist/core/workflow/approvals.js +6 -6
- package/dist/core/workflow/billing.d.ts +9 -9
- package/dist/core/workflow/billing.js +9 -9
- package/dist/core/workflow/child-env.d.ts +10 -2
- package/dist/core/workflow/child-env.d.ts.map +1 -1
- package/dist/core/workflow/child-env.js +12 -4
- package/dist/core/workflow/engine.d.ts +15 -5
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +138 -83
- package/dist/core/workflow/evidence-preflight.d.ts +24 -0
- package/dist/core/workflow/evidence-preflight.d.ts.map +1 -0
- package/dist/core/workflow/evidence-preflight.js +134 -0
- package/dist/core/workflow/index.d.ts +1 -1
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/proof.d.ts +11 -5
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +45 -36
- package/dist/core/workflow/run-state.d.ts +1 -1
- package/dist/core/workflow/run-state.js +7 -7
- package/dist/core/workflow/sandbox-projection.d.ts +6 -6
- package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
- package/dist/core/workflow/sandbox-projection.js +11 -11
- package/dist/core/workflow/spawn-claude.d.ts +3 -3
- package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
- package/dist/core/workflow/spawn-claude.js +9 -6
- package/dist/core/workflow/spawn-codex.d.ts +4 -4
- package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
- package/dist/core/workflow/spawn-codex.js +9 -6
- package/dist/core/workflow/spawn-cursor.d.ts +4 -4
- package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
- package/dist/core/workflow/spawn-cursor.js +9 -6
- package/dist/core/workflow/spawn-failure.d.ts +1 -1
- package/dist/core/workflow/spawn-failure.js +1 -1
- package/dist/core/workflow/specialists.js +2 -2
- package/dist/core/workflow/{journal.d.ts → transcript.d.ts} +8 -8
- package/dist/core/workflow/transcript.d.ts.map +1 -0
- package/dist/core/workflow/{journal.js → transcript.js} +14 -14
- package/dist/core/workflow/types.d.ts +98 -51
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/types.js +11 -1
- package/dist/core/workflow/validate.d.ts +1 -1
- package/dist/core/workflow/validate.js +1 -1
- package/dist/core/workflow/workspaces/cancellation.js +2 -2
- package/dist/core/workflow/workspaces/cleanup.js +2 -2
- package/dist/core/workflow/workspaces/execution.js +6 -6
- package/dist/core/workflow/workspaces/inspect.js +9 -9
- package/dist/core/workflow/workspaces/integration.js +14 -14
- package/dist/core/workflow/workspaces/lifecycle.d.ts +1 -1
- package/dist/core/workflow/workspaces/lifecycle.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/lifecycle.js +9 -9
- package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/local-git.js +39 -5
- package/dist/core/workflow/workspaces/recovery.js +3 -3
- package/dist/core/workflow/workspaces/state.d.ts +1 -1
- package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/state.js +3 -3
- package/dist/core/workflow/workspaces/types.d.ts +1 -1
- package/dist/core/workflow/workspaces/types.d.ts.map +1 -1
- package/dist/lib/browser/asserts.d.ts +28 -0
- package/dist/lib/browser/asserts.d.ts.map +1 -0
- package/dist/lib/browser/asserts.js +152 -0
- package/dist/lib/browser/client.d.ts +49 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +155 -14
- package/dist/lib/browser/content-checks.d.ts +108 -0
- package/dist/lib/browser/content-checks.d.ts.map +1 -0
- package/dist/lib/browser/content-checks.js +474 -0
- package/dist/lib/browser/critique.d.ts +91 -0
- package/dist/lib/browser/critique.d.ts.map +1 -0
- package/dist/lib/browser/critique.js +167 -0
- package/dist/lib/browser/geometry.d.ts +32 -0
- package/dist/lib/browser/geometry.d.ts.map +1 -1
- package/dist/lib/browser/geometry.js +244 -1
- package/dist/lib/browser/index.d.ts +4 -1
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +2 -0
- package/dist/lib/claude-desktop.d.ts.map +1 -1
- package/dist/lib/claude-desktop.js +4 -1
- package/dist/lib/council/index.d.ts +6 -6
- package/dist/lib/council/index.d.ts.map +1 -1
- package/dist/lib/council/index.js +8 -8
- package/dist/lib/identities/assume.d.ts +2 -2
- package/dist/lib/identities/assume.js +7 -7
- package/dist/lib/instructions/apply.d.ts +3 -3
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +75 -27
- package/dist/lib/instructions/host-addendum.d.ts +54 -0
- package/dist/lib/instructions/host-addendum.d.ts.map +1 -0
- package/dist/lib/instructions/host-addendum.js +107 -0
- package/dist/lib/instructions/templates.d.ts +10 -3
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +41 -12
- package/dist/lib/machine.d.ts +2 -2
- package/dist/lib/machine.js +2 -2
- package/package.json +26 -21
- package/schemas/config.schema.json +26 -1
- package/src/commander.ts +22 -13
- package/src/commands/{harness.ts → adapter.ts} +46 -46
- package/src/commands/agents.ts +71 -64
- package/src/commands/artifacts.ts +168 -0
- package/src/commands/backup.ts +47 -33
- package/src/commands/browse.ts +438 -2
- package/src/commands/checkpoint.ts +196 -0
- package/src/commands/context.ts +3 -176
- package/src/commands/decision.ts +41 -7
- package/src/commands/deinit.ts +16 -16
- package/src/commands/doctor.ts +28 -28
- package/src/commands/{supervisor.ts → governor.ts} +184 -154
- package/src/commands/init.ts +50 -34
- package/src/commands/{scratch.ts → journal.ts} +60 -60
- package/src/commands/policy.ts +1 -1
- package/src/commands/presence.ts +2 -2
- package/src/commands/sync.ts +3 -3
- package/src/commands/tunnel.ts +237 -34
- package/src/commands/web-fetch.ts +1 -1
- package/src/commands/web.ts +56 -1
- package/src/commands/work.ts +50 -35
- package/src/commands/workflow.ts +43 -34
- package/src/core/{harnesses → adapters}/attest-projection.ts +2 -2
- package/src/core/{harnesses → adapters}/attest.ts +27 -27
- package/src/core/{harnesses → adapters}/attestation.ts +41 -41
- package/src/core/{harnesses → adapters}/bench.ts +34 -43
- package/src/core/adapters/index.ts +56 -0
- package/src/core/{harnesses → adapters}/profiles.ts +16 -16
- package/src/core/{harnesses → adapters}/registry.ts +23 -23
- package/src/core/{harnesses → adapters}/types.ts +23 -23
- package/src/core/agents/canonical-emit.ts +6 -6
- package/src/core/agents/cli-emit.ts +1 -1
- package/src/core/agents/cli.ts +30 -28
- package/src/core/agents/codex-replay.ts +6 -6
- package/src/core/agents/coord-client.ts +119 -28
- package/src/core/agents/events/consume.ts +1 -1
- package/src/core/agents/events/emit.ts +7 -6
- package/src/core/agents/render/prompt-context.ts +107 -31
- package/src/core/agents/render/session-context.ts +6 -6
- package/src/core/agents/rules/claim-conflict.ts +4 -7
- package/src/core/agents/rules/commit-conflict.ts +103 -22
- package/src/core/agents/rules/stop-hook.ts +33 -17
- package/src/core/agents/rules/verdict.ts +13 -0
- package/src/core/agents/session-events.ts +4 -4
- package/src/core/agents/state/council.ts +1 -1
- package/src/core/agents/state/heartbeat-projector.ts +16 -12
- package/src/core/agents/state/heartbeat-writer.ts +12 -12
- package/src/core/agents/state/{scratch.ts → journal.ts} +12 -12
- package/src/core/agents/state/pidmap.ts +130 -15
- package/src/core/agents/state/proc-start.ts +208 -0
- package/src/core/agents/state/shell-mutation.ts +1 -1
- package/src/core/agents/state/stale-sweep.ts +7 -7
- package/src/core/artifacts/index.ts +557 -0
- package/src/core/config.ts +30 -2
- package/src/core/context/index.ts +15 -15
- package/src/core/governor/adapter-spread.ts +82 -0
- package/src/core/governor/index.ts +91 -0
- package/src/core/governor/plan-api.ts +115 -0
- package/src/core/{supervisor → governor}/plan-read.ts +112 -97
- package/src/core/{supervisor → governor}/plan-types.ts +59 -56
- package/src/core/{supervisor → governor}/planning.ts +223 -192
- package/src/core/governor/read.ts +59 -0
- package/src/core/{supervisor → governor}/runner.ts +39 -39
- package/src/core/{supervisor → governor}/service-read.ts +22 -22
- package/src/core/{supervisor → governor}/service.ts +117 -119
- package/src/core/{supervisor → governor}/state.ts +325 -167
- package/src/core/hooks/adapter/detect.ts +30 -0
- package/src/core/hooks/{harness → adapter}/events.ts +16 -14
- package/src/core/hooks/{harness → adapter}/output.ts +31 -23
- package/src/core/hooks/{harness → adapter}/parse.ts +5 -5
- package/src/core/hooks/{harness → adapter}/wiring.ts +21 -21
- package/src/core/hooks/cli.ts +185 -162
- package/src/core/hooks/effects/image-capture.ts +6 -6
- package/src/core/hooks/effects/index.ts +17 -17
- package/src/core/hooks/events/emit.ts +3 -3
- package/src/core/hooks/events/rotate.ts +1 -1
- package/src/core/hooks/events/schema.ts +15 -7
- package/src/core/hooks/guard-path.ts +2 -2
- package/src/core/hooks/index.ts +1 -1
- package/src/core/hooks/resolve/anchor.ts +63 -8
- package/src/core/hooks/resolve/coord-root.ts +4 -4
- package/src/core/hooks/resolve/intent.ts +1 -1
- package/src/core/hooks/resolve/owner.ts +11 -5
- package/src/core/{scratch → journal}/index.ts +53 -53
- package/src/core/policy/evaluate.ts +8 -8
- package/src/core/policy/types.ts +3 -3
- package/src/core/work/state.ts +65 -23
- package/src/core/workflow/adapters.ts +33 -0
- package/src/core/workflow/approvals.ts +7 -7
- package/src/core/workflow/billing.ts +12 -12
- package/src/core/workflow/child-env.ts +13 -4
- package/src/core/workflow/engine.ts +155 -90
- package/src/core/workflow/evidence-preflight.ts +165 -0
- package/src/core/workflow/index.ts +3 -3
- package/src/core/workflow/proof.ts +60 -50
- package/src/core/workflow/run-state.ts +7 -7
- package/src/core/workflow/sandbox-projection.ts +16 -16
- package/src/core/workflow/spawn-claude.ts +13 -10
- package/src/core/workflow/spawn-codex.ts +13 -10
- package/src/core/workflow/spawn-cursor.ts +13 -10
- package/src/core/workflow/spawn-failure.ts +1 -1
- package/src/core/workflow/specialists.ts +2 -2
- package/src/core/workflow/{journal.ts → transcript.ts} +16 -16
- package/src/core/workflow/types.ts +108 -51
- package/src/core/workflow/validate.ts +1 -1
- package/src/core/workflow/workspaces/cancellation.ts +2 -2
- package/src/core/workflow/workspaces/cleanup.ts +2 -2
- package/src/core/workflow/workspaces/execution.ts +6 -6
- package/src/core/workflow/workspaces/inspect.ts +14 -11
- package/src/core/workflow/workspaces/integration.ts +18 -14
- package/src/core/workflow/workspaces/lifecycle.ts +10 -10
- package/src/core/workflow/workspaces/local-git.ts +47 -5
- package/src/core/workflow/workspaces/recovery.ts +3 -3
- package/src/core/workflow/workspaces/state.ts +4 -3
- package/src/core/workflow/workspaces/types.ts +1 -1
- package/src/lib/browser/asserts.ts +177 -0
- package/src/lib/browser/client.ts +189 -14
- package/src/lib/browser/content-checks.ts +571 -0
- package/src/lib/browser/critique.ts +231 -0
- package/src/lib/browser/geometry.ts +297 -1
- package/src/lib/browser/index.ts +34 -0
- package/src/lib/claude-desktop.ts +4 -1
- package/src/lib/council/index.ts +9 -9
- package/src/lib/identities/assume.ts +7 -7
- package/src/lib/instructions/apply.ts +87 -25
- package/src/lib/instructions/host-addendum.ts +126 -0
- package/src/lib/instructions/templates.ts +44 -15
- package/src/lib/machine.ts +2 -2
- package/dist/commands/harness.d.ts +0 -12
- package/dist/commands/harness.d.ts.map +0 -1
- package/dist/commands/scratch.d.ts +0 -4
- package/dist/commands/scratch.d.ts.map +0 -1
- package/dist/commands/session.d.ts.map +0 -1
- package/dist/commands/session.js +0 -162
- package/dist/commands/supervisor.d.ts +0 -4
- package/dist/commands/supervisor.d.ts.map +0 -1
- package/dist/core/harnesses/attest-projection.d.ts.map +0 -1
- package/dist/core/harnesses/attest.d.ts.map +0 -1
- package/dist/core/harnesses/attestation.d.ts.map +0 -1
- package/dist/core/harnesses/bench.d.ts.map +0 -1
- package/dist/core/harnesses/index.d.ts +0 -13
- package/dist/core/harnesses/index.d.ts.map +0 -1
- package/dist/core/harnesses/index.js +0 -6
- package/dist/core/harnesses/profiles.d.ts.map +0 -1
- package/dist/core/harnesses/registry.d.ts +0 -15
- package/dist/core/harnesses/registry.d.ts.map +0 -1
- package/dist/core/harnesses/types.d.ts.map +0 -1
- package/dist/core/hooks/harness/detect.d.ts +0 -9
- package/dist/core/hooks/harness/events.d.ts.map +0 -1
- package/dist/core/hooks/harness/output.d.ts.map +0 -1
- package/dist/core/supervisor/index.d.ts +0 -7
- package/dist/core/supervisor/index.d.ts.map +0 -1
- package/dist/core/supervisor/index.js +0 -6
- package/dist/core/supervisor/plan-api.d.ts +0 -23
- package/dist/core/supervisor/plan-api.d.ts.map +0 -1
- package/dist/core/supervisor/plan-api.js +0 -50
- package/dist/core/supervisor/plan-read.d.ts +0 -5
- package/dist/core/supervisor/plan-read.d.ts.map +0 -1
- package/dist/core/supervisor/plan-types.d.ts.map +0 -1
- package/dist/core/supervisor/planning.d.ts +0 -33
- package/dist/core/supervisor/planning.d.ts.map +0 -1
- package/dist/core/supervisor/read.d.ts +0 -6
- package/dist/core/supervisor/read.d.ts.map +0 -1
- package/dist/core/supervisor/read.js +0 -4
- package/dist/core/supervisor/runner.d.ts +0 -37
- package/dist/core/supervisor/runner.d.ts.map +0 -1
- package/dist/core/supervisor/service-read.d.ts +0 -6
- package/dist/core/supervisor/service-read.d.ts.map +0 -1
- package/dist/core/supervisor/service.d.ts +0 -114
- package/dist/core/supervisor/service.d.ts.map +0 -1
- package/dist/core/supervisor/state.d.ts +0 -95
- package/dist/core/supervisor/state.d.ts.map +0 -1
- package/dist/core/workflow/harnesses.d.ts +0 -17
- package/dist/core/workflow/harnesses.d.ts.map +0 -1
- package/dist/core/workflow/harnesses.js +0 -21
- package/dist/core/workflow/journal.d.ts.map +0 -1
- package/src/commands/session.ts +0 -187
- package/src/core/harnesses/index.ts +0 -56
- package/src/core/hooks/harness/detect.ts +0 -30
- package/src/core/supervisor/index.ts +0 -89
- package/src/core/supervisor/plan-api.ts +0 -73
- package/src/core/supervisor/read.ts +0 -59
- package/src/core/workflow/harnesses.ts +0 -33
- /package/dist/core/{harnesses → adapters}/attest-projection.js +0 -0
package/src/commands/init.ts
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* if skipped):
|
|
6
6
|
* 1. Create the `.harnery/` coord root; without it `findCoordRoot` returns
|
|
7
7
|
* null and every hook no-ops forever.
|
|
8
|
-
* 2. Register the agent-hook entries in the
|
|
8
|
+
* 2. Register the agent-hook entries in the adapter settings file.
|
|
9
9
|
*
|
|
10
|
-
* Wires whichever
|
|
11
|
-
* Cursor `.cursor/hooks.json`, or Codex `.codex/hooks.json`): the per-
|
|
12
|
-
* file path, event list, and hook-entry shape all come from
|
|
10
|
+
* Wires whichever adapter `--adapter` names (Claude Code `.claude/settings.json`,
|
|
11
|
+
* Cursor `.cursor/hooks.json`, or Codex `.codex/hooks.json`): the per-adapter
|
|
12
|
+
* file path, event list, and hook-entry shape all come from ADAPTER_SPECS.
|
|
13
13
|
*
|
|
14
14
|
* `harn init` does both, non-destructively: it merges hook entries into an
|
|
15
15
|
* existing settings file (preserving any other hooks) and skips entries that are
|
|
@@ -23,25 +23,30 @@ import { fileURLToPath } from "node:url";
|
|
|
23
23
|
import type { Command } from "commander";
|
|
24
24
|
import type { EmitContext } from "../commander.ts";
|
|
25
25
|
import { DEFAULT_BIN_NAME, pinnedBinName, stripJsonComments } from "../core/config.ts";
|
|
26
|
-
import {
|
|
26
|
+
import { ADAPTER_SPECS, type AdapterId, type AdapterSpec } from "../core/hooks/adapter/events.ts";
|
|
27
27
|
import {
|
|
28
28
|
commandWiresSubcommand,
|
|
29
29
|
groupCommands,
|
|
30
30
|
type HookGroup,
|
|
31
31
|
makeEntry,
|
|
32
32
|
type SettingsFile,
|
|
33
|
-
} from "../core/hooks/
|
|
34
|
-
import {
|
|
33
|
+
} from "../core/hooks/adapter/wiring.ts";
|
|
34
|
+
import {
|
|
35
|
+
type ApplyResult,
|
|
36
|
+
applyInstructions,
|
|
37
|
+
checkInstructions,
|
|
38
|
+
} from "../lib/instructions/apply.ts";
|
|
39
|
+
import { HostAddendumError } from "../lib/instructions/host-addendum.ts";
|
|
35
40
|
|
|
36
41
|
// Re-exported for back-compat: callers (deinit, tests) import these names
|
|
37
|
-
// from init.ts. The definitions now live in core/hooks/
|
|
42
|
+
// from init.ts. The definitions now live in core/hooks/adapter/wiring.ts.
|
|
38
43
|
export type { HookGroup, SettingsFile };
|
|
39
44
|
|
|
40
45
|
// This file is src/commands/init.ts → harnery package root is two levels up.
|
|
41
46
|
const HARNERY_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
42
47
|
|
|
43
48
|
interface InitOpts {
|
|
44
|
-
|
|
49
|
+
adapter: string;
|
|
45
50
|
dryRun?: boolean;
|
|
46
51
|
check?: boolean;
|
|
47
52
|
projectRoot?: string;
|
|
@@ -51,20 +56,20 @@ export function registerInitCommand(program: Command, emit: EmitContext, binName
|
|
|
51
56
|
program
|
|
52
57
|
.command("init")
|
|
53
58
|
.description(
|
|
54
|
-
"Bootstrap harnery in this project: create .harnery/, wire the
|
|
59
|
+
"Bootstrap harnery in this project: create .harnery/, wire the adapter " +
|
|
55
60
|
"hooks, and inject the agent-facing instructions block + skills " +
|
|
56
61
|
"(idempotent; safe to re-run). Use --dry-run to preview, --check to " +
|
|
57
62
|
"report drift without writing (exit 0 fresh / 2 drift / 1 error).",
|
|
58
63
|
)
|
|
59
|
-
.option("--
|
|
64
|
+
.option("--adapter <id>", "claude-code | cursor | codex", "claude-code")
|
|
60
65
|
.option("--dry-run", "Show what would change without writing")
|
|
61
66
|
.option("--check", "Report instructions/skills drift without writing; exit 0/2/1")
|
|
62
67
|
.option("--project-root <path>", "Project root (default: git toplevel, else cwd)")
|
|
63
68
|
.action((opts: InitOpts) => {
|
|
64
|
-
const
|
|
65
|
-
const spec =
|
|
69
|
+
const adapter = opts.adapter as AdapterId;
|
|
70
|
+
const spec = ADAPTER_SPECS[adapter];
|
|
66
71
|
if (!spec) {
|
|
67
|
-
emit.text(`Unknown
|
|
72
|
+
emit.text(`Unknown adapter '${opts.adapter}'. Expected: claude-code | cursor | codex.`);
|
|
68
73
|
emit.setExitCode(1);
|
|
69
74
|
return;
|
|
70
75
|
}
|
|
@@ -79,7 +84,7 @@ export function registerInitCommand(program: Command, emit: EmitContext, binName
|
|
|
79
84
|
|
|
80
85
|
// ── --check: read-only drift report on the block + skills ──────────────
|
|
81
86
|
if (opts.check === true) {
|
|
82
|
-
const { status, issues } = checkInstructions(projectRoot, { binName: bin,
|
|
87
|
+
const { status, issues } = checkInstructions(projectRoot, { binName: bin, adapter });
|
|
83
88
|
const head =
|
|
84
89
|
status === "fresh"
|
|
85
90
|
? "harn init --check: instructions + skills are current"
|
|
@@ -122,7 +127,7 @@ export function registerInitCommand(program: Command, emit: EmitContext, binName
|
|
|
122
127
|
|
|
123
128
|
// ── 1c. workflow billing default ───────────────────────────────────────
|
|
124
129
|
// Every init'd project gets `workflow.subscriptionOnly: true`: workflow
|
|
125
|
-
// children ride the logged-in (subscription)
|
|
130
|
+
// children ride the logged-in (subscription) adapter auth, and the pin
|
|
126
131
|
// makes per-token API billing structurally impossible unless the project
|
|
127
132
|
// deliberately flips it. A committed `workflow` key of any shape is a
|
|
128
133
|
// deliberate choice and is never touched.
|
|
@@ -131,7 +136,7 @@ export function registerInitCommand(program: Command, emit: EmitContext, binName
|
|
|
131
136
|
if (stamp) actions.push(stamp);
|
|
132
137
|
}
|
|
133
138
|
|
|
134
|
-
// ── 2.
|
|
139
|
+
// ── 2. adapter hooks ───────────────────────────────────────────────────
|
|
135
140
|
const settingsPath = resolve(projectRoot, spec.settingsFile);
|
|
136
141
|
const agentHook = relative(projectRoot, resolve(HARNERY_ROOT, "bin", "agent-hook"));
|
|
137
142
|
|
|
@@ -150,11 +155,11 @@ export function registerInitCommand(program: Command, emit: EmitContext, binName
|
|
|
150
155
|
} else {
|
|
151
156
|
settings = {};
|
|
152
157
|
}
|
|
153
|
-
const { wired, already, removed, upgraded } = wireHooks(settings, spec, agentHook,
|
|
158
|
+
const { wired, already, removed, upgraded } = wireHooks(settings, spec, agentHook, adapter);
|
|
154
159
|
|
|
155
160
|
if (wired === 0 && removed === 0 && upgraded === 0) {
|
|
156
161
|
actions.push(
|
|
157
|
-
`· all ${spec.events.length} ${
|
|
162
|
+
`· all ${spec.events.length} ${adapter} hooks already wired in ${rel(projectRoot, settingsPath)}`,
|
|
158
163
|
);
|
|
159
164
|
} else if (dryRun) {
|
|
160
165
|
actions.push(
|
|
@@ -171,7 +176,18 @@ export function registerInitCommand(program: Command, emit: EmitContext, binName
|
|
|
171
176
|
}
|
|
172
177
|
|
|
173
178
|
// ── 3. agent-facing instructions block + skills ────────────────────────
|
|
174
|
-
|
|
179
|
+
// A misconfigured host addendum aborts here rather than half-writing: the
|
|
180
|
+
// apply step validates the configured source before it touches a file, so
|
|
181
|
+
// a bad path leaves the repo exactly as it found it.
|
|
182
|
+
let applied: ApplyResult;
|
|
183
|
+
try {
|
|
184
|
+
applied = applyInstructions(projectRoot, { binName: bin, adapter, dryRun });
|
|
185
|
+
} catch (err) {
|
|
186
|
+
if (!(err instanceof HostAddendumError)) throw err;
|
|
187
|
+
emit.text(`${bin} init: ${err.message}`);
|
|
188
|
+
emit.setExitCode(1);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
175
191
|
actions.push(...applied.actions);
|
|
176
192
|
|
|
177
193
|
emit.text(render(projectRoot, dryRun, actions, applied.warnings));
|
|
@@ -179,12 +195,12 @@ export function registerInitCommand(program: Command, emit: EmitContext, binName
|
|
|
179
195
|
}
|
|
180
196
|
|
|
181
197
|
/**
|
|
182
|
-
* Merge agent-hook entries into a
|
|
198
|
+
* Merge agent-hook entries into a adapter settings object in place, idempotently.
|
|
183
199
|
* Preserves every existing hook; rewrites events already wired to
|
|
184
200
|
* `agent-hook <subcommand>` when their command string is stale (e.g. an older
|
|
185
|
-
* harnery wired a bare relative path). Honors the
|
|
201
|
+
* harnery wired a bare relative path). Honors the adapter's entry shape
|
|
186
202
|
* (Claude/Codex nest under an inner `hooks` array; Cursor uses a flat
|
|
187
|
-
* `{ command }`) and ensures the root `version` key when the
|
|
203
|
+
* `{ command }`) and ensures the root `version` key when the adapter requires
|
|
188
204
|
* one. Pure (no fs/git) so it's unit-testable.
|
|
189
205
|
*
|
|
190
206
|
* The trailing space in the match (`agent-hook ${subcommand} `) is load-bearing:
|
|
@@ -192,9 +208,9 @@ export function registerInitCommand(program: Command, emit: EmitContext, binName
|
|
|
192
208
|
*/
|
|
193
209
|
export function wireHooks(
|
|
194
210
|
settings: SettingsFile,
|
|
195
|
-
spec:
|
|
211
|
+
spec: AdapterSpec,
|
|
196
212
|
agentHookPath: string,
|
|
197
|
-
|
|
213
|
+
adapter: AdapterId,
|
|
198
214
|
): { wired: number; already: number; removed: number; upgraded: number } {
|
|
199
215
|
if (spec.rootVersion !== undefined && settings.version === undefined) {
|
|
200
216
|
settings.version = spec.rootVersion;
|
|
@@ -215,7 +231,7 @@ export function wireHooks(
|
|
|
215
231
|
else settings.hooks[settingsKey] = kept;
|
|
216
232
|
}
|
|
217
233
|
for (const { settingsKey, subcommand } of spec.events) {
|
|
218
|
-
const command = hookCommand(spec, agentHookPath, subcommand,
|
|
234
|
+
const command = hookCommand(spec, agentHookPath, subcommand, adapter);
|
|
219
235
|
const groups = settings.hooks[settingsKey] ?? [];
|
|
220
236
|
let present = false;
|
|
221
237
|
for (const group of groups) {
|
|
@@ -235,23 +251,23 @@ export function wireHooks(
|
|
|
235
251
|
}
|
|
236
252
|
|
|
237
253
|
/**
|
|
238
|
-
* The canonical hook command for one event. When the
|
|
254
|
+
* The canonical hook command for one event. When the adapter exports a
|
|
239
255
|
* project-dir env var to hook processes (Claude Code's CLAUDE_PROJECT_DIR),
|
|
240
256
|
* anchor the agent-hook path on it: hook processes inherit the session
|
|
241
257
|
* shell's cwd, which follows `cd` away from the project root — a bare
|
|
242
258
|
* relative path silently fails to spawn from there (no events, no image
|
|
243
|
-
* capture, no guards). `:-.` keeps the command working on
|
|
259
|
+
* capture, no guards). `:-.` keeps the command working on adapter versions
|
|
244
260
|
* that don't set the var. Only the env expansion is quoted so the
|
|
245
261
|
* `agent-hook <subcommand> ` wiring match stays byte-identical.
|
|
246
262
|
*/
|
|
247
263
|
function hookCommand(
|
|
248
|
-
spec:
|
|
264
|
+
spec: AdapterSpec,
|
|
249
265
|
agentHookPath: string,
|
|
250
266
|
subcommand: string,
|
|
251
|
-
|
|
267
|
+
adapter: AdapterId,
|
|
252
268
|
): string {
|
|
253
269
|
const anchor = spec.projectDirEnv ? `"\${${spec.projectDirEnv}:-.}"/` : "";
|
|
254
|
-
return `bash ${anchor}${agentHookPath} ${subcommand} --
|
|
270
|
+
return `bash ${anchor}${agentHookPath} ${subcommand} --adapter ${adapter}`;
|
|
255
271
|
}
|
|
256
272
|
|
|
257
273
|
/**
|
|
@@ -295,8 +311,8 @@ function rewriteStaleCommands(
|
|
|
295
311
|
* contains `agent-hook ` (the trailing space matches `agent-hook <subcommand>`),
|
|
296
312
|
* so any non-harnery hook the consumer added is preserved. Emptied
|
|
297
313
|
* `hooks[settingsKey]` arrays are dropped; an emptied `hooks` object is dropped
|
|
298
|
-
* entirely.
|
|
299
|
-
*
|
|
314
|
+
* entirely. Adapter-agnostic (scans every key) so it removes entries left by any
|
|
315
|
+
* adapter. Pure (no fs) so it's unit-testable. Returns the count removed and the
|
|
300
316
|
* count of non-harnery hooks left behind.
|
|
301
317
|
*/
|
|
302
318
|
export function unwireHooks(settings: SettingsFile): { removed: number; remaining: number } {
|
|
@@ -384,7 +400,7 @@ export function stampBinName(configPath: string, binName: string, dryRun: boolea
|
|
|
384
400
|
|
|
385
401
|
/** The commented workflow-billing default block init stamps into config.jsonc. */
|
|
386
402
|
const WORKFLOW_DEFAULT_BLOCK =
|
|
387
|
-
` // Workflow children ride the logged-in (subscription)
|
|
403
|
+
` // Workflow children ride the logged-in (subscription) adapter auth; this pin\n` +
|
|
388
404
|
` // scrubs API-key vars from child envs so runs can never bill per-token rates.\n` +
|
|
389
405
|
` // Key-only hosts (CI): set false, or HARNERY_WORKFLOW_SUBSCRIPTION_ONLY=0.\n` +
|
|
390
406
|
` "workflow": { "subscriptionOnly": true }`;
|
|
@@ -2,38 +2,38 @@ import { existsSync, readdirSync, readFileSync, statSync, unlinkSync, watch } fr
|
|
|
2
2
|
import { resolve as resolvePath } from "node:path";
|
|
3
3
|
import type { Command } from "commander";
|
|
4
4
|
import type { EmitContext } from "../commander.ts";
|
|
5
|
-
import { emitCanonical,
|
|
5
|
+
import { emitCanonical, normalizeAdapter, readHeartbeat } from "../core/agents/index.ts";
|
|
6
6
|
import { resolveBinName } from "../core/config.ts";
|
|
7
7
|
import {
|
|
8
8
|
appendEntry,
|
|
9
|
-
|
|
9
|
+
archiveJournal,
|
|
10
10
|
currentOwnerOrThrow,
|
|
11
|
-
|
|
11
|
+
JOURNAL_CATEGORIES,
|
|
12
|
+
type JournalCategory,
|
|
13
|
+
type JournalDoc,
|
|
14
|
+
journalDir,
|
|
15
|
+
journalPath,
|
|
16
|
+
lintJournal,
|
|
12
17
|
listArchives,
|
|
13
|
-
|
|
14
|
-
|
|
18
|
+
loadJournal,
|
|
19
|
+
parseJournal,
|
|
15
20
|
pruneArchives,
|
|
16
21
|
resolveOwnerByName,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
type ScratchDoc,
|
|
20
|
-
scratchDir,
|
|
21
|
-
scratchPath,
|
|
22
|
-
sweepOrphanScratchpads,
|
|
23
|
-
} from "../core/scratch/index.ts";
|
|
22
|
+
sweepOrphanJournals,
|
|
23
|
+
} from "../core/journal/index.ts";
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* `harn
|
|
26
|
+
* `harn journal`: per-agent markdown journal at `.harnery/journal/<instance_id>.md`.
|
|
27
27
|
* Used both for self-notes (surviving compaction) and peer coordination (other
|
|
28
28
|
* agents pull-read it on demand). SessionEnd hook archives; SessionStart
|
|
29
29
|
* janitor surfaces the most-recent archive as a recovery cue.
|
|
30
30
|
*/
|
|
31
31
|
let emit: EmitContext;
|
|
32
32
|
|
|
33
|
-
export function
|
|
33
|
+
export function registerJournalCommand(program: Command, emitParam: EmitContext): void {
|
|
34
34
|
emit = emitParam;
|
|
35
35
|
const root = program
|
|
36
|
-
.command("
|
|
36
|
+
.command("journal")
|
|
37
37
|
.description(
|
|
38
38
|
"Per-agent markdown journal: append-only timestamped entries. " +
|
|
39
39
|
"Survives in-session compaction, archived at session end, pruned after 7 days.",
|
|
@@ -42,12 +42,12 @@ export function registerScratchCommand(program: Command, emitParam: EmitContext)
|
|
|
42
42
|
// ── add ───────────────────────────────────────────────────────────────
|
|
43
43
|
root
|
|
44
44
|
.command("add <category> <text...>")
|
|
45
|
-
.description(`Append an entry to my
|
|
45
|
+
.description(`Append an entry to my journal. Category: ${JOURNAL_CATEGORIES.join(" | ")}`)
|
|
46
46
|
.action((category: string, text: string[]) => {
|
|
47
47
|
const cat = validateCategory(category);
|
|
48
48
|
const body = text.join(" ");
|
|
49
49
|
if (!body.trim()) {
|
|
50
|
-
emit.error({ code: "empty_body", message: "
|
|
50
|
+
emit.error({ code: "empty_body", message: "journal add: body is empty" });
|
|
51
51
|
process.exit(1);
|
|
52
52
|
}
|
|
53
53
|
try {
|
|
@@ -55,10 +55,10 @@ export function registerScratchCommand(program: Command, emitParam: EmitContext)
|
|
|
55
55
|
const doc = appendEntry(owner, cat, body);
|
|
56
56
|
const hb = readHeartbeat(owner);
|
|
57
57
|
emitCanonical({
|
|
58
|
-
type: "state.
|
|
58
|
+
type: "state.journal_append",
|
|
59
59
|
owner,
|
|
60
60
|
session: hb?.session_id ?? owner,
|
|
61
|
-
|
|
61
|
+
adapter: normalizeAdapter(hb?.platform),
|
|
62
62
|
data: {
|
|
63
63
|
category: cat,
|
|
64
64
|
body_summary: body.length > 1000 ? `${body.slice(0, 997)}...` : body,
|
|
@@ -81,8 +81,8 @@ export function registerScratchCommand(program: Command, emitParam: EmitContext)
|
|
|
81
81
|
// ── read ──────────────────────────────────────────────────────────────
|
|
82
82
|
root
|
|
83
83
|
.command("read")
|
|
84
|
-
.description("Render a
|
|
85
|
-
.option("--name <name>", "Read the named peer's
|
|
84
|
+
.description("Render a journal to stdout. No --name: my own. With --name: a peer's.")
|
|
85
|
+
.option("--name <name>", "Read the named peer's journal (case-insensitive)")
|
|
86
86
|
.option("--owner <id>", "Read by instance_id directly")
|
|
87
87
|
.option("--archive <basename>", "Read an archive file (e.g. <owner>-<ts>.md)")
|
|
88
88
|
.option("--limit <n>", "Cap entries rendered (newest first)", "50")
|
|
@@ -98,8 +98,8 @@ export function registerScratchCommand(program: Command, emitParam: EmitContext)
|
|
|
98
98
|
// ── list ──────────────────────────────────────────────────────────────
|
|
99
99
|
root
|
|
100
100
|
.command("list")
|
|
101
|
-
.description("Summarize all active
|
|
102
|
-
.option("--archives", "List archive files instead of active
|
|
101
|
+
.description("Summarize all active journals + archive count")
|
|
102
|
+
.option("--archives", "List archive files instead of active journals")
|
|
103
103
|
.action((opts: { archives?: boolean }) => {
|
|
104
104
|
try {
|
|
105
105
|
if (opts.archives) {
|
|
@@ -120,7 +120,7 @@ export function registerScratchCommand(program: Command, emitParam: EmitContext)
|
|
|
120
120
|
emit.data({ rows: items });
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
|
-
const dir =
|
|
123
|
+
const dir = journalDir();
|
|
124
124
|
const rows: Array<{
|
|
125
125
|
instance_id: string;
|
|
126
126
|
name: string;
|
|
@@ -132,7 +132,7 @@ export function registerScratchCommand(program: Command, emitParam: EmitContext)
|
|
|
132
132
|
for (const f of readdirSync(dir)) {
|
|
133
133
|
if (!f.endsWith(".md")) continue;
|
|
134
134
|
const instanceId = f.replace(/\.md$/, "");
|
|
135
|
-
const doc =
|
|
135
|
+
const doc = loadJournal(instanceId);
|
|
136
136
|
if (!doc) continue;
|
|
137
137
|
rows.push({
|
|
138
138
|
instance_id: instanceId,
|
|
@@ -154,27 +154,27 @@ export function registerScratchCommand(program: Command, emitParam: EmitContext)
|
|
|
154
154
|
// ── tail ──────────────────────────────────────────────────────────────
|
|
155
155
|
root
|
|
156
156
|
.command("tail")
|
|
157
|
-
.description("Follow my
|
|
158
|
-
.option("--name <name>", "Tail the named peer's
|
|
157
|
+
.description("Follow my journal (or a peer's) for new entries.")
|
|
158
|
+
.option("--name <name>", "Tail the named peer's journal")
|
|
159
159
|
.option("--owner <id>", "Tail by instance_id directly")
|
|
160
160
|
.action(async (opts: { name?: string; owner?: string }) => {
|
|
161
161
|
try {
|
|
162
162
|
const owner = resolveTargetOwner(opts);
|
|
163
|
-
const path =
|
|
163
|
+
const path = journalPath(owner);
|
|
164
164
|
if (!existsSync(path)) {
|
|
165
|
-
emit.error({ code: "
|
|
165
|
+
emit.error({ code: "no_journal", message: `no journal at ${path} yet` });
|
|
166
166
|
process.exit(1);
|
|
167
167
|
}
|
|
168
168
|
process.stderr.write(`tailing ${path}\n`); // lint-ok-emission: tail banner, immediate stderr flush before streaming
|
|
169
169
|
let lastSize = statSync(path).size;
|
|
170
170
|
// Print initial render
|
|
171
|
-
process.stdout.write(`${
|
|
171
|
+
process.stdout.write(`${renderJournal(loadJournal(owner)!, 10)}\n`); // lint-ok-emission: streaming tail body
|
|
172
172
|
const w = watch(path, { persistent: true }, () => {
|
|
173
173
|
try {
|
|
174
174
|
const curr = statSync(path).size;
|
|
175
175
|
if (curr === lastSize) return;
|
|
176
176
|
lastSize = curr;
|
|
177
|
-
const doc =
|
|
177
|
+
const doc = loadJournal(owner);
|
|
178
178
|
if (!doc) return;
|
|
179
179
|
const newest = doc.entries[0];
|
|
180
180
|
if (!newest) return;
|
|
@@ -201,7 +201,7 @@ export function registerScratchCommand(program: Command, emitParam: EmitContext)
|
|
|
201
201
|
// ── clear ─────────────────────────────────────────────────────────────
|
|
202
202
|
root
|
|
203
203
|
.command("clear")
|
|
204
|
-
.description("Delete my
|
|
204
|
+
.description("Delete my journal (rare; mainly for testing)")
|
|
205
205
|
.option("--yes", "Confirm deletion")
|
|
206
206
|
.action((opts: { yes?: boolean }) => {
|
|
207
207
|
if (!opts.yes) {
|
|
@@ -210,7 +210,7 @@ export function registerScratchCommand(program: Command, emitParam: EmitContext)
|
|
|
210
210
|
}
|
|
211
211
|
try {
|
|
212
212
|
const owner = currentOwnerOrThrow();
|
|
213
|
-
const path =
|
|
213
|
+
const path = journalPath(owner);
|
|
214
214
|
if (existsSync(path)) {
|
|
215
215
|
unlinkSync(path);
|
|
216
216
|
emit.data({ cleared: true, path });
|
|
@@ -226,9 +226,9 @@ export function registerScratchCommand(program: Command, emitParam: EmitContext)
|
|
|
226
226
|
// ── lint ──────────────────────────────────────────────────────────────
|
|
227
227
|
root
|
|
228
228
|
.command("lint")
|
|
229
|
-
.description("Validate
|
|
230
|
-
.option("--all", "Lint every
|
|
231
|
-
.option("--owner <id>", "Lint a specific owner's
|
|
229
|
+
.description("Validate journal format + size")
|
|
230
|
+
.option("--all", "Lint every journal in .harnery/journal/")
|
|
231
|
+
.option("--owner <id>", "Lint a specific owner's journal")
|
|
232
232
|
.action((opts: { all?: boolean; owner?: string }) => {
|
|
233
233
|
try {
|
|
234
234
|
runLint(opts);
|
|
@@ -241,12 +241,12 @@ export function registerScratchCommand(program: Command, emitParam: EmitContext)
|
|
|
241
241
|
// ── archive (manual / hook helper) ────────────────────────────────────
|
|
242
242
|
root
|
|
243
243
|
.command("archive")
|
|
244
|
-
.description("Archive my
|
|
245
|
-
.option("--owner <id>", "Archive a specific owner's
|
|
244
|
+
.description("Archive my journal now (idempotent; fired by SessionEnd hook)")
|
|
245
|
+
.option("--owner <id>", "Archive a specific owner's journal")
|
|
246
246
|
.action((opts: { owner?: string }) => {
|
|
247
247
|
try {
|
|
248
248
|
const owner = opts.owner ?? currentOwnerOrThrow();
|
|
249
|
-
const dest =
|
|
249
|
+
const dest = archiveJournal(owner);
|
|
250
250
|
emit.data({ instance_id: owner, archived: !!dest, path: dest });
|
|
251
251
|
} catch (err) {
|
|
252
252
|
emit.error({ code: "archive_failed", message: (err as Error).message });
|
|
@@ -279,9 +279,9 @@ export function registerScratchCommand(program: Command, emitParam: EmitContext)
|
|
|
279
279
|
const bodyOneLine = last.body.replace(/\s+/g, " ").trim();
|
|
280
280
|
const bodyTrunc = bodyOneLine.length > 100 ? `${bodyOneLine.slice(0, 99)}…` : bodyOneLine;
|
|
281
281
|
const cue =
|
|
282
|
-
`Recent
|
|
282
|
+
`Recent journal archive (${ageStr} ago): agent-${doc.header.name}: ` +
|
|
283
283
|
`last entry [${last.category}] "${bodyTrunc}". ` +
|
|
284
|
-
`Read full: \`${resolveBinName()}
|
|
284
|
+
`Read full: \`${resolveBinName()} journal read --archive ${newest.basename}\`.`;
|
|
285
285
|
process.stdout.write(`${cue}\n`); // lint-ok-emission: bash hook reads stdout to compose SessionStart additionalContext
|
|
286
286
|
} catch (_err) {
|
|
287
287
|
// Recovery cue is best-effort; never fail the SessionStart hook.
|
|
@@ -292,14 +292,14 @@ export function registerScratchCommand(program: Command, emitParam: EmitContext)
|
|
|
292
292
|
root
|
|
293
293
|
.command("janitor")
|
|
294
294
|
.description(
|
|
295
|
-
"Prune old archives + sweep orphan
|
|
295
|
+
"Prune old archives + sweep orphan journals (heartbeat gone). Fired by SessionStart hook.",
|
|
296
296
|
)
|
|
297
297
|
.option("--days <n>", "Archive retention in days", "7")
|
|
298
298
|
.option("--quiet", "Suppress stdout output")
|
|
299
299
|
.action((opts: { days: string; quiet?: boolean }) => {
|
|
300
300
|
try {
|
|
301
301
|
const days = Number.parseInt(opts.days, 10);
|
|
302
|
-
const swept =
|
|
302
|
+
const swept = sweepOrphanJournals();
|
|
303
303
|
const pruned = pruneArchives(days);
|
|
304
304
|
if (!opts.quiet) {
|
|
305
305
|
emit.data({
|
|
@@ -320,7 +320,7 @@ export function registerScratchCommand(program: Command, emitParam: EmitContext)
|
|
|
320
320
|
function runRead(opts: { name?: string; owner?: string; archive?: string; limit: string }): void {
|
|
321
321
|
const limit = Number.parseInt(opts.limit, 10);
|
|
322
322
|
if (opts.archive) {
|
|
323
|
-
const dir =
|
|
323
|
+
const dir = journalDir();
|
|
324
324
|
const path = resolvePath(dir, "archived", opts.archive);
|
|
325
325
|
if (!existsSync(path)) {
|
|
326
326
|
emit.error({ code: "no_archive", message: `archive not found: ${opts.archive}` });
|
|
@@ -332,32 +332,32 @@ function runRead(opts: { name?: string; owner?: string; archive?: string; limit:
|
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
const owner = resolveTargetOwner(opts);
|
|
335
|
-
const doc =
|
|
335
|
+
const doc = loadJournal(owner);
|
|
336
336
|
if (!doc) {
|
|
337
337
|
emit.error({
|
|
338
|
-
code: "
|
|
339
|
-
message: `no
|
|
338
|
+
code: "no_journal",
|
|
339
|
+
message: `no journal for owner=${owner.slice(0, 8)}… (file not created yet)`,
|
|
340
340
|
});
|
|
341
341
|
process.exit(1);
|
|
342
342
|
}
|
|
343
343
|
|
|
344
344
|
const hb = readHeartbeat(owner);
|
|
345
345
|
const staleBanner = renderStaleBannerIfNeeded(hb?.last_heartbeat);
|
|
346
|
-
process.stdout.write(`${staleBanner +
|
|
346
|
+
process.stdout.write(`${staleBanner + renderJournal(doc, limit)}\n`); // lint-ok-emission: pretty render, multi-line markdown for direct TTY/pipe consumption
|
|
347
347
|
}
|
|
348
348
|
|
|
349
349
|
function runLint(opts: { all?: boolean; owner?: string }): void {
|
|
350
|
-
const dir =
|
|
350
|
+
const dir = journalDir();
|
|
351
351
|
const files: string[] = [];
|
|
352
352
|
if (opts.owner) {
|
|
353
|
-
files.push(
|
|
353
|
+
files.push(journalPath(opts.owner));
|
|
354
354
|
} else if (opts.all) {
|
|
355
355
|
for (const f of readdirSync(dir)) {
|
|
356
356
|
if (f.endsWith(".md")) files.push(resolvePath(dir, f));
|
|
357
357
|
}
|
|
358
358
|
} else {
|
|
359
359
|
const owner = currentOwnerOrThrow();
|
|
360
|
-
files.push(
|
|
360
|
+
files.push(journalPath(owner));
|
|
361
361
|
}
|
|
362
362
|
let totalIssues = 0;
|
|
363
363
|
const reports: Array<{ path: string; issues: { line: number; message: string }[] }> = [];
|
|
@@ -367,7 +367,7 @@ function runLint(opts: { all?: boolean; owner?: string }): void {
|
|
|
367
367
|
continue;
|
|
368
368
|
}
|
|
369
369
|
const content = readFileSync(path, "utf8");
|
|
370
|
-
const issues =
|
|
370
|
+
const issues = lintJournal(content);
|
|
371
371
|
if (issues.length > 0) totalIssues += issues.length;
|
|
372
372
|
reports.push({ path, issues });
|
|
373
373
|
}
|
|
@@ -377,15 +377,15 @@ function runLint(opts: { all?: boolean; owner?: string }): void {
|
|
|
377
377
|
|
|
378
378
|
// ─── Helpers ──────────────────────────────────────────────────────────────
|
|
379
379
|
|
|
380
|
-
function validateCategory(c: string):
|
|
381
|
-
if (!(
|
|
380
|
+
function validateCategory(c: string): JournalCategory {
|
|
381
|
+
if (!(JOURNAL_CATEGORIES as readonly string[]).includes(c)) {
|
|
382
382
|
emit.error({
|
|
383
383
|
code: "bad_category",
|
|
384
|
-
message: `category must be one of: ${
|
|
384
|
+
message: `category must be one of: ${JOURNAL_CATEGORIES.join(", ")}`,
|
|
385
385
|
});
|
|
386
386
|
process.exit(1);
|
|
387
387
|
}
|
|
388
|
-
return c as
|
|
388
|
+
return c as JournalCategory;
|
|
389
389
|
}
|
|
390
390
|
|
|
391
391
|
function resolveTargetOwner(opts: { name?: string; owner?: string }): string {
|
|
@@ -404,9 +404,9 @@ function resolveTargetOwner(opts: { name?: string; owner?: string }): string {
|
|
|
404
404
|
return currentOwnerOrThrow();
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
-
function
|
|
407
|
+
function renderJournal(doc: JournalDoc, limit: number): string {
|
|
408
408
|
const lines: string[] = [];
|
|
409
|
-
lines.push(`#
|
|
409
|
+
lines.push(`# Journal: agent-${doc.header.name}`);
|
|
410
410
|
if (doc.header.session_id) lines.push(`session_id: ${doc.header.session_id}`);
|
|
411
411
|
if (doc.header.machine) lines.push(`machine: ${doc.header.machine}`);
|
|
412
412
|
if (doc.header.started) lines.push(`started: ${doc.header.started}`);
|
|
@@ -434,11 +434,11 @@ function renderStaleBannerIfNeeded(lastHeartbeat: string | undefined): string {
|
|
|
434
434
|
return `[STALE: heartbeat ${m}m old, agent may be dead]\n\n`;
|
|
435
435
|
}
|
|
436
436
|
|
|
437
|
-
function parseSafe(path: string):
|
|
437
|
+
function parseSafe(path: string): JournalDoc | null {
|
|
438
438
|
try {
|
|
439
439
|
if (!existsSync(path)) return null;
|
|
440
440
|
const content = readFileSync(path, "utf8");
|
|
441
|
-
return
|
|
441
|
+
return parseJournal(path, content);
|
|
442
442
|
} catch {
|
|
443
443
|
return null;
|
|
444
444
|
}
|
package/src/commands/policy.ts
CHANGED
|
@@ -41,7 +41,7 @@ export function renderPolicy(policy: Readonly<NormalizedPolicy>, digest: string)
|
|
|
41
41
|
`unknown cost: ${policy.unknown_cost}`,
|
|
42
42
|
`network: ${policy.network}`,
|
|
43
43
|
`external actions: ${policy.external_actions}`,
|
|
44
|
-
`
|
|
44
|
+
`adapters: ${policy.allowed_adapters?.join(", ") ?? "any"}`,
|
|
45
45
|
`models: ${policy.allowed_models?.join(", ") ?? "any"}`,
|
|
46
46
|
`paths: ${policy.allowed_paths?.join(", ") ?? "any"}`,
|
|
47
47
|
`isolation: ${policy.allowed_isolation?.join(", ") ?? "any"}`,
|
package/src/commands/presence.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { EmitContext } from "../commander.ts";
|
|
|
3
3
|
import { monorepoRoot } from "../core/agents/coord-client.ts";
|
|
4
4
|
import {
|
|
5
5
|
emitCanonical,
|
|
6
|
-
|
|
6
|
+
normalizeAdapter,
|
|
7
7
|
readHeartbeat,
|
|
8
8
|
resolveOwner,
|
|
9
9
|
} from "../core/agents/index.ts";
|
|
@@ -252,7 +252,7 @@ function emitPresenceChange(
|
|
|
252
252
|
type: "state.presence_change",
|
|
253
253
|
owner,
|
|
254
254
|
session: hb?.session_id ?? owner,
|
|
255
|
-
|
|
255
|
+
adapter: normalizeAdapter(hb?.platform),
|
|
256
256
|
data: { from, to, source },
|
|
257
257
|
});
|
|
258
258
|
}
|
package/src/commands/sync.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* via rclone (typically a Google Drive remote, but any rclone remote works).
|
|
4
4
|
*
|
|
5
5
|
* Scope: a deliberately small set of file types: durable identities,
|
|
6
|
-
* archived
|
|
6
|
+
* archived journals, council manifests. The high-churn machine-local
|
|
7
7
|
* stuff (events.ndjson, .pid-map/, active/, .last-intent.*) stays put.
|
|
8
8
|
*
|
|
9
9
|
* Subcommands:
|
|
@@ -29,7 +29,7 @@ import { syncJsoncConfig } from "../core/config.ts";
|
|
|
29
29
|
|
|
30
30
|
// What we sync. Anything matching one of these (relative to .harnery/) is
|
|
31
31
|
// considered part of the sync set. Everything else stays local-only.
|
|
32
|
-
const SYNC_PATHS = ["identities/", "
|
|
32
|
+
const SYNC_PATHS = ["identities/", "journal/archived/", "councils/"];
|
|
33
33
|
|
|
34
34
|
interface SyncConfig {
|
|
35
35
|
remote: string;
|
|
@@ -145,7 +145,7 @@ export function registerSyncCommand(program: Command, emit: EmitContext): void {
|
|
|
145
145
|
.command("sync")
|
|
146
146
|
.description(
|
|
147
147
|
"Cross-machine sync of curated .harnery/ subset (identities, archived " +
|
|
148
|
-
"
|
|
148
|
+
"journals, council manifests) via rclone. Google Drive is the " +
|
|
149
149
|
"expected remote; any rclone backend works.",
|
|
150
150
|
);
|
|
151
151
|
|