@zerwiz/ymir 0.1.4 → 0.1.5
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/.agents/README.md +291 -0
- package/.agents/agents/bragi-marketer.md +111 -0
- package/.agents/agents/brokk.md +352 -0
- package/.agents/agents/forseti-reviewer.md +93 -0
- package/.agents/agents/frigg-consent.md +77 -0
- package/.agents/agents/groa-update.md +77 -0
- package/.agents/agents/hnoss-designer.md +69 -0
- package/.agents/agents/huginn-researcher.md +99 -0
- package/.agents/agents/jord-projects.md +78 -0
- package/.agents/agents/kvasir-scout.md +91 -0
- package/.agents/agents/mimir-planner.md +92 -0
- package/.agents/agents/muninn-stow.md +77 -0
- package/.agents/agents/saga-bearings.md +78 -0
- package/.agents/agents/sindri-developer.md +114 -0
- package/.agents/agents/snotra-documenter.md +105 -0
- package/.agents/agents/syn-recovery.md +78 -0
- package/.agents/agents/tyr-check.md +78 -0
- package/.agents/agents/urdh-hold.md +77 -0
- package/.agents/agents/volundr-smith.md +80 -0
- package/.agents/agents/vor-diagnostics.md +77 -0
- package/.agents/assets/agents/naming.md +50 -0
- package/.agents/assets/agents/registry.md +93 -0
- package/.agents/assets/agents/runtime.md +36 -0
- package/.agents/assets/agents/toon-tasks-cli.md +42 -0
- package/.agents/assets/templates/company_entity.template.md +37 -0
- package/.agents/backend/backends/cmux.sh +649 -0
- package/.agents/backend/backends/herdr-eventwait.py +157 -0
- package/.agents/backend/backends/herdr-workspace-move.py +114 -0
- package/.agents/backend/backends/herdr.sh +3386 -0
- package/.agents/backend/backends/orca.sh +290 -0
- package/.agents/backend/backends/tmux.sh +357 -0
- package/.agents/backend/backends/zellij.sh +700 -0
- package/.agents/backend/fm-afk-launch.sh +654 -0
- package/.agents/backend/fm-afk-return.sh +241 -0
- package/.agents/backend/fm-afk-start.sh +172 -0
- package/.agents/backend/fm-arm-command-policy.mjs +960 -0
- package/.agents/backend/fm-arm-pretool-check.sh +200 -0
- package/.agents/backend/fm-backend-hometag-lib.sh +52 -0
- package/.agents/backend/fm-backend.sh +981 -0
- package/.agents/backend/fm-backlog-handoff.sh +909 -0
- package/.agents/backend/fm-backlog-receive.sh +187 -0
- package/.agents/backend/fm-backlog-transition-lib.sh +779 -0
- package/.agents/backend/fm-bearings-board.sh +204 -0
- package/.agents/backend/fm-bearings-snapshot.sh +546 -0
- package/.agents/backend/fm-bootstrap.sh +1568 -0
- package/.agents/backend/fm-branch-outcome.sh +203 -0
- package/.agents/backend/fm-branch-prompt.sh +101 -0
- package/.agents/backend/fm-brief.sh +452 -0
- package/.agents/backend/fm-busy-event.sh +234 -0
- package/.agents/backend/fm-busy-lib.sh +986 -0
- package/.agents/backend/fm-captain-hold.sh +1001 -0
- package/.agents/backend/fm-cd-command-policy.mjs +153 -0
- package/.agents/backend/fm-cd-pretool-check.sh +190 -0
- package/.agents/backend/fm-check-lib.sh +74 -0
- package/.agents/backend/fm-check-register.sh +42 -0
- package/.agents/backend/fm-check-unregister.sh +52 -0
- package/.agents/backend/fm-classify-lib.sh +1770 -0
- package/.agents/backend/fm-claude-stop-autoarm.sh +334 -0
- package/.agents/backend/fm-composer-lib.sh +1416 -0
- package/.agents/backend/fm-config-inherit-lib.sh +1202 -0
- package/.agents/backend/fm-config-push.sh +254 -0
- package/.agents/backend/fm-control-lib.sh +251 -0
- package/.agents/backend/fm-control.sh +878 -0
- package/.agents/backend/fm-crew-state.sh +625 -0
- package/.agents/backend/fm-cursor-lib.sh +243 -0
- package/.agents/backend/fm-decision-hold.sh +232 -0
- package/.agents/backend/fm-doc-audience-check.sh +269 -0
- package/.agents/backend/fm-dod-lib.sh +67 -0
- package/.agents/backend/fm-ensure-agents-md.sh +253 -0
- package/.agents/backend/fm-extension-launch-barrier.mjs +129 -0
- package/.agents/backend/fm-extension.mjs +2577 -0
- package/.agents/backend/fm-extension.sh +16 -0
- package/.agents/backend/fm-ff-lib.sh +420 -0
- package/.agents/backend/fm-fleet-snapshot.sh +1463 -0
- package/.agents/backend/fm-fleet-sync.sh +458 -0
- package/.agents/backend/fm-fleet-view.sh +96 -0
- package/.agents/backend/fm-gate-refuse-lib.sh +102 -0
- package/.agents/backend/fm-guard.sh +242 -0
- package/.agents/backend/fm-harness.sh +195 -0
- package/.agents/backend/fm-herdr-ci-cleanup.sh +115 -0
- package/.agents/backend/fm-herdr-lab.sh +346 -0
- package/.agents/backend/fm-herdr-session-cleanup.sh +337 -0
- package/.agents/backend/fm-home-seed.sh +984 -0
- package/.agents/backend/fm-home-summary-refresh.sh +255 -0
- package/.agents/backend/fm-hook-host-lib.sh +36 -0
- package/.agents/backend/fm-inactive-reconcile.sh +531 -0
- package/.agents/backend/fm-inbox.sh +399 -0
- package/.agents/backend/fm-install-actionlint.sh +84 -0
- package/.agents/backend/fm-install-herdr.sh +96 -0
- package/.agents/backend/fm-install-shellcheck.sh +84 -0
- package/.agents/backend/fm-install-treehouse.sh +95 -0
- package/.agents/backend/fm-kimi-turnend-hook.sh +276 -0
- package/.agents/backend/fm-lease-lib.sh +218 -0
- package/.agents/backend/fm-lease.sh +189 -0
- package/.agents/backend/fm-line-cap-lib.sh +51 -0
- package/.agents/backend/fm-lint-workflows.sh +137 -0
- package/.agents/backend/fm-lint.sh +591 -0
- package/.agents/backend/fm-lock-lib.sh +104 -0
- package/.agents/backend/fm-lock.sh +107 -0
- package/.agents/backend/fm-marker-lib.sh +12 -0
- package/.agents/backend/fm-merge-local.sh +74 -0
- package/.agents/backend/fm-merge-outcome-lib.sh +138 -0
- package/.agents/backend/fm-nm-run-lib.sh +124 -0
- package/.agents/backend/fm-on.sh +125 -0
- package/.agents/backend/fm-operational-input.sh +253 -0
- package/.agents/backend/fm-peek.sh +46 -0
- package/.agents/backend/fm-pending-reply-lib.sh +1409 -0
- package/.agents/backend/fm-pr-check.sh +135 -0
- package/.agents/backend/fm-pr-lib.sh +1016 -0
- package/.agents/backend/fm-pr-merge.sh +707 -0
- package/.agents/backend/fm-pr-poll.sh +110 -0
- package/.agents/backend/fm-primary-scope-lib.sh +33 -0
- package/.agents/backend/fm-procevent-extension-capture.pl +259 -0
- package/.agents/backend/fm-procevent-lavish.sh +628 -0
- package/.agents/backend/fm-procevent-lib.sh +892 -0
- package/.agents/backend/fm-procevent-quota.sh +290 -0
- package/.agents/backend/fm-procevent-remote-reply.sh +577 -0
- package/.agents/backend/fm-procevent-when.sh +504 -0
- package/.agents/backend/fm-procevent.sh +1466 -0
- package/.agents/backend/fm-project-mode.sh +92 -0
- package/.agents/backend/fm-project-origin-lib.sh +180 -0
- package/.agents/backend/fm-promote.sh +282 -0
- package/.agents/backend/fm-public-followup-emit.sh +260 -0
- package/.agents/backend/fm-public-followup-lib.sh +398 -0
- package/.agents/backend/fm-public-followup.sh +1330 -0
- package/.agents/backend/fm-push-transition-lib.sh +168 -0
- package/.agents/backend/fm-quota-axi-lib.sh +93 -0
- package/.agents/backend/fm-quota-choose.sh +384 -0
- package/.agents/backend/fm-remote-delta-read.sh +189 -0
- package/.agents/backend/fm-remote-doctor.sh +800 -0
- package/.agents/backend/fm-remote-entrypoint.sh +193 -0
- package/.agents/backend/fm-remote-file.sh +234 -0
- package/.agents/backend/fm-remote-home-provision.sh +259 -0
- package/.agents/backend/fm-remote-home-seed.sh +259 -0
- package/.agents/backend/fm-remote-inherit-push.sh +90 -0
- package/.agents/backend/fm-remote-inherit.sh +179 -0
- package/.agents/backend/fm-remote-job-lib.sh +1241 -0
- package/.agents/backend/fm-remote-job-reap-orphans.sh +137 -0
- package/.agents/backend/fm-remote-job-worker.sh +1124 -0
- package/.agents/backend/fm-remote-readiness-lib.sh +44 -0
- package/.agents/backend/fm-remote-secondmate-control.sh +340 -0
- package/.agents/backend/fm-review-diff.sh +158 -0
- package/.agents/backend/fm-secondmate-charter-lib.sh +44 -0
- package/.agents/backend/fm-secondmate-nudge-lib.sh +68 -0
- package/.agents/backend/fm-secondmate-parent-lib.sh +70 -0
- package/.agents/backend/fm-secondmate-reconcile.sh +371 -0
- package/.agents/backend/fm-secondmate-registry-lib.sh +311 -0
- package/.agents/backend/fm-secondmate-report.sh +88 -0
- package/.agents/backend/fm-send.sh +1059 -0
- package/.agents/backend/fm-session-lock-lib.sh +176 -0
- package/.agents/backend/fm-session-start.sh +970 -0
- package/.agents/backend/fm-sessionstart-cursor.sh +40 -0
- package/.agents/backend/fm-sessionstart-nudge.sh +45 -0
- package/.agents/backend/fm-sessionstart-run.sh +145 -0
- package/.agents/backend/fm-spawn.sh +3153 -0
- package/.agents/backend/fm-startup-memory-budget-lib.sh +224 -0
- package/.agents/backend/fm-startup-memory-budget.sh +94 -0
- package/.agents/backend/fm-startup-network.sh +642 -0
- package/.agents/backend/fm-stow-cascade.sh +251 -0
- package/.agents/backend/fm-subagent-pretool-check.sh +207 -0
- package/.agents/backend/fm-supervise-daemon.sh +1732 -0
- package/.agents/backend/fm-supervision-instructions.sh +215 -0
- package/.agents/backend/fm-supervision-lib.sh +90 -0
- package/.agents/backend/fm-supervisor-target-lib.sh +78 -0
- package/.agents/backend/fm-tangle-lib.sh +53 -0
- package/.agents/backend/fm-task-inbox-lib.sh +402 -0
- package/.agents/backend/fm-tasks-axi-lib.sh +123 -0
- package/.agents/backend/fm-teardown.sh +2922 -0
- package/.agents/backend/fm-test-isolation-proof.sh +588 -0
- package/.agents/backend/fm-test-run.sh +2191 -0
- package/.agents/backend/fm-timeout-lib.sh +141 -0
- package/.agents/backend/fm-timing-lib.sh +179 -0
- package/.agents/backend/fm-tmux-lib.sh +291 -0
- package/.agents/backend/fm-tool-update-check.sh +898 -0
- package/.agents/backend/fm-trace-context-lib.sh +227 -0
- package/.agents/backend/fm-transition-lib.sh +103 -0
- package/.agents/backend/fm-turnend-guard-cursor.sh +391 -0
- package/.agents/backend/fm-turnend-guard-grok.sh +90 -0
- package/.agents/backend/fm-turnend-guard.sh +432 -0
- package/.agents/backend/fm-update.sh +110 -0
- package/.agents/backend/fm-vendor-auth-probe.sh +190 -0
- package/.agents/backend/fm-voice-client.py +1373 -0
- package/.agents/backend/fm-voice-relay.py +1256 -0
- package/.agents/backend/fm-wake-drain.sh +592 -0
- package/.agents/backend/fm-wake-grant.sh +127 -0
- package/.agents/backend/fm-wake-lib.sh +1849 -0
- package/.agents/backend/fm-watch-arm.sh +602 -0
- package/.agents/backend/fm-watch-checkpoint.sh +109 -0
- package/.agents/backend/fm-watch.sh +1962 -0
- package/.agents/backend/fm-x-dismiss.sh +116 -0
- package/.agents/backend/fm-x-followup.sh +286 -0
- package/.agents/backend/fm-x-lib.sh +1000 -0
- package/.agents/backend/fm-x-link.sh +234 -0
- package/.agents/backend/fm-x-poll.sh +185 -0
- package/.agents/backend/fm-x-reply.sh +385 -0
- package/.agents/backend/fm_voice_frame.py +166 -0
- package/.agents/backend/fm_voice_records.py +574 -0
- package/.agents/backend/model-bridge.py +290 -0
- package/.agents/backend/opencode-go-bridge.py +30 -0
- package/.agents/bus/README.md +12 -0
- package/.agents/bus/messages.json +1 -0
- package/.agents/config/agents.machine.example.yaml +16 -0
- package/.agents/config/agents.yaml +50 -0
- package/.agents/config/agents.yaml.example +72 -0
- package/.agents/config/crew-dispatch.json +22 -0
- package/.agents/config/cron.yaml +9 -0
- package/.agents/config/eindri-dispatch.json +67 -0
- package/.agents/config/eindri-harness +1 -0
- package/.agents/config/startup-memory-budget +1 -0
- package/.agents/config/tailscale-sync.yaml +27 -0
- package/.agents/filebrowser/.filebrowser.json +6 -0
- package/.agents/filebrowser/README.md +11 -0
- package/.agents/gateway/README.md +12 -0
- package/.agents/github/README.md +15 -0
- package/.agents/github/webhooks/.gitkeep +0 -0
- package/.agents/github/workflows/.gitkeep +0 -0
- package/.agents/harness/opencode/plugins/lib/rodd-operational-input.js +37 -0
- package/.agents/harness/opencode/plugins/package.json +4 -0
- package/.agents/harness/opencode/plugins/saga-sessionstart.js +77 -0
- package/.agents/harness/opencode/plugins/syn-cd-check.js +61 -0
- package/.agents/harness/opencode/plugins/syn-pretool-check.js +68 -0
- package/.agents/harness/opencode/plugins/syn-turnend-guard.js +105 -0
- package/.agents/harness/opencode/plugins/syn-watch-arm.js +521 -0
- package/.agents/memory/README.md +46 -0
- package/.agents/memory/kaia.engram +0 -0
- package/.agents/memory/kaia.engram-shm +0 -0
- package/.agents/memory/kaia.engram-wal +0 -0
- package/.agents/memory/runes_audit.md +5 -0
- package/.agents/memory/well/episodes.jsonl +367 -0
- package/.agents/memory/well/workspace.jsonl +27 -0
- package/.agents/migrations/0001-hodd-layout.sh +38 -0
- package/.agents/migrations/0002-a2a-mcp.sh +27 -0
- package/.agents/migrations/0003-private-data-separation.sh +111 -0
- package/.agents/migrations/0004-hoard-and-realms.sh +104 -0
- package/.agents/sandbox/Dockerfile.utgard +19 -0
- package/.agents/sandbox/README.md +14 -0
- package/.agents/sandbox/utgard.config.json +14 -0
- package/.agents/skills/README.md +59 -0
- package/.agents/skills/bragi-marketing/README.md +3 -0
- package/.agents/skills/bragi-marketing/SKILL.md +82 -0
- package/.agents/skills/eindri-homes/README.md +3 -0
- package/.agents/skills/eindri-homes/SKILL.md +291 -0
- package/.agents/skills/eindri-homes/assets/control-plane.md +122 -0
- package/.agents/skills/eindri-homes/assets/dispatch.md +80 -0
- package/.agents/skills/frigg-consent/README.md +3 -0
- package/.agents/skills/frigg-consent/SKILL.md +56 -0
- package/.agents/skills/galdr-ymirsystem/README.md +3 -0
- package/.agents/skills/galdr-ymirsystem/SKILL.md +158 -0
- package/.agents/skills/galdr-ymirsystem/assets/README.md +74 -0
- package/.agents/skills/galdr-ymirsystem/assets/brokk-distro-runtime.md +390 -0
- package/.agents/skills/galdr-ymirsystem/assets/build-method.md +113 -0
- package/.agents/skills/galdr-ymirsystem/assets/build-tool-categories.md +178 -0
- package/.agents/skills/galdr-ymirsystem/assets/eindri-orchestration.md +518 -0
- package/.agents/skills/galdr-ymirsystem/assets/eindri-profiles.md +136 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/README.md +673 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/claude-code.md +197 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/codex.md +191 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/cursor.md +193 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/opencode.md +262 -0
- package/.agents/skills/galdr-ymirsystem/assets/harness-integration/pi.md +295 -0
- package/.agents/skills/galdr-ymirsystem/assets/hlidskjalf-ui.md +496 -0
- package/.agents/skills/galdr-ymirsystem/assets/installation.md +571 -0
- package/.agents/skills/galdr-ymirsystem/assets/local-models/HOST-DATA.example.md +72 -0
- package/.agents/skills/galdr-ymirsystem/assets/local-models.md +274 -0
- package/.agents/skills/galdr-ymirsystem/assets/memory-well.md +161 -0
- package/.agents/skills/galdr-ymirsystem/assets/nornir-jobs.md +377 -0
- package/.agents/skills/galdr-ymirsystem/assets/norse-naming.md +325 -0
- package/.agents/skills/galdr-ymirsystem/assets/odrerir-hall.md +129 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/einherjar-spawn.schema.json +81 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/herdr-profile.toml +75 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/pi-profile.yml +96 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot/supervision-tree.yml +163 -0
- package/.agents/skills/galdr-ymirsystem/assets/pi-boot-guide.md +58 -0
- package/.agents/skills/galdr-ymirsystem/assets/porting-upstream-to-norse.md +301 -0
- package/.agents/skills/galdr-ymirsystem/assets/principles.md +385 -0
- package/.agents/skills/galdr-ymirsystem/assets/reference-adoption.md +99 -0
- package/.agents/skills/galdr-ymirsystem/assets/registry.md +379 -0
- package/.agents/skills/galdr-ymirsystem/assets/runtime-compliance.md +463 -0
- package/.agents/skills/galdr-ymirsystem/assets/runtime-components.md +553 -0
- package/.agents/skills/galdr-ymirsystem/assets/smidja.md +175 -0
- package/.agents/skills/galdr-ymirsystem/schemas/toon-schemas.md +190 -0
- package/.agents/skills/galdr-ymirsystem/scripts/README.md +45 -0
- package/.agents/skills/galdr-ymirsystem/scripts/bench-one.sh +248 -0
- package/.agents/skills/galdr-ymirsystem/scripts/compliance-check.sh +360 -0
- package/.agents/skills/galdr-ymirsystem/scripts/gpu-sample.sh +43 -0
- package/.agents/skills/galdr-ymirsystem/scripts/stop-all.sh +34 -0
- package/.agents/skills/galdr-ymirsystem/scripts/toon-check.py +188 -0
- package/.agents/skills/gjallarhorn-relay/README.md +3 -0
- package/.agents/skills/gjallarhorn-relay/SKILL.md +283 -0
- package/.agents/skills/groa-update/SKILL.md +70 -0
- package/.agents/skills/hamr-adapters/README.md +3 -0
- package/.agents/skills/hamr-adapters/SKILL.md +123 -0
- package/.agents/skills/hamr-adapters/references/common/control-and-recovery.md +37 -0
- package/.agents/skills/hamr-adapters/references/common/dispatch.md +32 -0
- package/.agents/skills/hamr-adapters/references/common/model-and-effort.md +42 -0
- package/.agents/skills/hamr-adapters/references/common/primary-hooks.md +40 -0
- package/.agents/skills/hamr-adapters/references/harness/claude.md +55 -0
- package/.agents/skills/hamr-adapters/references/harness/codex.md +43 -0
- package/.agents/skills/hamr-adapters/references/harness/cursor.md +75 -0
- package/.agents/skills/hamr-adapters/references/harness/grok.md +69 -0
- package/.agents/skills/hamr-adapters/references/harness/kimi.md +51 -0
- package/.agents/skills/hamr-adapters/references/harness/muse.md +70 -0
- package/.agents/skills/hamr-adapters/references/harness/opencode.md +42 -0
- package/.agents/skills/hamr-adapters/references/harness/pi.md +56 -0
- package/.agents/skills/herdr-panes/README.md +3 -0
- package/.agents/skills/herdr-panes/SKILL.md +92 -0
- package/.agents/skills/herdr-panes/assets/herdr-backend.md +346 -0
- package/.agents/skills/herdr-panes/assets/tmux-backend.md +115 -0
- package/.agents/skills/hnoss-design/DESIGN.md +19 -0
- package/.agents/skills/hnoss-design/README.md +3 -0
- package/.agents/skills/hnoss-design/SKILL.md +83 -0
- package/.agents/skills/hvild-afk/README.md +3 -0
- package/.agents/skills/hvild-afk/SKILL.md +241 -0
- package/.agents/skills/jord-projects/README.md +3 -0
- package/.agents/skills/jord-projects/SKILL.md +92 -0
- package/.agents/skills/lifecycle/SKILL.md +56 -0
- package/.agents/skills/lifecycle/smoke_test.sh +52 -0
- package/.agents/skills/lifecycle/start.sh +21 -0
- package/.agents/skills/lifecycle/status.sh +35 -0
- package/.agents/skills/lifecycle/stop.sh +16 -0
- package/.agents/skills/muninn-stow/README.md +3 -0
- package/.agents/skills/muninn-stow/SKILL.md +309 -0
- package/.agents/skills/no-mistakes/SKILL.md +379 -0
- package/.agents/skills/nornir-schedule/README.md +3 -0
- package/.agents/skills/nornir-schedule/SKILL.md +25 -0
- package/.agents/skills/nornir-schedule/assets/events.md +137 -0
- package/.agents/skills/nornir-schedule/assets/quota.md +131 -0
- package/.agents/skills/nsr-compliance/README.md +3 -0
- package/.agents/skills/nsr-compliance/SKILL.md +29 -0
- package/.agents/skills/nsr-compliance/assets/nsr/README.md +40 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/README.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/git-workflow.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/security.md +22 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/RULES/tech-stack.md +8 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/SKILL.md +71 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/config/core_four.yaml +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/validate_code.sh +29 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/gates/verify_docs.py +66 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/generate.sh +109 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/NSRcompliance/templates/compliance/telemetry/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/README.md +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/README.md +36 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/features/SKILL-template.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/README.md +25 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/SKILL.md +13 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/create_branch.sh +6 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/safe_commit.sh +9 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/git_ops/sync_upstream.sh +6 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/README.md +27 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/SKILL.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/smoke_test.sh +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/start.sh +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/status.sh +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/agents_skills/lifecycle/stop.sh +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/config/core_four.yaml +13 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/compliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/README.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/api.md +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/compliance-wiring.md +155 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/BEST_PRACTICES/frontend.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/README.md +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/README.md +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/clients/template-README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/deploy.sh +49 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/development.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/production.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/envs/staging.env.example +17 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/CI_CD/deployment/tenants/template.env.example +8 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/README.md +26 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/agent.md +7 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/developers/dev-1.md +20 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/linux.md +9 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/macos.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/shared.md +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/DEVELOPER_SETUP/windows.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/README.md +25 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/_template.md +41 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/HOSTING/hosting-1.md +41 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/README.md +21 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/README.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/deployment.md +19 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/disaster-recovery.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/RUNBOOK/ops-tasks.md +14 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/features/README.md +16 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/project-skills.md +146 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/research/software-compliance-research.md +269 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/docs/working-with-agents.md +260 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/AGENTS.md +38 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/ARCHITECTURE.md +36 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/BEST_PRACTICES.md +27 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/CI_CD.md +23 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/FEATURES.md +15 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/README.md +22 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/RULES.md +37 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/STRUCTURE.md +45 -0
- package/.agents/skills/nsr-compliance/assets/nsr/assets/root/TECH_STACK.md +28 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scaffold-spec.md +63 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scripts/scaffold.sh +103 -0
- package/.agents/skills/nsr-compliance/assets/nsr/scripts/validate.sh +52 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/SKILL.md +71 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/config/core_four.yaml +16 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_danger.sh +102 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/check_wiring.sh +69 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/validate_code.sh +29 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/gates/verify_docs.py +66 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/generate.sh +109 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/result_envelope.json +14 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/envelopes/task_envelope.json +20 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/harness/runner.py +303 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/telemetry/logger.py +112 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/README.md +18 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/config/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/README.md +12 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_env.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_paths.sh +20 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/gates/check_platform.sh +23 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/README.md +11 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/harness/envelopes/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/README.md +10 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/installer/install.sh +125 -0
- package/.agents/skills/nsr-compliance/assets/nsrcompliance/templates/compliance/telemetry/README.md +11 -0
- package/.agents/skills/pr-ops/README.md +3 -0
- package/.agents/skills/pr-ops/SKILL.md +109 -0
- package/.agents/skills/ratatoskr-a2a/README.md +3 -0
- package/.agents/skills/ratatoskr-a2a/SKILL.md +148 -0
- package/.agents/skills/rules-check-drift/SKILL.md +81 -0
- package/.agents/skills/saga-bearings/README.md +3 -0
- package/.agents/skills/saga-bearings/SKILL.md +26 -0
- package/.agents/skills/saga-bearings/assets/bearings.md +161 -0
- package/.agents/skills/saga-bearings/assets/board-template.html +731 -0
- package/.agents/skills/saga-bearings/assets/recap.md +56 -0
- package/.agents/skills/syn-recovery/README.md +3 -0
- package/.agents/skills/syn-recovery/SKILL.md +54 -0
- package/.agents/skills/tyr-check/README.md +3 -0
- package/.agents/skills/tyr-check/SKILL.md +218 -0
- package/.agents/skills/urdh-hold/README.md +3 -0
- package/.agents/skills/urdh-hold/SKILL.md +25 -0
- package/.agents/skills/urdh-hold/assets/decisions.md +15 -0
- package/.agents/skills/urdh-hold/assets/hold.md +54 -0
- package/.agents/skills/vor-diagnostics/README.md +3 -0
- package/.agents/skills/vor-diagnostics/SKILL.md +68 -0
- package/.agents/skills/ymir-host/README.md +3 -0
- package/.agents/skills/ymir-host/SKILL.md +34 -0
- package/.agents/skills/ymir-host/assets/desktop.md +36 -0
- package/.agents/skills/ymir-host/assets/omarchy.md +297 -0
- package/.agents/skills/ymir-host/assets/runbooks.md +15 -0
- package/.agents/skills/ymir-host/assets/thjazi.md +220 -0
- package/.agents/skills/ymir-host/assets/update.md +64 -0
- package/.agents/tests/assets/board-render-harness.mjs +117 -0
- package/.agents/tests/cmux-test-safety.sh +51 -0
- package/.agents/tests/fixtures.sh +291 -0
- package/.agents/tests/fm-afk-inject-e2e.test.sh +428 -0
- package/.agents/tests/fm-afk-inject-herdr-e2e.test.sh +536 -0
- package/.agents/tests/fm-afk-launch.test.sh +961 -0
- package/.agents/tests/fm-afk-pi-herdr-return-e2e.test.sh +297 -0
- package/.agents/tests/fm-afk-return.test.sh +283 -0
- package/.agents/tests/fm-arm-pretool-check.test.sh +482 -0
- package/.agents/tests/fm-ask-user-authority.test.sh +42 -0
- package/.agents/tests/fm-backend-autodetect-smoke.test.sh +176 -0
- package/.agents/tests/fm-backend-cmux-smoke.test.sh +188 -0
- package/.agents/tests/fm-backend-cmux.test.sh +1166 -0
- package/.agents/tests/fm-backend-herdr-eventwait-smoke.test.sh +136 -0
- package/.agents/tests/fm-backend-herdr-eventwait.test.py +106 -0
- package/.agents/tests/fm-backend-herdr-focus-flash-e2e.test.sh +409 -0
- package/.agents/tests/fm-backend-herdr-launcher-workspace-e2e.test.sh +437 -0
- package/.agents/tests/fm-backend-herdr-presentation-e2e.test.sh +1424 -0
- package/.agents/tests/fm-backend-herdr-prune-safety-e2e.test.sh +180 -0
- package/.agents/tests/fm-backend-herdr-respawn-idem-e2e.test.sh +182 -0
- package/.agents/tests/fm-backend-herdr-smoke.test.sh +355 -0
- package/.agents/tests/fm-backend-herdr-workspace-per-home-e2e.test.sh +251 -0
- package/.agents/tests/fm-backend-herdr.test.sh +4606 -0
- package/.agents/tests/fm-backend-orca.test.sh +1357 -0
- package/.agents/tests/fm-backend-tmux-smoke.test.sh +173 -0
- package/.agents/tests/fm-backend-zellij-smoke.test.sh +205 -0
- package/.agents/tests/fm-backend-zellij.test.sh +1360 -0
- package/.agents/tests/fm-backend.test.sh +1142 -0
- package/.agents/tests/fm-backlog-atomicity.test.sh +2302 -0
- package/.agents/tests/fm-backlog-handoff.test.sh +1360 -0
- package/.agents/tests/fm-bearings-board-render.test.sh +135 -0
- package/.agents/tests/fm-bearings-board.test.sh +414 -0
- package/.agents/tests/fm-bearings-snapshot.test.sh +1990 -0
- package/.agents/tests/fm-bootstrap-network-parallel.test.sh +316 -0
- package/.agents/tests/fm-bootstrap.test.sh +1178 -0
- package/.agents/tests/fm-branch-supervision.test.sh +552 -0
- package/.agents/tests/fm-brief.test.sh +785 -0
- package/.agents/tests/fm-busy-adapter-wiring.test.sh +324 -0
- package/.agents/tests/fm-busy-state.test.sh +465 -0
- package/.agents/tests/fm-calm-pi-extension.test.sh +3979 -0
- package/.agents/tests/fm-captain-hold-lifecycle.test.sh +1187 -0
- package/.agents/tests/fm-cd-pretool-check.test.sh +400 -0
- package/.agents/tests/fm-check-unregister.test.sh +198 -0
- package/.agents/tests/fm-classify-corr-token.test.sh +543 -0
- package/.agents/tests/fm-classify-decision-key.test.sh +340 -0
- package/.agents/tests/fm-claude-stop-autoarm-live-e2e.test.sh +164 -0
- package/.agents/tests/fm-claude-stop-autoarm.test.sh +1190 -0
- package/.agents/tests/fm-cmux-claude-composer-live-e2e.test.sh +110 -0
- package/.agents/tests/fm-codex-continuity-live-e2e.test.sh +55 -0
- package/.agents/tests/fm-composer-ghost.test.sh +716 -0
- package/.agents/tests/fm-composer-lib.test.sh +666 -0
- package/.agents/tests/fm-composer-matrix-live-e2e.test.sh +220 -0
- package/.agents/tests/fm-control-herdr-smoke.test.sh +149 -0
- package/.agents/tests/fm-control-relaunch.test.sh +1530 -0
- package/.agents/tests/fm-control.test.sh +910 -0
- package/.agents/tests/fm-crew-state.test.sh +1610 -0
- package/.agents/tests/fm-cursor-harness.test.sh +404 -0
- package/.agents/tests/fm-cursor-primary-live-e2e.test.sh +217 -0
- package/.agents/tests/fm-cursor-primary.test.sh +708 -0
- package/.agents/tests/fm-daemon.test.sh +2740 -0
- package/.agents/tests/fm-documentation-audiences.test.sh +141 -0
- package/.agents/tests/fm-ensure-agents-md.test.sh +371 -0
- package/.agents/tests/fm-extension-binding.test.sh +2187 -0
- package/.agents/tests/fm-fleet-snapshot-view.test.sh +816 -0
- package/.agents/tests/fm-fleet-sync.test.sh +721 -0
- package/.agents/tests/fm-gate-refuse.test.sh +356 -0
- package/.agents/tests/fm-gitignore-config.test.sh +89 -0
- package/.agents/tests/fm-gotmp.test.sh +230 -0
- package/.agents/tests/fm-grok-continuity-live-e2e.test.sh +112 -0
- package/.agents/tests/fm-grok-harness.test.sh +117 -0
- package/.agents/tests/fm-grok-stop-live-e2e.test.sh +219 -0
- package/.agents/tests/fm-guard-stale-banner.test.sh +709 -0
- package/.agents/tests/fm-harness-adapter-instructions-live-e2e.test.sh +134 -0
- package/.agents/tests/fm-harness-adapter-references.test.sh +30 -0
- package/.agents/tests/fm-harness-liveness-drift-live-e2e.test.sh +151 -0
- package/.agents/tests/fm-herdr-lab.test.sh +243 -0
- package/.agents/tests/fm-herdr-session-cleanup-e2e.test.sh +146 -0
- package/.agents/tests/fm-herdr-session-cleanup.test.sh +329 -0
- package/.agents/tests/fm-herdr-submit-confirm-live-e2e.test.sh +125 -0
- package/.agents/tests/fm-herdr-version-floor-live-e2e.test.sh +144 -0
- package/.agents/tests/fm-home-summary-refresh.test.sh +971 -0
- package/.agents/tests/fm-inactive-reconcile.test.sh +485 -0
- package/.agents/tests/fm-kimi-harness.test.sh +687 -0
- package/.agents/tests/fm-lint-workflows.test.sh +532 -0
- package/.agents/tests/fm-lint.test.sh +1023 -0
- package/.agents/tests/fm-muse-harness.test.sh +932 -0
- package/.agents/tests/fm-muse-signals-live-e2e.test.sh +205 -0
- package/.agents/tests/fm-no-mistakes-required.test.sh +72 -0
- package/.agents/tests/fm-on.test.sh +507 -0
- package/.agents/tests/fm-opencode-primary-live-e2e.test.sh +357 -0
- package/.agents/tests/fm-operational-input.test.sh +160 -0
- package/.agents/tests/fm-peek-remote.test.sh +110 -0
- package/.agents/tests/fm-pending-reply.test.sh +1288 -0
- package/.agents/tests/fm-pi-branch-extension.test.sh +3182 -0
- package/.agents/tests/fm-pi-branch-live-e2e.test.sh +527 -0
- package/.agents/tests/fm-pi-primary-live-e2e.test.sh +345 -0
- package/.agents/tests/fm-pi-primary-types.test.sh +68 -0
- package/.agents/tests/fm-pi-watch-extension.test.sh +2843 -0
- package/.agents/tests/fm-pr-check-security.test.sh +2140 -0
- package/.agents/tests/fm-pr-merge.test.sh +2135 -0
- package/.agents/tests/fm-procevent-quota.test.sh +225 -0
- package/.agents/tests/fm-procevent-when.test.sh +406 -0
- package/.agents/tests/fm-procevent.test.sh +1745 -0
- package/.agents/tests/fm-project-origin.test.sh +110 -0
- package/.agents/tests/fm-public-followup.test.sh +2272 -0
- package/.agents/tests/fm-quota-array-dispatch-live-e2e.test.sh +526 -0
- package/.agents/tests/fm-quota-choose.test.sh +626 -0
- package/.agents/tests/fm-remote-backlog-handoff.test.sh +453 -0
- package/.agents/tests/fm-remote-doctor.test.sh +625 -0
- package/.agents/tests/fm-remote-entrypoint.test.sh +59 -0
- package/.agents/tests/fm-remote-job-orphan-reap.test.sh +205 -0
- package/.agents/tests/fm-remote-job.test.sh +768 -0
- package/.agents/tests/fm-remote-reply.test.sh +520 -0
- package/.agents/tests/fm-remote-secondmate-lifecycle-e2e.test.sh +1256 -0
- package/.agents/tests/fm-remote-secondmate-parent-binding.test.sh +326 -0
- package/.agents/tests/fm-remote-secondmate-trace-context.test.sh +310 -0
- package/.agents/tests/fm-remote-transport-lanes.test.sh +431 -0
- package/.agents/tests/fm-review-diff.test.sh +176 -0
- package/.agents/tests/fm-secondmate-harness.test.sh +2600 -0
- package/.agents/tests/fm-secondmate-lifecycle-e2e.test.sh +259 -0
- package/.agents/tests/fm-secondmate-liveness.test.sh +559 -0
- package/.agents/tests/fm-secondmate-reconcile.test.sh +732 -0
- package/.agents/tests/fm-secondmate-safety.test.sh +2972 -0
- package/.agents/tests/fm-secondmate-sync.test.sh +913 -0
- package/.agents/tests/fm-send-inbox-doorbell-live-e2e.test.sh +206 -0
- package/.agents/tests/fm-send-inbox.test.sh +352 -0
- package/.agents/tests/fm-send-popup-settle.test.sh +167 -0
- package/.agents/tests/fm-send-remote-delivery.test.sh +796 -0
- package/.agents/tests/fm-send-resolve-key.test.sh +551 -0
- package/.agents/tests/fm-send-secondmate-marker-herdr-e2e.test.sh +187 -0
- package/.agents/tests/fm-send-secondmate-marker.test.sh +278 -0
- package/.agents/tests/fm-send-settle.test.sh +147 -0
- package/.agents/tests/fm-send-strict.test.sh +241 -0
- package/.agents/tests/fm-session-lock-ancestry.test.sh +365 -0
- package/.agents/tests/fm-session-start.test.sh +2515 -0
- package/.agents/tests/fm-sessionstart-hook-live-e2e.test.sh +631 -0
- package/.agents/tests/fm-sessionstart-instruction-refresh-live-e2e.test.sh +230 -0
- package/.agents/tests/fm-sessionstart-nudge.test.sh +1039 -0
- package/.agents/tests/fm-shared-captain-inheritance.test.sh +404 -0
- package/.agents/tests/fm-spawn-batch.test.sh +148 -0
- package/.agents/tests/fm-spawn-dispatch-profile.test.sh +827 -0
- package/.agents/tests/fm-spawn-pool-base-freshen.test.sh +440 -0
- package/.agents/tests/fm-spawn-worktree-settle.test.sh +147 -0
- package/.agents/tests/fm-startup-memory-budget.test.sh +333 -0
- package/.agents/tests/fm-startup-network.test.sh +712 -0
- package/.agents/tests/fm-stow-cascade.test.sh +370 -0
- package/.agents/tests/fm-subagent-pretool-check.test.sh +291 -0
- package/.agents/tests/fm-supervision-events.test.sh +156 -0
- package/.agents/tests/fm-supervision-instructions.test.sh +189 -0
- package/.agents/tests/fm-tangle-guard.test.sh +277 -0
- package/.agents/tests/fm-task-delivery.test.sh +420 -0
- package/.agents/tests/fm-task-inbox.test.sh +513 -0
- package/.agents/tests/fm-teardown-endpoint-safety.test.sh +374 -0
- package/.agents/tests/fm-teardown.test.sh +2665 -0
- package/.agents/tests/fm-test-fixture-cleanup.test.sh +172 -0
- package/.agents/tests/fm-test-fixtures.test.sh +132 -0
- package/.agents/tests/fm-test-isolation-proof.test.sh +278 -0
- package/.agents/tests/fm-test-run.test.sh +1196 -0
- package/.agents/tests/fm-tmux-agent-liveness.test.sh +354 -0
- package/.agents/tests/fm-tmux-submit-busy.test.sh +340 -0
- package/.agents/tests/fm-tool-update-check.test.sh +1044 -0
- package/.agents/tests/fm-trace-context-lib.test.sh +253 -0
- package/.agents/tests/fm-trace-context-spawn.test.sh +581 -0
- package/.agents/tests/fm-transition-lib.test.sh +54 -0
- package/.agents/tests/fm-turnend-guard.test.sh +1822 -0
- package/.agents/tests/fm-update.test.sh +304 -0
- package/.agents/tests/fm-vendor-auth-probe.test.sh +395 -0
- package/.agents/tests/fm-voice-relay.test.sh +4741 -0
- package/.agents/tests/fm-wake-daemon-lifecycle-e2e.test.sh +171 -0
- package/.agents/tests/fm-wake-drain-open-decisions-cursor.test.sh +356 -0
- package/.agents/tests/fm-wake-drain-open-decisions.test.sh +226 -0
- package/.agents/tests/fm-wake-drain-unread-status.test.sh +379 -0
- package/.agents/tests/fm-wake-queue.test.sh +1224 -0
- package/.agents/tests/fm-watch-arm.test.sh +821 -0
- package/.agents/tests/fm-watch-checkpoint.test.sh +87 -0
- package/.agents/tests/fm-watch-recovery-loop.test.sh +223 -0
- package/.agents/tests/fm-watch-triage.test.sh +3889 -0
- package/.agents/tests/fm-watcher-lock.test.sh +1133 -0
- package/.agents/tests/fm-x-mode.test.sh +3042 -0
- package/.agents/tests/gleipnir-guard-pretool-check.test.sh +51 -0
- package/.agents/tests/gleipnir-machine-lock.test.sh +130 -0
- package/.agents/tests/herdr-test-safety.sh +42 -0
- package/.agents/tests/lib.sh +315 -0
- package/.agents/tests/remote-herdr-fixture.sh +125 -0
- package/.agents/tests/secondmate-helpers.sh +193 -0
- package/.agents/tests/smoke.test.sh +93 -0
- package/.agents/tests/wake-helpers.sh +338 -0
- package/.agents/tests/zellij-test-safety.sh +60 -0
- package/.agents/tools/README.md +10 -0
- package/.agents/tools/bin/tasks-cli +267 -0
- package/.agents/tools/tasks-cli.ts +216 -0
- package/AGENTS.md +454 -0
- package/CHANGELOG.md +881 -0
- package/LICENSE +1 -1
- package/NOTICE +63 -0
- package/README.md +113 -59
- package/RULES/01-domains.md +51 -0
- package/RULES/02-agents.md +78 -0
- package/RULES/03-houses.md +61 -0
- package/RULES/04-hoard.md +65 -0
- package/RULES/05-platforms.md +67 -0
- package/RULES/06-append-only.md +58 -0
- package/RULES/07-config.md +45 -0
- package/RULES/08-delivery-gate.md +75 -0
- package/RULES/README.md +20 -0
- package/bin/README.md +107 -0
- package/bin/a2a-mcp.sh +98 -0
- package/bin/a2a-serve.py +103 -0
- package/bin/a2a-serve.sh +8 -0
- package/bin/a2a-talk.sh +50 -0
- package/bin/a2abridge-ensure.sh +108 -0
- package/bin/agent-run.sh +43 -0
- package/bin/agents-config.sh +233 -0
- package/bin/apodex-smoke-test.sh +92 -0
- package/bin/bifrost-bridge.sh +112 -0
- package/bin/bifrost-ingress.sh +77 -0
- package/bin/bootstrap-macos.sh +107 -0
- package/bin/bootstrap-windows.ps1 +112 -0
- package/bin/branch-guard.sh +64 -0
- package/bin/brokk +73 -0
- package/bin/brokk-classify-lib.sh +1770 -0
- package/bin/brokk-lease-lib.sh +222 -0
- package/bin/brokk-lease.sh +193 -0
- package/bin/brokk-lint.sh +65 -0
- package/bin/brokk-send.sh +38 -0
- package/bin/brokk-update.sh +9 -0
- package/bin/brokk-wake-grant.sh +127 -0
- package/bin/brokk-wake-lib.sh +1849 -0
- package/bin/changelog-guard.sh +165 -0
- package/bin/crash-sense.sh +160 -0
- package/bin/desktop-place.sh +224 -0
- package/bin/docs-guard.sh +39 -0
- package/bin/editor-place.sh +207 -0
- package/bin/eindri-acclaim.sh +34 -0
- package/bin/eindri-control.sh +28 -0
- package/bin/eindri-role.sh +83 -0
- package/bin/eindri-seen.sh +41 -0
- package/bin/eindri-send.sh +15 -0
- package/bin/eindri-start.sh +85 -0
- package/bin/eindri-watch.sh +57 -0
- package/bin/einherjar-spawn.sh +576 -0
- package/bin/eir-doctor.sh +112 -0
- package/bin/erindi-brief.sh +271 -0
- package/bin/fleet-apply.sh +68 -0
- package/bin/github-deploy.sh +81 -0
- package/bin/gjallarhorn-expose.sh +102 -0
- package/bin/gjallarhorn-notify.sh +58 -0
- package/bin/gjallarhorn-purge.sh +54 -0
- package/bin/gjallarhorn-tunnel.sh +72 -0
- package/bin/gleipnir-lock-lib.sh +284 -0
- package/bin/groa-update.sh +122 -0
- package/bin/hall-snapshot.sh +92 -0
- package/bin/hamr-harness.sh +246 -0
- package/bin/heimdall-ssh-keys.sh +374 -0
- package/bin/herdr-agents.py +44 -0
- package/bin/herdr-ensure.sh +104 -0
- package/bin/herdr-run.sh +431 -0
- package/bin/hermes-ensure.sh +88 -0
- package/bin/hoard-lib.sh +25 -0
- package/bin/hodd.sh +78 -0
- package/bin/host-sense.sh +199 -0
- package/bin/huginn-research-worker.sh +108 -0
- package/bin/local-model-lock.sh +51 -0
- package/bin/mimir-bridge.py +226 -0
- package/bin/mimir-bridge.sh +87 -0
- package/bin/mimir-ingest.sh +131 -0
- package/bin/mimir.sh +113 -0
- package/bin/mjollnir-webhook.sh +59 -0
- package/bin/mjollnir.sh +85 -0
- package/bin/model-hardware.sh +82 -0
- package/bin/model-resolve.sh +147 -0
- package/bin/models-detect.sh +178 -0
- package/bin/nornir-cron-start.sh +162 -0
- package/bin/nornir-job-daily-briefing.sh +191 -0
- package/bin/nornir-job-git-sync.sh +152 -0
- package/bin/nornir-job-memory-housekeeping.sh +114 -0
- package/bin/nornir-job-observer.sh +166 -0
- package/bin/nornir-job-skillopt-sleep.sh +76 -0
- package/bin/omarchy-hook-install.sh +60 -0
- package/bin/omarchy-install.sh +148 -0
- package/bin/omarchy-plugins.sh +174 -0
- package/bin/omarchy-sense.sh +149 -0
- package/bin/perm-guard.sh +30 -0
- package/bin/pi-agent.sh +68 -0
- package/bin/pi-ensure.sh +77 -0
- package/bin/pi-local.sh +37 -0
- package/bin/pi-seat.sh +63 -0
- package/bin/prereq-ensure.sh +166 -0
- package/bin/private-guard.sh +38 -0
- package/bin/project-git.sh +55 -0
- package/bin/public-guard.sh +70 -0
- package/bin/ratatoskr.sh +49 -0
- package/bin/realm-lib.sh +32 -0
- package/bin/repo-scrub.sh +62 -0
- package/bin/rodd-operational-input.sh +250 -0
- package/bin/runes-append.sh +198 -0
- package/bin/saga-session-start.sh +172 -0
- package/bin/saga-sessionstart-run.sh +79 -0
- package/bin/saga-wake-drain.sh +41 -0
- package/bin/secret-guard.sh +63 -0
- package/bin/sessrumnir-ensure.sh +100 -0
- package/bin/sessrumnir-sync.sh +237 -0
- package/bin/sessrumnir.sh +91 -0
- package/bin/skillopt-setup.sh +76 -0
- package/bin/skuld-branch-outcome.sh +203 -0
- package/bin/skuld-branch-prompt.sh +101 -0
- package/bin/smidja-bootstrap.sh +90 -0
- package/bin/smidja-observe.sh +86 -0
- package/bin/syn-arm-pretool-check.sh +57 -0
- package/bin/syn-asset-pretool-check.sh +76 -0
- package/bin/syn-cd-pretool-check.sh +28 -0
- package/bin/syn-guard-pretool-check.sh +83 -0
- package/bin/syn-turnend-guard.sh +36 -0
- package/bin/syn-watch-arm.sh +99 -0
- package/bin/tailscale-sync.sh +190 -0
- package/bin/telegram-bot.sh +69 -0
- package/bin/toolchain.sh +74 -0
- package/bin/utgard.sh +111 -0
- package/bin/valhalla.sh +115 -0
- package/bin/valknut-load.sh +260 -0
- package/bin/vor-crew-state.sh +124 -0
- package/bin/wedge-notify.sh +47 -0
- package/bin/workspace-provision.sh +80 -0
- package/bin/workspace-rag.sh +150 -0
- package/bin/wyrd-db.sh +47 -0
- package/bin/yggdrasil.sh +152 -0
- package/bin/ymir-edit.sh +145 -0
- package/bin/ymir-install.sh +641 -0
- package/bin/ymir-invite.sh +93 -0
- package/bin/ymir-isolation.sh +88 -0
- package/bin/ymir-migrate.sh +61 -0
- package/bin/ymir-platform.sh +348 -0
- package/bin/ymir-say.sh +97 -0
- package/bin/ymir-setup-auth.sh +108 -0
- package/bin/ymir-validate.sh +173 -0
- package/bin/ymir.js +74 -16
- package/docs/Architecture.md +339 -0
- package/docs/design.md +351 -0
- package/docs/installations/README.md +63 -0
- package/docs/installations/ymir-home.md +93 -0
- package/docs/integration.md +105 -0
- package/docs/lore.md +1056 -0
- package/docs/research/agent-harnesses.md +290 -0
- package/docs/runbooks/README.md +19 -0
- package/docs/runbooks/a2a.md +91 -0
- package/docs/runbooks/agent-permissions.md +99 -0
- package/docs/runbooks/agents.md +57 -0
- package/docs/runbooks/models.md +69 -0
- package/docs/runbooks/realm-onboarding.md +60 -0
- package/docs/runbooks/secrets-and-hoard.md +60 -0
- package/docs/runbooks/updates-and-migrations.md +110 -0
- package/docs/runbooks/worktrees-isolation.md +72 -0
- package/docs/session-start.md +105 -0
- package/docs/skillopt-integration.md +321 -0
- package/docs/sync-system.md +66 -0
- package/docs/workspaces.md +104 -0
- package/docs/ymir-rut.md +260 -0
- package/package.json +44 -14
- package/packaging/build.sh +74 -0
- package/packaging/macos/Ymir Installer.command +43 -0
- package/packaging/windows/ymir-setup.nsi +74 -0
- package/scripts/README.md +22 -0
- package/scripts/electron.sh +210 -0
- package/scripts/start.sh +167 -0
- package/scripts/stop.sh +113 -0
- package/install.sh +0 -35
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# bin/backends/orca.sh - the Orca terminal session-provider adapter.
|
|
3
|
+
#
|
|
4
|
+
# Orca owns both the task worktree and the terminal endpoint. Escape key support
|
|
5
|
+
# remains unsupported until Orca exposes a terminal-send primitive for it.
|
|
6
|
+
#
|
|
7
|
+
# Target string shape: the Orca terminal id accepted by `orca terminal ...`.
|
|
8
|
+
|
|
9
|
+
# Shared composer-content classifier (empty|pending|unknown, and the fleet-wide
|
|
10
|
+
# dead-shell-vs-agent-composer rule). Owned by bin/fm-composer-lib.sh, reused by
|
|
11
|
+
# every backend so the decision cannot drift.
|
|
12
|
+
# shellcheck source=bin/fm-composer-lib.sh
|
|
13
|
+
. "$(dirname -- "${BASH_SOURCE[0]}")/../fm-composer-lib.sh"
|
|
14
|
+
|
|
15
|
+
fm_backend_orca_tool_check() {
|
|
16
|
+
command -v orca >/dev/null 2>&1 || { echo "error: backend=orca selected but the 'orca' CLI is not installed" >&2; return 1; }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
fm_backend_orca_runtime_check() {
|
|
20
|
+
fm_backend_orca_tool_check || return 1
|
|
21
|
+
local out
|
|
22
|
+
out=$(orca status --json 2>/dev/null) || {
|
|
23
|
+
echo "error: backend=orca selected but 'orca status --json' failed; start Orca and wait for the runtime to be ready" >&2
|
|
24
|
+
return 1
|
|
25
|
+
}
|
|
26
|
+
# shellcheck disable=SC2016 # Single quotes are deliberate: ${...} belongs to the Node snippet.
|
|
27
|
+
printf '%s' "$out" | node -e '
|
|
28
|
+
const fs = require("fs");
|
|
29
|
+
let data;
|
|
30
|
+
try {
|
|
31
|
+
data = JSON.parse(fs.readFileSync(0, "utf8"));
|
|
32
|
+
} catch (err) {
|
|
33
|
+
console.error("error: invalid Orca status JSON: " + err.message);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
if (data.ok === false) {
|
|
37
|
+
const msg = data.error && (data.error.message || data.error.code);
|
|
38
|
+
console.error("error: Orca runtime is not ready" + (msg ? ": " + msg : ""));
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
const r = data.result || {};
|
|
42
|
+
const runtime = r.runtime || {};
|
|
43
|
+
const reachable = runtime.reachable ?? r.runtimeReachable;
|
|
44
|
+
const state = runtime.state || r.runtimeState || "";
|
|
45
|
+
if (reachable === true && state === "ready") process.exit(0);
|
|
46
|
+
console.error(`error: backend=orca requires a ready Orca runtime (reachable=${String(reachable)}, state=${state || "unknown"})`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
fm_backend_orca_json_get() { # <field> ; fields: worktree-id worktree-path terminal-handle worktree-terminal-handle repo-id
|
|
52
|
+
# Terminal handles are accepted only from verified terminal result shapes:
|
|
53
|
+
# result.terminal or a root terminal object with .handle. Undocumented
|
|
54
|
+
# result.id and result.worktree.terminal shapes are ignored until a real Orca
|
|
55
|
+
# smoke run proves them.
|
|
56
|
+
local field=$1
|
|
57
|
+
node -e '
|
|
58
|
+
const fs = require("fs");
|
|
59
|
+
const field = process.argv[1];
|
|
60
|
+
const data = JSON.parse(fs.readFileSync(0, "utf8"));
|
|
61
|
+
if (data.ok === false) {
|
|
62
|
+
const msg = data.error && (data.error.message || data.error.code);
|
|
63
|
+
if (msg) console.error(msg);
|
|
64
|
+
process.exit(2);
|
|
65
|
+
}
|
|
66
|
+
const r = data.result || {};
|
|
67
|
+
const wt = r.worktree || r.item || r;
|
|
68
|
+
const explicitTerm = r.terminal || null;
|
|
69
|
+
const repo = r.repo || r.repository || r;
|
|
70
|
+
function scalar(v) {
|
|
71
|
+
return (typeof v === "string" || typeof v === "number") ? String(v) : "";
|
|
72
|
+
}
|
|
73
|
+
function handle(obj) {
|
|
74
|
+
if (!obj) return "";
|
|
75
|
+
if (typeof obj === "string" || typeof obj === "number") return String(obj);
|
|
76
|
+
return scalar(obj.handle) || "";
|
|
77
|
+
}
|
|
78
|
+
let v = "";
|
|
79
|
+
if (field === "worktree-id") v = wt.id || wt.worktreeId || r.worktreeId || "";
|
|
80
|
+
if (field === "worktree-path") v = wt.path || (wt.git && wt.git.path) || r.path || "";
|
|
81
|
+
if (field === "terminal-handle") v = handle(explicitTerm || r) || "";
|
|
82
|
+
if (field === "worktree-terminal-handle") v = handle(explicitTerm) || "";
|
|
83
|
+
if (field === "repo-id") v = repo.id || repo.repoId || r.repoId || "";
|
|
84
|
+
if (!v) process.exit(1);
|
|
85
|
+
process.stdout.write(String(v));
|
|
86
|
+
' "$field"
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
fm_backend_orca_json_ok() {
|
|
90
|
+
node -e '
|
|
91
|
+
const fs = require("fs");
|
|
92
|
+
const input = fs.readFileSync(0, "utf8").trim();
|
|
93
|
+
if (!input) process.exit(0);
|
|
94
|
+
let data;
|
|
95
|
+
try {
|
|
96
|
+
data = JSON.parse(input);
|
|
97
|
+
} catch (err) {
|
|
98
|
+
console.error("invalid Orca JSON: " + err.message);
|
|
99
|
+
process.exit(2);
|
|
100
|
+
}
|
|
101
|
+
if (data.ok === false) {
|
|
102
|
+
const msg = data.error && (data.error.message || data.error.code);
|
|
103
|
+
if (msg) console.error(msg);
|
|
104
|
+
process.exit(2);
|
|
105
|
+
}
|
|
106
|
+
'
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
fm_backend_orca_run_json() {
|
|
110
|
+
local out
|
|
111
|
+
out=$("$@") || return 1
|
|
112
|
+
printf '%s' "$out" | fm_backend_orca_json_ok
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
fm_backend_orca_repo_ensure() { # <project-path>
|
|
116
|
+
local project=$1 out repo_id
|
|
117
|
+
fm_backend_orca_tool_check || return 1
|
|
118
|
+
out=$(orca repo show --repo "path:$project" --json 2>/dev/null || true)
|
|
119
|
+
if repo_id=$(printf '%s' "$out" | fm_backend_orca_json_get repo-id 2>/dev/null); then
|
|
120
|
+
printf '%s' "$repo_id"
|
|
121
|
+
return 0
|
|
122
|
+
fi
|
|
123
|
+
out=$(orca repo add --path "$project" --json) || return 1
|
|
124
|
+
repo_id=$(printf '%s' "$out" | fm_backend_orca_json_get repo-id) || {
|
|
125
|
+
echo "error: orca repo add did not return a repo id for $project" >&2
|
|
126
|
+
return 1
|
|
127
|
+
}
|
|
128
|
+
printf '%s' "$repo_id"
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
fm_backend_orca_worktree_create() { # <project-path> <name>
|
|
132
|
+
local project=$1 name=$2 repo_id out wt_id wt_path terminal
|
|
133
|
+
repo_id=$(fm_backend_orca_repo_ensure "$project") || return 1
|
|
134
|
+
out=$(orca worktree create --repo "id:$repo_id" --name "$name" --no-parent --setup skip --json) || return 1
|
|
135
|
+
wt_id=$(printf '%s' "$out" | fm_backend_orca_json_get worktree-id) || {
|
|
136
|
+
echo "error: orca worktree create did not return a worktree id for $name" >&2
|
|
137
|
+
return 1
|
|
138
|
+
}
|
|
139
|
+
terminal=$(printf '%s' "$out" | fm_backend_orca_json_get worktree-terminal-handle 2>/dev/null || true)
|
|
140
|
+
wt_path=$(printf '%s' "$out" | fm_backend_orca_json_get worktree-path) || {
|
|
141
|
+
echo "error: orca worktree create did not return a path for $name" >&2
|
|
142
|
+
[ -z "$terminal" ] || fm_backend_orca_kill "$terminal" >/dev/null 2>&1 || true
|
|
143
|
+
if fm_backend_orca_remove_worktree "$wt_id" >/dev/null; then
|
|
144
|
+
return 1
|
|
145
|
+
fi
|
|
146
|
+
if [ -n "$terminal" ]; then
|
|
147
|
+
printf '%s\t\t%s' "$wt_id" "$terminal"
|
|
148
|
+
else
|
|
149
|
+
printf '%s\t' "$wt_id"
|
|
150
|
+
fi
|
|
151
|
+
return 2
|
|
152
|
+
}
|
|
153
|
+
printf '%s\t%s' "$wt_id" "$wt_path"
|
|
154
|
+
[ -z "$terminal" ] || printf '\t%s' "$terminal"
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
fm_backend_orca_terminal_create() { # <worktree-id> <title>
|
|
158
|
+
local worktree_id=$1 title=$2 out terminal
|
|
159
|
+
fm_backend_orca_tool_check || return 1
|
|
160
|
+
out=$(orca terminal create --worktree "id:$worktree_id" --title "$title" --json) || return 1
|
|
161
|
+
terminal=$(printf '%s' "$out" | fm_backend_orca_json_get terminal-handle) || {
|
|
162
|
+
echo "error: orca terminal create did not return a terminal handle for $title" >&2
|
|
163
|
+
return 1
|
|
164
|
+
}
|
|
165
|
+
printf '%s' "$terminal"
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
fm_backend_orca_send_text_line() { # <terminal-id> <text>
|
|
169
|
+
local terminal=$1 text=$2
|
|
170
|
+
fm_backend_orca_tool_check || return 1
|
|
171
|
+
fm_backend_orca_run_json orca terminal send --terminal "$terminal" --text "$text" --enter --json
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
fm_backend_orca_send_literal() { # <terminal-id> <text>
|
|
175
|
+
local terminal=$1 text=$2
|
|
176
|
+
fm_backend_orca_tool_check || return 1
|
|
177
|
+
fm_backend_orca_run_json orca terminal send --terminal "$terminal" --text "$text" --json
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
fm_backend_orca_remove_worktree() { # <worktree-id>
|
|
181
|
+
local worktree_id=${1:-}
|
|
182
|
+
[ -n "$worktree_id" ] || { echo "error: missing Orca worktree id; cannot remove worktree" >&2; return 1; }
|
|
183
|
+
fm_backend_orca_tool_check || return 1
|
|
184
|
+
fm_backend_orca_run_json orca worktree rm --worktree "id:$worktree_id" --force --json
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
fm_backend_orca_worktree_path() {
|
|
188
|
+
local worktree_id=${1:-} out path
|
|
189
|
+
[ -n "$worktree_id" ] || { echo "error: missing Orca worktree id; cannot resolve worktree path" >&2; return 1; }
|
|
190
|
+
fm_backend_orca_tool_check || return 1
|
|
191
|
+
out=$(orca worktree show --worktree "id:$worktree_id" --json) || return 1
|
|
192
|
+
path=$(printf '%s' "$out" | fm_backend_orca_json_get worktree-path) || {
|
|
193
|
+
echo "error: orca worktree show did not return a path for $worktree_id" >&2
|
|
194
|
+
return 1
|
|
195
|
+
}
|
|
196
|
+
printf '%s' "$path"
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
fm_backend_orca_capture() { # <terminal-id> <lines>
|
|
200
|
+
local terminal=$1 lines=${2:-40} out
|
|
201
|
+
fm_backend_orca_tool_check || return 1
|
|
202
|
+
out=$(orca terminal read --terminal "$terminal" --limit "$lines" --json) || return 1
|
|
203
|
+
fm_backend_orca_json_text "$out"
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
fm_backend_orca_json_text() { # <json>
|
|
207
|
+
printf '%s' "$1" | node -e '
|
|
208
|
+
const fs = require("fs");
|
|
209
|
+
const data = JSON.parse(fs.readFileSync(0, "utf8"));
|
|
210
|
+
if (data.ok === false) {
|
|
211
|
+
const msg = data.error && (data.error.message || data.error.code);
|
|
212
|
+
if (msg) console.error(msg);
|
|
213
|
+
process.exit(2);
|
|
214
|
+
}
|
|
215
|
+
const r = data.result || {};
|
|
216
|
+
if (r.terminal && Array.isArray(r.terminal.tail)) {
|
|
217
|
+
process.stdout.write(r.terminal.tail.join("\n"));
|
|
218
|
+
} else if (Array.isArray(r.tail)) {
|
|
219
|
+
process.stdout.write(r.tail.join("\n"));
|
|
220
|
+
} else {
|
|
221
|
+
process.stdout.write(r.text || r.output || r.content || r.preview || "");
|
|
222
|
+
}
|
|
223
|
+
'
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
# fm_backend_orca_composer_capture: the orca composer screen - one bounded
|
|
227
|
+
# tail read of the live terminal. Deliberately NOT the old 200-line
|
|
228
|
+
# backward-paged read: the composer is bottom-anchored, and paging back into
|
|
229
|
+
# scrollback is what let a stale startup banner (codex's bordered
|
|
230
|
+
# "permissions" box) compete with - and once outrank - the live composer.
|
|
231
|
+
fm_backend_orca_composer_capture() { # <terminal-id> [expected-label]
|
|
232
|
+
fm_backend_orca_capture "$1" "$FM_COMPOSER_CAPTURE_LINES"
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
# fm_backend_orca_composer_caps: static capability facts, not logic (see the
|
|
236
|
+
# capability model in bin/fm-composer-lib.sh). Orca's `terminal read` returns
|
|
237
|
+
# plain text; whether it can emit ANSI is unverified (orca is not installed
|
|
238
|
+
# on the verification machine), so styled stays 0 - the conservative
|
|
239
|
+
# degradation - until a live capture proves otherwise.
|
|
240
|
+
fm_backend_orca_composer_caps() {
|
|
241
|
+
printf 'styled=0\ncursor=0\nidentity=0\nrows=%s\n' "$FM_COMPOSER_CAPTURE_LINES"
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
# fm_backend_orca_composer_state: thin adapter - capture plus capabilities in,
|
|
245
|
+
# shared verdict out. Every shape (bordered boxes AND the borderless bare-glyph
|
|
246
|
+
# row this adapter never learned, which left every claude/codex/pi/muse steer
|
|
247
|
+
# unconfirmed) lives in bin/fm-composer-lib.sh.
|
|
248
|
+
fm_backend_orca_composer_state() { # <terminal-id> [expected-label] -> empty|pending|pending-unproven|unknown
|
|
249
|
+
local cap verdict
|
|
250
|
+
cap=$(fm_backend_orca_composer_capture "$1") || { printf 'unknown'; return 0; }
|
|
251
|
+
verdict=$(fm_composer_classify_screen "$(fm_backend_orca_composer_caps)" "$cap")
|
|
252
|
+
[ "$verdict" != need-identity ] || verdict=unknown
|
|
253
|
+
printf '%s' "$verdict"
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
fm_backend_orca_send_key() { # <terminal-id> <key>
|
|
257
|
+
local terminal=$1 key=$2
|
|
258
|
+
fm_backend_orca_tool_check || return 1
|
|
259
|
+
case "$key" in
|
|
260
|
+
C-c|ctrl+c|Ctrl-c|Ctrl-C)
|
|
261
|
+
fm_backend_orca_run_json orca terminal send --terminal "$terminal" --interrupt --json
|
|
262
|
+
;;
|
|
263
|
+
Enter|enter)
|
|
264
|
+
fm_backend_orca_run_json orca terminal send --terminal "$terminal" --text "" --enter --json
|
|
265
|
+
;;
|
|
266
|
+
*)
|
|
267
|
+
echo "error: unsupported Orca key '$key'" >&2
|
|
268
|
+
return 1
|
|
269
|
+
;;
|
|
270
|
+
esac
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
# fm_backend_orca_send_text_submit: type <text> once, then drive the shared
|
|
274
|
+
# verify-and-retry-Enter loop (bin/fm-composer-lib.sh:
|
|
275
|
+
# fm_composer_submit_retry_core) against the shared composer verdict, so a
|
|
276
|
+
# slash-command popup placeholder fill gets the required second Enter without
|
|
277
|
+
# duplicating text.
|
|
278
|
+
fm_backend_orca_send_text_submit() { # <terminal-id> <text> <retries> <enter-sleep> <settle>
|
|
279
|
+
local terminal=$1 text=$2 retries=$3 sleep_s=$4 settle=$5
|
|
280
|
+
fm_backend_orca_tool_check || { printf 'send-failed'; return 0; }
|
|
281
|
+
fm_backend_orca_send_literal "$terminal" "$text" || { printf 'send-failed'; return 0; }
|
|
282
|
+
sleep "$settle"
|
|
283
|
+
fm_composer_submit_retry_core fm_backend_orca_send_key fm_backend_orca_composer_state \
|
|
284
|
+
"$terminal" "$retries" "$sleep_s"
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
fm_backend_orca_kill() { # <terminal-id>
|
|
288
|
+
fm_backend_orca_tool_check || return 0
|
|
289
|
+
orca terminal close --terminal "$1" --json >/dev/null 2>&1 || true
|
|
290
|
+
}
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# bin/backends/tmux.sh - the tmux session-provider adapter.
|
|
3
|
+
#
|
|
4
|
+
# Reference backend (AGENTS.md section 8; data/fm-backend-design-d7). P1 moves
|
|
5
|
+
# the tmux command sequences that fm-send.sh, fm-peek.sh, fm-watch.sh,
|
|
6
|
+
# fm-spawn.sh, and fm-teardown.sh already ran inline into named functions
|
|
7
|
+
# here, running the EXACT same commands in the EXACT same order, so the
|
|
8
|
+
# default (tmux, `backend=` absent) path stays byte-identical. Sourced only
|
|
9
|
+
# through bin/fm-backend.sh's fm_backend_source, never directly.
|
|
10
|
+
#
|
|
11
|
+
# Worktree acquisition (running `treehouse get` inside the pane, and polling
|
|
12
|
+
# its cwd) is unchanged by this extraction: P1 scopes only the session
|
|
13
|
+
# provider, not the worktree provider, so fm-spawn.sh still drives that part
|
|
14
|
+
# inline with these same send/current-path primitives.
|
|
15
|
+
#
|
|
16
|
+
# The verified composer/busy-detection and verify-and-retry-submit primitives
|
|
17
|
+
# already live in bin/fm-tmux-lib.sh, shared with the away-mode daemon
|
|
18
|
+
# (bin/fm-supervise-daemon.sh); this adapter sources that file and re-exports
|
|
19
|
+
# its submit core under the backend's naming convention rather than
|
|
20
|
+
# duplicating it, so the two consumers cannot drift apart.
|
|
21
|
+
# shellcheck source=bin/fm-tmux-lib.sh
|
|
22
|
+
. "$FM_BACKEND_LIB_DIR/fm-tmux-lib.sh"
|
|
23
|
+
# shellcheck source=bin/fm-session-lock-lib.sh
|
|
24
|
+
. "$FM_BACKEND_LIB_DIR/fm-session-lock-lib.sh"
|
|
25
|
+
# shellcheck source=bin/fm-cursor-lib.sh
|
|
26
|
+
. "$FM_BACKEND_LIB_DIR/fm-cursor-lib.sh"
|
|
27
|
+
|
|
28
|
+
# fm_backend_tmux_resolve_bare_selector: the live-window-listing fallback for a
|
|
29
|
+
# selector that is neither an explicit target nor a task selector routed
|
|
30
|
+
# through meta - an ad hoc window name with no recorded task. Mirrors the
|
|
31
|
+
# `tmux list-windows -a ... | grep` pipeline that used to live inline in
|
|
32
|
+
# fm-send.sh's and fm-peek.sh's own (until now duplicated) resolve().
|
|
33
|
+
fm_backend_tmux_resolve_bare_selector() { # <name>
|
|
34
|
+
local name=$1
|
|
35
|
+
tmux list-windows -a -F '#{session_name}:#{window_name}' | grep -m1 ":$name\$" \
|
|
36
|
+
|| { echo "error: no window named $name" >&2; return 1; }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# fm_backend_tmux_capture: bounded plain-text pane capture. Mirrors
|
|
40
|
+
# fm-peek.sh's and fm-watch.sh's `tmux capture-pane -p -t "$T" -S -"$N"`.
|
|
41
|
+
fm_backend_tmux_capture() { # <target> <lines>
|
|
42
|
+
tmux capture-pane -p -t "$1" -S -"$2"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# fm_backend_tmux_send_key: one named key. Mirrors fm-send.sh's --key path:
|
|
46
|
+
# `tmux display-message -p -t "$T" '#{pane_id}' >/dev/null`, then
|
|
47
|
+
# `tmux send-keys -t "$T" "$2"`.
|
|
48
|
+
fm_backend_tmux_send_key() { # <target> <key>
|
|
49
|
+
tmux display-message -p -t "$1" '#{pane_id}' >/dev/null
|
|
50
|
+
tmux send-keys -t "$1" "$2"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# fm_backend_tmux_send_text_submit: type <text> into <target> once, then
|
|
54
|
+
# submit with Enter, retried (Enter only, never retyped) until the composer
|
|
55
|
+
# clears. Re-exports fm_tmux_submit_core (bin/fm-tmux-lib.sh) verbatim; see
|
|
56
|
+
# that file for the composer-verification contract and echoed verdicts.
|
|
57
|
+
fm_backend_tmux_send_text_submit() { # <target> <text> <retries> <enter-sleep> <settle>
|
|
58
|
+
fm_tmux_submit_core "$@"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# fm_backend_tmux_container_ensure: reuse the current tmux session when
|
|
62
|
+
# firstmate itself runs inside tmux, else ensure a dedicated detached
|
|
63
|
+
# "firstmate" session exists. Mirrors fm-spawn.sh's container-ensure block;
|
|
64
|
+
# prints the resolved session name.
|
|
65
|
+
fm_backend_tmux_container_ensure() {
|
|
66
|
+
if [ -n "${TMUX:-}" ]; then
|
|
67
|
+
tmux display-message -p '#S'
|
|
68
|
+
else
|
|
69
|
+
tmux has-session -t firstmate 2>/dev/null || tmux new-session -d -s firstmate
|
|
70
|
+
printf 'firstmate'
|
|
71
|
+
fi
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# fm_backend_tmux_create_task: create the task's window in <proj-abs>,
|
|
75
|
+
# refusing an existing <window-name> in <session>. Mirrors fm-spawn.sh's
|
|
76
|
+
# duplicate-check-then-new-window sequence, including the exact error text
|
|
77
|
+
# (session:window, matching how fm-spawn.sh composed its own $T). Prints the
|
|
78
|
+
# created window's stable window id on stdout for the caller to target.
|
|
79
|
+
#
|
|
80
|
+
# Robustness (fm-spawn tmux window handling under a non-default captain config):
|
|
81
|
+
# - Capture a STABLE window id with -P -F '#{window_id}', and let tmux append
|
|
82
|
+
# at the next free index by targeting the session with a trailing colon
|
|
83
|
+
# ("$ses:"), so a non-default base-index (e.g. base-index 1) cannot collide.
|
|
84
|
+
# - PIN the window name by disabling automatic-rename and allow-rename on the
|
|
85
|
+
# new window: the captain's tmux may rename the window away from fm-<id> once
|
|
86
|
+
# treehouse cd's into the worktree, which would break name-based targeting.
|
|
87
|
+
# The returned window id lets callers target the window even if its name is ever
|
|
88
|
+
# lost, so worktree discovery cannot fall back to the active client's window.
|
|
89
|
+
fm_backend_tmux_create_task() { # <session> <window-name> <proj-abs> -> prints window id
|
|
90
|
+
local ses=$1 wname=$2 proj_abs=$3 wid
|
|
91
|
+
if tmux list-windows -t "$ses" -F '#{window_name}' | grep -qx "$wname"; then
|
|
92
|
+
echo "error: window $ses:$wname already exists" >&2
|
|
93
|
+
return 1
|
|
94
|
+
fi
|
|
95
|
+
wid=$(tmux new-window -dP -F '#{window_id}' -t "$ses:" -n "$wname" -c "$proj_abs") || return 1
|
|
96
|
+
tmux set-window-option -t "$wid" automatic-rename off 2>/dev/null || true
|
|
97
|
+
tmux set-window-option -t "$wid" allow-rename off 2>/dev/null || true
|
|
98
|
+
printf '%s\n' "$wid"
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
# fm_backend_tmux_current_path: the live pane's current working directory, or
|
|
102
|
+
# empty on any tmux error. Mirrors fm-spawn.sh's worktree-discovery poll:
|
|
103
|
+
# `tmux display-message -p -t "$T" '#{pane_current_path}'`.
|
|
104
|
+
fm_backend_tmux_current_path() { # <target>
|
|
105
|
+
tmux display-message -p -t "$1" '#{pane_current_path}' 2>/dev/null
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# fm_backend_tmux_send_text_line: send one line of TEXT then Enter, with no
|
|
109
|
+
# composer verification - used for the fixed spawn-time commands
|
|
110
|
+
# (`treehouse get`, the GOTMPDIR export) that already ran this exact sequence
|
|
111
|
+
# inline in fm-spawn.sh. Mirrors `tmux send-keys -t "$T" "<text>" Enter`.
|
|
112
|
+
fm_backend_tmux_send_text_line() { # <target> <text>
|
|
113
|
+
tmux send-keys -t "$1" "$2" Enter
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
# fm_backend_tmux_send_literal: send TEXT as literal bytes with no
|
|
117
|
+
# submission - the caller sends Enter separately (fm-spawn.sh's launch-command
|
|
118
|
+
# send pauses between the literal send and Enter for the harness to settle).
|
|
119
|
+
# Mirrors `tmux send-keys -t "$T" -l "<text>"`.
|
|
120
|
+
fm_backend_tmux_send_literal() { # <target> <text>
|
|
121
|
+
tmux send-keys -t "$1" -l "$2"
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
# fm_backend_tmux_kill: remove one explicitly named task window, best-effort.
|
|
125
|
+
# Empty, omitted, and malformed targets return nonzero before invoking tmux so
|
|
126
|
+
# tmux can never interpret an empty target as the caller's current window.
|
|
127
|
+
fm_backend_tmux_kill() { # <target>
|
|
128
|
+
local target=${1:-} session window
|
|
129
|
+
case "$target" in
|
|
130
|
+
*:*)
|
|
131
|
+
session=${target%%:*}
|
|
132
|
+
window=${target#*:}
|
|
133
|
+
;;
|
|
134
|
+
*) return 1 ;;
|
|
135
|
+
esac
|
|
136
|
+
case "$session:$window" in
|
|
137
|
+
:*|*:|*:*:*) return 1 ;;
|
|
138
|
+
esac
|
|
139
|
+
tmux kill-window -t "=$session:=$window" 2>/dev/null || true
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
# fm_backend_tmux_current_command: <target>'s live foreground process name -
|
|
143
|
+
# tmux's own `#{pane_current_command}`, already resolved from the pty's
|
|
144
|
+
# foreground process group (verified empirically with real tmux 3.6a: a
|
|
145
|
+
# harness invoked interactively stays the reported command even while it
|
|
146
|
+
# shells out to subcommands that do not take over the pty - e.g. `bash -c
|
|
147
|
+
# "sleep 30"` alone reports "sleep" because bash execs directly into it, but
|
|
148
|
+
# a persisting parent script running `sleep` as a child reports the PARENT's
|
|
149
|
+
# own name throughout; the value reverts to the shell's own name only once
|
|
150
|
+
# the foreground command actually exits). Empty on any tmux error.
|
|
151
|
+
fm_backend_tmux_current_command() { # <target>
|
|
152
|
+
tmux display-message -p -t "$1" '#{pane_current_command}' 2>/dev/null
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
# fm_backend_tmux_classify_process_name: the single owner of the process-name
|
|
156
|
+
# vocabulary shared by every liveness signal below - `agent` for a verified
|
|
157
|
+
# harness, `shell` for an idle login/interactive shell, `other` for anything
|
|
158
|
+
# else. Keeping one classifier means the two independent name sources can never
|
|
159
|
+
# drift into disagreeing about what a given name means.
|
|
160
|
+
fm_backend_tmux_classify_process_name() { # <path> [argv0] -> agent|shell|other
|
|
161
|
+
local path=$1 argv0=${2:-} base
|
|
162
|
+
base=${path##*/}
|
|
163
|
+
base=${base#-}
|
|
164
|
+
case "$base" in
|
|
165
|
+
# muse is anchored rather than globbed like its neighbours: its installed
|
|
166
|
+
# binary is muse-bin-<version> (the launcher execs it, so the version is the
|
|
167
|
+
# live process name and changes on every auto-update), and unlike `claude` or
|
|
168
|
+
# `codex` the substring `muse` is a common English fragment - a *muse* glob
|
|
169
|
+
# would classify musescore or amuse as a live agent pane. The install path
|
|
170
|
+
# cannot carry it either: ~/.local/bin/muse-bin-<version> has no `muse` path
|
|
171
|
+
# COMPONENT, so the fm_harness_path_name fallback below never fires for it.
|
|
172
|
+
muse|muse-bin-*) printf 'agent' ;;
|
|
173
|
+
*claude*|*codex*|*opencode*|*grok*|*kimi*|pi|pi-signed|pi-launcher|Pi) printf 'agent' ;;
|
|
174
|
+
zsh|bash|sh|dash|ash|ksh|mksh|tcsh|csh|fish) printf 'shell' ;;
|
|
175
|
+
*)
|
|
176
|
+
if fm_harness_path_name "$path" >/dev/null || fm_harness_path_name "$argv0" >/dev/null; then
|
|
177
|
+
printf 'agent'
|
|
178
|
+
# cursor-agent runs as a bundled node script, so tmux reports the pane
|
|
179
|
+
# command as a bare `node` that no name pattern above can own, and its
|
|
180
|
+
# other installed name is the far-too-generic `agent` (verified live on
|
|
181
|
+
# cursor-agent 2026.08.11-e8db854: #{pane_current_command} is `node` while
|
|
182
|
+
# `ps -o comm=` carries the cursor-agent install path). Identity therefore
|
|
183
|
+
# comes from the narrowed structural rule in bin/fm-cursor-lib.sh, which
|
|
184
|
+
# demands Cursor's own name or install tree in the path or argv[0]. An
|
|
185
|
+
# unrelated `node` or `agent` matches nothing here and stays `other`,
|
|
186
|
+
# which the callers above fold into `ambiguous` rather than `dead`, so a
|
|
187
|
+
# stranger's node pane is never reported as an agent-free pane.
|
|
188
|
+
elif fm_cursor_process_matches "${path:-$argv0}" '' "$argv0"; then
|
|
189
|
+
printf 'agent'
|
|
190
|
+
else
|
|
191
|
+
printf 'other'
|
|
192
|
+
fi
|
|
193
|
+
;;
|
|
194
|
+
esac
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
# fm_backend_tmux_foreground_comms: the kernel-side names of every process in
|
|
198
|
+
# <target>'s pane tty foreground process group, one full value per line.
|
|
199
|
+
# Empty on any failure.
|
|
200
|
+
#
|
|
201
|
+
# This is the foreground-process-group half of the liveness probe, and it exists
|
|
202
|
+
# because `#{pane_current_command}` and `ps -o comm=` expose different name
|
|
203
|
+
# fields whose roles vary by platform. On macOS the tmux field can carry a
|
|
204
|
+
# harness-rewritten title (Claude Code 2.1.220 reports `2.1.220`) while `comm`
|
|
205
|
+
# retains executable identity; the portable Linux regression observes the
|
|
206
|
+
# reverse for its version-named executable. Reading both `comm` and argv[0]
|
|
207
|
+
# preserves an identifying install path without making either platform's field
|
|
208
|
+
# assignment load-bearing.
|
|
209
|
+
#
|
|
210
|
+
# Scoping to the foreground process group rather than to the pane's descendants
|
|
211
|
+
# is what keeps the probe honest in the other direction: a harness-named process
|
|
212
|
+
# left running in the background of an otherwise idle pane is deliberately NOT
|
|
213
|
+
# reported, so a genuinely agent-free pane still classifies `dead`. It also
|
|
214
|
+
# reports every member of a multi-process launcher (the Pi Launcher path runs a
|
|
215
|
+
# `pi-signed` wrapper and a `pi` engine in one group), so no launcher needs its
|
|
216
|
+
# own special case here.
|
|
217
|
+
#
|
|
218
|
+
# Like fm_backend_tmux_current_command this is a RAW pane read: tmux answers an
|
|
219
|
+
# absent target from the client's active window rather than failing, so callers
|
|
220
|
+
# must confirm exact window membership first, exactly as the classifier below
|
|
221
|
+
# does, or they will describe some other pane entirely.
|
|
222
|
+
fm_backend_tmux_foreground_comms() { # <target>
|
|
223
|
+
local target=$1 tty pid pgid tpgid comm
|
|
224
|
+
tty=$(tmux display-message -p -t "$target" '#{pane_tty}' 2>/dev/null) || return 0
|
|
225
|
+
[ -n "$tty" ] || return 0
|
|
226
|
+
LC_ALL=C ps -t "${tty#/dev/}" -o pid=,pgid=,tpgid=,comm= 2>/dev/null \
|
|
227
|
+
| while read -r pid pgid tpgid comm; do
|
|
228
|
+
[ -n "$comm" ] || continue
|
|
229
|
+
[ "$pgid" = "$tpgid" ] || continue
|
|
230
|
+
printf '%s\n' "$comm"
|
|
231
|
+
done
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
fm_backend_tmux_foreground_argv0s() { # <target>
|
|
235
|
+
local target=$1 tty pid pgid tpgid comm args argv0
|
|
236
|
+
tty=$(tmux display-message -p -t "$target" '#{pane_tty}' 2>/dev/null) || return 0
|
|
237
|
+
[ -n "$tty" ] || return 0
|
|
238
|
+
LC_ALL=C ps -t "${tty#/dev/}" -o pid=,pgid=,tpgid=,comm= 2>/dev/null \
|
|
239
|
+
| while read -r pid pgid tpgid comm; do
|
|
240
|
+
[ -n "$comm" ] || continue
|
|
241
|
+
[ "$pgid" = "$tpgid" ] || continue
|
|
242
|
+
args=$(LC_ALL=C ps -p "$pid" -o args= 2>/dev/null) || continue
|
|
243
|
+
args=${args#"${args%%[![:space:]]*}"}
|
|
244
|
+
argv0=${args%%[[:space:]]*}
|
|
245
|
+
[ -n "$argv0" ] && printf '%s\n' "$argv0"
|
|
246
|
+
done
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
# fm_backend_tmux_agent_state: recovery-grade harness-agent state for one
|
|
250
|
+
# recorded target. See bin/fm-backend.sh's fm_backend_agent_state for the
|
|
251
|
+
# shared state vocabulary and docs/tmux-backend.md "Agent liveness probe" for
|
|
252
|
+
# the empirical basis. Tmux silently falls back to the active window when a
|
|
253
|
+
# named target is absent, so the exact recorded window must appear in a
|
|
254
|
+
# successful session inventory before its foreground command can be trusted.
|
|
255
|
+
# An omitted window or a definitive missing-session/server response is
|
|
256
|
+
# `missing`; any other inventory or pane read failure is `unreadable`, so a
|
|
257
|
+
# transient tmux problem never licenses a duplicate.
|
|
258
|
+
#
|
|
259
|
+
# The verdict combines two independent name sources rather than trusting either
|
|
260
|
+
# alone. Either source naming a verified harness is enough for `alive`, because
|
|
261
|
+
# a false `dead` is the one outcome that can launch a duplicate agent onto a
|
|
262
|
+
# live worktree, while the foreground process group - when it is readable - is
|
|
263
|
+
# authoritative for the negative verdicts, since it is the only source that can
|
|
264
|
+
# distinguish a truly idle pane from a rewritten process title.
|
|
265
|
+
fm_backend_tmux_agent_state() { # <target>
|
|
266
|
+
local target=$1 comm session window windows inventory_status
|
|
267
|
+
local foreground argv0s name fg_seen=0 fg_shell=0 fg_other=0
|
|
268
|
+
case "$target" in
|
|
269
|
+
*:*:*|'':*|*:'') printf 'unreadable'; return 0 ;;
|
|
270
|
+
*:*) ;;
|
|
271
|
+
*) printf 'unreadable'; return 0 ;;
|
|
272
|
+
esac
|
|
273
|
+
session=${target%%:*}
|
|
274
|
+
window=${target#*:}
|
|
275
|
+
if windows=$(LC_ALL=C tmux list-windows -t "$session" -F '#{window_name}' 2>&1); then
|
|
276
|
+
inventory_status=0
|
|
277
|
+
else
|
|
278
|
+
inventory_status=$?
|
|
279
|
+
fi
|
|
280
|
+
if [ "$inventory_status" -ne 0 ]; then
|
|
281
|
+
case "$windows" in
|
|
282
|
+
*"can't find session:"*|*"no server running on "*|*"error connecting to "*" (No such file or directory)"|*"error connecting to "*" (Connection refused)")
|
|
283
|
+
printf 'missing'
|
|
284
|
+
;;
|
|
285
|
+
*)
|
|
286
|
+
printf 'unreadable'
|
|
287
|
+
;;
|
|
288
|
+
esac
|
|
289
|
+
return 0
|
|
290
|
+
fi
|
|
291
|
+
if ! printf '%s\n' "$windows" | grep -Fqx "$window"; then
|
|
292
|
+
printf 'missing'
|
|
293
|
+
return 0
|
|
294
|
+
fi
|
|
295
|
+
|
|
296
|
+
foreground=$(fm_backend_tmux_foreground_comms "$target")
|
|
297
|
+
while IFS= read -r name; do
|
|
298
|
+
[ -n "$name" ] || continue
|
|
299
|
+
fg_seen=1
|
|
300
|
+
case "$(fm_backend_tmux_classify_process_name "$name")" in
|
|
301
|
+
agent) printf 'alive'; return 0 ;;
|
|
302
|
+
shell) fg_shell=1 ;;
|
|
303
|
+
*) fg_other=1 ;;
|
|
304
|
+
esac
|
|
305
|
+
done <<EOF
|
|
306
|
+
$foreground
|
|
307
|
+
EOF
|
|
308
|
+
|
|
309
|
+
argv0s=$(fm_backend_tmux_foreground_argv0s "$target")
|
|
310
|
+
while IFS= read -r name; do
|
|
311
|
+
[ -n "$name" ] || continue
|
|
312
|
+
if [ "$(fm_backend_tmux_classify_process_name '' "$name")" = agent ]; then
|
|
313
|
+
printf 'alive'
|
|
314
|
+
return 0
|
|
315
|
+
fi
|
|
316
|
+
done <<EOF
|
|
317
|
+
$argv0s
|
|
318
|
+
EOF
|
|
319
|
+
|
|
320
|
+
comm=$(fm_backend_tmux_current_command "$target") || {
|
|
321
|
+
printf 'unreadable'
|
|
322
|
+
return 0
|
|
323
|
+
}
|
|
324
|
+
if [ "$(fm_backend_tmux_classify_process_name "$comm")" = agent ]; then
|
|
325
|
+
printf 'alive'
|
|
326
|
+
return 0
|
|
327
|
+
fi
|
|
328
|
+
|
|
329
|
+
# A readable foreground process group settles the negative verdicts: only a
|
|
330
|
+
# group that is nothing but shells is confidently agent-free.
|
|
331
|
+
if [ "$fg_seen" -eq 1 ]; then
|
|
332
|
+
if [ "$fg_other" -eq 0 ] && [ "$fg_shell" -eq 1 ]; then
|
|
333
|
+
printf 'dead'
|
|
334
|
+
else
|
|
335
|
+
printf 'ambiguous'
|
|
336
|
+
fi
|
|
337
|
+
return 0
|
|
338
|
+
fi
|
|
339
|
+
|
|
340
|
+
case "$comm" in
|
|
341
|
+
'') printf 'unreadable'; return 0 ;;
|
|
342
|
+
esac
|
|
343
|
+
case "$(fm_backend_tmux_classify_process_name "$comm")" in
|
|
344
|
+
shell) printf 'dead' ;;
|
|
345
|
+
*) printf 'ambiguous' ;;
|
|
346
|
+
esac
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
# Backward-compatible three-state view for callers that only need a yes/no
|
|
350
|
+
# agent verdict. The detailed state contract is owned by fm_backend_agent_state.
|
|
351
|
+
fm_backend_tmux_agent_alive() { # <target>
|
|
352
|
+
case "$(fm_backend_tmux_agent_state "$1")" in
|
|
353
|
+
alive) printf 'alive' ;;
|
|
354
|
+
dead|missing) printf 'dead' ;;
|
|
355
|
+
*) printf 'unknown' ;;
|
|
356
|
+
esac
|
|
357
|
+
}
|