@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,51 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Unit tests for the Sýn PreToolUse seatbelts:
|
|
3
|
+
# bin/syn-arm-pretool-check.sh - the watcher arm is never backgrounded
|
|
4
|
+
# bin/syn-guard-pretool-check.sh - load-bearing invariants stay untouched
|
|
5
|
+
set -u
|
|
6
|
+
|
|
7
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
8
|
+
ARM="$ROOT/bin/syn-arm-pretool-check.sh"
|
|
9
|
+
GUARD="$ROOT/bin/syn-guard-pretool-check.sh"
|
|
10
|
+
fail=0
|
|
11
|
+
|
|
12
|
+
allows() { # <script> <command>
|
|
13
|
+
if "$1" --command "$2" >/dev/null 2>&1; then :
|
|
14
|
+
else printf 'not ok - should allow: %s\n' "$2" >&2; fail=1; fi
|
|
15
|
+
}
|
|
16
|
+
denies() { # <script> <command>
|
|
17
|
+
if "$1" --command "$2" >/dev/null 2>&1; then
|
|
18
|
+
printf 'not ok - should deny: %s\n' "$2" >&2; fail=1
|
|
19
|
+
fi
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# --- arm seatbelt: real backgrounding vs chaining and syntax checks ----------
|
|
23
|
+
|
|
24
|
+
allows "$ARM" 'bash -n bin/syn-watch-arm.sh && echo "syntax OK"'
|
|
25
|
+
allows "$ARM" 'cat bin/syn-watch-arm.sh'
|
|
26
|
+
allows "$ARM" 'echo "chained" && ls'
|
|
27
|
+
denies "$ARM" 'bin/syn-watch-arm.sh --restart &'
|
|
28
|
+
denies "$ARM" 'nohup bin/syn-watch-arm.sh --restart'
|
|
29
|
+
denies "$ARM" 'setsid bin/syn-watch-arm.sh --restart'
|
|
30
|
+
denies "$ARM" 'disown; bin/syn-watch-arm.sh --restart'
|
|
31
|
+
|
|
32
|
+
# --- invariant seatbelt: destructive shapes are denied -----------------------
|
|
33
|
+
|
|
34
|
+
denies "$GUARD" 'rm -f state/.lock'
|
|
35
|
+
denies "$GUARD" 'echo 123 > state/.supervision-armed'
|
|
36
|
+
denies "$GUARD" 'sed -i s/x/y/ workspace/memory/runes_audit.md'
|
|
37
|
+
denies "$GUARD" 'rm -f bin/syn-watch-arm.sh'
|
|
38
|
+
denies "$GUARD" 'cat .env.local'
|
|
39
|
+
denies "$GUARD" 'git add .env.realm'
|
|
40
|
+
denies "$GUARD" 'echo x > config/cron.yaml'
|
|
41
|
+
|
|
42
|
+
# --- invariant seatbelt: reads and ordinary work are allowed -----------------
|
|
43
|
+
|
|
44
|
+
allows "$GUARD" 'cat state/.lock'
|
|
45
|
+
allows "$GUARD" 'rg wake state/.wake-queue'
|
|
46
|
+
allows "$GUARD" 'git status'
|
|
47
|
+
allows "$GUARD" 'bin/runes-append.sh brokk test --message hi'
|
|
48
|
+
allows "$GUARD" 'bash -n bin/syn-guard-pretool-check.sh'
|
|
49
|
+
|
|
50
|
+
[ "$fail" = 0 ] && echo "ALL PASS" || echo "FAILURES"
|
|
51
|
+
exit "$fail"
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Unit tests for the machine-scoped primary session lock (bin/gleipnir-lock-lib.sh).
|
|
3
|
+
#
|
|
4
|
+
# The primary holds ONE machine-global lock so a second checkout of the same
|
|
5
|
+
# machine cannot run a competing session; an Eindri-home keeps its own per-home
|
|
6
|
+
# lock so workers run in parallel. A pre-contract session lives at the legacy
|
|
7
|
+
# state/.lock and must still resolve during migration.
|
|
8
|
+
set -u
|
|
9
|
+
|
|
10
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
11
|
+
LIB="$ROOT/bin/gleipnir-lock-lib.sh"
|
|
12
|
+
fail=0
|
|
13
|
+
ok() { printf 'ok - %s\n' "$1"; }
|
|
14
|
+
bad() { printf 'not ok - %s\n' "$1" >&2; fail=1; }
|
|
15
|
+
|
|
16
|
+
TMP="$(mktemp -d)"
|
|
17
|
+
trap 'rm -rf "$TMP"' EXIT
|
|
18
|
+
|
|
19
|
+
# --- path resolution ---------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
out=$(BROKK_HOME="$TMP/home" BROKK_MACHINE_STATE_DIR="$TMP/machine" \
|
|
22
|
+
bash -c '. "$0"; gleipnir_lock_path p; printf "%s" "$p"' "$LIB")
|
|
23
|
+
[ "$out" = "$TMP/machine/brokk.lock" ] && ok "primary lock is machine-global" \
|
|
24
|
+
|| bad "primary lock path: $out"
|
|
25
|
+
|
|
26
|
+
mkdir -p "$TMP/ehome/data"; : > "$TMP/ehome/data/eindri-home"
|
|
27
|
+
out=$(BROKK_HOME="$TMP/ehome" BROKK_MACHINE_STATE_DIR="$TMP/machine" \
|
|
28
|
+
bash -c '. "$0"; gleipnir_lock_path p; printf "%s" "$p"' "$LIB")
|
|
29
|
+
[ "$out" = "$TMP/ehome/state/.lock" ] && ok "Eindri-home marker keeps a per-home lock" \
|
|
30
|
+
|| bad "Eindri-home lock path: $out"
|
|
31
|
+
|
|
32
|
+
out=$(BROKK_HOME_KIND=eindri BROKK_HOME="$TMP/ehome2" BROKK_MACHINE_STATE_DIR="$TMP/machine" \
|
|
33
|
+
bash -c '. "$0"; gleipnir_lock_path p; printf "%s" "$p"' "$LIB")
|
|
34
|
+
[ "$out" = "$TMP/ehome2/state/.lock" ] && ok "BROKK_HOME_KIND=eindri keeps a per-home lock" \
|
|
35
|
+
|| bad "env Eindri-home lock path: $out"
|
|
36
|
+
|
|
37
|
+
# --- acquire writes the machine lock and the pointer -------------------------
|
|
38
|
+
|
|
39
|
+
mkdir -p "$TMP/home/state"
|
|
40
|
+
BROKK_HOME="$TMP/home" BROKK_MACHINE_STATE_DIR="$TMP/machine" BROKK_SESSION_PID="$$" \
|
|
41
|
+
bash -c '. "$0"; gleipnir_lock_acquire; gleipnir_lock_owner o; printf "%s" "$o"' "$LIB" > "$TMP/owner"
|
|
42
|
+
[ "$(cat "$TMP/owner")" = "$$" ] && ok "acquire records the session pid" \
|
|
43
|
+
|| bad "owner: $(cat "$TMP/owner")"
|
|
44
|
+
[ -f "$TMP/machine/brokk.lock" ] && ok "machine lock file written" \
|
|
45
|
+
|| bad "machine lock file missing"
|
|
46
|
+
[ "$(cat "$TMP/home/state/.lock-path" 2>/dev/null)" = "$TMP/machine/brokk.lock" ] \
|
|
47
|
+
&& ok "pointer records the resolved lock path" \
|
|
48
|
+
|| bad "pointer missing or wrong"
|
|
49
|
+
|
|
50
|
+
# --- a second session on the same machine is refused -------------------------
|
|
51
|
+
|
|
52
|
+
out=$(BROKK_HOME="$TMP/other" BROKK_MACHINE_STATE_DIR="$TMP/machine" BROKK_SESSION_PID="1" \
|
|
53
|
+
bash -c '. "$0"; if gleipnir_lock_acquire; then printf acquired; else printf refused; fi' "$LIB")
|
|
54
|
+
[ "$out" = "refused" ] && ok "a live machine lock refuses a second session" \
|
|
55
|
+
|| bad "second session: $out"
|
|
56
|
+
|
|
57
|
+
# --- migration: a legacy home lock is still honored --------------------------
|
|
58
|
+
|
|
59
|
+
rm -f "$TMP/machine/brokk.lock"; mkdir -p "$TMP/home2/state"; printf '%s\n' "$$" > "$TMP/home2/state/.lock"
|
|
60
|
+
out=$(BROKK_HOME="$TMP/home2" BROKK_MACHINE_STATE_DIR="$TMP/machine" \
|
|
61
|
+
bash -c '. "$0"; gleipnir_lock_owner o; printf "%s" "$o"' "$LIB")
|
|
62
|
+
[ "$out" = "$$" ] && ok "legacy home lock is honored during migration" \
|
|
63
|
+
|| bad "legacy owner: $out"
|
|
64
|
+
|
|
65
|
+
# --- reap clears a dead machine lock -----------------------------------------
|
|
66
|
+
|
|
67
|
+
mkdir -p "$TMP/machine"; printf '999999\n' > "$TMP/machine/brokk.lock"
|
|
68
|
+
BROKK_HOME="$TMP/home" BROKK_MACHINE_STATE_DIR="$TMP/machine" \
|
|
69
|
+
bash -c '. "$0"; gleipnir_lock_reap' "$LIB" >/dev/null 2>&1
|
|
70
|
+
[ -e "$TMP/machine/brokk.lock" ] && bad "stale machine lock not reaped" \
|
|
71
|
+
|| ok "a dead machine lock is reaped"
|
|
72
|
+
|
|
73
|
+
# --- acquire records a starttime sidecar --------------------------------------
|
|
74
|
+
|
|
75
|
+
BROKK_HOME="$TMP/home" BROKK_MACHINE_STATE_DIR="$TMP/machine" BROKK_SESSION_PID="$$" \
|
|
76
|
+
bash -c '. "$0"; gleipnir_lock_acquire' "$LIB" >/dev/null 2>&1
|
|
77
|
+
[ -s "$TMP/machine/brokk.lock.starttime" ] && ok "acquire records a starttime sidecar" \
|
|
78
|
+
|| bad "starttime sidecar missing after acquire"
|
|
79
|
+
|
|
80
|
+
# --- reap clears a lock whose recorded starttime no longer matches (pid reuse) --
|
|
81
|
+
|
|
82
|
+
# Use a live unrelated process (this shell) with a deliberately wrong starttime:
|
|
83
|
+
# liveness sees the pid "alive" via kill(0) but the recorded starttime belongs
|
|
84
|
+
# to a process that is no longer the owner — i.e. the kernel recycled the pid.
|
|
85
|
+
mkdir -p "$TMP/machine"; printf '%s\n' "$$" > "$TMP/machine/brokk.lock"
|
|
86
|
+
printf '0\n' > "$TMP/machine/brokk.lock.starttime"
|
|
87
|
+
BROKK_HOME="$TMP/home" BROKK_MACHINE_STATE_DIR="$TMP/machine" \
|
|
88
|
+
bash -c '. "$0"; gleipnir_lock_reap' "$LIB" >/dev/null 2>&1
|
|
89
|
+
[ -e "$TMP/machine/brokk.lock" ] && bad "recycled-pid lock not reaped" \
|
|
90
|
+
|| ok "a lock whose pid was recycled is reaped"
|
|
91
|
+
|
|
92
|
+
# --- reap clears a lock held by a real zombie ---------------------------------
|
|
93
|
+
|
|
94
|
+
# Fork a child, kill it, and keep the parent alive WITHOUT waiting: the child
|
|
95
|
+
# becomes a zombie. kill(0) on a zombie succeeds — the old liveness checked
|
|
96
|
+
# only that and missed the death; reap must now see the Z state and clear it.
|
|
97
|
+
python3 -c '
|
|
98
|
+
import os, signal, sys, time
|
|
99
|
+
p = os.fork()
|
|
100
|
+
if p == 0:
|
|
101
|
+
time.sleep(10); os._exit(0)
|
|
102
|
+
else:
|
|
103
|
+
time.sleep(0.3)
|
|
104
|
+
os.kill(p, signal.SIGKILL)
|
|
105
|
+
time.sleep(0.3)
|
|
106
|
+
with open(sys.argv[1], "w") as h:
|
|
107
|
+
h.write(str(p))
|
|
108
|
+
time.sleep(30)
|
|
109
|
+
' "$TMP/zombie.pid" &
|
|
110
|
+
zombie_keeper=$!
|
|
111
|
+
for _i in 1 2 3 4 5 6 7 8 9 10; do
|
|
112
|
+
[ -s "$TMP/zombie.pid" ] && break
|
|
113
|
+
sleep 0.2
|
|
114
|
+
done
|
|
115
|
+
zombie_pid=$(cat "$TMP/zombie.pid" 2>/dev/null || true)
|
|
116
|
+
state=$(awk '{print $3}' "/proc/$zombie_pid/stat" 2>/dev/null)
|
|
117
|
+
if [ -n "$zombie_pid" ] && [ "$state" = "Z" ]; then
|
|
118
|
+
printf '%s\n' "$zombie_pid" > "$TMP/machine/brokk.lock"
|
|
119
|
+
rm -f "$TMP/machine/brokk.lock.starttime"
|
|
120
|
+
BROKK_HOME="$TMP/home" BROKK_MACHINE_STATE_DIR="$TMP/machine" \
|
|
121
|
+
bash -c '. "$0"; gleipnir_lock_reap' "$LIB" >/dev/null 2>&1
|
|
122
|
+
[ -e "$TMP/machine/brokk.lock" ] && bad "zombie-held lock not reaped" \
|
|
123
|
+
|| ok "a zombie-held lock is reaped (kill(0) alone cannot see this)"
|
|
124
|
+
else
|
|
125
|
+
bad "test setup: expected a zombie child (got state ${state:-none})"
|
|
126
|
+
fi
|
|
127
|
+
kill "$zombie_keeper" 2>/dev/null || true
|
|
128
|
+
|
|
129
|
+
[ "$fail" = 0 ] && echo "ALL PASS" || echo "FAILURES"
|
|
130
|
+
exit "$fail"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Compatibility source for real-Herdr tests.
|
|
3
|
+
# The production owner of the isolation, refuse-default, teardown, and
|
|
4
|
+
# fleet-state tripwire contract is bin/fm-herdr-lab.sh.
|
|
5
|
+
set -u
|
|
6
|
+
|
|
7
|
+
# Herdr backend tests drive the real fm-spawn/fm-teardown but do not source
|
|
8
|
+
# tests/lib.sh, so exempt them from the gate-lifecycle refusal here too (see
|
|
9
|
+
# tests/lib.sh and bin/fm-gate-refuse-lib.sh for why firstmate's own suite,
|
|
10
|
+
# which the no-mistakes gate runs from a gate worktree, must be exempt).
|
|
11
|
+
export FM_GATE_REFUSE_BYPASS=1
|
|
12
|
+
|
|
13
|
+
HERDR_TEST_SAFETY_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
14
|
+
# shellcheck source=/dev/null
|
|
15
|
+
. "$HERDR_TEST_SAFETY_DIR/bin/fm-herdr-lab.sh"
|
|
16
|
+
|
|
17
|
+
# herdr_forget_inherited_pane: drop the Herdr PANE identity this test process
|
|
18
|
+
# inherited from whatever terminal it was started in.
|
|
19
|
+
#
|
|
20
|
+
# Herdr injects HERDR_ENV, HERDR_PANE_ID, HERDR_TAB_ID, HERDR_WORKSPACE_ID,
|
|
21
|
+
# HERDR_SOCKET_PATH, and HERDR_SESSION into every process it manages a pane for
|
|
22
|
+
# (verified 0.7.5 - docs/verification/runtime-backends.md), and a test run from
|
|
23
|
+
# inside a Herdr pane inherits all of them. Spawn now treats that pane as the
|
|
24
|
+
# authoritative parent to place workers next to, so a leaked identity from the
|
|
25
|
+
# developer's own session would follow the test into its isolated lab session
|
|
26
|
+
# and be refused there as a cross-session parent - a result that depends on
|
|
27
|
+
# where the suite was launched from, not on what it asserts.
|
|
28
|
+
#
|
|
29
|
+
# Call this before exporting the lab HERDR_SESSION in any suite whose subject is
|
|
30
|
+
# the per-home container path. A suite that means to exercise a launcher-bound
|
|
31
|
+
# spawn sets HERDR_PANE_ID itself, to a pane it created in its own lab session.
|
|
32
|
+
herdr_forget_inherited_pane() {
|
|
33
|
+
unset HERDR_ENV HERDR_PANE_ID HERDR_TAB_ID HERDR_WORKSPACE_ID HERDR_SOCKET_PATH HERDR_SESSION
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
herdr_refuse_if_default() { # <session>
|
|
37
|
+
fm_herdr_lab_refuse_if_default "$1"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
herdr_safe_stop_and_delete() { # <session>
|
|
41
|
+
fm_herdr_lab_teardown "$1"
|
|
42
|
+
}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tests/lib.sh - shared primitives for firstmate behavior tests.
|
|
3
|
+
#
|
|
4
|
+
# Source this from a test file:
|
|
5
|
+
# # shellcheck source=tests/lib.sh
|
|
6
|
+
# . "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
7
|
+
#
|
|
8
|
+
# It provides the boilerplate every test file used to re-roll: ok/not-ok
|
|
9
|
+
# reporters, a self-cleaning temp root, fakebin/PATH-shim helpers, deterministic
|
|
10
|
+
# git identity and fixture builders, state/<id>.meta writers, and the common
|
|
11
|
+
# string/exit-code/file assertions. Shared fake-toolchain and spawn-world
|
|
12
|
+
# builders live in tests/fixtures.sh; wake-queue mocks in wake-helpers.sh;
|
|
13
|
+
# secondmate-lifecycle mocks in secondmate-helpers.sh. Suite-specific fakes
|
|
14
|
+
# that encode a single test's terminal or lifecycle assumptions still belong
|
|
15
|
+
# with the tests that own them.
|
|
16
|
+
#
|
|
17
|
+
# ROOT is exported as the firstmate repo root (this file lives in tests/), so a
|
|
18
|
+
# sourcing test can use "$ROOT/bin/..." without recomputing it.
|
|
19
|
+
|
|
20
|
+
# Idempotent guard: behavior-area helper files (secondmate-helpers.sh,
|
|
21
|
+
# wake-helpers.sh, fixtures.sh) source this library for ROOT/fail/pass, and the
|
|
22
|
+
# test that includes them may also source it directly. Re-sourcing must not wipe
|
|
23
|
+
# the registered-cleanup array or reset state.
|
|
24
|
+
if [ -n "${FM_TEST_LIB_SOURCED:-}" ]; then
|
|
25
|
+
return 0
|
|
26
|
+
fi
|
|
27
|
+
FM_TEST_LIB_SOURCED=1
|
|
28
|
+
|
|
29
|
+
# Exempt firstmate's own test suite from the gate-lifecycle refusal
|
|
30
|
+
# (bin/fm-gate-refuse-lib.sh). The no-mistakes gate runs this suite FROM a gate
|
|
31
|
+
# worktree - the exact environment that guard refuses - so without this every
|
|
32
|
+
# test that drives the real fm-spawn/fm-send/fm-teardown would be refused during
|
|
33
|
+
# firstmate's own validation. A confused gate agent never sources this helper, so
|
|
34
|
+
# the boundary against the real hazard is unaffected. tests/fm-gate-refuse.test.sh
|
|
35
|
+
# strips this to verify real refusal.
|
|
36
|
+
export FM_GATE_REFUSE_BYPASS=1
|
|
37
|
+
|
|
38
|
+
# Resolve the repo root from this library's own location. Consumed by sourcing
|
|
39
|
+
# test files, not by this library, so it reads as "unused" here.
|
|
40
|
+
# shellcheck disable=SC2034
|
|
41
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
42
|
+
|
|
43
|
+
# --- reporters --------------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
fail() {
|
|
46
|
+
printf 'not ok - %s\n' "$1" >&2
|
|
47
|
+
exit 1
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
pass() {
|
|
51
|
+
printf 'ok - %s\n' "$1"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# --- self-cleaning temp root ------------------------------------------------
|
|
55
|
+
#
|
|
56
|
+
# fm_test_tmproot <prefix> echoes a fresh temp dir and registers it for removal
|
|
57
|
+
# on EXIT/INT/TERM. A test file that needs extra teardown (e.g. killing a
|
|
58
|
+
# daemon) should define its own EXIT trap and call fm_test_cleanup from inside
|
|
59
|
+
# it so registered dirs are still removed.
|
|
60
|
+
#
|
|
61
|
+
# The call site is almost always `TMP_ROOT=$(fm_test_tmproot prefix)`, which
|
|
62
|
+
# forks a subshell to capture stdout. Anything that function does to the
|
|
63
|
+
# current shell's state - an array append, a trap - dies with that subshell
|
|
64
|
+
# and never reaches the real caller, so registration cannot go through
|
|
65
|
+
# in-process state. `$$` is the one thing bash keeps stable across that
|
|
66
|
+
# boundary (it always resolves to the invoking shell's PID, not the
|
|
67
|
+
# subshell's - see `man bash` on `$$`), so fm_test_tmproot records the
|
|
68
|
+
# directory in a `$$`-keyed registry file instead, and the trap that reaps
|
|
69
|
+
# that file is armed once, here, at source time - which always runs in the
|
|
70
|
+
# real caller, never a subshell.
|
|
71
|
+
|
|
72
|
+
FM_TEST_CLEANUP_DIRS=()
|
|
73
|
+
FM_TEST_CLEANUP_REGISTRY=$(mktemp "${TMPDIR:-/tmp}/.fm-test-cleanup.$$.XXXXXX") || return 1
|
|
74
|
+
|
|
75
|
+
fm_test_pid_identity() {
|
|
76
|
+
local pid=$1
|
|
77
|
+
FM_STATE_OVERRIDE="${TMPDIR:-/tmp}" bash -c \
|
|
78
|
+
'. "$1"; fm_pid_identity "$2"' _ "$ROOT/bin/fm-wake-lib.sh" "$pid"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
FM_TEST_OWNER_IDENTITY=$(fm_test_pid_identity "$$") || {
|
|
82
|
+
rm -f "$FM_TEST_CLEANUP_REGISTRY"
|
|
83
|
+
return 1
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
fm_test_cleanup() {
|
|
87
|
+
local d
|
|
88
|
+
for d in "${FM_TEST_CLEANUP_DIRS[@]:-}"; do
|
|
89
|
+
[ -n "$d" ] && rm -rf "$d"
|
|
90
|
+
done
|
|
91
|
+
if [ -f "$FM_TEST_CLEANUP_REGISTRY" ]; then
|
|
92
|
+
while IFS= read -r d; do
|
|
93
|
+
[ -n "$d" ] && rm -rf "$d"
|
|
94
|
+
done < "$FM_TEST_CLEANUP_REGISTRY"
|
|
95
|
+
rm -f "$FM_TEST_CLEANUP_REGISTRY"
|
|
96
|
+
fi
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
fm_test_tmproot() {
|
|
100
|
+
local prefix=${1:-fm-test} root
|
|
101
|
+
root=$(mktemp -d "${TMPDIR:-/tmp}/${prefix}.XXXXXX") || return 1
|
|
102
|
+
if ! printf '%s\n%s\n' "$$" "$FM_TEST_OWNER_IDENTITY" > "$root/.fm-test-fixture" ||
|
|
103
|
+
! printf '%s\n' "$root" >> "$FM_TEST_CLEANUP_REGISTRY"; then
|
|
104
|
+
rm -rf "$root"
|
|
105
|
+
return 1
|
|
106
|
+
fi
|
|
107
|
+
printf '%s\n' "$root"
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
trap fm_test_cleanup EXIT
|
|
111
|
+
trap 'fm_test_cleanup; exit 130' INT
|
|
112
|
+
trap 'fm_test_cleanup; exit 143' TERM
|
|
113
|
+
|
|
114
|
+
# fm_test_reap_orphans: best-effort sweep for fixture roots left behind by a
|
|
115
|
+
# prior run that was killed hard enough to skip the traps above (e.g. a
|
|
116
|
+
# SIGKILL timeout). Only removes directories carrying the .fm-test-fixture
|
|
117
|
+
# marker fm_test_tmproot writes, so it never touches unrelated fm-* tmp dirs
|
|
118
|
+
# from real (non-test) firstmate commands. The marker identifies the owning
|
|
119
|
+
# shell across PID reuse, so the same live owner always wins over the age
|
|
120
|
+
# fallback for dead or unowned roots.
|
|
121
|
+
FM_TEST_ORPHAN_MAX_AGE_SECONDS=${FM_TEST_ORPHAN_MAX_AGE_SECONDS:-3600}
|
|
122
|
+
|
|
123
|
+
fm_test_reap_orphans() {
|
|
124
|
+
local marker dir mtime now owner_pid owner_identity current_identity
|
|
125
|
+
now=$(date +%s)
|
|
126
|
+
for marker in "${TMPDIR:-/tmp}"/fm-*/.fm-test-fixture; do
|
|
127
|
+
[ -e "$marker" ] || continue
|
|
128
|
+
owner_pid=$(sed -n '1p' "$marker" 2>/dev/null) || owner_pid=
|
|
129
|
+
owner_identity=$(sed -n '2,$p' "$marker" 2>/dev/null) || owner_identity=
|
|
130
|
+
case "$owner_pid" in
|
|
131
|
+
'' | *[!0-9]*) ;;
|
|
132
|
+
*)
|
|
133
|
+
current_identity=$(fm_test_pid_identity "$owner_pid" 2>/dev/null) || current_identity=
|
|
134
|
+
if [ -n "$owner_identity" ] && [ "$current_identity" = "$owner_identity" ]; then
|
|
135
|
+
continue
|
|
136
|
+
fi
|
|
137
|
+
;;
|
|
138
|
+
esac
|
|
139
|
+
mtime=$(stat -c %Y "$marker" 2>/dev/null || stat -f %m "$marker" 2>/dev/null) || continue
|
|
140
|
+
[ $((now - mtime)) -ge "$FM_TEST_ORPHAN_MAX_AGE_SECONDS" ] || continue
|
|
141
|
+
dir=$(dirname "$marker")
|
|
142
|
+
if [ -d "$dir" ] && [ ! -L "$dir" ]; then
|
|
143
|
+
find "$dir" -type d -exec chmod u+rwx {} + 2>/dev/null || true
|
|
144
|
+
fi
|
|
145
|
+
rm -rf "$dir"
|
|
146
|
+
done
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
# A parent coordinator can reap once before it starts isolated child sections.
|
|
150
|
+
# Those children use their own EXIT cleanup and must not spend their bounded
|
|
151
|
+
# execution window repeating the same global stale-fixture scan.
|
|
152
|
+
if [ "${FM_TEST_SKIP_ORPHAN_REAP:-0}" != 1 ]; then
|
|
153
|
+
fm_test_reap_orphans
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
# --- fakebin / PATH shims ---------------------------------------------------
|
|
157
|
+
#
|
|
158
|
+
# fm_fakebin <dir> creates <dir>/fakebin and echoes it; prepend it to PATH to
|
|
159
|
+
# shadow real tools with stubs. fm_fake_exit0 drops trivial exit-0 stubs for the
|
|
160
|
+
# named tools into a fakebin dir. fm_fake_version_tool drops a stub for a tool
|
|
161
|
+
# whose installed version bootstrap gates, so a fixture cannot be reported as an
|
|
162
|
+
# unparseable build simply for answering `--version` with nothing.
|
|
163
|
+
|
|
164
|
+
fm_fakebin() {
|
|
165
|
+
local dir=$1 fakebin="$1/fakebin"
|
|
166
|
+
mkdir -p "$fakebin"
|
|
167
|
+
printf '%s\n' "$fakebin"
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
fm_fake_exit0() {
|
|
171
|
+
local fakebin=$1 tool
|
|
172
|
+
shift
|
|
173
|
+
for tool in "$@"; do
|
|
174
|
+
cat > "$fakebin/$tool" <<'SH'
|
|
175
|
+
#!/usr/bin/env bash
|
|
176
|
+
exit 0
|
|
177
|
+
SH
|
|
178
|
+
chmod +x "$fakebin/$tool"
|
|
179
|
+
done
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
# fm_fake_version_tool <fakebin> <tool> <override-env-var> <default-version>
|
|
183
|
+
# The stub answers `--version` with <override-env-var> when that variable is set
|
|
184
|
+
# and non-empty, and with <default-version> otherwise; every other invocation
|
|
185
|
+
# exits 0. A case that needs to drive a version floor exports the variable.
|
|
186
|
+
fm_fake_version_tool() {
|
|
187
|
+
local fakebin=$1 tool=$2 override=$3 default=$4
|
|
188
|
+
cat > "$fakebin/$tool" <<SH
|
|
189
|
+
#!/usr/bin/env bash
|
|
190
|
+
if [ "\${1:-}" = --version ]; then
|
|
191
|
+
printf '%s\n' "\${$override:-$default}"
|
|
192
|
+
exit 0
|
|
193
|
+
fi
|
|
194
|
+
exit 0
|
|
195
|
+
SH
|
|
196
|
+
chmod +x "$fakebin/$tool"
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
# --- deterministic git identity and fixtures --------------------------------
|
|
200
|
+
|
|
201
|
+
# fm_git_identity [name] [email]: export a fixed author/committer identity so
|
|
202
|
+
# fixture commits never depend on the host git config.
|
|
203
|
+
fm_git_identity() {
|
|
204
|
+
export GIT_AUTHOR_NAME=${1:-fmtest} GIT_AUTHOR_EMAIL=${2:-fmtest@example.invalid}
|
|
205
|
+
export GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
# fm_git_init_commit <dir>: create a git repo at <dir> with a README and one
|
|
209
|
+
# commit. Uses an inline identity so it works whether or not fm_git_identity was
|
|
210
|
+
# called.
|
|
211
|
+
fm_git_init_commit() {
|
|
212
|
+
local dir=$1
|
|
213
|
+
mkdir -p "$dir"
|
|
214
|
+
git -C "$dir" init -q
|
|
215
|
+
printf '# %s\n' "$(basename "$dir")" > "$dir/README.md"
|
|
216
|
+
git -C "$dir" add README.md
|
|
217
|
+
git -C "$dir" -c user.name='Firstmate Tests' -c user.email='tests@example.invalid' commit -qm initial
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
# fm_git_add_origin <repo> <bare>: clone <repo> bare into <bare> and register it
|
|
221
|
+
# as <repo>'s origin via a file:// URL (so later clones resolve an absolute path).
|
|
222
|
+
fm_git_add_origin() {
|
|
223
|
+
local repo=$1 remote=$2 remote_abs
|
|
224
|
+
git clone --quiet --bare "$repo" "$remote"
|
|
225
|
+
remote_abs=$(cd "$remote" && pwd)
|
|
226
|
+
git -C "$repo" remote add origin "file://$remote_abs"
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
# fm_git_worktree <repo> <worktree> <branch>: initialize <repo> with one commit
|
|
230
|
+
# and a local bare origin, then add a worktree on a fresh branch.
|
|
231
|
+
fm_git_worktree() {
|
|
232
|
+
local repo=$1 worktree=$2 branch=$3
|
|
233
|
+
fm_git_init_commit "$repo"
|
|
234
|
+
fm_git_add_origin "$repo" "$repo.origin.git"
|
|
235
|
+
git -C "$repo" worktree add --quiet -b "$branch" "$worktree"
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
# --- state/<id>.meta writers ------------------------------------------------
|
|
239
|
+
|
|
240
|
+
# fm_write_meta <file> <key=val> ...: write the given key=val lines to a meta
|
|
241
|
+
# file (truncating any prior content).
|
|
242
|
+
fm_write_meta() {
|
|
243
|
+
local file=$1 kv
|
|
244
|
+
shift
|
|
245
|
+
: > "$file"
|
|
246
|
+
for kv in "$@"; do
|
|
247
|
+
printf '%s\n' "$kv" >> "$file"
|
|
248
|
+
done
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
# fm_write_secondmate_meta <file> <home> [window] [projects] [harness]: write the
|
|
252
|
+
# standard kind=secondmate meta block used across the secondmate suites. Window
|
|
253
|
+
# defaults to firstmate:fm-<id>, projects defaults to alpha, and harness defaults
|
|
254
|
+
# to echo to match the common case.
|
|
255
|
+
fm_write_secondmate_meta() {
|
|
256
|
+
local file=$1 home=$2 id window projects=${4:-alpha} harness=${5:-echo}
|
|
257
|
+
id=$(basename "$file" .meta)
|
|
258
|
+
window=${3:-firstmate:fm-$id}
|
|
259
|
+
fm_write_meta "$file" \
|
|
260
|
+
"window=$window" \
|
|
261
|
+
"endpoint_task_id=$id" \
|
|
262
|
+
"worktree=$home" \
|
|
263
|
+
"project=$home" \
|
|
264
|
+
"harness=$harness" \
|
|
265
|
+
"kind=secondmate" \
|
|
266
|
+
"mode=secondmate" \
|
|
267
|
+
"yolo=off" \
|
|
268
|
+
"home=$home" \
|
|
269
|
+
"projects=$projects"
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
# --- common assertions ------------------------------------------------------
|
|
273
|
+
|
|
274
|
+
# assert_contains <haystack> <needle> <msg>
|
|
275
|
+
assert_contains() {
|
|
276
|
+
case "$1" in
|
|
277
|
+
*"$2"*) : ;;
|
|
278
|
+
*) fail "$3 (missing: '$2')"$'\n'"--- output ---"$'\n'"$1" ;;
|
|
279
|
+
esac
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
# assert_not_contains <haystack> <needle> <msg>
|
|
283
|
+
assert_not_contains() {
|
|
284
|
+
case "$1" in
|
|
285
|
+
*"$2"*) fail "$3 (unexpected: '$2')"$'\n'"--- output ---"$'\n'"$1" ;;
|
|
286
|
+
*) : ;;
|
|
287
|
+
esac
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
# expect_code <expected> <actual> <label>
|
|
291
|
+
expect_code() {
|
|
292
|
+
local expected=$1 actual=$2 label=$3
|
|
293
|
+
[ "$actual" = "$expected" ] || fail "$label: expected exit $expected, got $actual"
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
# assert_grep <pattern> <file> <msg>: fixed-string grep must match in <file>.
|
|
297
|
+
# `--` guards patterns that begin with '-' (e.g. backlog/registry lines).
|
|
298
|
+
assert_grep() {
|
|
299
|
+
grep -F -- "$1" "$2" >/dev/null || fail "$3"
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
# assert_no_grep <pattern> <file> <msg>: fixed-string grep must NOT match.
|
|
303
|
+
assert_no_grep() {
|
|
304
|
+
! grep -F -- "$1" "$2" >/dev/null || fail "$3"
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
# assert_absent <path> <msg>: path must not exist.
|
|
308
|
+
assert_absent() {
|
|
309
|
+
[ ! -e "$1" ] || fail "$2"
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
# assert_present <path> <msg>: path must exist.
|
|
313
|
+
assert_present() {
|
|
314
|
+
[ -e "$1" ] || fail "$2"
|
|
315
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tests/remote-herdr-fixture.sh - the stateful herdr CLI fixture the remote
|
|
3
|
+
# second-mate suites install on their fake remote host.
|
|
4
|
+
#
|
|
5
|
+
# A remote second mate always launches on the Herdr backend
|
|
6
|
+
# (docs/remote-secondmates.md), so a remote-route test needs a herdr CLI on the
|
|
7
|
+
# remote code root's own bin directory. This fixture models the workspace, tab,
|
|
8
|
+
# pane, and agent facts bin/backends/herdr.sh actually reads, backed by a JSON
|
|
9
|
+
# state file mutated with real jq, using the same verified herdr behaviors as
|
|
10
|
+
# tests/fm-backend-herdr.test.sh's stateful fake: workspace create seeds one
|
|
11
|
+
# default tab and returns its tab and root pane in the same response, closing a
|
|
12
|
+
# tab's only pane closes the tab, and agent get reports agent_not_found for a
|
|
13
|
+
# pane no agent has registered on.
|
|
14
|
+
#
|
|
15
|
+
# Beyond that it models the pane IO a real launch performs. A pane reports a
|
|
16
|
+
# registered agent once anything has been typed into it, and submitting starts
|
|
17
|
+
# one turn: the next agent read reports working and the pane settles back to
|
|
18
|
+
# idle, which is the native transition the adapter confirms a submit with.
|
|
19
|
+
#
|
|
20
|
+
# Usage:
|
|
21
|
+
# . "$(dirname "${BASH_SOURCE[0]}")/remote-herdr-fixture.sh"
|
|
22
|
+
# install_remote_herdr_fixture <remote-root> <state-file> <log-file> \
|
|
23
|
+
# <send-fail-flag> <socket-path>
|
|
24
|
+
#
|
|
25
|
+
# Every invocation is appended verbatim to <log-file>, so a test reads back what
|
|
26
|
+
# the remote pane received. Creating <send-fail-flag> makes every pane write
|
|
27
|
+
# fail, which is how a test simulates an endpoint that cannot be reached.
|
|
28
|
+
|
|
29
|
+
install_remote_herdr_fixture() { # <remote-root> <state> <log> <send-fail> <socket>
|
|
30
|
+
local remote_root=$1 state=$2 log=$3 send_fail=$4 socket=$5 script="$1/bin/herdr"
|
|
31
|
+
mkdir -p "$remote_root/bin"
|
|
32
|
+
cat > "$script" <<SH
|
|
33
|
+
#!/usr/bin/env bash
|
|
34
|
+
set -u
|
|
35
|
+
STATE='$state'
|
|
36
|
+
LOG='$log'
|
|
37
|
+
SEND_FAIL='$send_fail'
|
|
38
|
+
SOCKET='$socket'
|
|
39
|
+
SH
|
|
40
|
+
cat >> "$script" <<'SH'
|
|
41
|
+
printf '%s\n' "$*" >> "$LOG"
|
|
42
|
+
jq_state() { jq "$@" "$STATE"; }
|
|
43
|
+
save() { tmp="$STATE.tmp.$$"; cat > "$tmp" && mv "$tmp" "$STATE"; }
|
|
44
|
+
ws=""; label=""; cwd=""
|
|
45
|
+
args=("$@")
|
|
46
|
+
for ((i=0; i<${#args[@]}; i++)); do
|
|
47
|
+
case "${args[$i]}" in
|
|
48
|
+
--workspace) ws=${args[$((i+1))]:-} ;;
|
|
49
|
+
--label) label=${args[$((i+1))]:-} ;;
|
|
50
|
+
--cwd) cwd=${args[$((i+1))]:-} ;;
|
|
51
|
+
esac
|
|
52
|
+
done
|
|
53
|
+
case "${1:-} ${2:-}" in
|
|
54
|
+
"status --json")
|
|
55
|
+
printf '{"client":{"version":"0.7.5","protocol":16},"server":{"running":true}}\n' ;;
|
|
56
|
+
"server "*|"server") : ;;
|
|
57
|
+
"workspace list") jq_state '{result:{workspaces:.workspaces}}' ;;
|
|
58
|
+
"workspace create")
|
|
59
|
+
n=$(jq_state -r '.next'); wsid="w$n"; dn=$((n + 1))
|
|
60
|
+
jq_state --arg wsid "$wsid" --arg wlabel "$label" --arg cwd "$cwd" \
|
|
61
|
+
--arg tabid "$wsid:t$dn" --arg paneid "$wsid:p$dn" \
|
|
62
|
+
'.workspaces += [{workspace_id:$wsid, label:$wlabel, cwd:$cwd}]
|
|
63
|
+
| .tabs += [{tab_id:$tabid, label:"1", workspace_id:$wsid, pane_id:$paneid}]
|
|
64
|
+
| .next = (.next + 2)' | save
|
|
65
|
+
printf '{"result":{"workspace":{"workspace_id":"%s","label":"%s"},"tab":{"tab_id":"%s"},"root_pane":{"pane_id":"%s"}}}\n' \
|
|
66
|
+
"$wsid" "$label" "$wsid:t$dn" "$wsid:p$dn"
|
|
67
|
+
;;
|
|
68
|
+
"tab list") jq_state --arg w "$ws" '{result:{tabs:[.tabs[]|select(.workspace_id==$w)]}}' ;;
|
|
69
|
+
"tab create")
|
|
70
|
+
n=$(jq_state -r '.next'); tabid="$ws:t$n"; paneid="$ws:p$n"
|
|
71
|
+
jq_state --arg w "$ws" --arg wlabel "$label" --arg cwd "$cwd" --arg tabid "$tabid" --arg paneid "$paneid" \
|
|
72
|
+
'.tabs += [{tab_id:$tabid, label:$wlabel, workspace_id:$w, pane_id:$paneid, cwd:$cwd}]
|
|
73
|
+
| .next = (.next + 1)' | save
|
|
74
|
+
printf '{"result":{"tab":{"tab_id":"%s"},"root_pane":{"pane_id":"%s"}}}\n' "$tabid" "$paneid"
|
|
75
|
+
;;
|
|
76
|
+
"tab close")
|
|
77
|
+
jq_state --arg t "${3:-}" '.tabs |= [.[]|select(.tab_id != $t)]' | save ;;
|
|
78
|
+
"pane list")
|
|
79
|
+
jq_state --arg w "$ws" '{result:{panes:[.tabs[]|select(.workspace_id==$w)|{pane_id:.pane_id, tab_id:.tab_id}]}}' ;;
|
|
80
|
+
"pane get")
|
|
81
|
+
pane=${3:-}
|
|
82
|
+
if [ "$(jq_state -r --arg p "$pane" '[.tabs[]|select(.pane_id==$p)]|length')" = 0 ]; then
|
|
83
|
+
printf '{"error":{"code":"pane_not_found","message":"%s"}}\n' "$pane"
|
|
84
|
+
else
|
|
85
|
+
printf '{"result":{"pane":{"pane_id":"%s"}}}\n' "$pane"
|
|
86
|
+
fi
|
|
87
|
+
;;
|
|
88
|
+
"pane close")
|
|
89
|
+
jq_state --arg p "${3:-}" \
|
|
90
|
+
'.tabs |= [.[]|select(.pane_id != $p)]
|
|
91
|
+
| .typed |= with_entries(select(.key != $p))
|
|
92
|
+
| .working |= with_entries(select(.key != $p))' | save ;;
|
|
93
|
+
"pane send-text")
|
|
94
|
+
[ ! -f "$SEND_FAIL" ] || exit 1
|
|
95
|
+
jq_state --arg p "${3:-}" '.typed[$p] = true' | save ;;
|
|
96
|
+
"pane send-keys")
|
|
97
|
+
[ ! -f "$SEND_FAIL" ] || exit 1
|
|
98
|
+
jq_state --arg p "${3:-}" '.typed[$p] = true | .working[$p] = true' | save ;;
|
|
99
|
+
"pane read") printf '\n' ;;
|
|
100
|
+
"pane process-info") printf '{"result":{"process":{"name":"codex"}}}\n' ;;
|
|
101
|
+
"agent get")
|
|
102
|
+
pane=${3:-}
|
|
103
|
+
if [ "$(jq_state -r --arg p "$pane" '.working[$p] // false')" = true ]; then
|
|
104
|
+
jq_state --arg p "$pane" '.working |= with_entries(select(.key != $p))' | save
|
|
105
|
+
printf '{"result":{"agent":{"agent_status":"working"}}}\n'
|
|
106
|
+
elif [ "$(jq_state -r --arg p "$pane" '.typed[$p] // false')" = true ]; then
|
|
107
|
+
printf '{"result":{"agent":{"agent_status":"idle"}}}\n'
|
|
108
|
+
else
|
|
109
|
+
printf '{"error":{"code":"agent_not_found","message":"%s"}}\n' "$pane"
|
|
110
|
+
fi
|
|
111
|
+
;;
|
|
112
|
+
"session list"*)
|
|
113
|
+
printf '{"sessions":[{"name":"default","running":true,"socket_path":"%s"},{"name":"fm-remote","running":true,"socket_path":"%s"}]}\n' "$SOCKET" "$SOCKET" ;;
|
|
114
|
+
esac
|
|
115
|
+
exit 0
|
|
116
|
+
SH
|
|
117
|
+
chmod +x "$script"
|
|
118
|
+
reset_remote_herdr_fixture "$state"
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# reset_remote_herdr_fixture <state>: return the fake host to "no workspaces,
|
|
122
|
+
# tabs, or panes", which is what a test means by "the previous endpoint is gone".
|
|
123
|
+
reset_remote_herdr_fixture() { # <state>
|
|
124
|
+
printf '{"next":1,"workspaces":[],"tabs":[],"typed":{},"working":{}}\n' > "$1"
|
|
125
|
+
}
|