@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,628 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Lavish adapter for the generic process-to-event runner.
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# fm-procevent-lavish.sh arm <artifact.html>
|
|
6
|
+
# fm-procevent-lavish.sh classify <result-file>
|
|
7
|
+
# fm-procevent-lavish.sh terminal <result-file>
|
|
8
|
+
# fm-procevent-lavish.sh silent <result-file>
|
|
9
|
+
# fm-procevent-lavish.sh answers <result-file>
|
|
10
|
+
# fm-procevent-lavish.sh read <result-file>
|
|
11
|
+
# fm-procevent-lavish.sh source-id <artifact.html>
|
|
12
|
+
# fm-procevent-lavish.sh retire <artifact.html>
|
|
13
|
+
# fm-procevent-lavish.sh poll <artifact.html>
|
|
14
|
+
#
|
|
15
|
+
# classify Print the lifecycle state a handler should act on: feedback, ended,
|
|
16
|
+
# waiting, missing, or unknown.
|
|
17
|
+
# read Print a structured presentation of one already-captured result so a
|
|
18
|
+
# handler consumes every queued item without grepping the raw file.
|
|
19
|
+
# It is read-only over the capture: it does not arm, poll, or change
|
|
20
|
+
# what Lavish delivered. The session-ending freeform message
|
|
21
|
+
# (tag=message) is its own labeled field, printed first and distinct
|
|
22
|
+
# from per-element annotations. Declared and presented item counts,
|
|
23
|
+
# plus a completeness verdict, follow before all annotations so a
|
|
24
|
+
# partial read is obvious. Each annotation retains its element uid,
|
|
25
|
+
# selector, tag, and text. A non-choice freeform comment (`prompt`)
|
|
26
|
+
# is printed as its own field even when a selector is also present
|
|
27
|
+
# and even when that comment matches the element text, so typed
|
|
28
|
+
# words are never dropped. Choice Context data is not a comment.
|
|
29
|
+
# Captain-supplied body lines are visibly prefixed so they cannot
|
|
30
|
+
# forge structural labels. Empty message and annotation sections
|
|
31
|
+
# are reported explicitly.
|
|
32
|
+
# poll The registered listener command `arm` publishes, not a command to
|
|
33
|
+
# run in a conversational turn. It runs the published blocking poll
|
|
34
|
+
# and prints its response verbatim, absorbing only the one exact
|
|
35
|
+
# transient interruption described below.
|
|
36
|
+
# terminal Exit 0 when the captured result means this Lavish source will never
|
|
37
|
+
# produce another result, so the runner may retire it; any other exit
|
|
38
|
+
# keeps it armed. This is the generic adapter contract bin/fm-procevent.sh
|
|
39
|
+
# calls, and the only place Lavish's notion of "ended" is decided.
|
|
40
|
+
# silent Exit 0 when the captured result is a routine no-op the runner should
|
|
41
|
+
# record and never announce; any other exit publishes the wake. This
|
|
42
|
+
# is the generic no-op contract bin/fm-procevent.sh calls, and the
|
|
43
|
+
# only place Lavish's notion of "nothing was said" is decided.
|
|
44
|
+
#
|
|
45
|
+
# AN EMPTY BOARD CLOSE IS NOT NEWS, and that is what `silent` exists to say.
|
|
46
|
+
# Closing a review surface that carried nothing is the single most common Lavish
|
|
47
|
+
# result: the captain reads a board, says nothing, and closes it. Announcing that
|
|
48
|
+
# put a wake in front of the handler whose entire content was that nothing
|
|
49
|
+
# happened. `silent` therefore holds one narrow, positively-determined shape -
|
|
50
|
+
# a session this adapter classifies `ended` that carries no queued content block
|
|
51
|
+
# at all - and every other result stays announced.
|
|
52
|
+
#
|
|
53
|
+
# Deliberately narrow, in both directions. A `Send & End` close carrying the
|
|
54
|
+
# captain's actual answer arrives as `status: feedback` with `session_ended`, so
|
|
55
|
+
# it classifies `feedback`, never `ended`, and is announced exactly as before; so
|
|
56
|
+
# is any `ended` result that still carries a `prompts` or `feedback` block, which
|
|
57
|
+
# the published poll is not expected to produce but which must never be dropped
|
|
58
|
+
# on that expectation. A `waiting` session, a `missing` one, an `unknown` or
|
|
59
|
+
# unreadable result, and any error all stay announced, because none of them
|
|
60
|
+
# positively proves nothing was said. Silence is only ever an absence this
|
|
61
|
+
# adapter can see in the result, never an absence it assumes.
|
|
62
|
+
#
|
|
63
|
+
# This adapter is deliberately thin. It owns only what is specific to Lavish:
|
|
64
|
+
# canonical source identity, the argv for the currently published poll command,
|
|
65
|
+
# and how to read a completed result. Ownership, durable capture, publication,
|
|
66
|
+
# and restart recovery all belong to bin/fm-procevent.sh.
|
|
67
|
+
#
|
|
68
|
+
# `answers` is this adapter's half of the generic keyed-answer contract in
|
|
69
|
+
# bin/fm-procevent.sh. It reports what the captain actually chose, as
|
|
70
|
+
# `<task-id>\t<answer>\t<label>` lines, and stops there. It maps nothing to a
|
|
71
|
+
# task, records no decision, and closes nothing: a captain answer is not special
|
|
72
|
+
# to Lavish, so every rule about what a keyed answer DOES belongs to the one
|
|
73
|
+
# intake in bin/fm-captain-hold.sh, which the runner feeds. A Lavish review is
|
|
74
|
+
# just an ephemeral discussion format that happens to carry answers.
|
|
75
|
+
#
|
|
76
|
+
# Only rows tagged `choice` are read. A freeform captain message is prose that may
|
|
77
|
+
# contain anything, and must never be able to forge a decision key.
|
|
78
|
+
#
|
|
79
|
+
# `read` is the presentation command summarized above; keyed intake remains
|
|
80
|
+
# the separate `answers` contract described here.
|
|
81
|
+
#
|
|
82
|
+
# It wraps ONLY the currently published interface, verified against 0.1.45:
|
|
83
|
+
# Usage: lavish-axi poll <html-file> [--agent-reply "..."]
|
|
84
|
+
# and that command "long-polls indefinitely" server-side. The adapter therefore
|
|
85
|
+
# runs the plain blocking form with no timeout flag, so results arrive as real
|
|
86
|
+
# server-side events. It adds no periodic discovery, no timer fallback, and no
|
|
87
|
+
# dependency on any unreleased capability.
|
|
88
|
+
#
|
|
89
|
+
# BOUNDED QUIET RETRY, owned here and nowhere else. A live listener can be cut
|
|
90
|
+
# short by the server with exactly this two-line response while the session's
|
|
91
|
+
# marks remain available:
|
|
92
|
+
#
|
|
93
|
+
# error: Lavish Editor poll response was interrupted
|
|
94
|
+
# code: SERVER_ERROR
|
|
95
|
+
#
|
|
96
|
+
# That is an internal retry, not news, so registering the raw poll made the
|
|
97
|
+
# generic runner capture it and wake the whole fleet. `poll` therefore re-runs
|
|
98
|
+
# the published poll up to POLL_RETRY_LIMIT times for that exact response, with
|
|
99
|
+
# POLL_RETRY_DELAY_DEFAULT seconds between attempts. The match is exact and
|
|
100
|
+
# deliberately narrow: real feedback, ended and missing sessions, any other
|
|
101
|
+
# SERVER_ERROR, and the same interruption still standing after the bound is
|
|
102
|
+
# spent are all printed straight through and captured normally. The retry is a
|
|
103
|
+
# Lavish fact, so the generic runner in bin/fm-procevent.sh stays
|
|
104
|
+
# adapter-agnostic and learns nothing about it.
|
|
105
|
+
#
|
|
106
|
+
# LOSS LIMITATION, stated plainly. The published poll destructively clears
|
|
107
|
+
# feedback before returning it. A result lost after that clearing and before the
|
|
108
|
+
# runner reads the process output is unrecoverable, and no Firstmate wrapper can
|
|
109
|
+
# close that source-side handoff window. Never describe this path as
|
|
110
|
+
# at-least-once, no-loss, or lossless. The only durability this proves is the
|
|
111
|
+
# runner's own: output that reached the runner is stored before it is announced.
|
|
112
|
+
set -u
|
|
113
|
+
|
|
114
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
115
|
+
FM_ROOT="${FM_ROOT_OVERRIDE:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
116
|
+
FM_HOME="${FM_HOME:-${FM_ROOT_OVERRIDE:-$FM_ROOT}}"
|
|
117
|
+
|
|
118
|
+
# shellcheck source=bin/fm-pr-lib.sh
|
|
119
|
+
. "$SCRIPT_DIR/fm-pr-lib.sh"
|
|
120
|
+
# shellcheck source=bin/fm-wake-lib.sh
|
|
121
|
+
. "$SCRIPT_DIR/fm-wake-lib.sh"
|
|
122
|
+
# shellcheck source=bin/fm-procevent-lib.sh
|
|
123
|
+
. "$SCRIPT_DIR/fm-procevent-lib.sh"
|
|
124
|
+
|
|
125
|
+
die() { printf 'error: %s\n' "$1" >&2; exit 1; }
|
|
126
|
+
usage() { sed -n '2,111p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'; exit 2; }
|
|
127
|
+
|
|
128
|
+
# Canonical identity is physical, not the path string: Lavish itself keys a
|
|
129
|
+
# session on the realpath of the artifact, so two names for one file are one
|
|
130
|
+
# source and must never become two owners.
|
|
131
|
+
cmd_source_id() {
|
|
132
|
+
local artifact=${1-} real
|
|
133
|
+
[ -n "$artifact" ] || usage
|
|
134
|
+
case "$artifact" in *$'\n'*) die "artifact paths cannot contain newlines" ;; esac
|
|
135
|
+
real=$(perl -MCwd=realpath -e '$p = realpath($ARGV[0]); defined($p) or exit 1; print "$p\n"' "$artifact" 2>/dev/null) \
|
|
136
|
+
|| die "cannot resolve the artifact path: $artifact"
|
|
137
|
+
[ -f "$real" ] || die "artifact does not exist: $artifact"
|
|
138
|
+
if command -v shasum >/dev/null 2>&1; then
|
|
139
|
+
printf 'lavish-%s\n' "$(printf '%s' "$real" | shasum -a 256 | awk '{print substr($1,1,16)}')"
|
|
140
|
+
else
|
|
141
|
+
printf 'lavish-%s\n' "$(printf '%s' "$real" | sha256sum | awk '{print substr($1,1,16)}')"
|
|
142
|
+
fi
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
cmd_arm() {
|
|
146
|
+
local artifact=${1-} id real
|
|
147
|
+
[ -n "$artifact" ] || usage
|
|
148
|
+
[ "$#" -eq 1 ] || usage
|
|
149
|
+
command -v lavish-axi >/dev/null 2>&1 || die "lavish-axi is not installed"
|
|
150
|
+
poll_retry_delay >/dev/null
|
|
151
|
+
id=$(cmd_source_id "$artifact") || exit 1
|
|
152
|
+
real=$(perl -MCwd=realpath -e '$p = realpath($ARGV[0]); defined($p) or exit 1; print "$p\n"' "$artifact" 2>/dev/null) \
|
|
153
|
+
|| die "cannot resolve the artifact path: $artifact"
|
|
154
|
+
# This adapter's own listener command, which runs the plain blocking form with
|
|
155
|
+
# no --timeout-ms so completion is a server event, and absorbs only the exact
|
|
156
|
+
# transient interruption. Registering raw poll output is what let that
|
|
157
|
+
# interruption reach the runner as a captured result.
|
|
158
|
+
"$SCRIPT_DIR/fm-procevent.sh" register lavish "$id" \
|
|
159
|
+
-- "$SCRIPT_DIR/fm-procevent-lavish.sh" poll "$real" || exit 1
|
|
160
|
+
printf 'armed: %s\n' "$id"
|
|
161
|
+
printf 'artifact: %s\n' "$real"
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
cmd_retire() {
|
|
165
|
+
local artifact=${1-} id
|
|
166
|
+
[ -n "$artifact" ] || usage
|
|
167
|
+
id=$(cmd_source_id "$artifact") || exit 1
|
|
168
|
+
"$SCRIPT_DIR/fm-procevent.sh" retire "$id"
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
# The bounded quiet retry described in the header. The bound is a constant
|
|
172
|
+
# because it is a property of the transient response, not an operator choice;
|
|
173
|
+
# only the delay takes an override, so a test can exercise the real bound
|
|
174
|
+
# without waiting it out.
|
|
175
|
+
POLL_RETRY_LIMIT=12
|
|
176
|
+
POLL_RETRY_DELAY_DEFAULT=5
|
|
177
|
+
POLL_RETRY_DELAY_MAX=60
|
|
178
|
+
|
|
179
|
+
# Exit 0 only for the exact two-line interruption, and nothing else. The whole
|
|
180
|
+
# response must be those two lines with those exact bytes: whitespace variants,
|
|
181
|
+
# a longer response that merely opens with them, and any other SERVER_ERROR are
|
|
182
|
+
# genuine errors this adapter must never swallow.
|
|
183
|
+
poll_response_filter() { # <response-file>
|
|
184
|
+
perl -e '
|
|
185
|
+
use strict;
|
|
186
|
+
use warnings;
|
|
187
|
+
my ($stage) = @ARGV;
|
|
188
|
+
my $expected = "error: Lavish Editor poll response was interrupted\ncode: SERVER_ERROR\n";
|
|
189
|
+
open my $staged, ">", $stage or exit 2;
|
|
190
|
+
binmode STDIN;
|
|
191
|
+
binmode STDOUT;
|
|
192
|
+
binmode $staged;
|
|
193
|
+
my ($candidate, $streaming) = ("", 0);
|
|
194
|
+
sub write_all {
|
|
195
|
+
my ($handle, $bytes) = @_;
|
|
196
|
+
my $offset = 0;
|
|
197
|
+
while ($offset < length $bytes) {
|
|
198
|
+
my $written = syswrite $handle, $bytes, length($bytes) - $offset, $offset;
|
|
199
|
+
exit 2 unless defined $written;
|
|
200
|
+
$offset += $written;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
while (1) {
|
|
204
|
+
my $count = sysread STDIN, my $chunk, 65536;
|
|
205
|
+
exit 2 unless defined $count;
|
|
206
|
+
last if $count == 0;
|
|
207
|
+
if ($streaming) {
|
|
208
|
+
write_all(*STDOUT, $chunk);
|
|
209
|
+
next;
|
|
210
|
+
}
|
|
211
|
+
my $room = length($expected) + 1 - length($candidate);
|
|
212
|
+
my $take = length($chunk) < $room ? length($chunk) : $room;
|
|
213
|
+
my $prefix = substr($chunk, 0, $take);
|
|
214
|
+
$candidate .= $prefix;
|
|
215
|
+
write_all($staged, $prefix);
|
|
216
|
+
my $matches_prefix = length($candidate) <= length($expected)
|
|
217
|
+
&& substr($expected, 0, length($candidate)) eq $candidate;
|
|
218
|
+
if (!$matches_prefix) {
|
|
219
|
+
write_all(*STDOUT, $candidate);
|
|
220
|
+
write_all(*STDOUT, substr($chunk, $take));
|
|
221
|
+
$streaming = 1;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
exit 10 if !$streaming && $candidate eq $expected;
|
|
225
|
+
write_all(*STDOUT, $candidate) unless $streaming;
|
|
226
|
+
' "$1"
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
# Seconds between retries. FM_LAVISH_POLL_RETRY_DELAY is a bounded test
|
|
230
|
+
# override; a malformed or out-of-range value is refused rather than quietly
|
|
231
|
+
# rounded, because silently changing a retry cadence is how a bound stops
|
|
232
|
+
# meaning anything.
|
|
233
|
+
poll_retry_delay() {
|
|
234
|
+
local delay=${FM_LAVISH_POLL_RETRY_DELAY-}
|
|
235
|
+
if [ -z "$delay" ]; then
|
|
236
|
+
printf '%s\n' "$POLL_RETRY_DELAY_DEFAULT"
|
|
237
|
+
return 0
|
|
238
|
+
fi
|
|
239
|
+
case "$delay" in
|
|
240
|
+
*[!0-9]*) die "FM_LAVISH_POLL_RETRY_DELAY must be whole seconds from 0 to $POLL_RETRY_DELAY_MAX: $delay" ;;
|
|
241
|
+
esac
|
|
242
|
+
[ "$delay" -le "$POLL_RETRY_DELAY_MAX" ] \
|
|
243
|
+
|| die "FM_LAVISH_POLL_RETRY_DELAY must be whole seconds from 0 to $POLL_RETRY_DELAY_MAX: $delay"
|
|
244
|
+
printf '%s\n' "$delay"
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
cmd_poll() {
|
|
248
|
+
local artifact=${1-} delay attempt=0 response cleanup_command rc filter_rc
|
|
249
|
+
local pipeline_status
|
|
250
|
+
[ -n "$artifact" ] || usage
|
|
251
|
+
[ "$#" -eq 1 ] || usage
|
|
252
|
+
command -v lavish-axi >/dev/null 2>&1 || die "lavish-axi is not installed"
|
|
253
|
+
delay=$(poll_retry_delay) || exit 1
|
|
254
|
+
response=$(mktemp "${TMPDIR:-/tmp}/fm-lavish-poll.XXXXXX") || die "cannot stage the poll response"
|
|
255
|
+
printf -v cleanup_command 'rm -f -- %q' "$response"
|
|
256
|
+
# shellcheck disable=SC2064 # $cleanup_command must expand now, while the staged path is still set.
|
|
257
|
+
trap "$cleanup_command" EXIT
|
|
258
|
+
# Retirement stops this listener by signalling its process group, and bash runs
|
|
259
|
+
# no EXIT trap for an uncaught signal, so each one cleans up the staged
|
|
260
|
+
# response and then re-raises itself with the default disposition, leaving the
|
|
261
|
+
# process dying exactly as the runner expects.
|
|
262
|
+
local signal
|
|
263
|
+
for signal in INT TERM HUP; do
|
|
264
|
+
# shellcheck disable=SC2064 # Same reason: expand now, while both are set.
|
|
265
|
+
trap "$cleanup_command; trap - $signal; kill -$signal $$" "$signal"
|
|
266
|
+
done
|
|
267
|
+
while :; do
|
|
268
|
+
lavish-axi poll "$artifact" | poll_response_filter "$response"
|
|
269
|
+
pipeline_status=("${PIPESTATUS[@]}")
|
|
270
|
+
rc=${pipeline_status[0]}
|
|
271
|
+
filter_rc=${pipeline_status[1]}
|
|
272
|
+
case "$filter_rc" in
|
|
273
|
+
0) break ;;
|
|
274
|
+
10)
|
|
275
|
+
if [ "$attempt" -lt "$POLL_RETRY_LIMIT" ]; then
|
|
276
|
+
attempt=$((attempt + 1))
|
|
277
|
+
sleep "$delay"
|
|
278
|
+
else
|
|
279
|
+
cat -- "$response"
|
|
280
|
+
break
|
|
281
|
+
fi
|
|
282
|
+
;;
|
|
283
|
+
*) die "cannot classify the poll response" ;;
|
|
284
|
+
esac
|
|
285
|
+
done
|
|
286
|
+
return "$rc"
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
# Read one field of the response's leading `session:` block. Those fields are
|
|
290
|
+
# INDENTED, so each is read as the first indented match inside that block rather
|
|
291
|
+
# than an anchored whole-line match; anchoring on "^status:" silently never
|
|
292
|
+
# matches and treats every ended review as feedback. Confining the read to the
|
|
293
|
+
# leading block is also what stops prompt payload text from forging a session
|
|
294
|
+
# field. <field> is a fixed field name supplied by this adapter, never by input.
|
|
295
|
+
session_field() { # <result-file> <field>
|
|
296
|
+
awk -v field="$2" '
|
|
297
|
+
$0 == "session:" { in_s=1; next }
|
|
298
|
+
in_s && $0 !~ /^[[:space:]]/ { exit }
|
|
299
|
+
in_s && $0 ~ "^[[:space:]]+" field ":[[:space:]]*[A-Za-z_]+[[:space:]]*$" {
|
|
300
|
+
sub("^[[:space:]]+" field ":[[:space:]]*", ""); sub(/[[:space:]]*$/, ""); print; exit }
|
|
301
|
+
' "$1"
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
# Classify a completed result into a lifecycle state for the handler.
|
|
305
|
+
cmd_classify() {
|
|
306
|
+
local file=${1-} status error_code error_message
|
|
307
|
+
[ -n "$file" ] || usage
|
|
308
|
+
[ -f "$file" ] || die "result file does not exist: $file"
|
|
309
|
+
status=$(session_field "$file" status)
|
|
310
|
+
case "$status" in
|
|
311
|
+
feedback) printf 'feedback\n'; return 0 ;;
|
|
312
|
+
ended) printf 'ended\n'; return 0 ;;
|
|
313
|
+
waiting) printf 'waiting\n'; return 0 ;;
|
|
314
|
+
esac
|
|
315
|
+
error_message=$(awk 'NR == 1 && /^error:[[:space:]]*/ { sub(/^error:[[:space:]]*/, ""); print }' "$file")
|
|
316
|
+
error_code=$(awk '
|
|
317
|
+
NR == 1 && /^error:[[:space:]]*/ { in_error=1; next }
|
|
318
|
+
in_error && /^code:[[:space:]]*[A-Z_]+[[:space:]]*$/ {
|
|
319
|
+
sub(/^code:[[:space:]]*/, ""); sub(/[[:space:]]*$/, ""); print; exit }
|
|
320
|
+
in_error { exit }
|
|
321
|
+
' "$file")
|
|
322
|
+
if [ "$error_code" = NOT_FOUND ] || [[ "$error_message" == "No active Lavish Editor session"* ]]; then
|
|
323
|
+
printf 'missing\n'
|
|
324
|
+
else
|
|
325
|
+
printf 'unknown\n'
|
|
326
|
+
fi
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
# Whether a captured result ends this source, for the generic runner's automatic
|
|
330
|
+
# retirement. Lavish's notion of "ended" lives here and nowhere else: an ended
|
|
331
|
+
# session produces nothing further, a missing session has nothing left to
|
|
332
|
+
# produce, and the published poll delivers the final feedback of a `Send & End`
|
|
333
|
+
# review marked with session_ended and returns only empty ended sessions after
|
|
334
|
+
# it. Anything else - including an unreadable result - keeps the source armed.
|
|
335
|
+
cmd_terminal() {
|
|
336
|
+
local file=${1-}
|
|
337
|
+
[ -n "$file" ] || usage
|
|
338
|
+
[ -f "$file" ] || die "result file does not exist: $file"
|
|
339
|
+
case "$(cmd_classify "$file")" in
|
|
340
|
+
ended|missing) return 0 ;;
|
|
341
|
+
esac
|
|
342
|
+
case "$(session_field "$file" session_ended)" in
|
|
343
|
+
true|True|TRUE) return 0 ;;
|
|
344
|
+
esac
|
|
345
|
+
return 1
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
# Whether a completed result carries any queued content block at all. The
|
|
349
|
+
# published response frames content as a top-level `prompts[N]{...}:` or
|
|
350
|
+
# `feedback[N]{...}:` header whose rows are INDENTED, so this anchors on column
|
|
351
|
+
# zero: an indented payload line is captain-supplied text and must never be able
|
|
352
|
+
# to forge - or, here, to hide behind - a content header. Any recognized block
|
|
353
|
+
# is content regardless of its declared count, while a malformed top-level
|
|
354
|
+
# prompts or feedback header makes the result indeterminate.
|
|
355
|
+
#
|
|
356
|
+
# 0 = content present, 1 = provably no content, anything else = the check did
|
|
357
|
+
# not complete. The caller must distinguish those three, because "the check
|
|
358
|
+
# failed" is never proof that nothing was said.
|
|
359
|
+
result_has_queued_content() { # <result-file>
|
|
360
|
+
awk '
|
|
361
|
+
/^(prompts|feedback)\[[0-9]+\]\{[^}]*\}:[[:space:]]*$/ {
|
|
362
|
+
verdict = "present"
|
|
363
|
+
exit
|
|
364
|
+
}
|
|
365
|
+
/^(prompts|feedback)/ {
|
|
366
|
+
verdict = "indeterminate"
|
|
367
|
+
exit
|
|
368
|
+
}
|
|
369
|
+
END {
|
|
370
|
+
if (verdict == "present") exit 0
|
|
371
|
+
if (verdict == "indeterminate") exit 2
|
|
372
|
+
exit 1
|
|
373
|
+
}
|
|
374
|
+
' "$1"
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
# Whether a captured result is a routine no-op the runner should record without
|
|
378
|
+
# announcing, for the generic runner's silence seam. Lavish's notion of "nothing
|
|
379
|
+
# was said" lives here and nowhere else: an ended session carrying no queued
|
|
380
|
+
# content block is a board the captain closed without saying anything, and the
|
|
381
|
+
# handler learns nothing from being told. Anything else - a real answer, a
|
|
382
|
+
# missing or waiting session, an unreadable result - is announced.
|
|
383
|
+
cmd_silent() {
|
|
384
|
+
local file=${1-} content_rc
|
|
385
|
+
[ -n "$file" ] || usage
|
|
386
|
+
[ -f "$file" ] && [ ! -L "$file" ] || die "result file does not exist: $file"
|
|
387
|
+
[ "$(cmd_classify "$file")" = ended ] || return 1
|
|
388
|
+
result_has_queued_content "$file"
|
|
389
|
+
content_rc=$?
|
|
390
|
+
# Only a completed check that proved the result carries nothing declares
|
|
391
|
+
# silence; a check that could not complete announces, like every other
|
|
392
|
+
# uncertainty here.
|
|
393
|
+
[ "$content_rc" -eq 1 ]
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
# Print `key<TAB>answer<TAB>label[<TAB>mode]` for every structured choice the
|
|
397
|
+
# captain submitted in a captured result; the optional mode column relays the
|
|
398
|
+
# card's declared close mode (`done` or `release`) to the keyed-answer intake. The published response frames queued feedback as
|
|
399
|
+
# a `prompts[N]{field,...}:` header followed by exactly N indented CSV rows whose
|
|
400
|
+
# quoted fields carry JSON-style escapes, so this reads the declared field ORDER
|
|
401
|
+
# rather than assuming a fixed column, and takes only rows whose `tag` field is
|
|
402
|
+
# `choice`. A freeform `message` row is captain prose and is deliberately never a
|
|
403
|
+
# source of decision keys. A row that does not carry both a slug-shaped `question`
|
|
404
|
+
# and an `answer` inside its `Context data:` block is skipped, so a deck that does
|
|
405
|
+
# not key its forms by decision key simply yields nothing.
|
|
406
|
+
# The question cap is 128 so any task id fits, including the long legacy
|
|
407
|
+
# `<origin>-decision-<key>` identities pre-collapse decks still carry; the
|
|
408
|
+
# security property is the slug SHAPE, which is unchanged.
|
|
409
|
+
cmd_answers() {
|
|
410
|
+
local file=${1-}
|
|
411
|
+
[ -n "$file" ] || usage
|
|
412
|
+
[ -f "$file" ] && [ ! -L "$file" ] || die "result file does not exist: $file"
|
|
413
|
+
perl -MJSON::PP -e '
|
|
414
|
+
use strict; use warnings;
|
|
415
|
+
my ($path) = @ARGV;
|
|
416
|
+
open my $fh, "<", $path or exit 1;
|
|
417
|
+
my (@fields, $want, @rows);
|
|
418
|
+
while (my $line = <$fh>) {
|
|
419
|
+
if (!@fields) {
|
|
420
|
+
next unless $line =~ /^prompts\[(\d+)\]\{([^}]*)\}:\s*$/;
|
|
421
|
+
($want, @fields) = ($1, split /,/, $2);
|
|
422
|
+
next;
|
|
423
|
+
}
|
|
424
|
+
last unless $line =~ /^\s/;
|
|
425
|
+
last if @rows >= $want;
|
|
426
|
+
chomp $line;
|
|
427
|
+
push @rows, $line;
|
|
428
|
+
}
|
|
429
|
+
close $fh;
|
|
430
|
+
my %seen;
|
|
431
|
+
my @out;
|
|
432
|
+
for my $row (@rows) {
|
|
433
|
+
$row =~ s/^\s+//;
|
|
434
|
+
my @vals;
|
|
435
|
+
while (length $row) {
|
|
436
|
+
if ($row =~ s/^"((?:[^"\\]|\\.)*)"//) {
|
|
437
|
+
my $v = $1;
|
|
438
|
+
$v =~ s/\\(.)/$1 eq "n" ? "\n" : $1 eq "t" ? "\t" : $1 eq "r" ? "\r" : $1/ge;
|
|
439
|
+
push @vals, $v;
|
|
440
|
+
} else {
|
|
441
|
+
$row =~ s/^([^,]*)//;
|
|
442
|
+
push @vals, $1;
|
|
443
|
+
}
|
|
444
|
+
last unless $row =~ s/^,//;
|
|
445
|
+
}
|
|
446
|
+
my %f;
|
|
447
|
+
$f{$fields[$_]} = $vals[$_] for 0 .. $#fields;
|
|
448
|
+
next unless defined $f{tag} && $f{tag} eq "choice";
|
|
449
|
+
my $prompt = $f{prompt};
|
|
450
|
+
next unless defined $prompt && $prompt =~ /Context data:\s*(\{.*\})/s;
|
|
451
|
+
my $ctx = $1;
|
|
452
|
+
my $data = eval { decode_json($ctx) };
|
|
453
|
+
next unless ref($data) eq "HASH";
|
|
454
|
+
my $key = $data->{question};
|
|
455
|
+
my $answer = $data->{answer};
|
|
456
|
+
next if !defined($key) || ref($key) || !defined($answer) || ref($answer);
|
|
457
|
+
my $mode = "";
|
|
458
|
+
if (exists $data->{close}) {
|
|
459
|
+
next if !defined($data->{close}) || ref($data->{close})
|
|
460
|
+
|| ($data->{close} ne "done" && $data->{close} ne "release");
|
|
461
|
+
$mode = $data->{close};
|
|
462
|
+
}
|
|
463
|
+
next unless $key =~ /\A[A-Za-z0-9._-]{1,128}\z/;
|
|
464
|
+
next unless length $answer && length($answer) <= 512;
|
|
465
|
+
my $label = defined $f{text} ? $f{text} : "";
|
|
466
|
+
s/[\x00-\x1f\x7f]/ /g for ($answer, $label);
|
|
467
|
+
$label = substr($label, 0, 512);
|
|
468
|
+
# A re-answered form appears again later in the queue; the last submission wins.
|
|
469
|
+
if (defined $seen{$key}) { $out[$seen{$key}] = undef }
|
|
470
|
+
$seen{$key} = scalar @out;
|
|
471
|
+
push @out, length $mode ? "$key\t$answer\t$label\t$mode" : "$key\t$answer\t$label";
|
|
472
|
+
}
|
|
473
|
+
print "$_\n" for grep { defined } @out;
|
|
474
|
+
' "$file"
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
# Present one already-captured result for a handler. Body lines are prefixed
|
|
478
|
+
# so a captain-supplied string cannot forge a section label. The session-ending
|
|
479
|
+
# message is printed before the count line and before any annotation, because
|
|
480
|
+
# that is the field a truncated grep of the raw capture historically dropped.
|
|
481
|
+
# A non-choice annotation that carries a freeform `prompt` prints that comment
|
|
482
|
+
# as its own field; a selector must not hide the typed words, even when the
|
|
483
|
+
# comment matches the captured element text. Choice rows keep Context data
|
|
484
|
+
# out of that field. A pure annotation has no prompt.
|
|
485
|
+
cmd_read() {
|
|
486
|
+
local file=${1-} lifecycle session_ended
|
|
487
|
+
[ -n "$file" ] || usage
|
|
488
|
+
[ -f "$file" ] && [ ! -L "$file" ] || die "result file does not exist: $file"
|
|
489
|
+
lifecycle=$(cmd_classify "$file")
|
|
490
|
+
session_ended=$(session_field "$file" session_ended)
|
|
491
|
+
perl -e '
|
|
492
|
+
use strict; use warnings;
|
|
493
|
+
my ($path, $lifecycle, $session_ended) = @ARGV;
|
|
494
|
+
open my $fh, "<", $path or exit 1;
|
|
495
|
+
my (@fields, $want, @rows);
|
|
496
|
+
while (my $line = <$fh>) {
|
|
497
|
+
if (!@fields) {
|
|
498
|
+
next unless $line =~ /^(?:prompts|feedback)\[(\d+)\]\{([^}]*)\}:\s*$/;
|
|
499
|
+
($want, @fields) = ($1, split /,/, $2);
|
|
500
|
+
next;
|
|
501
|
+
}
|
|
502
|
+
last unless $line =~ /^\s/;
|
|
503
|
+
last if defined($want) && @rows >= $want;
|
|
504
|
+
chomp $line;
|
|
505
|
+
push @rows, $line;
|
|
506
|
+
}
|
|
507
|
+
close $fh;
|
|
508
|
+
$want = 0 unless defined $want;
|
|
509
|
+
my @parsed;
|
|
510
|
+
my $malformed = 0;
|
|
511
|
+
for my $row (@rows) {
|
|
512
|
+
$row =~ s/^\s+//;
|
|
513
|
+
my @vals;
|
|
514
|
+
while (length $row) {
|
|
515
|
+
if ($row =~ s/^"((?:[^"\\]|\\.)*)"//) {
|
|
516
|
+
push @vals, $1;
|
|
517
|
+
} else {
|
|
518
|
+
$row =~ s/^([^,]*)//;
|
|
519
|
+
push @vals, $1;
|
|
520
|
+
}
|
|
521
|
+
last unless $row =~ s/^,//;
|
|
522
|
+
}
|
|
523
|
+
if (@vals > @fields) {
|
|
524
|
+
my ($preserve) = grep { $fields[$_] eq "prompt" } 0 .. $#fields;
|
|
525
|
+
($preserve) = grep { $fields[$_] eq "text" } 0 .. $#fields unless defined $preserve;
|
|
526
|
+
if (defined $preserve) {
|
|
527
|
+
my $count = @vals - @fields + 1;
|
|
528
|
+
my @parts = splice @vals, $preserve, $count;
|
|
529
|
+
splice @vals, $preserve, 0, join(",", @parts);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
if (@vals != @fields) {
|
|
533
|
+
$malformed++;
|
|
534
|
+
next;
|
|
535
|
+
}
|
|
536
|
+
s/\\(.)/$1 eq "n" ? "\n" : $1 eq "t" ? "\t" : $1 eq "r" ? "\r" : $1/ge for @vals;
|
|
537
|
+
my %f;
|
|
538
|
+
$f{$fields[$_]} = $vals[$_] for 0 .. $#fields;
|
|
539
|
+
push @parsed, \%f;
|
|
540
|
+
}
|
|
541
|
+
my $presented = scalar @parsed;
|
|
542
|
+
my $complete = ($presented == $want && !$malformed) ? "yes" : "no";
|
|
543
|
+
my @messages;
|
|
544
|
+
my @annotations;
|
|
545
|
+
for my $f (@parsed) {
|
|
546
|
+
my $tag = defined $f->{tag} ? $f->{tag} : "";
|
|
547
|
+
if ($tag eq "message") {
|
|
548
|
+
push @messages, $f;
|
|
549
|
+
} else {
|
|
550
|
+
push @annotations, $f;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
sub emit_body {
|
|
554
|
+
my ($text) = @_;
|
|
555
|
+
$text = "" unless defined $text;
|
|
556
|
+
$text =~ s/\r\n/\n/g;
|
|
557
|
+
$text =~ s/\r/\n/g;
|
|
558
|
+
my @lines = split /\n/, $text, -1;
|
|
559
|
+
pop @lines if @lines && $lines[-1] eq "";
|
|
560
|
+
return if !@lines || (@lines == 1 && $lines[0] eq "");
|
|
561
|
+
print "| $_\n" for @lines;
|
|
562
|
+
}
|
|
563
|
+
if (@messages) {
|
|
564
|
+
print "SESSION-ENDING MESSAGE\n";
|
|
565
|
+
for my $i (0 .. $#messages) {
|
|
566
|
+
print "SESSION-ENDING MESSAGE PART ", ($i + 1), " of ", scalar(@messages), "\n" if @messages > 1;
|
|
567
|
+
my $body = defined $messages[$i]{prompt} && length $messages[$i]{prompt}
|
|
568
|
+
? $messages[$i]{prompt}
|
|
569
|
+
: (defined $messages[$i]{text} ? $messages[$i]{text} : "");
|
|
570
|
+
emit_body($body);
|
|
571
|
+
}
|
|
572
|
+
print "END SESSION-ENDING MESSAGE\n";
|
|
573
|
+
} else {
|
|
574
|
+
print "SESSION-ENDING MESSAGE: (none)\n";
|
|
575
|
+
}
|
|
576
|
+
print "\n";
|
|
577
|
+
print "declared_items: $want\n";
|
|
578
|
+
print "presented_items: $presented\n";
|
|
579
|
+
print "malformed_items: $malformed\n";
|
|
580
|
+
print "complete: $complete\n";
|
|
581
|
+
print "lifecycle: $lifecycle\n";
|
|
582
|
+
print "session_ended: ", (length $session_ended ? $session_ended : "(unset)"), "\n";
|
|
583
|
+
print "annotation_count: ", scalar(@annotations), "\n";
|
|
584
|
+
print "session_ending_message_count: ", scalar(@messages), "\n";
|
|
585
|
+
print "\n";
|
|
586
|
+
if (@annotations) {
|
|
587
|
+
print "ANNOTATIONS\n";
|
|
588
|
+
my $n = 0;
|
|
589
|
+
for my $f (@annotations) {
|
|
590
|
+
$n++;
|
|
591
|
+
my $uid = defined $f->{uid} ? $f->{uid} : "";
|
|
592
|
+
my $selector = defined $f->{selector} ? $f->{selector} : "";
|
|
593
|
+
my $tag = defined $f->{tag} ? $f->{tag} : "";
|
|
594
|
+
print "ANNOTATION $n of ", scalar(@annotations), "\n";
|
|
595
|
+
print "element_uid: $uid\n";
|
|
596
|
+
print "element_selector: $selector\n";
|
|
597
|
+
print "tag: $tag\n";
|
|
598
|
+
print "text:\n";
|
|
599
|
+
my $elem = defined $f->{text} ? $f->{text} : "";
|
|
600
|
+
my $comment = defined $f->{prompt} ? $f->{prompt} : "";
|
|
601
|
+
my $body = length $elem ? $elem : $comment;
|
|
602
|
+
emit_body($body);
|
|
603
|
+
if ($tag ne "choice" && length $comment) {
|
|
604
|
+
print "prompt:\n";
|
|
605
|
+
emit_body($comment);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
print "END ANNOTATIONS\n";
|
|
609
|
+
} else {
|
|
610
|
+
print "ANNOTATIONS: (none)\n";
|
|
611
|
+
}
|
|
612
|
+
print "END LAVISH RESULT ($presented of $want)\n";
|
|
613
|
+
' "$file" "$lifecycle" "$session_ended"
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
case "${1-}" in
|
|
617
|
+
arm) shift; cmd_arm "$@" ;;
|
|
618
|
+
retire) shift; cmd_retire "$@" ;;
|
|
619
|
+
poll) shift; cmd_poll "$@" ;;
|
|
620
|
+
source-id) shift; cmd_source_id "$@" ;;
|
|
621
|
+
classify) shift; cmd_classify "$@" ;;
|
|
622
|
+
terminal) shift; cmd_terminal "$@" ;;
|
|
623
|
+
silent) shift; cmd_silent "$@" ;;
|
|
624
|
+
answers) shift; cmd_answers "$@" ;;
|
|
625
|
+
read) shift; cmd_read "$@" ;;
|
|
626
|
+
''|-h|--help|help) usage ;;
|
|
627
|
+
*) die "unknown command: $1" ;;
|
|
628
|
+
esac
|