@openrig/cli 0.5.6 → 0.5.7
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/daemon/assets/plugins/openrig-core/README.md +1 -1
- package/daemon/assets/plugins/openrig-core/skills/loading-addressable-markdown/SKILL.md +34 -0
- package/daemon/assets/plugins/openrig-core/skills/loading-addressable-markdown/scripts/resolve-markdown.mjs +170 -0
- package/daemon/assets/plugins/openrig-core/skills/openrig-skills/SKILL.md +1 -4
- package/daemon/assets/plugins/openrig-core/skills/retiring-and-inheriting-a-seat/SKILL.md +3 -3
- package/daemon/assets/plugins/openrig-core/skills/software-for-agents/SKILL.md +4 -9
- package/daemon/assets/vm-preview-fixtures/workflows/sample-basic-loop.yaml +3 -3
- package/daemon/context-packs/onboarding-width/manifest.yaml +1 -1
- package/daemon/context-packs/skills/applying-a-permission-policy/SKILL.md +120 -0
- package/daemon/context-packs/skills/applying-a-permission-policy/manifest.yaml +10 -0
- package/daemon/context-packs/skills/claude-compaction-restore/SKILL.md +166 -0
- package/daemon/context-packs/skills/claude-compaction-restore/manifest.yaml +18 -0
- package/daemon/context-packs/skills/claude-compaction-restore/scripts/precompact-hook.mjs +174 -0
- package/daemon/context-packs/skills/claude-compaction-restore/scripts/restore-from-jsonl.mjs +487 -0
- package/daemon/context-packs/skills/claude-compaction-restore/templates/compact-instruction.md +1 -0
- package/daemon/context-packs/skills/claude-compaction-restore/templates/post-compact-restore-instruction.md +1 -0
- package/daemon/context-packs/skills/core/agent-starters/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/agent-startup-and-context-ingestion/SKILL.md +1 -1
- package/daemon/context-packs/skills/core/agent-startup-and-context-ingestion/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/cross-host-rig-commands/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/human-in-the-loop/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/messaging-the-human/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/openrig-architect/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/openrig-cmux/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/openrig-herdr/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/openrig-skills/SKILL.md +1 -4
- package/daemon/context-packs/skills/core/openrig-skills/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/openrig-upgrade/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/rig-bundles-and-shareable-artifacts/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/rig-lifecycle/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/session-source-fork/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/specification-system/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/topology-mutation-and-seat-management/manifest.yaml +1 -1
- package/daemon/context-packs/skills/core/watchdog/manifest.yaml +1 -1
- package/daemon/context-packs/skills/delegating-work/SKILL.md +43 -0
- package/daemon/context-packs/skills/delegating-work/manifest.yaml +10 -0
- package/daemon/context-packs/skills/forming-an-openrig-mental-model/SKILL.md +318 -0
- package/daemon/context-packs/skills/forming-an-openrig-mental-model/manifest.yaml +10 -0
- package/daemon/context-packs/skills/loading-addressable-markdown/SKILL.md +34 -0
- package/daemon/context-packs/skills/loading-addressable-markdown/manifest.yaml +12 -0
- package/daemon/context-packs/skills/loading-addressable-markdown/scripts/resolve-markdown.mjs +170 -0
- package/daemon/context-packs/skills/mission-slice-sop/SKILL.md +94 -0
- package/daemon/context-packs/skills/mission-slice-sop/manifest.yaml +10 -0
- package/daemon/context-packs/skills/openrig-operating-model/SKILL.md +397 -0
- package/daemon/context-packs/skills/openrig-operating-model/manifest.yaml +30 -0
- package/daemon/context-packs/skills/openrig-operating-model/scripts/compose.py +572 -0
- package/daemon/context-packs/skills/openrig-operating-model/scripts/scaffold.sh +34 -0
- package/daemon/context-packs/skills/openrig-operating-model/scripts/trace-due.sh +32 -0
- package/daemon/context-packs/skills/openrig-operating-model/scripts/trace-stamp.sh +5 -0
- package/daemon/context-packs/skills/openrig-operating-model/scripts/trunk-diff.sh +18 -0
- package/daemon/context-packs/skills/openrig-operating-model/templates/LEARNED.md +40 -0
- package/daemon/context-packs/skills/openrig-operating-model/templates/NOTES.md +9 -0
- package/daemon/context-packs/skills/openrig-operating-model/templates/PLAYBOOK.md +5 -0
- package/daemon/context-packs/skills/openrig-operating-model/templates/SOP.md +24 -0
- package/daemon/context-packs/skills/openrig-operating-model/templates/SPEC.md +54 -0
- package/daemon/context-packs/skills/openrig-user/SKILL.md +1374 -0
- package/daemon/context-packs/skills/openrig-user/manifest.yaml +10 -0
- package/daemon/context-packs/skills/orienting-to-an-inherited-seat/CHANGELOG.md +64 -0
- package/daemon/context-packs/skills/orienting-to-an-inherited-seat/SKILL.md +250 -0
- package/daemon/context-packs/skills/orienting-to-an-inherited-seat/manifest.yaml +12 -0
- package/daemon/context-packs/skills/pm/backlog-capture/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pm/context-builder/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pm/exec-summary/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pm/office-hours/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pm/plan-review/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pm/requirements-writer/SKILL.md +21 -15
- package/daemon/context-packs/skills/pm/requirements-writer/manifest.yaml +3 -3
- package/daemon/context-packs/skills/pm/ui-mockup/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pods/development-team/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pods/orchestration-team/SKILL.md +1 -1
- package/daemon/context-packs/skills/pods/orchestration-team/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pods/oversight-team/manifest.yaml +1 -1
- package/daemon/context-packs/skills/pods/review-team/SKILL.md +1 -1
- package/daemon/context-packs/skills/pods/review-team/manifest.yaml +1 -1
- package/daemon/context-packs/skills/process/agent-browser/manifest.yaml +1 -1
- package/daemon/context-packs/skills/process/context-engineering/manifest.yaml +1 -1
- package/daemon/context-packs/skills/process/dogfood/manifest.yaml +1 -1
- package/daemon/context-packs/skills/process/frontend-design/manifest.yaml +1 -1
- package/daemon/context-packs/skills/process/systematic-debugging/manifest.yaml +1 -1
- package/daemon/context-packs/skills/process/test-driven-development/manifest.yaml +1 -1
- package/daemon/context-packs/skills/process/verification-before-completion/manifest.yaml +1 -1
- package/daemon/context-packs/skills/queue-handoff/SKILL.md +192 -0
- package/daemon/context-packs/skills/queue-handoff/manifest.yaml +10 -0
- package/daemon/context-packs/skills/refocusing/SKILL.md +31 -0
- package/daemon/context-packs/skills/refocusing/manifest.yaml +14 -0
- package/daemon/context-packs/skills/refocusing/references/refocus.md +22 -0
- package/daemon/context-packs/skills/refocusing/scripts/trace-to-root.py +264 -0
- package/daemon/context-packs/skills/retiring-and-inheriting-a-seat/CHANGELOG.md +48 -0
- package/daemon/context-packs/skills/retiring-and-inheriting-a-seat/SKILL.md +231 -0
- package/daemon/context-packs/skills/retiring-and-inheriting-a-seat/manifest.yaml +12 -0
- package/daemon/context-packs/skills/seat-continuity-and-handover/SKILL.md +151 -0
- package/daemon/context-packs/skills/seat-continuity-and-handover/manifest.yaml +16 -0
- package/daemon/context-packs/skills/seat-continuity-and-handover/references/apprentice-evidence-toolkit.md +32 -0
- package/daemon/context-packs/skills/seat-continuity-and-handover/references/apprentice-successor-seat-cutover.md +256 -0
- package/daemon/context-packs/skills/seat-continuity-and-handover/references/orchestrator-role.md +40 -0
- package/daemon/context-packs/skills/session-compaction-and-restore/SKILL.md +163 -0
- package/daemon/context-packs/skills/session-compaction-and-restore/manifest.yaml +10 -0
- package/daemon/context-packs/skills/software-for-agents/SKILL.md +187 -0
- package/daemon/context-packs/skills/software-for-agents/manifest.yaml +10 -0
- package/daemon/context-packs/world-example/manifest.yaml +1 -1
- package/daemon/context-packs/world-public/manifest.yaml +1 -1
- package/daemon/dist/build-info.js +3 -3
- package/daemon/dist/builtins/workflow-specs/basic-loop.yaml +3 -3
- package/daemon/dist/builtins/workflow-specs/conveyor.yaml +1 -1
- package/daemon/dist/builtins/workflow-specs/factory-rsi.yaml +1 -1
- package/daemon/dist/db/all-migrations.d.ts +1 -1
- package/daemon/dist/db/all-migrations.d.ts.map +1 -1
- package/daemon/dist/db/all-migrations.js +4 -2
- package/daemon/dist/db/all-migrations.js.map +1 -1
- package/daemon/dist/db/migrations/077_node_session_source.d.ts +4 -0
- package/daemon/dist/db/migrations/077_node_session_source.d.ts.map +1 -0
- package/daemon/dist/db/migrations/077_node_session_source.js +6 -0
- package/daemon/dist/db/migrations/077_node_session_source.js.map +1 -0
- package/daemon/dist/domain/context-packs/manifest-parser.d.ts.map +1 -1
- package/daemon/dist/domain/context-packs/manifest-parser.js +5 -6
- package/daemon/dist/domain/context-packs/manifest-parser.js.map +1 -1
- package/daemon/dist/domain/context-packs/profile-composer.d.ts +1 -1
- package/daemon/dist/domain/context-packs/profile-composer.d.ts.map +1 -1
- package/daemon/dist/domain/context-packs/profile-composer.js +2 -2
- package/daemon/dist/domain/context-packs/profile-composer.js.map +1 -1
- package/daemon/dist/domain/context-packs/profile-source-resolver.d.ts +3 -1
- package/daemon/dist/domain/context-packs/profile-source-resolver.d.ts.map +1 -1
- package/daemon/dist/domain/context-packs/profile-source-resolver.js +3 -2
- package/daemon/dist/domain/context-packs/profile-source-resolver.js.map +1 -1
- package/daemon/dist/domain/rig-lifecycle-service.d.ts +24 -4
- package/daemon/dist/domain/rig-lifecycle-service.d.ts.map +1 -1
- package/daemon/dist/domain/rig-lifecycle-service.js +116 -6
- package/daemon/dist/domain/rig-lifecycle-service.js.map +1 -1
- package/daemon/dist/domain/rig-repository.d.ts +2 -1
- package/daemon/dist/domain/rig-repository.d.ts.map +1 -1
- package/daemon/dist/domain/rig-repository.js +7 -0
- package/daemon/dist/domain/rig-repository.js.map +1 -1
- package/daemon/dist/domain/rigspec-exporter.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-exporter.js +2 -0
- package/daemon/dist/domain/rigspec-exporter.js.map +1 -1
- package/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
- package/daemon/dist/domain/rigspec-instantiator.js +2 -0
- package/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
- package/daemon/dist/domain/types.d.ts +2 -0
- package/daemon/dist/domain/types.d.ts.map +1 -1
- package/daemon/dist/domain/types.js.map +1 -1
- package/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
- package/daemon/dist/domain/workspace/default-workspace-scaffold.js +37 -2
- package/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
- package/daemon/dist/routes/context-packs.d.ts.map +1 -1
- package/daemon/dist/routes/context-packs.js +146 -6
- package/daemon/dist/routes/context-packs.js.map +1 -1
- package/daemon/dist/routes/rigs.js +7 -3
- package/daemon/dist/routes/rigs.js.map +1 -1
- package/daemon/dist/routes/sessions.js +7 -3
- package/daemon/dist/routes/sessions.js.map +1 -1
- package/daemon/dist/startup.d.ts.map +1 -1
- package/daemon/dist/startup.js +3 -1
- package/daemon/dist/startup.js.map +1 -1
- package/daemon/docs/reference/agent-spec.md +1 -1
- package/daemon/docs/reference/mission-install.md +23 -2
- package/daemon/docs/reference/product-journey-sdlc.md +305 -0
- package/daemon/docs/reference/sdlc-conventions.md +9 -2
- package/daemon/specs/agents/apps/vault-specialist/agent.yaml +1 -1
- package/daemon/specs/agents/apps/vault-specialist/guidance/role.md +0 -1
- package/daemon/specs/agents/conveyor/builder/agent.yaml +1 -1
- package/daemon/specs/agents/conveyor/builder/guidance/role.md +0 -1
- package/daemon/specs/agents/conveyor/lead/agent.yaml +1 -1
- package/daemon/specs/agents/conveyor/lead/guidance/role.md +0 -3
- package/daemon/specs/agents/conveyor/planner/agent.yaml +1 -1
- package/daemon/specs/agents/conveyor/planner/guidance/role.md +0 -1
- package/daemon/specs/agents/design/product-designer/agent.yaml +3 -4
- package/daemon/specs/agents/design/product-designer/guidance/role.md +0 -3
- package/daemon/specs/agents/development/implementer/agent.yaml +3 -4
- package/daemon/specs/agents/development/implementer/guidance/role.md +0 -3
- package/daemon/specs/agents/development/qa/agent.yaml +4 -4
- package/daemon/specs/agents/development/qa/guidance/role.md +1 -4
- package/daemon/specs/agents/factory-rsi/dogfood/agent.yaml +1 -1
- package/daemon/specs/agents/factory-rsi/release-manager/agent.yaml +1 -1
- package/daemon/specs/agents/orchestration/orchestrator/agent.yaml +3 -4
- package/daemon/specs/agents/orchestration/orchestrator/guidance/role.md +0 -4
- package/daemon/specs/agents/review/independent-reviewer/agent.yaml +3 -4
- package/daemon/specs/agents/review/independent-reviewer/guidance/role.md +0 -3
- package/daemon/specs/agents/shared/agent.yaml +2 -10
- package/daemon/specs/agents/shared/skills/core/agent-startup-and-context-ingestion/SKILL.md +1 -1
- package/daemon/specs/agents/shared/skills/core/openrig-skills/SKILL.md +1 -4
- package/daemon/specs/agents/shared/skills/pm/requirements-writer/SKILL.md +21 -15
- package/daemon/specs/agents/shared/skills/pods/orchestration-team/SKILL.md +1 -1
- package/daemon/specs/agents/shared/skills/pods/review-team/SKILL.md +1 -1
- package/daemon/specs/rigs/launch/kernel/agents/advisor/lead/agent.yaml +1 -1
- package/daemon/specs/rigs/launch/kernel/agents/advisor/lead/guidance/role.md +2 -3
- package/dist/build-info.js +3 -3
- package/dist/commands/config-init-workspace.d.ts.map +1 -1
- package/dist/commands/config-init-workspace.js +38 -3
- package/dist/commands/config-init-workspace.js.map +1 -1
- package/dist/commands/context.d.ts.map +1 -1
- package/dist/commands/context.js +37 -0
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/create.d.ts +4 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +84 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/grow.d.ts +4 -0
- package/dist/commands/grow.d.ts.map +1 -0
- package/dist/commands/grow.js +182 -0
- package/dist/commands/grow.js.map +1 -0
- package/dist/commands/remove.d.ts.map +1 -1
- package/dist/commands/remove.js +9 -1
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/rig.d.ts.map +1 -1
- package/dist/commands/rig.js +48 -1
- package/dist/commands/rig.js.map +1 -1
- package/dist/commands/scope.d.ts.map +1 -1
- package/dist/commands/scope.js +21 -2
- package/dist/commands/scope.js.map +1 -1
- package/dist/commands/shrink.d.ts.map +1 -1
- package/dist/commands/shrink.js +6 -1
- package/dist/commands/shrink.js.map +1 -1
- package/dist/commands/topology-default-agent.d.ts +4 -0
- package/dist/commands/topology-default-agent.d.ts.map +1 -0
- package/dist/commands/topology-default-agent.js +13 -0
- package/dist/commands/topology-default-agent.js.map +1 -0
- package/dist/commands/walk.d.ts.map +1 -1
- package/dist/commands/walk.js +3 -0
- package/dist/commands/walk.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/work-install.d.ts +39 -0
- package/dist/lib/work-install.d.ts.map +1 -0
- package/dist/lib/work-install.js +278 -0
- package/dist/lib/work-install.js.map +1 -0
- package/node_modules/@openrig/daemon/dist/build-info.js +3 -3
- package/node_modules/@openrig/daemon/dist/builtins/workflow-specs/basic-loop.yaml +3 -3
- package/node_modules/@openrig/daemon/dist/builtins/workflow-specs/conveyor.yaml +1 -1
- package/node_modules/@openrig/daemon/dist/builtins/workflow-specs/factory-rsi.yaml +1 -1
- package/node_modules/@openrig/daemon/dist/db/all-migrations.d.ts +1 -1
- package/node_modules/@openrig/daemon/dist/db/all-migrations.d.ts.map +1 -1
- package/node_modules/@openrig/daemon/dist/db/all-migrations.js +4 -2
- package/node_modules/@openrig/daemon/dist/db/all-migrations.js.map +1 -1
- package/node_modules/@openrig/daemon/dist/db/migrations/077_node_session_source.d.ts +4 -0
- package/node_modules/@openrig/daemon/dist/db/migrations/077_node_session_source.d.ts.map +1 -0
- package/node_modules/@openrig/daemon/dist/db/migrations/077_node_session_source.js +6 -0
- package/node_modules/@openrig/daemon/dist/db/migrations/077_node_session_source.js.map +1 -0
- package/node_modules/@openrig/daemon/dist/domain/context-packs/manifest-parser.d.ts.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/context-packs/manifest-parser.js +5 -6
- package/node_modules/@openrig/daemon/dist/domain/context-packs/manifest-parser.js.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/context-packs/profile-composer.d.ts +1 -1
- package/node_modules/@openrig/daemon/dist/domain/context-packs/profile-composer.d.ts.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/context-packs/profile-composer.js +2 -2
- package/node_modules/@openrig/daemon/dist/domain/context-packs/profile-composer.js.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/context-packs/profile-source-resolver.d.ts +3 -1
- package/node_modules/@openrig/daemon/dist/domain/context-packs/profile-source-resolver.d.ts.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/context-packs/profile-source-resolver.js +3 -2
- package/node_modules/@openrig/daemon/dist/domain/context-packs/profile-source-resolver.js.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/rig-lifecycle-service.d.ts +24 -4
- package/node_modules/@openrig/daemon/dist/domain/rig-lifecycle-service.d.ts.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/rig-lifecycle-service.js +116 -6
- package/node_modules/@openrig/daemon/dist/domain/rig-lifecycle-service.js.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/rig-repository.d.ts +2 -1
- package/node_modules/@openrig/daemon/dist/domain/rig-repository.d.ts.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/rig-repository.js +7 -0
- package/node_modules/@openrig/daemon/dist/domain/rig-repository.js.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/rigspec-exporter.d.ts.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/rigspec-exporter.js +2 -0
- package/node_modules/@openrig/daemon/dist/domain/rigspec-exporter.js.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/rigspec-instantiator.d.ts.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/rigspec-instantiator.js +2 -0
- package/node_modules/@openrig/daemon/dist/domain/rigspec-instantiator.js.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/types.d.ts +2 -0
- package/node_modules/@openrig/daemon/dist/domain/types.d.ts.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/types.js.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/workspace/default-workspace-scaffold.d.ts.map +1 -1
- package/node_modules/@openrig/daemon/dist/domain/workspace/default-workspace-scaffold.js +37 -2
- package/node_modules/@openrig/daemon/dist/domain/workspace/default-workspace-scaffold.js.map +1 -1
- package/node_modules/@openrig/daemon/dist/routes/context-packs.d.ts.map +1 -1
- package/node_modules/@openrig/daemon/dist/routes/context-packs.js +146 -6
- package/node_modules/@openrig/daemon/dist/routes/context-packs.js.map +1 -1
- package/node_modules/@openrig/daemon/dist/routes/rigs.js +7 -3
- package/node_modules/@openrig/daemon/dist/routes/rigs.js.map +1 -1
- package/node_modules/@openrig/daemon/dist/routes/sessions.js +7 -3
- package/node_modules/@openrig/daemon/dist/routes/sessions.js.map +1 -1
- package/node_modules/@openrig/daemon/dist/startup.d.ts.map +1 -1
- package/node_modules/@openrig/daemon/dist/startup.js +3 -1
- package/node_modules/@openrig/daemon/dist/startup.js.map +1 -1
- package/node_modules/@openrig/daemon/package.json +1 -1
- package/package.json +1 -1
- package/daemon/context-packs/skills/process/brainstorming/OPENRIG.md +0 -48
- package/daemon/context-packs/skills/process/brainstorming/SKILL.md +0 -107
- package/daemon/context-packs/skills/process/brainstorming/manifest.yaml +0 -12
- package/daemon/context-packs/skills/process/executing-plans/OPENRIG.md +0 -56
- package/daemon/context-packs/skills/process/executing-plans/SKILL.md +0 -94
- package/daemon/context-packs/skills/process/executing-plans/manifest.yaml +0 -12
- package/daemon/context-packs/skills/process/using-superpowers/OPENRIG.md +0 -48
- package/daemon/context-packs/skills/process/using-superpowers/SKILL.md +0 -106
- package/daemon/context-packs/skills/process/using-superpowers/manifest.yaml +0 -12
- package/daemon/context-packs/skills/process/writing-plans/OPENRIG.md +0 -52
- package/daemon/context-packs/skills/process/writing-plans/SKILL.md +0 -126
- package/daemon/context-packs/skills/process/writing-plans/manifest.yaml +0 -12
- package/daemon/specs/agents/shared/skills/process/brainstorming/OPENRIG.md +0 -48
- package/daemon/specs/agents/shared/skills/process/brainstorming/SKILL.md +0 -107
- package/daemon/specs/agents/shared/skills/process/executing-plans/OPENRIG.md +0 -56
- package/daemon/specs/agents/shared/skills/process/executing-plans/SKILL.md +0 -94
- package/daemon/specs/agents/shared/skills/process/using-superpowers/OPENRIG.md +0 -48
- package/daemon/specs/agents/shared/skills/process/using-superpowers/SKILL.md +0 -106
- package/daemon/specs/agents/shared/skills/process/writing-plans/OPENRIG.md +0 -52
- package/daemon/specs/agents/shared/skills/process/writing-plans/SKILL.md +0 -126
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { spawnSync } from "node:child_process";
|
|
6
|
+
|
|
7
|
+
const skillRoot = path.resolve(new URL("..", import.meta.url).pathname);
|
|
8
|
+
const restoreScript = path.join(skillRoot, "scripts", "restore-from-jsonl.mjs");
|
|
9
|
+
const outRoot = "/tmp/claude-compaction-restore";
|
|
10
|
+
const defaultRestoreInstruction =
|
|
11
|
+
"Read the claude-compaction-restore skill and follow its \"If You Just Compacted\" protocol.";
|
|
12
|
+
|
|
13
|
+
function emit(payload) {
|
|
14
|
+
process.stdout.write(`${JSON.stringify(payload)}\n`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function readHookInput() {
|
|
18
|
+
const raw = fs.readFileSync(0, "utf8").trim();
|
|
19
|
+
if (!raw) return {};
|
|
20
|
+
return JSON.parse(raw);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getOpenRigHome() {
|
|
24
|
+
return process.env.OPENRIG_HOME || process.env.RIGGED_HOME || path.join(os.homedir(), ".openrig");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function expandInstructionPath(filePath) {
|
|
28
|
+
if (filePath.startsWith("~/")) return path.join(os.homedir(), filePath.slice(2));
|
|
29
|
+
if (filePath.startsWith("${OPENRIG_HOME}/")) {
|
|
30
|
+
return path.join(getOpenRigHome(), filePath.slice("${OPENRIG_HOME}/".length));
|
|
31
|
+
}
|
|
32
|
+
if (filePath.startsWith("$OPENRIG_HOME/")) {
|
|
33
|
+
return path.join(getOpenRigHome(), filePath.slice("$OPENRIG_HOME/".length));
|
|
34
|
+
}
|
|
35
|
+
return filePath;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function readInstructionFile(filePath) {
|
|
39
|
+
const expanded = expandInstructionPath(filePath);
|
|
40
|
+
if (!fs.existsSync(expanded)) return "";
|
|
41
|
+
return fs.readFileSync(expanded, "utf8");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function sessionKey(input) {
|
|
45
|
+
const raw = [
|
|
46
|
+
process.env.OPENRIG_SESSION_NAME,
|
|
47
|
+
process.env.RIGGED_SESSION_NAME,
|
|
48
|
+
input.session_id,
|
|
49
|
+
input.sessionId,
|
|
50
|
+
input.session_name,
|
|
51
|
+
input.sessionName,
|
|
52
|
+
input.transcript_path ? path.basename(input.transcript_path, ".jsonl") : "",
|
|
53
|
+
].find((value) => typeof value === "string" && value.trim().length > 0) || "unknown-session";
|
|
54
|
+
return raw.replace(/[^a-zA-Z0-9_.@-]/g, "_");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function pendingMarkerPath(input) {
|
|
58
|
+
return path.join(getOpenRigHome(), "compaction", "restore-pending", `${sessionKey(input)}.json`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function writePendingRestoreMarker(input, parsed, restoreInstruction, customMessage) {
|
|
62
|
+
const markerPath = pendingMarkerPath(input);
|
|
63
|
+
fs.mkdirSync(path.dirname(markerPath), { recursive: true });
|
|
64
|
+
const payload = {
|
|
65
|
+
version: 1,
|
|
66
|
+
createdAt: new Date().toISOString(),
|
|
67
|
+
sessionName: process.env.OPENRIG_SESSION_NAME || process.env.RIGGED_SESSION_NAME || null,
|
|
68
|
+
sessionId: input.session_id || input.sessionId || null,
|
|
69
|
+
transcriptPath: input.transcript_path || null,
|
|
70
|
+
cwd: input.cwd || null,
|
|
71
|
+
outputDir: parsed.outputDir,
|
|
72
|
+
restoreInstruction,
|
|
73
|
+
postCompactInstruction: customMessage || "",
|
|
74
|
+
expectedAck: "restored from packet at <path>; resumed at step <X>",
|
|
75
|
+
deliveredAt: null,
|
|
76
|
+
deliveryCount: 0,
|
|
77
|
+
};
|
|
78
|
+
fs.writeFileSync(markerPath, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
|
|
79
|
+
return markerPath;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Slice 27 — read the OpenRig config directly (no daemon HTTP dependency
|
|
83
|
+
// so the hook still works when the daemon isn't running or isn't
|
|
84
|
+
// reachable from this process). Returns "" for either field when the
|
|
85
|
+
// config is missing, malformed, or the policy isn't set. If the policy is
|
|
86
|
+
// enabled but restore text has not been written yet, use OpenRig's default
|
|
87
|
+
// instruction to load the canonical restore skill. Inline instructions and
|
|
88
|
+
// file-path content are both included when both are configured.
|
|
89
|
+
function readClaudeCompactionMessage() {
|
|
90
|
+
const configPath = path.join(getOpenRigHome(), "config.json");
|
|
91
|
+
let inline = "";
|
|
92
|
+
let filePath = "";
|
|
93
|
+
let inlineConfigured = false;
|
|
94
|
+
let filePathConfigured = false;
|
|
95
|
+
let policyEnabled = false;
|
|
96
|
+
try {
|
|
97
|
+
if (!fs.existsSync(configPath)) return "";
|
|
98
|
+
const raw = fs.readFileSync(configPath, "utf8");
|
|
99
|
+
const parsed = JSON.parse(raw);
|
|
100
|
+
const policy = parsed?.policies?.claudeCompaction;
|
|
101
|
+
if (policy && typeof policy === "object") {
|
|
102
|
+
policyEnabled = policy.enabled === true;
|
|
103
|
+
if (typeof policy.messageInline === "string") {
|
|
104
|
+
inlineConfigured = true;
|
|
105
|
+
inline = policy.messageInline;
|
|
106
|
+
}
|
|
107
|
+
if (typeof policy.messageFilePath === "string") {
|
|
108
|
+
filePathConfigured = true;
|
|
109
|
+
filePath = policy.messageFilePath;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
} catch {
|
|
113
|
+
return "";
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const parts = [];
|
|
117
|
+
if (inline && inline.length > 0) {
|
|
118
|
+
parts.push(`Inline restore instruction:\n${inline}`);
|
|
119
|
+
}
|
|
120
|
+
if (filePath && filePath.length > 0) {
|
|
121
|
+
try {
|
|
122
|
+
const fileText = readInstructionFile(filePath);
|
|
123
|
+
if (fileText) {
|
|
124
|
+
parts.push(`Additional restore instruction file (${filePath}):\n${fileText}`);
|
|
125
|
+
}
|
|
126
|
+
} catch {
|
|
127
|
+
// Keep any inline instruction; unreadable extra files degrade quietly.
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (parts.length > 0) return parts.join("\n\n");
|
|
131
|
+
if (policyEnabled && !inlineConfigured && !filePathConfigured) {
|
|
132
|
+
return defaultRestoreInstruction;
|
|
133
|
+
}
|
|
134
|
+
return "";
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function buildSystemMessage(restoreInstruction, customMessage) {
|
|
138
|
+
if (!customMessage) return restoreInstruction;
|
|
139
|
+
return `${restoreInstruction}\n\n--- Operator-configured post-compaction restore instruction ---\n${customMessage}`;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
const input = readHookInput();
|
|
144
|
+
const args = [restoreScript, "--out", outRoot, "--json"];
|
|
145
|
+
if (input.cwd) args.push("--cwd", input.cwd);
|
|
146
|
+
if (input.transcript_path && input.transcript_path.endsWith(".jsonl") && fs.existsSync(input.transcript_path)) {
|
|
147
|
+
args.push(input.transcript_path);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const customMessage = readClaudeCompactionMessage();
|
|
151
|
+
|
|
152
|
+
const result = spawnSync("node", args, { encoding: "utf8" });
|
|
153
|
+
if (result.status !== 0) {
|
|
154
|
+
const baseFailure = `Claude compaction restore packet generation failed: ${(result.stderr || result.stdout || "unknown error").trim()}. After compaction, load the claude-compaction-restore skill and run restore-from-jsonl manually.`;
|
|
155
|
+
emit({
|
|
156
|
+
continue: true,
|
|
157
|
+
systemMessage: buildSystemMessage(baseFailure, customMessage),
|
|
158
|
+
});
|
|
159
|
+
process.exit(0);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const parsed = JSON.parse(result.stdout);
|
|
163
|
+
const baseRestore = `Pre-compaction restore seed packet prepared at ${parsed.outputDir}. This hook output is informational. After compaction, OpenRig may send a later normal user message asking you to restore from this packet; treat that later normal user message as the action request. The restore protocol is: load/read the claude-compaction-restore skill, run "node ~/.claude/skills/claude-compaction-restore/scripts/restore-from-jsonl.mjs --out /tmp/claude-compaction-restore --json" yourself when needed, read the generated restore-instructions.md, read the generated touched-files.md, identify remembered important files, read those files in full, read root/as-built/codemap docs before real work, then reply with "restored from packet at <path>; resumed at step <X>" with the files you read in full. If any step fails, report the failure explicitly.`;
|
|
164
|
+
const markerPath = writePendingRestoreMarker(input, parsed, baseRestore, customMessage);
|
|
165
|
+
emit({
|
|
166
|
+
continue: true,
|
|
167
|
+
systemMessage: buildSystemMessage(`${baseRestore} OpenRig also wrote a pending restore marker at ${markerPath}.`, customMessage),
|
|
168
|
+
});
|
|
169
|
+
} catch (error) {
|
|
170
|
+
emit({
|
|
171
|
+
continue: true,
|
|
172
|
+
systemMessage: `Claude compaction restore hook errored: ${error.message}. After compaction, load the claude-compaction-restore skill and run restore-from-jsonl manually.`,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { spawnSync } from "node:child_process";
|
|
6
|
+
import crypto from "node:crypto";
|
|
7
|
+
|
|
8
|
+
const TEXT_LIMIT = 4000;
|
|
9
|
+
const BASE64_RUN = 800; // strip contiguous base64 runs at least this long (screenshots, data URIs)
|
|
10
|
+
|
|
11
|
+
function sha256(text) {
|
|
12
|
+
return crypto.createHash("sha256").update(String(text ?? "")).digest("hex").slice(0, 16);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// R3: replace binary / base64 payloads (data: URIs, long base64 runs) with a compact marker,
|
|
16
|
+
// so a single screenshot block does not blow the transcript into un-chunkable size.
|
|
17
|
+
function stripBinary(text) {
|
|
18
|
+
let s = String(text ?? "");
|
|
19
|
+
s = s.replace(/data:([\w.+-]+\/[\w.+-]+)?;base64,[A-Za-z0-9+/=\s]{200,}/g,
|
|
20
|
+
(m, mime) => `[binary omitted: ~${m.length} bytes${mime ? `, ${mime}` : ""}]`);
|
|
21
|
+
s = s.replace(new RegExp(`[A-Za-z0-9+/]{${BASE64_RUN},}={0,2}`, "g"),
|
|
22
|
+
(m) => `[base64 omitted: ~${m.length} bytes]`);
|
|
23
|
+
return s;
|
|
24
|
+
}
|
|
25
|
+
const DEFAULT_OUT = "/tmp/claude-compaction-restore";
|
|
26
|
+
|
|
27
|
+
function parseArgs(argv) {
|
|
28
|
+
const args = {
|
|
29
|
+
jsonl: null,
|
|
30
|
+
out: DEFAULT_OUT,
|
|
31
|
+
cwd: process.cwd(),
|
|
32
|
+
json: false,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
36
|
+
const arg = argv[i];
|
|
37
|
+
if (arg === "--jsonl") args.jsonl = argv[++i];
|
|
38
|
+
else if (arg === "--out") args.out = argv[++i];
|
|
39
|
+
else if (arg === "--cwd") args.cwd = argv[++i];
|
|
40
|
+
else if (arg === "--json") args.json = true;
|
|
41
|
+
else if (!arg.startsWith("-") && !args.jsonl) args.jsonl = arg;
|
|
42
|
+
else throw new Error(`unknown argument: ${arg}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return args;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function readJsonLines(file) {
|
|
49
|
+
const raw = fs.readFileSync(file, "utf8");
|
|
50
|
+
return raw
|
|
51
|
+
.split(/\r?\n/)
|
|
52
|
+
.filter(Boolean)
|
|
53
|
+
.map((line, index) => {
|
|
54
|
+
try {
|
|
55
|
+
return JSON.parse(line);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return { type: "parse-error", line: index + 1, error: String(error), raw: line };
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function findLatestJsonl(cwd) {
|
|
63
|
+
const projectsRoot = path.join(os.homedir(), ".claude", "projects");
|
|
64
|
+
if (!fs.existsSync(projectsRoot)) return null;
|
|
65
|
+
|
|
66
|
+
const encoded = cwd ? cwd.replaceAll("/", "-") : null;
|
|
67
|
+
const candidates = [];
|
|
68
|
+
const roots = [];
|
|
69
|
+
|
|
70
|
+
if (encoded) {
|
|
71
|
+
const exact = path.join(projectsRoot, encoded);
|
|
72
|
+
if (fs.existsSync(exact)) roots.push(exact);
|
|
73
|
+
}
|
|
74
|
+
roots.push(projectsRoot);
|
|
75
|
+
|
|
76
|
+
for (const root of roots) {
|
|
77
|
+
const result = spawnSync("find", [root, "-name", "*.jsonl", "-maxdepth", root === projectsRoot ? "4" : "2"], {
|
|
78
|
+
encoding: "utf8",
|
|
79
|
+
});
|
|
80
|
+
if (result.status !== 0 && !result.stdout) continue;
|
|
81
|
+
for (const file of result.stdout.split(/\r?\n/).filter(Boolean)) {
|
|
82
|
+
try {
|
|
83
|
+
const stat = fs.statSync(file);
|
|
84
|
+
candidates.push({ file, mtimeMs: stat.mtimeMs });
|
|
85
|
+
} catch {
|
|
86
|
+
// Ignore raced/deleted transcript files.
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (candidates.length) break;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
candidates.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
93
|
+
return candidates[0]?.file ?? null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function stringifyContent(content) {
|
|
97
|
+
if (typeof content === "string") return content;
|
|
98
|
+
if (Array.isArray(content)) {
|
|
99
|
+
return content
|
|
100
|
+
.map((block) => {
|
|
101
|
+
if (typeof block === "string") return block;
|
|
102
|
+
if (block?.type === "text") return block.text ?? "";
|
|
103
|
+
if (block?.type === "image") return `[image omitted: ${block.source?.media_type ?? "image"}]`;
|
|
104
|
+
if (block?.type === "tool_use") return `[tool_use:${block.name}] ${JSON.stringify(block.input ?? {})}`;
|
|
105
|
+
if (block?.type === "tool_result") return `[tool_result] ${truncate(stripBinary(stringifyContent(block.content)), TEXT_LIMIT)}`;
|
|
106
|
+
return JSON.stringify(block);
|
|
107
|
+
})
|
|
108
|
+
.join("\n");
|
|
109
|
+
}
|
|
110
|
+
if (content == null) return "";
|
|
111
|
+
return JSON.stringify(content);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function truncate(text, max) {
|
|
115
|
+
const s = String(text ?? "");
|
|
116
|
+
if (s.length <= max) return s;
|
|
117
|
+
return `${s.slice(0, max)}\n[...truncated ${s.length - max} chars...]`;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function walkStrings(value, acc = []) {
|
|
121
|
+
if (typeof value === "string") acc.push(value);
|
|
122
|
+
else if (Array.isArray(value)) value.forEach((item) => walkStrings(item, acc));
|
|
123
|
+
else if (value && typeof value === "object") Object.values(value).forEach((item) => walkStrings(item, acc));
|
|
124
|
+
return acc;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function normalizeFile(candidate, cwd) {
|
|
128
|
+
let file = candidate.trim().replace(/[),.;:'"`\]\}>]+$/g, "").replace(/^[('"`<\[]+/g, "");
|
|
129
|
+
if (!file || file.includes("\n")) return null;
|
|
130
|
+
if (/\.(?:md|mdx|txt|json|jsonl|yaml|yml|toml|ts|tsx|js|jsx|mjs|cjs|py|sh|rs|go|sql|css|scss|html|xml|svg|csv|log|lock)\//i.test(file)) return null;
|
|
131
|
+
if (file.startsWith("~")) file = path.join(os.homedir(), file.slice(1));
|
|
132
|
+
let normalized = null;
|
|
133
|
+
if (file.startsWith("/")) normalized = path.normalize(file);
|
|
134
|
+
else if (file.startsWith("./") || file.startsWith("../")) normalized = path.normalize(path.resolve(cwd, file));
|
|
135
|
+
else if (/^[A-Za-z0-9_@.+-][A-Za-z0-9_@.+/\-:]*\.[A-Za-z0-9]+$/.test(file)) {
|
|
136
|
+
normalized = path.normalize(path.resolve(cwd, file));
|
|
137
|
+
} else if (/^(CLAUDE|AGENTS|README|DESIGN|CULTURE|MEMORY)\.md$/.test(file)) {
|
|
138
|
+
normalized = path.normalize(path.resolve(cwd, file));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (!normalized) return null;
|
|
142
|
+
try {
|
|
143
|
+
if (fs.existsSync(normalized) && fs.statSync(normalized).isDirectory()) return null;
|
|
144
|
+
} catch {
|
|
145
|
+
// Keep the candidate if stat races; the restore agent can decide.
|
|
146
|
+
}
|
|
147
|
+
return normalized;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function extractPaths(text, cwd) {
|
|
151
|
+
const paths = new Set();
|
|
152
|
+
const s = String(text ?? "");
|
|
153
|
+
const absolute = /(?:^|[\s"'(<\[])(\/(?:Users|private|tmp|var|opt|Volumes)\/[^\s"'()\]<>]+)/g;
|
|
154
|
+
const relative = /(?:^|[\s"'(<\[])((?:\.{1,2}\/)?[A-Za-z0-9_@.+-][A-Za-z0-9_@.+/\-:]*\.(?:md|mdx|txt|json|jsonl|yaml|yml|toml|ts|tsx|js|jsx|mjs|cjs|py|sh|rs|go|sql|css|scss|html|xml|svg|csv|log|lock))(?:$|[\s"')>\],.;:])/g;
|
|
155
|
+
const namedMarkdown = /(?:^|[\s"'(<\[])((?:CLAUDE|AGENTS|README|DESIGN|CULTURE|MEMORY)\.md)(?:$|[\s"')>\],.;:])/g;
|
|
156
|
+
|
|
157
|
+
for (const regex of [absolute, relative, namedMarkdown]) {
|
|
158
|
+
let match;
|
|
159
|
+
while ((match = regex.exec(s)) !== null) {
|
|
160
|
+
const normalized = normalizeFile(match[1], cwd);
|
|
161
|
+
if (normalized) paths.add(normalized);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return [...paths];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function createRegistry() {
|
|
168
|
+
const files = new Map();
|
|
169
|
+
let sequence = 0;
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
add(file, kind, source) {
|
|
173
|
+
if (!file) return;
|
|
174
|
+
const existing = files.get(file) ?? {
|
|
175
|
+
path: file,
|
|
176
|
+
kinds: {},
|
|
177
|
+
sources: new Set(),
|
|
178
|
+
firstSeen: sequence,
|
|
179
|
+
lastSeen: sequence,
|
|
180
|
+
};
|
|
181
|
+
existing.kinds[kind] = (existing.kinds[kind] ?? 0) + 1;
|
|
182
|
+
existing.sources.add(source);
|
|
183
|
+
existing.lastSeen = sequence;
|
|
184
|
+
files.set(file, existing);
|
|
185
|
+
},
|
|
186
|
+
tick() {
|
|
187
|
+
sequence += 1;
|
|
188
|
+
},
|
|
189
|
+
values() {
|
|
190
|
+
return [...files.values()].map((entry) => ({
|
|
191
|
+
...entry,
|
|
192
|
+
sources: [...entry.sources].slice(0, 8),
|
|
193
|
+
}));
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function toolKind(name, input) {
|
|
199
|
+
if (["Write", "Edit", "MultiEdit", "NotebookEdit"].includes(name)) return "written";
|
|
200
|
+
if (name === "Read") return "read";
|
|
201
|
+
if (["Grep", "Glob", "LS"].includes(name)) return "discovered";
|
|
202
|
+
if (name === "Bash") {
|
|
203
|
+
const command = input?.command ?? "";
|
|
204
|
+
if (/\b(apply_patch|tee|touch|mkdir|mv|cp|rm)\b|(^|[^>])>{1,2}[^>]/.test(command)) return "shell-write";
|
|
205
|
+
return "shell-mentioned";
|
|
206
|
+
}
|
|
207
|
+
return "mentioned";
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function scoreFile(entry) {
|
|
211
|
+
const ext = path.extname(entry.path).toLowerCase();
|
|
212
|
+
let score = 0;
|
|
213
|
+
if (entry.kinds.written) score += 40;
|
|
214
|
+
if (entry.kinds["shell-write"]) score += 30;
|
|
215
|
+
if (entry.kinds["file-history"]) score += 35;
|
|
216
|
+
if (ext === ".md" || ext === ".mdx") score += 20;
|
|
217
|
+
if (entry.kinds.read) score += 10;
|
|
218
|
+
if (entry.kinds.discovered) score += 4;
|
|
219
|
+
if (/\/docs\/as-built\//.test(entry.path)) score += 25;
|
|
220
|
+
if (/(codemap|architecture|CLAUDE|AGENTS|README|DESIGN|CULTURE|session\.log|queue\.md)/i.test(entry.path)) score += 15;
|
|
221
|
+
score += Math.min(10, Object.values(entry.kinds).reduce((a, b) => a + b, 0));
|
|
222
|
+
return score;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function discoverDocs(cwd) {
|
|
226
|
+
const candidates = [
|
|
227
|
+
"CLAUDE.md",
|
|
228
|
+
"AGENTS.md",
|
|
229
|
+
"README.md",
|
|
230
|
+
"docs/as-built",
|
|
231
|
+
"docs",
|
|
232
|
+
];
|
|
233
|
+
const docs = new Set();
|
|
234
|
+
|
|
235
|
+
for (const candidate of candidates) {
|
|
236
|
+
const full = path.resolve(cwd, candidate);
|
|
237
|
+
if (!fs.existsSync(full)) continue;
|
|
238
|
+
const stat = fs.statSync(full);
|
|
239
|
+
if (stat.isFile()) docs.add(full);
|
|
240
|
+
if (stat.isDirectory()) {
|
|
241
|
+
const result = spawnSync("find", [full, "-maxdepth", candidate === "docs" ? "2" : "1", "-type", "f", "-name", "*.md"], {
|
|
242
|
+
encoding: "utf8",
|
|
243
|
+
});
|
|
244
|
+
for (const file of result.stdout.split(/\r?\n/).filter(Boolean)) {
|
|
245
|
+
if (/as-built|codemap|architecture|README|overview/i.test(file)) docs.add(path.normalize(file));
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return [...docs].sort();
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function analyze(jsonlPath, cwd) {
|
|
254
|
+
const records = readJsonLines(jsonlPath);
|
|
255
|
+
const registry = createRegistry();
|
|
256
|
+
const transcript = [];
|
|
257
|
+
const narrative = []; // R4: message-turns only (assistant/user text), no tool bodies
|
|
258
|
+
const readTargets = new Map(); // R1: tool_use_id -> file_path for Read calls
|
|
259
|
+
const cwdCounts = new Map();
|
|
260
|
+
let sessionId = null;
|
|
261
|
+
|
|
262
|
+
for (const record of records) {
|
|
263
|
+
registry.tick();
|
|
264
|
+
if (record.sessionId || record.session_id) sessionId = record.sessionId ?? record.session_id;
|
|
265
|
+
if (record.cwd) {
|
|
266
|
+
cwdCounts.set(record.cwd, (cwdCounts.get(record.cwd) ?? 0) + 1);
|
|
267
|
+
cwd = record.cwd;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (record.type === "file-history-snapshot") {
|
|
271
|
+
const backups = record.snapshot?.trackedFileBackups ?? {};
|
|
272
|
+
for (const file of Object.keys(backups)) registry.add(path.normalize(file), "file-history", "file-history-snapshot");
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const message = record.message;
|
|
276
|
+
if (!message) continue;
|
|
277
|
+
const role = message.role ?? record.type ?? "unknown";
|
|
278
|
+
const content = message.content;
|
|
279
|
+
|
|
280
|
+
if (typeof content === "string") {
|
|
281
|
+
transcript.push(`\n## ${role}\n\n${content}`);
|
|
282
|
+
narrative.push(`\n## ${role}\n\n${content}`);
|
|
283
|
+
for (const file of extractPaths(content, cwd)) registry.add(file, "mentioned", `${role}:text`);
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (!Array.isArray(content)) continue;
|
|
288
|
+
const parts = [];
|
|
289
|
+
const narrativeParts = [];
|
|
290
|
+
for (const block of content) {
|
|
291
|
+
if (block?.type === "text") {
|
|
292
|
+
parts.push(block.text ?? "");
|
|
293
|
+
narrativeParts.push(block.text ?? "");
|
|
294
|
+
for (const file of extractPaths(block.text ?? "", cwd)) registry.add(file, "mentioned", `${role}:text`);
|
|
295
|
+
} else if (block?.type === "tool_use") {
|
|
296
|
+
const name = block.name ?? "unknown";
|
|
297
|
+
const input = block.input ?? {};
|
|
298
|
+
parts.push(`\n[tool_use:${name}]\n${JSON.stringify(input, null, 2)}`);
|
|
299
|
+
if (name === "Read" && block.id && (input.file_path || input.path)) {
|
|
300
|
+
readTargets.set(block.id, input.file_path || input.path);
|
|
301
|
+
}
|
|
302
|
+
const kind = toolKind(name, input);
|
|
303
|
+
if (input.file_path) registry.add(normalizeFile(input.file_path, cwd), kind, `tool:${name}:file_path`);
|
|
304
|
+
if (input.path) registry.add(normalizeFile(input.path, cwd), kind, `tool:${name}:path`);
|
|
305
|
+
if (input.notebook_path) registry.add(normalizeFile(input.notebook_path, cwd), kind, `tool:${name}:notebook_path`);
|
|
306
|
+
for (const text of walkStrings(input)) {
|
|
307
|
+
for (const file of extractPaths(text, cwd)) registry.add(file, kind, `tool:${name}:input`);
|
|
308
|
+
}
|
|
309
|
+
} else if (block?.type === "tool_result") {
|
|
310
|
+
const resultText = stripBinary(stringifyContent(block.content));
|
|
311
|
+
const target = block.tool_use_id && readTargets.get(block.tool_use_id);
|
|
312
|
+
if (target) {
|
|
313
|
+
// R1: a Read result reproduces a whole file — emit a pointer, not the body.
|
|
314
|
+
// The live file is current; this transcript copy is a snapshot that may be stale.
|
|
315
|
+
const lineCount = resultText.split("\n").length;
|
|
316
|
+
parts.push(`\n[tool_result: Read ${target} — ${lineCount} lines, sha256 ${sha256(resultText)} — READ THE LIVE FILE; this snapshot may be stale]`);
|
|
317
|
+
} else {
|
|
318
|
+
parts.push(`\n[tool_result]\n${truncate(resultText, TEXT_LIMIT)}`);
|
|
319
|
+
}
|
|
320
|
+
for (const file of extractPaths(resultText, cwd)) registry.add(file, "mentioned", "tool_result");
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (parts.length) transcript.push(`\n## ${role}\n\n${parts.join("\n")}`);
|
|
324
|
+
if (narrativeParts.some((p) => String(p).trim())) narrative.push(`\n## ${role}\n\n${narrativeParts.join("\n")}`);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const rankedFiles = registry
|
|
328
|
+
.values()
|
|
329
|
+
.map((entry) => ({ ...entry, score: scoreFile(entry), markdown: [".md", ".mdx"].includes(path.extname(entry.path).toLowerCase()) }))
|
|
330
|
+
.sort((a, b) => b.score - a.score || a.path.localeCompare(b.path));
|
|
331
|
+
|
|
332
|
+
const cwdRanked = [...cwdCounts.entries()].sort((a, b) => b[1] - a[1]);
|
|
333
|
+
const effectiveCwd = cwdRanked[0]?.[0] ?? cwd;
|
|
334
|
+
|
|
335
|
+
const transcriptText = transcript.join("\n");
|
|
336
|
+
const narrativeText = narrative.join("\n");
|
|
337
|
+
return {
|
|
338
|
+
sessionId,
|
|
339
|
+
jsonlPath,
|
|
340
|
+
cwd: effectiveCwd,
|
|
341
|
+
records: records.length,
|
|
342
|
+
transcript: transcriptText,
|
|
343
|
+
narrative: narrativeText,
|
|
344
|
+
transcriptTokens: Math.round(transcriptText.length / 4),
|
|
345
|
+
narrativeTokens: Math.round(narrativeText.length / 4),
|
|
346
|
+
files: rankedFiles,
|
|
347
|
+
docs: discoverDocs(effectiveCwd),
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function markdownFileList(files) {
|
|
352
|
+
const lines = [];
|
|
353
|
+
lines.push("# Touched Files");
|
|
354
|
+
lines.push("");
|
|
355
|
+
lines.push("Files are ranked for restore relevance. Markdown and written files are the first candidates to read in full.");
|
|
356
|
+
lines.push("");
|
|
357
|
+
|
|
358
|
+
const sections = [
|
|
359
|
+
["Highest-priority Markdown/state files", (f) => f.markdown && (f.kinds.written || f.kinds["shell-write"] || f.kinds["file-history"])],
|
|
360
|
+
["Other written/tracked files", (f) => !f.markdown && (f.kinds.written || f.kinds["shell-write"] || f.kinds["file-history"])],
|
|
361
|
+
["Read/discovered/mentioned files", (f) => !(f.kinds.written || f.kinds["shell-write"] || f.kinds["file-history"])],
|
|
362
|
+
];
|
|
363
|
+
|
|
364
|
+
for (const [title, predicate] of sections) {
|
|
365
|
+
const group = files.filter(predicate);
|
|
366
|
+
if (!group.length) continue;
|
|
367
|
+
lines.push(`## ${title}`);
|
|
368
|
+
lines.push("");
|
|
369
|
+
for (const file of group) {
|
|
370
|
+
const kinds = Object.entries(file.kinds).map(([kind, count]) => `${kind}:${count}`).join(", ");
|
|
371
|
+
lines.push(`- score ${file.score} — \`${file.path}\` — ${kinds}`);
|
|
372
|
+
}
|
|
373
|
+
lines.push("");
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return lines.join("\n");
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
function restoreInstructions(summary, outputPaths) {
|
|
380
|
+
const lines = [];
|
|
381
|
+
lines.push("# Claude Compaction Restore Instructions");
|
|
382
|
+
lines.push("");
|
|
383
|
+
lines.push("You have just been compacted or are restoring a compacted Claude Code seat. Your mental model is compressed and unreliable.");
|
|
384
|
+
lines.push("");
|
|
385
|
+
lines.push(`- JSONL transcript: \`${summary.jsonlPath}\``);
|
|
386
|
+
lines.push(`- Reconstructed transcript: \`${outputPaths.transcript}\` (~${summary.transcriptTokens ?? "?"} tokens — do NOT read front-to-back)`);
|
|
387
|
+
lines.push(`- Narrative companion (READ THIS FIRST): \`${outputPaths.narrative}\` (~${summary.narrativeTokens ?? "?"} tokens — message turns only, no tool bodies)`);
|
|
388
|
+
lines.push(`- Touched-file triage: \`${outputPaths.touchedFiles}\``);
|
|
389
|
+
lines.push(`- Working directory inferred: \`${summary.cwd}\``);
|
|
390
|
+
lines.push("");
|
|
391
|
+
lines.push("## Read budget (the restore must leave room for the work)");
|
|
392
|
+
lines.push("");
|
|
393
|
+
lines.push(`- The full transcript is ~${summary.transcriptTokens ?? "?"} tokens. **Reading it front-to-back can consume the window the restore exists to rebuild.**`);
|
|
394
|
+
lines.push(`- Default order: read the **narrative companion first** (~${summary.narrativeTokens ?? "?"} tokens — message turns + decisions), tail-first (most recent first).`);
|
|
395
|
+
lines.push("- Drop to the full transcript only for a specific question the narrative can't answer. File bodies inside tool-results are pointers now — **read the live file, not the transcript snapshot.**");
|
|
396
|
+
lines.push("- Read to a budget with a stopping rule; report depth honestly (an honest PARTIAL beats a false completion). See the skill's *Required Read-Depth Audit*.");
|
|
397
|
+
lines.push("");
|
|
398
|
+
lines.push("## Required Sequence");
|
|
399
|
+
lines.push("");
|
|
400
|
+
lines.push("1. Read this file and `touched-files.md`.");
|
|
401
|
+
lines.push("2. Ask yourself: which files do I recognize as important to the work and project state?");
|
|
402
|
+
lines.push("3. Mark those files mentally or in a short note.");
|
|
403
|
+
lines.push("4. Read every important Markdown/state/planning file in full.");
|
|
404
|
+
lines.push("5. Read project root docs in full when present: `CLAUDE.md`, `AGENTS.md`, `README.md`.");
|
|
405
|
+
lines.push("6. Read as-built docs and codemaps in full before product work, code review, or architecture decisions.");
|
|
406
|
+
lines.push("7. State exactly: `restored from packet at <path>; resumed at step <X>`.");
|
|
407
|
+
lines.push("");
|
|
408
|
+
lines.push("## Documentation Candidates");
|
|
409
|
+
lines.push("");
|
|
410
|
+
if (summary.docs.length) {
|
|
411
|
+
for (const doc of summary.docs) lines.push(`- \`${doc}\``);
|
|
412
|
+
} else {
|
|
413
|
+
lines.push("- No root/as-built/codemap candidates were found automatically. Search manually before resuming code/review work.");
|
|
414
|
+
}
|
|
415
|
+
lines.push("");
|
|
416
|
+
lines.push("## Top File Candidates");
|
|
417
|
+
lines.push("");
|
|
418
|
+
for (const file of summary.files.slice(0, 30)) {
|
|
419
|
+
lines.push(`- \`${file.path}\` — score ${file.score}`);
|
|
420
|
+
}
|
|
421
|
+
lines.push("");
|
|
422
|
+
lines.push("Do not continue from fuzzy memory alone.");
|
|
423
|
+
return lines.join("\n");
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function writeOutputs(summary, outRoot) {
|
|
427
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
428
|
+
const base = path.join(outRoot, `${summary.sessionId ?? "unknown-session"}-${stamp}`);
|
|
429
|
+
fs.mkdirSync(base, { recursive: true });
|
|
430
|
+
|
|
431
|
+
const outputPaths = {
|
|
432
|
+
dir: base,
|
|
433
|
+
transcript: path.join(base, "transcript.txt"),
|
|
434
|
+
narrative: path.join(base, "transcript-narrative.txt"),
|
|
435
|
+
touchedFiles: path.join(base, "touched-files.md"),
|
|
436
|
+
instructions: path.join(base, "restore-instructions.md"),
|
|
437
|
+
summary: path.join(base, "restore-summary.json"),
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
fs.writeFileSync(outputPaths.transcript, summary.transcript || "(no message transcript reconstructed)\n");
|
|
441
|
+
fs.writeFileSync(outputPaths.narrative, summary.narrative || "(no narrative reconstructed)\n");
|
|
442
|
+
fs.writeFileSync(outputPaths.touchedFiles, markdownFileList(summary.files));
|
|
443
|
+
fs.writeFileSync(outputPaths.instructions, restoreInstructions(summary, outputPaths));
|
|
444
|
+
fs.writeFileSync(outputPaths.summary, JSON.stringify({ ...summary, transcript: undefined, narrative: undefined, outputPaths }, null, 2));
|
|
445
|
+
|
|
446
|
+
return outputPaths;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
function main() {
|
|
450
|
+
const args = parseArgs(process.argv.slice(2));
|
|
451
|
+
const cwd = path.resolve(args.cwd);
|
|
452
|
+
const jsonlPath = args.jsonl ? path.resolve(args.jsonl) : findLatestJsonl(cwd);
|
|
453
|
+
if (!jsonlPath) throw new Error("could not find a Claude JSONL transcript; pass one explicitly");
|
|
454
|
+
if (!fs.existsSync(jsonlPath)) throw new Error(`JSONL transcript not found: ${jsonlPath}`);
|
|
455
|
+
|
|
456
|
+
const summary = analyze(jsonlPath, cwd);
|
|
457
|
+
const outputPaths = writeOutputs(summary, path.resolve(args.out));
|
|
458
|
+
const result = {
|
|
459
|
+
ok: true,
|
|
460
|
+
jsonlPath,
|
|
461
|
+
outputDir: outputPaths.dir,
|
|
462
|
+
transcript: outputPaths.transcript,
|
|
463
|
+
narrative: outputPaths.narrative,
|
|
464
|
+
transcriptTokens: summary.transcriptTokens,
|
|
465
|
+
narrativeTokens: summary.narrativeTokens,
|
|
466
|
+
touchedFiles: outputPaths.touchedFiles,
|
|
467
|
+
instructions: outputPaths.instructions,
|
|
468
|
+
fileCount: summary.files.length,
|
|
469
|
+
topFiles: summary.files.slice(0, 12).map((file) => file.path),
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
if (args.json) console.log(JSON.stringify(result, null, 2));
|
|
473
|
+
else {
|
|
474
|
+
console.log(`Restore packet: ${result.outputDir}`);
|
|
475
|
+
console.log(`Instructions: ${result.instructions}`);
|
|
476
|
+
console.log(`Touched files: ${result.touchedFiles}`);
|
|
477
|
+
console.log(`Narrative (read first): ${result.narrative} (~${result.narrativeTokens} tokens)`);
|
|
478
|
+
console.log(`Transcript (drill-down): ${result.transcript} (~${result.transcriptTokens} tokens)`);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
try {
|
|
483
|
+
main();
|
|
484
|
+
} catch (error) {
|
|
485
|
+
console.error(`claude-compaction-restore failed: ${error.message}`);
|
|
486
|
+
process.exit(1);
|
|
487
|
+
}
|
package/daemon/context-packs/skills/claude-compaction-restore/templates/compact-instruction.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Optional. Leave blank to use Claude Code's native compaction summary behavior; OpenRig's pre-compaction preparation and post-compaction restore prompts carry the durable continuity protocol.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Read the claude-compaction-restore skill and follow its "If You Just Compacted" protocol.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# GENERATED by scripts/generate-context-packs.mjs — DO NOT EDIT.
|
|
2
2
|
# Package-time projection of a canonical skill; regenerated every build.
|
|
3
3
|
name: "agent-starters"
|
|
4
|
-
version: "0.5.
|
|
4
|
+
version: "0.5.7"
|
|
5
5
|
taxonomy: "skills"
|
|
6
6
|
purpose: "Use when creating, refreshing, packaging, inspecting, promoting, or deprecating a named per-seat starting point — Agent Starter manifest authoring, the 6-state lifecycle (captured → named → inspectable → used → promoted → deprecated), provenance honesty, and refusal rules. NOT a VM image; a managed starting point composed from agent role + startup context + optional native session source + provenance."
|
|
7
7
|
files:
|
|
@@ -102,7 +102,7 @@ culture / pod / member / operator) handles the layering.
|
|
|
102
102
|
|
|
103
103
|
## See also
|
|
104
104
|
|
|
105
|
-
- `mission-slice-sop` skill — the universal operating procedure for working a mission/slice (the canonical PROGRESS
|
|
105
|
+
- `mission-slice-sop` skill — the universal operating procedure for working a mission/slice (the canonical SPEC.md, NOTES.md, PROGRESS.md, PROOF.md, and proof/ surfaces); every agent should reach for it at startup, so this general reading contract points at it here (do NOT duplicate the SOP into seat-specific startup files).
|
|
106
106
|
- `writing-skills-for-openrig` skill — authoring discipline for skill content (what doesn't belong in startup)
|
|
107
107
|
- `forming-an-openrig-mental-model` skill — orientation for new agents
|
|
108
108
|
- `session-compaction-and-restore` skill — restore-time startup ingestion
|