@zerwiz/ymir 0.1.3 → 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 -39
- 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,187 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Real Pi/Herdr regression for exact-id secondmate marker delivery.
|
|
3
|
+
#
|
|
4
|
+
# This is opt-in because it launches a real interactive Pi process and a real
|
|
5
|
+
# isolated Herdr lab session.
|
|
6
|
+
# It exercises the end-user command shape against metadata written by a real
|
|
7
|
+
# fm-spawn.sh --secondmate launch, captures Pi's before_agent_start prompt bytes,
|
|
8
|
+
# and proves both sides of the routing boundary:
|
|
9
|
+
# - exact task id through explicit FM_HOME receives exactly one marker;
|
|
10
|
+
# - direct terminal input remains unmarked.
|
|
11
|
+
#
|
|
12
|
+
# Every Herdr call, including calls made inside the production backend adapter,
|
|
13
|
+
# is routed through bin/fm-herdr-lab.sh. The PATH shim strips only the adapter's
|
|
14
|
+
# already-validated trailing --session pair, then delegates to the lab helper,
|
|
15
|
+
# which appends its own required trailing --session before invoking real Herdr.
|
|
16
|
+
set -u
|
|
17
|
+
|
|
18
|
+
# shellcheck source=tests/lib.sh
|
|
19
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
20
|
+
# shellcheck source=/dev/null
|
|
21
|
+
. "$ROOT/bin/fm-marker-lib.sh"
|
|
22
|
+
# shellcheck source=/dev/null
|
|
23
|
+
. "$ROOT/bin/fm-backend.sh"
|
|
24
|
+
|
|
25
|
+
if [ "${FM_SEND_MARKER_HERDR_E2E:-0}" != 1 ]; then
|
|
26
|
+
echo "skip: set FM_SEND_MARKER_HERDR_E2E=1 to run the real Pi/Herdr secondmate-marker regression"
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
for tool in git herdr jq pi; do
|
|
31
|
+
command -v "$tool" >/dev/null 2>&1 || { echo "skip: $tool not found"; exit 0; }
|
|
32
|
+
done
|
|
33
|
+
|
|
34
|
+
LAB_HELPER=${HERDR_LAB_HELPER:-$ROOT/bin/fm-herdr-lab.sh}
|
|
35
|
+
SESSION=$("$LAB_HELPER" name fm-send-secondmate-marker-v7)
|
|
36
|
+
TMP_ROOT=$(mktemp -d "${TMPDIR:-/tmp}/fm-send-marker-herdr-e2e.XXXXXX")
|
|
37
|
+
SENDER_HOME="$TMP_ROOT/sender-home"
|
|
38
|
+
SECOND_HOME="$TMP_ROOT/secondmate-home"
|
|
39
|
+
CAPTURE="$TMP_ROOT/pi-before-agent.jsonl"
|
|
40
|
+
FAKEBIN="$TMP_ROOT/fakebin"
|
|
41
|
+
ORIGINAL_PATH=$PATH
|
|
42
|
+
REAL_PI=$(command -v pi)
|
|
43
|
+
ID='marker-pi-sm'
|
|
44
|
+
REQUEST='FM_MARKER_HERDR_E2E exact-id request'
|
|
45
|
+
DIRECT='FM_MARKER_HERDR_DIRECT captain input'
|
|
46
|
+
|
|
47
|
+
cleanup() {
|
|
48
|
+
local rc=$?
|
|
49
|
+
trap - EXIT
|
|
50
|
+
if ! "$LAB_HELPER" teardown "$SESSION"; then
|
|
51
|
+
rc=1
|
|
52
|
+
fi
|
|
53
|
+
rm -rf "$TMP_ROOT"
|
|
54
|
+
exit "$rc"
|
|
55
|
+
}
|
|
56
|
+
trap cleanup EXIT
|
|
57
|
+
|
|
58
|
+
mkdir -p "$SENDER_HOME/state" "$SENDER_HOME/data" "$SENDER_HOME/config" "$SENDER_HOME/projects" "$FAKEBIN"
|
|
59
|
+
|
|
60
|
+
# Route production adapter invocations through the same guarded helper as every
|
|
61
|
+
# explicit E2E probe. The helper itself runs with the original PATH, preventing
|
|
62
|
+
# recursion into this shim.
|
|
63
|
+
cat > "$FAKEBIN/herdr" <<EOF
|
|
64
|
+
#!/usr/bin/env bash
|
|
65
|
+
set -euo pipefail
|
|
66
|
+
helper='$LAB_HELPER'
|
|
67
|
+
session='$SESSION'
|
|
68
|
+
real_path='$ORIGINAL_PATH'
|
|
69
|
+
args=("\$@")
|
|
70
|
+
n=\${#args[@]}
|
|
71
|
+
if [ "\$n" -ge 2 ] && [ "\${args[\$((n-2))]}" = --session ]; then
|
|
72
|
+
[ "\${args[\$((n-1))]}" = "\$session" ] || { echo "wrapper refused foreign session" >&2; exit 97; }
|
|
73
|
+
args=("\${args[@]:0:\$((n-2))}")
|
|
74
|
+
else
|
|
75
|
+
[ "\${HERDR_SESSION:-}" = "\$session" ] || { echo "wrapper requires the isolated lab session" >&2; exit 98; }
|
|
76
|
+
for arg in "\${args[@]}"; do
|
|
77
|
+
case "\$arg" in
|
|
78
|
+
--session|--session=*) echo "wrapper refused non-trailing session flag" >&2; exit 99 ;;
|
|
79
|
+
esac
|
|
80
|
+
done
|
|
81
|
+
fi
|
|
82
|
+
PATH="\$real_path" exec "\$helper" run "\$session" "\${args[@]}"
|
|
83
|
+
EOF
|
|
84
|
+
chmod +x "$FAKEBIN/herdr"
|
|
85
|
+
|
|
86
|
+
git clone -q --no-hardlinks "$ROOT" "$SECOND_HOME"
|
|
87
|
+
git -C "$SECOND_HOME" checkout -q --detach HEAD
|
|
88
|
+
mkdir -p "$SECOND_HOME/state" "$SECOND_HOME/data" "$SECOND_HOME/config" "$SECOND_HOME/projects"
|
|
89
|
+
printf '%s\n' "$ID" > "$SECOND_HOME/.fm-secondmate-home"
|
|
90
|
+
cat > "$SECOND_HOME/data/charter.md" <<'EOF'
|
|
91
|
+
# Isolated marker capture secondmate
|
|
92
|
+
|
|
93
|
+
You are a task-local secondmate used only for the marker transport regression.
|
|
94
|
+
Stay idle and do not initiate work.
|
|
95
|
+
EOF
|
|
96
|
+
|
|
97
|
+
# A separate explicit Pi extension grants session-only project trust, records
|
|
98
|
+
# before_agent_start prompt bytes, and aborts before any provider request.
|
|
99
|
+
# The PATH wrapper adds only that test resource while preserving the production
|
|
100
|
+
# secondmate launch and its own extension arguments unchanged.
|
|
101
|
+
CAPTURE_JSON=$(printf '%s' "$CAPTURE" | jq -Rs .)
|
|
102
|
+
CAPTURE_EXTENSION="$TMP_ROOT/fm-send-marker-capture.ts"
|
|
103
|
+
cat > "$CAPTURE_EXTENSION" <<EOF
|
|
104
|
+
import { appendFileSync } from "node:fs";
|
|
105
|
+
const capturePath = $CAPTURE_JSON;
|
|
106
|
+
export default function (pi: any) {
|
|
107
|
+
pi.on("project_trust", () => ({ trusted: "yes", remember: false }));
|
|
108
|
+
pi.on("before_agent_start", (event, ctx) => {
|
|
109
|
+
appendFileSync(capturePath, \`\${JSON.stringify({ prompt: event.prompt, hex: Buffer.from(event.prompt, "utf8").toString("hex") })}\\n\`);
|
|
110
|
+
ctx.abort();
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
EOF
|
|
114
|
+
printf '#!/usr/bin/env bash\nexec %q -e %q "$@"\n' "$REAL_PI" "$CAPTURE_EXTENSION" > "$FAKEBIN/pi"
|
|
115
|
+
chmod +x "$FAKEBIN/pi"
|
|
116
|
+
|
|
117
|
+
"$LAB_HELPER" provision "$SESSION"
|
|
118
|
+
PATH="$FAKEBIN:$ORIGINAL_PATH" FM_GATE_REFUSE_BYPASS=1 FM_HOME="$SENDER_HOME" HERDR_SESSION="$SESSION" \
|
|
119
|
+
"$ROOT/bin/fm-spawn.sh" "$ID" "$SECOND_HOME" --secondmate --harness pi --backend herdr >/dev/null
|
|
120
|
+
|
|
121
|
+
META="$SENDER_HOME/state/$ID.meta"
|
|
122
|
+
[ -f "$META" ] || fail "real secondmate spawn did not write exact-id metadata"
|
|
123
|
+
[ "$(fm_meta_get "$META" kind)" = secondmate ] || fail "real secondmate metadata did not record kind=secondmate"
|
|
124
|
+
TARGET=$(fm_backend_target_of_meta "$META")
|
|
125
|
+
PANE=${TARGET#*:}
|
|
126
|
+
case "$TARGET" in
|
|
127
|
+
"$SESSION":w*:p*) : ;;
|
|
128
|
+
*) fail "real secondmate metadata recorded an unexpected Herdr target: $TARGET" ;;
|
|
129
|
+
esac
|
|
130
|
+
|
|
131
|
+
wait_for_prompt() { # <needle>
|
|
132
|
+
local needle=$1 _
|
|
133
|
+
for _ in $(seq 1 240); do
|
|
134
|
+
if [ -s "$CAPTURE" ] && jq -e --arg needle "$needle" 'select(.prompt | contains($needle))' "$CAPTURE" >/dev/null 2>&1; then
|
|
135
|
+
return 0
|
|
136
|
+
fi
|
|
137
|
+
sleep 0.25
|
|
138
|
+
done
|
|
139
|
+
return 1
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
wait_for_idle() {
|
|
143
|
+
local status _ stable=0
|
|
144
|
+
for _ in $(seq 1 240); do
|
|
145
|
+
status=$("$LAB_HELPER" run "$SESSION" agent get "$PANE" 2>/dev/null \
|
|
146
|
+
| jq -r '.result.agent.agent_status // empty' 2>/dev/null || true)
|
|
147
|
+
case "$status" in
|
|
148
|
+
idle|done)
|
|
149
|
+
stable=$((stable + 1))
|
|
150
|
+
[ "$stable" -ge 4 ] && return 0
|
|
151
|
+
;;
|
|
152
|
+
*) stable=0 ;;
|
|
153
|
+
esac
|
|
154
|
+
sleep 0.25
|
|
155
|
+
done
|
|
156
|
+
return 1
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# The startup charter proves the CLI extension loaded. Wait until ctx.abort()
|
|
160
|
+
# has remained idle long enough for the Pi composer to fully settle before
|
|
161
|
+
# exercising it. A single native idle sample can precede Pi's final redraw.
|
|
162
|
+
wait_for_prompt 'Isolated marker capture secondmate' \
|
|
163
|
+
|| fail "real Pi before_agent_start capture did not load for the startup charter"
|
|
164
|
+
wait_for_idle || fail "real Pi did not become idle after the startup capture"
|
|
165
|
+
|
|
166
|
+
PATH="$FAKEBIN:$ORIGINAL_PATH" FM_GATE_REFUSE_BYPASS=1 FM_HOME="$SENDER_HOME" \
|
|
167
|
+
"$ROOT/bin/fm-send.sh" "$ID" "$REQUEST" >/dev/null
|
|
168
|
+
wait_for_prompt "$REQUEST" || fail "real Pi did not receive the exact-id fm-send request"
|
|
169
|
+
GOT=$(jq -r --arg needle "$REQUEST" 'select(.prompt | contains($needle)) | .prompt' "$CAPTURE" | tail -1)
|
|
170
|
+
[ "$GOT" = "${FM_FROMFIRST_MARK}${REQUEST}" ] \
|
|
171
|
+
|| fail "real Pi exact-id prompt did not contain exactly one terminal-safe marker"$'\n'"--- bytes ---"$'\n'"$(printf '%s' "$GOT" | od -An -tx1)"
|
|
172
|
+
printf 'evidence: exact-id received-hex=%s\n' "$(printf '%s' "$GOT" | od -An -tx1 | tr -d ' \n')"
|
|
173
|
+
pass "real Pi/Herdr: exact-id FM_HOME send delivers exactly one from-firstmate marker"
|
|
174
|
+
wait_for_idle || fail "real Pi did not become idle after the exact-id capture"
|
|
175
|
+
|
|
176
|
+
# Direct terminal input bypasses fm-send's metadata-routed transformation and
|
|
177
|
+
# therefore remains conversational captain input.
|
|
178
|
+
"$LAB_HELPER" run "$SESSION" pane send-text "$PANE" "$DIRECT" >/dev/null
|
|
179
|
+
"$LAB_HELPER" run "$SESSION" pane send-keys "$PANE" enter >/dev/null
|
|
180
|
+
wait_for_prompt "$DIRECT" || fail "real Pi did not receive direct terminal input"
|
|
181
|
+
GOT=$(jq -r --arg needle "$DIRECT" 'select(.prompt | contains($needle)) | .prompt' "$CAPTURE" | tail -1)
|
|
182
|
+
[ "$GOT" = "$DIRECT" ] || fail "direct captain input was changed or marked"$'\n'"--- bytes ---"$'\n'"$(printf '%s' "$GOT" | od -An -tx1)"
|
|
183
|
+
if fm_message_from_firstmate "$GOT"; then
|
|
184
|
+
fail "direct captain input was classified as from-firstmate"
|
|
185
|
+
fi
|
|
186
|
+
printf 'evidence: direct-input received-hex=%s\n' "$(printf '%s' "$GOT" | od -An -tx1 | tr -d ' \n')"
|
|
187
|
+
pass "real Pi/Herdr: direct captain terminal input stays unmarked"
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# fm-send from-firstmate marker for secondmate targets.
|
|
3
|
+
#
|
|
4
|
+
# A secondmate is itself a firstmate, so a request relayed to it lands in its own
|
|
5
|
+
# chat - which the main firstmate never reads (the only channel back is the terse
|
|
6
|
+
# status file). fm-send therefore prepends a from-firstmate marker
|
|
7
|
+
# (bin/fm-marker-lib.sh) when, and only when, the resolved target is a task
|
|
8
|
+
# selector whose meta records kind=secondmate, so the secondmate can recognize
|
|
9
|
+
# the request and route its reply via the status path. The marker now travels
|
|
10
|
+
# inside the durable inbox record's body (the payload is never typed; only the
|
|
11
|
+
# doorbell is). These tests pin that behavior hermetically (stubbed tmux, no
|
|
12
|
+
# real agent):
|
|
13
|
+
# 1. Exact-id and stable-label kind=secondmate selectors prepend the marker
|
|
14
|
+
# to the recorded steer, never to the typed doorbell.
|
|
15
|
+
# 2. Exact-id and stable-label ordinary crewmate selectors stay unmarked.
|
|
16
|
+
# 3. Explicit endpoints stay unmarked and typed, with or without local meta.
|
|
17
|
+
# 4. The --key path never carries the marker and never enqueues a record.
|
|
18
|
+
# 5. Direct captain text stays unmarked, and already-marked text is idempotent.
|
|
19
|
+
# 6. The marker is the label plus terminal-safe U+2063 INVISIBLE SEPARATOR.
|
|
20
|
+
set -u
|
|
21
|
+
|
|
22
|
+
# shellcheck source=tests/lib.sh
|
|
23
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
24
|
+
# shellcheck source=/dev/null
|
|
25
|
+
. "$ROOT/bin/fm-marker-lib.sh"
|
|
26
|
+
|
|
27
|
+
SEND="$ROOT/bin/fm-send.sh"
|
|
28
|
+
|
|
29
|
+
TMP_ROOT=$(fm_test_tmproot fm-send-marker)
|
|
30
|
+
|
|
31
|
+
# A fake tmux that (a) records the literal text of every `send-keys -l` to
|
|
32
|
+
# FM_SEND_LOG and (b) lets fm-send's submit path reach a clean "empty" verdict.
|
|
33
|
+
# display-message yields a numeric cursor_y; capture-pane returns an empty
|
|
34
|
+
# bordered composer so fm_tmux_composer_state reads "empty" (submit landed) on the
|
|
35
|
+
# first Enter. Only the literal (-l) text is logged; Enter retries and --key sends
|
|
36
|
+
# are not, so the log holds exactly what was typed into the composer.
|
|
37
|
+
make_stubs() { # <dir> -> echoes fakebin dir
|
|
38
|
+
local dir=$1 fb="$1/fakebin"
|
|
39
|
+
mkdir -p "$fb"
|
|
40
|
+
cat > "$fb/tmux" <<'SH'
|
|
41
|
+
#!/usr/bin/env bash
|
|
42
|
+
set -u
|
|
43
|
+
case "${1:-}" in
|
|
44
|
+
send-keys)
|
|
45
|
+
shift
|
|
46
|
+
literal=0
|
|
47
|
+
while [ $# -gt 0 ]; do
|
|
48
|
+
case "$1" in
|
|
49
|
+
-t) shift 2 ;;
|
|
50
|
+
-l) literal=1; shift ;;
|
|
51
|
+
*) break ;;
|
|
52
|
+
esac
|
|
53
|
+
done
|
|
54
|
+
if [ "$literal" = 1 ]; then
|
|
55
|
+
printf '%s' "${1:-}" >> "$FM_SEND_LOG"
|
|
56
|
+
fi
|
|
57
|
+
exit 0 ;;
|
|
58
|
+
display-message)
|
|
59
|
+
for a in "$@"; do case "$a" in *cursor_y*) printf '1\n'; exit 0 ;; esac; done
|
|
60
|
+
printf 'fakepane\n'; exit 0 ;;
|
|
61
|
+
capture-pane) printf '╭────╮\n│ │\n╰────╯\n'; exit 0 ;;
|
|
62
|
+
list-windows) exit 0 ;;
|
|
63
|
+
esac
|
|
64
|
+
exit 0
|
|
65
|
+
SH
|
|
66
|
+
chmod +x "$fb/tmux"
|
|
67
|
+
cat > "$fb/sleep" <<'SH'
|
|
68
|
+
#!/usr/bin/env bash
|
|
69
|
+
exit 0
|
|
70
|
+
SH
|
|
71
|
+
chmod +x "$fb/sleep"
|
|
72
|
+
printf '%s\n' "$fb"
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
# run_send <fakebin> <home> <send-log> -- <fm-send args...>
|
|
76
|
+
# Runs fm-send.sh with the stubs on PATH against the given home (which holds
|
|
77
|
+
# state/<id>.meta). FM_ROOT_OVERRIDE points at the same non-repo home so
|
|
78
|
+
# fm-guard's tangle check stays silent; guard noise goes to stderr (discarded).
|
|
79
|
+
# FM_SEND_SETTLE=0 keeps the run fast. Truncates the log first; returns fm-send's
|
|
80
|
+
# exit code.
|
|
81
|
+
run_send() {
|
|
82
|
+
local fb=$1 home=$2 log=$3; shift 3
|
|
83
|
+
: > "$log"
|
|
84
|
+
env PATH="$fb:$PATH" \
|
|
85
|
+
FM_ROOT_OVERRIDE="$home" FM_HOME="$home" FM_SEND_LOG="$log" FM_SEND_SETTLE=0 \
|
|
86
|
+
"$SEND" "$@" 2>/dev/null
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# setup_home <name> -> echoes a fresh home dir with an empty state/.
|
|
90
|
+
setup_home() {
|
|
91
|
+
local home="$TMP_ROOT/$1-$RANDOM"
|
|
92
|
+
mkdir -p "$home/state"
|
|
93
|
+
printf '%s\n' "$home"
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# The exact enqueued text of one inbox record, read through the production
|
|
97
|
+
# owner (bin/fm-task-inbox-lib.sh). Command substitution strips trailing
|
|
98
|
+
# newlines, so byte-exact trailing assertions read the raw record instead.
|
|
99
|
+
record_body() { # <record-path>
|
|
100
|
+
bash -c '. "$1"; fm_task_inbox_body "$2"' _ "$ROOT/bin/fm-task-inbox-lib.sh" "$1"
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
test_secondmate_target_is_marked() {
|
|
104
|
+
local dir fb log home rc got corr
|
|
105
|
+
dir="$TMP_ROOT/sm"; mkdir -p "$dir"
|
|
106
|
+
fb=$(make_stubs "$dir"); log="$dir/send.log"
|
|
107
|
+
home=$(setup_home sm)
|
|
108
|
+
fm_write_secondmate_meta "$home/state/domain.meta" "$home" "sess:fm-domain"
|
|
109
|
+
run_send "$fb" "$home" "$log" "fm-domain" "audit the build"; rc=$?
|
|
110
|
+
expect_code 0 "$rc" "send to a secondmate target should succeed"
|
|
111
|
+
got=$(record_body "$home/state/domain.inbox/001.msg")
|
|
112
|
+
case "$got" in
|
|
113
|
+
"$FM_FROMFIRST_MARK"corr=[a-f0-9][a-f0-9]*) : ;;
|
|
114
|
+
*) fail "secondmate send: the recorded steer should be marker+corr+text"$'\n'"--- bytes ---"$'\n'"$(printf '%s' "$got" | od -An -c)" ;;
|
|
115
|
+
esac
|
|
116
|
+
case "$got" in
|
|
117
|
+
*audit\ the\ build) : ;;
|
|
118
|
+
*) fail "secondmate send lost the request body"$'\n'"$got" ;;
|
|
119
|
+
esac
|
|
120
|
+
case "$(cat "$log")" in
|
|
121
|
+
*"$FM_FROMFIRST_MARK"*) fail "the marker must ride the record, never the typed doorbell" ;;
|
|
122
|
+
esac
|
|
123
|
+
# shellcheck source=/dev/null
|
|
124
|
+
. "$ROOT/bin/fm-pending-reply-lib.sh"
|
|
125
|
+
corr=$(fm_pending_reply_extract_corr "$got")
|
|
126
|
+
[ -f "$(fm_pending_reply_path "$home/state" "$corr")" ] \
|
|
127
|
+
|| fail "marked secondmate send should create a parent pending-reply record"
|
|
128
|
+
pass "fm-send: a kind=secondmate target gets the from-firstmate marker and corr prepended"
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
test_exact_secondmate_task_id_is_marked() {
|
|
132
|
+
local dir fb log home rc got already_marked corr
|
|
133
|
+
dir="$TMP_ROOT/sm-exact"; mkdir -p "$dir"
|
|
134
|
+
fb=$(make_stubs "$dir"); log="$dir/send.log"
|
|
135
|
+
home=$(setup_home sm-exact)
|
|
136
|
+
fm_write_secondmate_meta "$home/state/domain.meta" "$home" "sess:fm-domain"
|
|
137
|
+
run_send "$fb" "$home" "$log" "domain" "audit the build"; rc=$?
|
|
138
|
+
expect_code 0 "$rc" "send to an exact secondmate task id should succeed"
|
|
139
|
+
got=$(record_body "$home/state/domain.inbox/001.msg")
|
|
140
|
+
case "$got" in
|
|
141
|
+
"$FM_FROMFIRST_MARK"corr=[a-f0-9]*) : ;;
|
|
142
|
+
*) fail "exact secondmate send: the recorded steer should be marker+corr+text"$'\n'"--- bytes ---"$'\n'"$(printf '%s' "$got" | od -An -c)" ;;
|
|
143
|
+
esac
|
|
144
|
+
# shellcheck source=/dev/null
|
|
145
|
+
. "$ROOT/bin/fm-pending-reply-lib.sh"
|
|
146
|
+
corr=$(fm_pending_reply_extract_corr "$got")
|
|
147
|
+
# Resend with the same corr already present: embed is idempotent for that corr.
|
|
148
|
+
already_marked="${FM_FROMFIRST_MARK}corr=${corr} already routed"
|
|
149
|
+
run_send "$fb" "$home" "$log" "domain" "$already_marked"; rc=$?
|
|
150
|
+
expect_code 0 "$rc" "send of already-marked exact-id content should succeed"
|
|
151
|
+
got=$(record_body "$home/state/domain.inbox/002.msg")
|
|
152
|
+
case "$got" in
|
|
153
|
+
"${FM_FROMFIRST_MARK}corr=${corr} already routed") : ;;
|
|
154
|
+
*) fail "exact secondmate send altered already-correlated content"$'\n'"--- bytes ---"$'\n'"$(printf '%s' "$got" | od -An -tx1)" ;;
|
|
155
|
+
esac
|
|
156
|
+
pass "fm-send: an exact kind=secondmate task id is marked with corr exactly once"
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
test_crewmate_target_is_not_marked() {
|
|
160
|
+
local dir fb log home rc got
|
|
161
|
+
dir="$TMP_ROOT/crew"; mkdir -p "$dir"
|
|
162
|
+
fb=$(make_stubs "$dir"); log="$dir/send.log"
|
|
163
|
+
home=$(setup_home crew)
|
|
164
|
+
fm_write_meta "$home/state/build.meta" \
|
|
165
|
+
"window=sess:fm-build" "worktree=$home/wt" "project=$home/p" \
|
|
166
|
+
"harness=echo" "kind=ship" "mode=no-mistakes" "yolo=off"
|
|
167
|
+
run_send "$fb" "$home" "$log" "fm-build" "fix the test"; rc=$?
|
|
168
|
+
expect_code 0 "$rc" "send to a stable-label crewmate target should succeed"
|
|
169
|
+
got=$(record_body "$home/state/build.inbox/001.msg")
|
|
170
|
+
[ "$got" = "fix the test" ] \
|
|
171
|
+
|| fail "stable-label crewmate send: expected bare recorded text, got marker or other"$'\n'"--- bytes ---"$'\n'"$(printf '%s' "$got" | od -An -c)"
|
|
172
|
+
run_send "$fb" "$home" "$log" "build" "fix the exact test"; rc=$?
|
|
173
|
+
expect_code 0 "$rc" "send to an exact-id crewmate target should succeed"
|
|
174
|
+
got=$(record_body "$home/state/build.inbox/002.msg")
|
|
175
|
+
[ "$got" = "fix the exact test" ] \
|
|
176
|
+
|| fail "exact-id crewmate send: expected bare recorded text, got marker or other"$'\n'"--- bytes ---"$'\n'"$(printf '%s' "$got" | od -An -c)"
|
|
177
|
+
pass "fm-send: exact-id and stable-label kind=ship selectors are sent unmarked"
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
test_explicit_window_is_not_marked() {
|
|
181
|
+
local dir fb log home rc got
|
|
182
|
+
dir="$TMP_ROOT/explicit"; mkdir -p "$dir"
|
|
183
|
+
fb=$(make_stubs "$dir"); log="$dir/send.log"
|
|
184
|
+
home=$(setup_home explicit)
|
|
185
|
+
# An explicit endpoint is not a task selector, so even matching secondmate
|
|
186
|
+
# metadata must not make fm-send guess the caller's intent and mark it.
|
|
187
|
+
fm_write_secondmate_meta "$home/state/win.meta" "$home" "other:win"
|
|
188
|
+
run_send "$fb" "$home" "$log" "other:win" "ping"; rc=$?
|
|
189
|
+
expect_code 0 "$rc" "send to an explicit window with matching meta should succeed"
|
|
190
|
+
got=$(cat "$log")
|
|
191
|
+
[ "$got" = "ping" ] \
|
|
192
|
+
|| fail "explicit session:window send with meta: expected bare text, got marker"$'\n'"--- bytes ---"$'\n'"$(printf '%s' "$got" | od -An -c)"
|
|
193
|
+
|
|
194
|
+
home=$(setup_home explicit-no-meta)
|
|
195
|
+
run_send "$fb" "$home" "$log" "outside:window" "outside ping"; rc=$?
|
|
196
|
+
expect_code 0 "$rc" "send to an explicit window with no local meta should succeed"
|
|
197
|
+
got=$(cat "$log")
|
|
198
|
+
[ "$got" = "outside ping" ] \
|
|
199
|
+
|| fail "explicit session:window send without meta: expected bare text, got marker"$'\n'"--- bytes ---"$'\n'"$(printf '%s' "$got" | od -An -c)"
|
|
200
|
+
pass "fm-send: explicit endpoints stay unmarked with or without local metadata"
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
test_key_path_is_not_marked() {
|
|
204
|
+
local dir fb log home rc
|
|
205
|
+
dir="$TMP_ROOT/key"; mkdir -p "$dir"
|
|
206
|
+
fb=$(make_stubs "$dir"); log="$dir/send.log"
|
|
207
|
+
home=$(setup_home key)
|
|
208
|
+
fm_write_secondmate_meta "$home/state/domain.meta" "$home" "sess:fm-domain"
|
|
209
|
+
run_send "$fb" "$home" "$log" "fm-domain" --key Escape; rc=$?
|
|
210
|
+
expect_code 0 "$rc" "--key send to a secondmate should succeed"
|
|
211
|
+
[ ! -s "$log" ] \
|
|
212
|
+
|| fail "--key path logged a literal send (marker leaked into a keypress)"$'\n'"--- bytes ---"$'\n'"$(od -An -c "$log")"
|
|
213
|
+
[ ! -d "$home/state/domain.inbox" ] \
|
|
214
|
+
|| fail "--key path must never enqueue an inbox record"
|
|
215
|
+
pass "fm-send: the --key path carries no marker (no literal text is typed)"
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
test_marker_is_label_plus_invisible_separator() {
|
|
219
|
+
local separator hex
|
|
220
|
+
separator=$(printf '\342\201\243')
|
|
221
|
+
[ "$FM_FROMFIRST_MARK" = "[fm-from-firstmate]$separator" ] \
|
|
222
|
+
|| fail "marker is not the expected label + U+2063 sequence"$'\n'"--- bytes ---"$'\n'"$(printf '%s' "$FM_FROMFIRST_MARK" | od -An -tx1)"
|
|
223
|
+
hex=$(printf '%s' "$FM_FROMFIRST_MARK" | od -An -tx1 | tr -d ' \n')
|
|
224
|
+
case "$hex" in
|
|
225
|
+
*e281a3) : ;;
|
|
226
|
+
*) fail "marker does not end in UTF-8 U+2063 bytes e2 81 a3; bytes were: $hex" ;;
|
|
227
|
+
esac
|
|
228
|
+
fm_message_from_firstmate "${FM_FROMFIRST_MARK}do the work" \
|
|
229
|
+
|| fail "detector should recognize a marked message"
|
|
230
|
+
fm_message_from_firstmate "do the work" \
|
|
231
|
+
&& fail "direct captain input must remain unmarked"
|
|
232
|
+
fm_message_from_firstmate "[fm-from-firstmate]do the work" \
|
|
233
|
+
&& fail "detector must reject the label without U+2063"
|
|
234
|
+
pass "fm-send: the marker is '[fm-from-firstmate]' + terminal-safe U+2063, while direct captain text stays unmarked"
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
test_marker_transformation_is_idempotent() {
|
|
238
|
+
local once twice
|
|
239
|
+
fm_message_mark_from_firstmate "do the work" once
|
|
240
|
+
fm_message_mark_from_firstmate "$once" twice
|
|
241
|
+
[ "$once" = "$twice" ] \
|
|
242
|
+
|| fail "already-marked content was double-prefixed"$'\n'"--- once ---"$'\n'"$(printf '%s' "$once" | od -An -tx1)"$'\n'"--- twice ---"$'\n'"$(printf '%s' "$twice" | od -An -tx1)"
|
|
243
|
+
[ "$once" = "${FM_FROMFIRST_MARK}do the work" ] \
|
|
244
|
+
|| fail "marker transformation did not prefix bare content exactly once"
|
|
245
|
+
pass "fm-marker: from-firstmate transformation is idempotent"
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
test_marked_send_preserves_trailing_newlines() {
|
|
249
|
+
local dir fb log home rc payload corr expected actual expected_message
|
|
250
|
+
dir="$TMP_ROOT/sm-trailing-newlines"; mkdir -p "$dir"
|
|
251
|
+
fb=$(make_stubs "$dir"); log="$dir/send.log"
|
|
252
|
+
home=$(setup_home sm-trailing-newlines)
|
|
253
|
+
fm_write_secondmate_meta "$home/state/domain.meta" "$home" "sess:fm-domain"
|
|
254
|
+
payload=$'audit the build\n\n'
|
|
255
|
+
run_send "$fb" "$home" "$log" "domain" "$payload"; rc=$?
|
|
256
|
+
expect_code 0 "$rc" "marked send with trailing newlines should succeed"
|
|
257
|
+
# shellcheck source=/dev/null
|
|
258
|
+
. "$ROOT/bin/fm-pending-reply-lib.sh"
|
|
259
|
+
corr=$(fm_pending_reply_extract_corr "$(record_body "$home/state/domain.inbox/001.msg")")
|
|
260
|
+
[ -n "$corr" ] || fail "marked send should embed a corr id"
|
|
261
|
+
fm_pending_reply_embed_corr "$payload" "$corr" expected_message
|
|
262
|
+
expected="$dir/expected.body"
|
|
263
|
+
actual="$dir/actual.body"
|
|
264
|
+
printf '%s' "$expected_message" > "$expected"
|
|
265
|
+
record_body "$home/state/domain.inbox/001.msg" > "$actual"
|
|
266
|
+
cmp -s "$expected" "$actual" \
|
|
267
|
+
|| fail "the marked record did not preserve trailing newline bytes exactly"
|
|
268
|
+
pass "fm-send: marked secondmate payload preserves trailing newline bytes in its record"
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
test_secondmate_target_is_marked
|
|
272
|
+
test_exact_secondmate_task_id_is_marked
|
|
273
|
+
test_crewmate_target_is_not_marked
|
|
274
|
+
test_explicit_window_is_not_marked
|
|
275
|
+
test_key_path_is_not_marked
|
|
276
|
+
test_marker_is_label_plus_invisible_separator
|
|
277
|
+
test_marker_transformation_is_idempotent
|
|
278
|
+
test_marked_send_preserves_trailing_newlines
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# fm-send typed-plane post-submit settle pause (FM_SEND_SETTLE).
|
|
3
|
+
#
|
|
4
|
+
# A typed-plane fm-send success only proves the composer cleared - the Enter
|
|
5
|
+
# landed and the text was submitted. The harness then takes a beat to spin up the
|
|
6
|
+
# turn before its busy footer appears, so an immediate peek after fm-send returns
|
|
7
|
+
# would see the stale idle pane. fm-send therefore pauses FM_SEND_SETTLE seconds
|
|
8
|
+
# (default 1, 0 disables) after a successful typed submit, so the receiving turn
|
|
9
|
+
# has time to visibly start. These tests use an explicit backend target to stay on
|
|
10
|
+
# that plane and pin the behavior hermetically (stubbed tmux + sleep, no real
|
|
11
|
+
# agent):
|
|
12
|
+
# 1. A successful typed text send pauses for the FM_SEND_SETTLE value (default 1).
|
|
13
|
+
# 2. FM_SEND_SETTLE=0 produces no pause at all (sleep is never invoked for it).
|
|
14
|
+
# 3. The pause is tunable (FM_SEND_SETTLE=7 pauses 7).
|
|
15
|
+
# 4. The --key path never pauses (it bypasses the submit/settle path entirely).
|
|
16
|
+
set -u
|
|
17
|
+
|
|
18
|
+
# shellcheck source=tests/lib.sh
|
|
19
|
+
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
20
|
+
# shellcheck source=/dev/null
|
|
21
|
+
. "$ROOT/bin/fm-busy-lib.sh"
|
|
22
|
+
|
|
23
|
+
SEND="$ROOT/bin/fm-send.sh"
|
|
24
|
+
|
|
25
|
+
TMP_ROOT=$(fm_test_tmproot fm-send-settle)
|
|
26
|
+
|
|
27
|
+
# A fake tmux that lets fm-send's submit path reach a clean "empty" verdict, plus a
|
|
28
|
+
# fake sleep that records every requested duration (one per line) instead of
|
|
29
|
+
# sleeping. send-keys always succeeds; display-message yields a numeric cursor_y;
|
|
30
|
+
# capture-pane returns an empty bordered composer so fm_tmux_composer_state reads
|
|
31
|
+
# "empty" (submit landed) on the first Enter. The sleep log path comes from
|
|
32
|
+
# FM_SLEEP_LOG.
|
|
33
|
+
make_stubs() { # <dir> -> echoes fakebin dir
|
|
34
|
+
local dir=$1 fb="$1/fakebin"
|
|
35
|
+
mkdir -p "$fb"
|
|
36
|
+
cat > "$fb/tmux" <<'SH'
|
|
37
|
+
#!/usr/bin/env bash
|
|
38
|
+
set -u
|
|
39
|
+
case "${1:-}" in
|
|
40
|
+
send-keys) exit 0 ;;
|
|
41
|
+
display-message)
|
|
42
|
+
for a in "$@"; do case "$a" in *cursor_y*) printf '1\n'; exit 0 ;; esac; done
|
|
43
|
+
printf 'fakepane\n'; exit 0 ;;
|
|
44
|
+
capture-pane) printf '╭────╮\n│ │\n╰────╯\n'; exit 0 ;;
|
|
45
|
+
list-windows) exit 0 ;;
|
|
46
|
+
esac
|
|
47
|
+
exit 0
|
|
48
|
+
SH
|
|
49
|
+
chmod +x "$fb/tmux"
|
|
50
|
+
cat > "$fb/sleep" <<'SH'
|
|
51
|
+
#!/usr/bin/env bash
|
|
52
|
+
printf '%s\n' "${1:-}" >> "$FM_SLEEP_LOG"
|
|
53
|
+
exit 0
|
|
54
|
+
SH
|
|
55
|
+
chmod +x "$fb/sleep"
|
|
56
|
+
printf '%s\n' "$fb"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# run_send <fakebin> <sleep-log> [env-assignments...] -- <fm-send args...>
|
|
60
|
+
# Runs fm-send.sh with the stubs on PATH. FM_ROOT_OVERRIDE points at a non-repo
|
|
61
|
+
# temp dir so fm-guard's tangle check stays silent, and FM_HOME at an empty home so
|
|
62
|
+
# no in-flight task is seen; guard noise goes to stderr (discarded). Echoes nothing;
|
|
63
|
+
# returns fm-send's exit code.
|
|
64
|
+
run_send() {
|
|
65
|
+
local fb=$1 log=$2 home; shift 2
|
|
66
|
+
home="$TMP_ROOT/home-$RANDOM"; mkdir -p "$home/state"
|
|
67
|
+
: > "$log"
|
|
68
|
+
env "$@" PATH="$fb:$PATH" \
|
|
69
|
+
FM_ROOT_OVERRIDE="$home" FM_HOME="$home" FM_SLEEP_LOG="$log" \
|
|
70
|
+
"$SEND" "sess:win" "hello captain" 2>/dev/null
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
test_default_send_pauses_one_second() {
|
|
74
|
+
local dir fb log rc last
|
|
75
|
+
dir="$TMP_ROOT/default"; mkdir -p "$dir"
|
|
76
|
+
fb=$(make_stubs "$dir"); log="$dir/sleep.log"
|
|
77
|
+
run_send "$fb" "$log"; rc=$?
|
|
78
|
+
expect_code 0 "$rc" "default send should succeed"
|
|
79
|
+
last=$(tail -1 "$log")
|
|
80
|
+
[ "$last" = 1 ] || fail "default send: expected a trailing 1s settle pause, got '$last'"$'\n'"--- sleeps ---"$'\n'"$(cat "$log")"
|
|
81
|
+
pass "fm-send: a successful text send pauses the default 1s after submit"
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
test_zero_disables_pause() {
|
|
85
|
+
local dir fb log rc
|
|
86
|
+
dir="$TMP_ROOT/zero"; mkdir -p "$dir"
|
|
87
|
+
fb=$(make_stubs "$dir"); log="$dir/sleep.log"
|
|
88
|
+
run_send "$fb" "$log" FM_SEND_SETTLE=0; rc=$?
|
|
89
|
+
expect_code 0 "$rc" "FM_SEND_SETTLE=0 send should succeed"
|
|
90
|
+
# The disable path must not invoke sleep with 0 at all - the only sleeps left are
|
|
91
|
+
# the submit core's own settle/enter waits, none of which is "0".
|
|
92
|
+
if grep -qx '0' "$log"; then
|
|
93
|
+
fail "FM_SEND_SETTLE=0 still paused (a sleep 0 was recorded)"$'\n'"--- sleeps ---"$'\n'"$(cat "$log")"
|
|
94
|
+
fi
|
|
95
|
+
pass "fm-send: FM_SEND_SETTLE=0 produces no settle pause"
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
test_pause_is_tunable() {
|
|
99
|
+
local dir fb log rc last
|
|
100
|
+
dir="$TMP_ROOT/tunable"; mkdir -p "$dir"
|
|
101
|
+
fb=$(make_stubs "$dir"); log="$dir/sleep.log"
|
|
102
|
+
run_send "$fb" "$log" FM_SEND_SETTLE=7; rc=$?
|
|
103
|
+
expect_code 0 "$rc" "FM_SEND_SETTLE=7 send should succeed"
|
|
104
|
+
last=$(tail -1 "$log")
|
|
105
|
+
[ "$last" = 7 ] || fail "FM_SEND_SETTLE=7: expected a trailing 7s settle pause, got '$last'"$'\n'"--- sleeps ---"$'\n'"$(cat "$log")"
|
|
106
|
+
pass "fm-send: the settle pause is tunable via FM_SEND_SETTLE"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
test_key_path_never_pauses() {
|
|
110
|
+
local dir fb log rc home
|
|
111
|
+
dir="$TMP_ROOT/key"; mkdir -p "$dir"
|
|
112
|
+
fb=$(make_stubs "$dir"); log="$dir/sleep.log"
|
|
113
|
+
home="$dir/home"; mkdir -p "$home/state"
|
|
114
|
+
: > "$log"
|
|
115
|
+
env PATH="$fb:$PATH" FM_ROOT_OVERRIDE="$home" FM_HOME="$home" FM_SLEEP_LOG="$log" \
|
|
116
|
+
"$SEND" "sess:win" --key Escape 2>/dev/null; rc=$?
|
|
117
|
+
expect_code 0 "$rc" "--key send should succeed"
|
|
118
|
+
[ ! -s "$log" ] || fail "--key path paused but must not"$'\n'"--- sleeps ---"$'\n'"$(cat "$log")"
|
|
119
|
+
pass "fm-send: the --key path never pauses (settle scoped to text submit)"
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
test_claude_escape_records_interrupt_idle() {
|
|
123
|
+
local dir fb log rc home gen out
|
|
124
|
+
dir="$TMP_ROOT/claude-interrupt"; mkdir -p "$dir"
|
|
125
|
+
fb=$(make_stubs "$dir"); log="$dir/sleep.log"
|
|
126
|
+
home="$dir/home"; mkdir -p "$home/state"
|
|
127
|
+
fm_write_meta "$home/state/task.meta" \
|
|
128
|
+
"window=sess:win" "worktree=$home/wt" "project=$home/project" \
|
|
129
|
+
"harness=claude" "kind=ship" "mode=no-mistakes" "yolo=off"
|
|
130
|
+
gen=$("$ROOT/bin/fm-busy-event.sh" arm "$home/state" task)
|
|
131
|
+
printf 'busy_gen=%s\n' "$gen" >> "$home/state/task.meta"
|
|
132
|
+
: > "$log"
|
|
133
|
+
|
|
134
|
+
env PATH="$fb:$PATH" FM_HOME="$home" FM_SLEEP_LOG="$log" \
|
|
135
|
+
"$SEND" task --key Escape 2>/dev/null; rc=$?
|
|
136
|
+
expect_code 0 "$rc" "Claude Escape send should succeed"
|
|
137
|
+
out=$(fm_busy_classify tmux sess:win claude task "$home/state")
|
|
138
|
+
[ "$out" = "idle fm-interrupt" ] \
|
|
139
|
+
|| fail "Claude Escape must classify idle/fm-interrupt, got '$out'"
|
|
140
|
+
pass "fm-send: a successful Claude Escape records the interrupt lifecycle edge"
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
test_default_send_pauses_one_second
|
|
144
|
+
test_zero_disables_pause
|
|
145
|
+
test_pause_is_tunable
|
|
146
|
+
test_key_path_never_pauses
|
|
147
|
+
test_claude_escape_records_interrupt_idle
|