@stravica-ai/digital-operator-pa 0.1.0
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/LICENSE +21 -0
- package/README.md +170 -0
- package/bin/desk +9 -0
- package/bin/distill +2 -0
- package/bin/estate-sync +2 -0
- package/bin/launch +2 -0
- package/bin/memory-sync +2 -0
- package/bin/migrate-inspect +2 -0
- package/bin/pa +2 -0
- package/bin/pa-coordinator-hook +2 -0
- package/bin/pa-init +2 -0
- package/bin/research +2 -0
- package/bin/scheduler +2 -0
- package/bin/secrets +2 -0
- package/bin/slice +2 -0
- package/bin/smoke +9 -0
- package/bin/sync +2 -0
- package/dist/engineering-pa-cli/README.md +205 -0
- package/dist/engineering-pa-cli/bin/estate-sync +2 -0
- package/dist/engineering-pa-cli/bin/launch +2 -0
- package/dist/engineering-pa-cli/bin/pa +2 -0
- package/dist/engineering-pa-cli/bin/pa-coordinator-hook +12 -0
- package/dist/engineering-pa-cli/bin/research +2 -0
- package/dist/engineering-pa-cli/bin/scheduler +2 -0
- package/dist/engineering-pa-cli/bin/secrets +2 -0
- package/dist/engineering-pa-cli/bin/smoke +9 -0
- package/dist/engineering-pa-cli/bin/sync +2 -0
- package/dist/engineering-pa-cli/config/coordinator-allowlist.json +118 -0
- package/dist/engineering-pa-cli/docs/coordinator-hook.md +211 -0
- package/dist/engineering-pa-cli/docs/estate-sync.md +412 -0
- package/dist/engineering-pa-cli/docs/gsc.md +175 -0
- package/dist/engineering-pa-cli/docs/lint-linkedin.md +139 -0
- package/dist/engineering-pa-cli/docs/secrets.md +221 -0
- package/dist/engineering-pa-cli/docs/smoke.md +113 -0
- package/dist/engineering-pa-cli/docs/staging-alias.md +114 -0
- package/dist/engineering-pa-cli/index.mjs +17 -0
- package/dist/engineering-pa-cli/package.json +37 -0
- package/dist/engineering-pa-cli/src/autonomy/cli.mjs +329 -0
- package/dist/engineering-pa-cli/src/autonomy/envelope.mjs +301 -0
- package/dist/engineering-pa-cli/src/coordinator-hook/cli.mjs +140 -0
- package/dist/engineering-pa-cli/src/coordinator-hook/config.mjs +134 -0
- package/dist/engineering-pa-cli/src/coordinator-hook/message.mjs +47 -0
- package/dist/engineering-pa-cli/src/coordinator-hook/policy.mjs +211 -0
- package/dist/engineering-pa-cli/src/coordinator-hook/repo-root.mjs +44 -0
- package/dist/engineering-pa-cli/src/coordinator-hook/self.mjs +30 -0
- package/dist/engineering-pa-cli/src/environment/cli.mjs +287 -0
- package/dist/engineering-pa-cli/src/environment/probes.mjs +302 -0
- package/dist/engineering-pa-cli/src/gsc/auth.mjs +148 -0
- package/dist/engineering-pa-cli/src/gsc/cli.mjs +93 -0
- package/dist/engineering-pa-cli/src/gsc/cloudflare.mjs +318 -0
- package/dist/engineering-pa-cli/src/gsc/commands/add-property.mjs +70 -0
- package/dist/engineering-pa-cli/src/gsc/commands/list-properties.mjs +33 -0
- package/dist/engineering-pa-cli/src/gsc/commands/pull-analytics.mjs +130 -0
- package/dist/engineering-pa-cli/src/gsc/commands/submit-sitemap.mjs +41 -0
- package/dist/engineering-pa-cli/src/gsc/commands/verify-via-cf-dns.mjs +189 -0
- package/dist/engineering-pa-cli/src/knowledge/call-log.mjs +59 -0
- package/dist/engineering-pa-cli/src/knowledge/cli.mjs +242 -0
- package/dist/engineering-pa-cli/src/knowledge/eval.mjs +446 -0
- package/dist/engineering-pa-cli/src/knowledge/formatters.mjs +331 -0
- package/dist/engineering-pa-cli/src/knowledge/graph.mjs +710 -0
- package/dist/engineering-pa-cli/src/launch/README.md +214 -0
- package/dist/engineering-pa-cli/src/launch/cli.mjs +51 -0
- package/dist/engineering-pa-cli/src/launch/commands/launch.mjs +106 -0
- package/dist/engineering-pa-cli/src/launch/identity.mjs +43 -0
- package/dist/engineering-pa-cli/src/launch/planner.mjs +44 -0
- package/dist/engineering-pa-cli/src/launch/repo-root.mjs +53 -0
- package/dist/engineering-pa-cli/src/launch/runner.mjs +147 -0
- package/dist/engineering-pa-cli/src/launch/task-loader.mjs +85 -0
- package/dist/engineering-pa-cli/src/lint/cli.mjs +61 -0
- package/dist/engineering-pa-cli/src/lint/commands/linkedin.mjs +133 -0
- package/dist/engineering-pa-cli/src/lint/detectors.mjs +90 -0
- package/dist/engineering-pa-cli/src/lint/linter.mjs +69 -0
- package/dist/engineering-pa-cli/src/lint/reporter.mjs +32 -0
- package/dist/engineering-pa-cli/src/lint/rules.mjs +132 -0
- package/dist/engineering-pa-cli/src/pa/cli.mjs +369 -0
- package/dist/engineering-pa-cli/src/pa/doc-groups.mjs +164 -0
- package/dist/engineering-pa-cli/src/pa/io.mjs +80 -0
- package/dist/engineering-pa-cli/src/pa/project-cli.mjs +385 -0
- package/dist/engineering-pa-cli/src/pa/projects.mjs +352 -0
- package/dist/engineering-pa-cli/src/pa/repo-root.mjs +64 -0
- package/dist/engineering-pa-cli/src/pa/session.mjs +254 -0
- package/dist/engineering-pa-cli/src/pa/work-cli.mjs +164 -0
- package/dist/engineering-pa-cli/src/pa/work.mjs +196 -0
- package/dist/engineering-pa-cli/src/pa/workstreams.mjs +201 -0
- package/dist/engineering-pa-cli/src/research/README.md +360 -0
- package/dist/engineering-pa-cli/src/research/briefs/extractor.md +103 -0
- package/dist/engineering-pa-cli/src/research/briefs/searcher.md +113 -0
- package/dist/engineering-pa-cli/src/research/briefs/synthesizer.md +124 -0
- package/dist/engineering-pa-cli/src/research/briefs/verifier.md +86 -0
- package/dist/engineering-pa-cli/src/research/cli.mjs +141 -0
- package/dist/engineering-pa-cli/src/research/commands/gates.mjs +176 -0
- package/dist/engineering-pa-cli/src/research/commands/list.mjs +56 -0
- package/dist/engineering-pa-cli/src/research/commands/mark.mjs +97 -0
- package/dist/engineering-pa-cli/src/research/commands/paths.mjs +69 -0
- package/dist/engineering-pa-cli/src/research/commands/prune.mjs +86 -0
- package/dist/engineering-pa-cli/src/research/commands/run.mjs +94 -0
- package/dist/engineering-pa-cli/src/research/commands/show.mjs +43 -0
- package/dist/engineering-pa-cli/src/research/docs/operator-present-flow.md +120 -0
- package/dist/engineering-pa-cli/src/research/format.mjs +59 -0
- package/dist/engineering-pa-cli/src/research/promote.mjs +260 -0
- package/dist/engineering-pa-cli/src/research/schema/finding.schema.json +55 -0
- package/dist/engineering-pa-cli/src/research/schema/gates.schema.json +34 -0
- package/dist/engineering-pa-cli/src/research/schema/manifest.schema.json +59 -0
- package/dist/engineering-pa-cli/src/research/schema/plan.schema.json +41 -0
- package/dist/engineering-pa-cli/src/research/schema/sources.schema.json +31 -0
- package/dist/engineering-pa-cli/src/research/store/findings.mjs +61 -0
- package/dist/engineering-pa-cli/src/research/store/gates.mjs +73 -0
- package/dist/engineering-pa-cli/src/research/store/index.mjs +312 -0
- package/dist/engineering-pa-cli/src/research/store/manifest.mjs +56 -0
- package/dist/engineering-pa-cli/src/research/store/plan.mjs +59 -0
- package/dist/engineering-pa-cli/src/research/store/sources.mjs +44 -0
- package/dist/engineering-pa-cli/src/research/store/validate.mjs +92 -0
- package/dist/engineering-pa-cli/src/research/workflows/research-normal.js +573 -0
- package/dist/engineering-pa-cli/src/scheduler/cli.mjs +197 -0
- package/dist/engineering-pa-cli/src/secrets/cli.mjs +254 -0
- package/dist/engineering-pa-cli/src/secrets/commands/backup-template.mjs +67 -0
- package/dist/engineering-pa-cli/src/secrets/commands/backup.mjs +85 -0
- package/dist/engineering-pa-cli/src/secrets/commands/delete.mjs +58 -0
- package/dist/engineering-pa-cli/src/secrets/commands/find.mjs +36 -0
- package/dist/engineering-pa-cli/src/secrets/commands/get.mjs +49 -0
- package/dist/engineering-pa-cli/src/secrets/commands/init.mjs +69 -0
- package/dist/engineering-pa-cli/src/secrets/commands/list.mjs +37 -0
- package/dist/engineering-pa-cli/src/secrets/commands/rotate.mjs +46 -0
- package/dist/engineering-pa-cli/src/secrets/commands/set.mjs +123 -0
- package/dist/engineering-pa-cli/src/secrets/commands/status.mjs +146 -0
- package/dist/engineering-pa-cli/src/secrets/commands/vaults.mjs +57 -0
- package/dist/engineering-pa-cli/src/secrets/commands/verify.mjs +143 -0
- package/dist/engineering-pa-cli/src/secrets/vault.mjs +766 -0
- package/dist/engineering-pa-cli/src/smoke/checks.mjs +199 -0
- package/dist/engineering-pa-cli/src/smoke/cli.mjs +108 -0
- package/dist/engineering-pa-cli/src/smoke/commands/run.mjs +237 -0
- package/dist/engineering-pa-cli/src/smoke/runner.mjs +191 -0
- package/dist/engineering-pa-cli/src/staging-alias/cli.mjs +91 -0
- package/dist/engineering-pa-cli/src/staging-alias/cloudflare.mjs +380 -0
- package/dist/engineering-pa-cli/src/staging-alias/commands/list.mjs +36 -0
- package/dist/engineering-pa-cli/src/staging-alias/commands/set.mjs +188 -0
- package/dist/engineering-pa-cli/src/staging-alias/commands/status.mjs +113 -0
- package/dist/engineering-pa-cli/src/staging-alias/commands/unset.mjs +95 -0
- package/dist/engineering-pa-cli/src/staging-alias/sites.mjs +105 -0
- package/dist/engineering-pa-cli/src/sync/cli.mjs +151 -0
- package/dist/engineering-pa-cli/src/sync/git.mjs +149 -0
- package/dist/engineering-pa-cli/src/sync/lock.mjs +30 -0
- package/dist/engineering-pa-cli/src/sync/regenerated-artifacts.mjs +114 -0
- package/dist/engineering-pa-cli/src/sync/registry-scope.mjs +260 -0
- package/dist/engineering-pa-cli/src/sync/run.mjs +531 -0
- package/dist/engineering-pa-cli/src/sync/runner.mjs +62 -0
- package/dist/engineering-pa-cli/src/sync/runs-digest.mjs +138 -0
- package/dist/engineering-pa-core/README.md +60 -0
- package/dist/engineering-pa-core/bin/desk +9 -0
- package/dist/engineering-pa-core/bin/distill +2 -0
- package/dist/engineering-pa-core/bin/memory-sync +2 -0
- package/dist/engineering-pa-core/bin/slice +2 -0
- package/dist/engineering-pa-core/docs/autonomy-envelope-tracker.md +111 -0
- package/dist/engineering-pa-core/docs/blueprints/README.md +45 -0
- package/dist/engineering-pa-core/docs/blueprints/docker-services/blueprint.md +168 -0
- package/dist/engineering-pa-core/docs/blueprints/git-identity/blueprint.md +116 -0
- package/dist/engineering-pa-core/docs/blueprints/ideas/custom-workspace-views.md +9 -0
- package/dist/engineering-pa-core/docs/blueprints/ideas/knowledge-domain-patterns.md +15 -0
- package/dist/engineering-pa-core/docs/blueprints/ideas/office-integration.md +11 -0
- package/dist/engineering-pa-core/docs/blueprints/ideas/team-scaling.md +9 -0
- package/dist/engineering-pa-core/docs/blueprints/ideas/work-personal-separation.md +9 -0
- package/dist/engineering-pa-core/docs/blueprints/scheduled-distillation/blueprint.md +129 -0
- package/dist/engineering-pa-core/docs/blueprints/tool-integration/blueprint.md +110 -0
- package/dist/engineering-pa-core/docs/commands/init.md +159 -0
- package/dist/engineering-pa-core/docs/commands/schedule.md +98 -0
- package/dist/engineering-pa-core/docs/commands/upgrade.md +67 -0
- package/dist/engineering-pa-core/docs/entity-location-map.md +93 -0
- package/dist/engineering-pa-core/docs/knowledge-scaffold.md +121 -0
- package/dist/engineering-pa-core/docs/lock.md +155 -0
- package/dist/engineering-pa-core/docs/memory-sync.md +28 -0
- package/dist/engineering-pa-core/docs/pa-operating-model.md +457 -0
- package/dist/engineering-pa-core/docs/scheduling.md +35 -0
- package/dist/engineering-pa-core/docs/standards/README.md +24 -0
- package/dist/engineering-pa-core/docs/standards/briefing-contract.md +161 -0
- package/dist/engineering-pa-core/docs/standards/tooling.md +240 -0
- package/dist/engineering-pa-core/docs/tools/distill.md +230 -0
- package/dist/engineering-pa-core/docs/tools/memory-sync.md +98 -0
- package/dist/engineering-pa-core/docs/tools/scheduler.md +243 -0
- package/dist/engineering-pa-core/docs/tools/slice.md +150 -0
- package/dist/engineering-pa-core/docs/upstream-issue-filing.md +88 -0
- package/dist/engineering-pa-core/docs/working-directory.md +29 -0
- package/dist/engineering-pa-core/docs/workspace-operations.md +46 -0
- package/dist/engineering-pa-core/index.mjs +21 -0
- package/dist/engineering-pa-core/knowledge/README.md +53 -0
- package/dist/engineering-pa-core/knowledge/canonical/.gitkeep +0 -0
- package/dist/engineering-pa-core/knowledge/content-voice/README.md +64 -0
- package/dist/engineering-pa-core/knowledge/content-voice/banned-ai-tells-baseline.md +133 -0
- package/dist/engineering-pa-core/knowledge/content-voice/banned-ai-tells-shape.md +58 -0
- package/dist/engineering-pa-core/knowledge/content-voice/banned-ai-tells-taxonomy.md +33 -0
- package/dist/engineering-pa-core/knowledge/content-voice/content-pipeline-routing.md +58 -0
- package/dist/engineering-pa-core/knowledge/content-voice/new-tell-capture-procedure.md +40 -0
- package/dist/engineering-pa-core/knowledge/content-voice/voice-guide-shape.md +43 -0
- package/dist/engineering-pa-core/knowledge/delegation-dispatch/README.md +34 -0
- package/dist/engineering-pa-core/knowledge/delegation-dispatch/briefing-contract.md +77 -0
- package/dist/engineering-pa-core/knowledge/delegation-dispatch/delegation-modes.md +84 -0
- package/dist/engineering-pa-core/knowledge/delegation-dispatch/dispatch-envelope.md +238 -0
- package/dist/engineering-pa-core/knowledge/delegation-dispatch/task-groups-and-orchestrators.md +62 -0
- package/dist/engineering-pa-core/knowledge/delegation-dispatch/team-improvement-loop.md +48 -0
- package/dist/engineering-pa-core/knowledge/delegation-dispatch/tool-development-policy.md +48 -0
- package/dist/engineering-pa-core/knowledge/engineering-discipline/README.md +33 -0
- package/dist/engineering-pa-core/knowledge/engineering-discipline/blast-radius-and-safety.md +50 -0
- package/dist/engineering-pa-core/knowledge/engineering-discipline/investigate-root-causes.md +48 -0
- package/dist/engineering-pa-core/knowledge/engineering-discipline/role-ladder.md +57 -0
- package/dist/engineering-pa-core/knowledge/engineering-discipline/verify-runtime-behaviour.md +53 -0
- package/dist/engineering-pa-core/knowledge/engineering-discipline/worktree-isolation.md +50 -0
- package/dist/engineering-pa-core/knowledge/knowledge-memory/README.md +33 -0
- package/dist/engineering-pa-core/knowledge/knowledge-memory/claude-md-hygiene.md +47 -0
- package/dist/engineering-pa-core/knowledge/knowledge-memory/journal-and-self-improvement.md +53 -0
- package/dist/engineering-pa-core/knowledge/knowledge-memory/knowledge-retrieval-discipline.md +62 -0
- package/dist/engineering-pa-core/knowledge/knowledge-memory/librarian-synthesis-mandate.md +56 -0
- package/dist/engineering-pa-core/knowledge/knowledge-memory/staging-and-observations.md +58 -0
- package/dist/engineering-pa-core/knowledge/operator-interface/README.md +32 -0
- package/dist/engineering-pa-core/knowledge/operator-interface/communication-style.md +33 -0
- package/dist/engineering-pa-core/knowledge/operator-interface/escalation-and-correction.md +45 -0
- package/dist/engineering-pa-core/knowledge/operator-interface/push-back-discipline.md +42 -0
- package/dist/engineering-pa-core/knowledge/operator-interface/session-boot-and-end.md +56 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/README.md +37 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/desk-cli-reference.md +52 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/environment-awareness.md +91 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/mcp-servers-catalogue.md +52 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/pa-cli-reference.md +55 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/scheduling-and-launchd.md +56 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/tool-discovery-discipline.md +49 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/working-directory-vs-project-root.md +43 -0
- package/dist/engineering-pa-core/knowledge/platform-tooling/workspace-server.md +51 -0
- package/dist/engineering-pa-core/knowledge/raw/.gitkeep +0 -0
- package/dist/engineering-pa-core/knowledge/scaffold/domains.json +5 -0
- package/dist/engineering-pa-core/knowledge/schema/.gitkeep +0 -0
- package/dist/engineering-pa-core/knowledge/work-management/README.md +33 -0
- package/dist/engineering-pa-core/knowledge/work-management/desk-cli.md +84 -0
- package/dist/engineering-pa-core/knowledge/work-management/progress-md.md +48 -0
- package/dist/engineering-pa-core/knowledge/work-management/projects.md +64 -0
- package/dist/engineering-pa-core/knowledge/work-management/spawn-log.md +48 -0
- package/dist/engineering-pa-core/knowledge/work-management/work-items.md +67 -0
- package/dist/engineering-pa-core/package.json +26 -0
- package/dist/engineering-pa-core/roles/agent-ops/definition.md +79 -0
- package/dist/engineering-pa-core/roles/dispatch-briefer/definition.md +195 -0
- package/dist/engineering-pa-core/roles/librarian/definition.md +176 -0
- package/dist/engineering-pa-core/roles/pa/definition.md +93 -0
- package/dist/engineering-pa-core/roles/system-admin/definition.md +106 -0
- package/dist/engineering-pa-core/roles/tool-developer/definition.md +116 -0
- package/dist/engineering-pa-core/roles/writer/definition.md +130 -0
- package/dist/engineering-pa-core/schema/autonomy-envelope.schema.json +61 -0
- package/dist/engineering-pa-core/schema/project.json +114 -0
- package/dist/engineering-pa-core/schema/schedule.json +63 -0
- package/dist/engineering-pa-core/schema/work-item.json +92 -0
- package/dist/engineering-pa-core/src/config/pa-package-name.mjs +30 -0
- package/dist/engineering-pa-core/src/desk/cli.mjs +95 -0
- package/dist/engineering-pa-core/src/desk/commands.mjs +398 -0
- package/dist/engineering-pa-core/src/desk/format.mjs +84 -0
- package/dist/engineering-pa-core/src/desk/repo.mjs +172 -0
- package/dist/engineering-pa-core/src/desk/team-scope.mjs +142 -0
- package/dist/engineering-pa-core/src/distill/cli.mjs +112 -0
- package/dist/engineering-pa-core/src/distill/prereqs.mjs +171 -0
- package/dist/engineering-pa-core/src/distill/prompt.mjs +74 -0
- package/dist/engineering-pa-core/src/distill/run.mjs +230 -0
- package/dist/engineering-pa-core/src/distill/runner.mjs +86 -0
- package/dist/engineering-pa-core/src/distill/staging.mjs +59 -0
- package/dist/engineering-pa-core/src/knowledge/retrieval/backlink-indexer.mjs +154 -0
- package/dist/engineering-pa-core/src/knowledge/retrieval/graph-builder.mjs +186 -0
- package/dist/engineering-pa-core/src/knowledge/retrieval/index-builder.mjs +225 -0
- package/dist/engineering-pa-core/src/knowledge/retrieval/query.mjs +263 -0
- package/dist/engineering-pa-core/src/lock/lock.mjs +202 -0
- package/dist/engineering-pa-core/src/memory-sync/cli-support.mjs +12 -0
- package/dist/engineering-pa-core/src/memory-sync/cli.mjs +56 -0
- package/dist/engineering-pa-core/src/memory-sync/commands/pull.mjs +44 -0
- package/dist/engineering-pa-core/src/memory-sync/commands/push.mjs +46 -0
- package/dist/engineering-pa-core/src/memory-sync/mirror.mjs +114 -0
- package/dist/engineering-pa-core/src/memory-sync/repo.mjs +65 -0
- package/dist/engineering-pa-core/src/scheduler/detect.mjs +111 -0
- package/dist/engineering-pa-core/src/scheduler/host.mjs +38 -0
- package/dist/engineering-pa-core/src/scheduler/index.mjs +13 -0
- package/dist/engineering-pa-core/src/scheduler/install.mjs +854 -0
- package/dist/engineering-pa-core/src/scheduler/list.mjs +168 -0
- package/dist/engineering-pa-core/src/scheduler/remove.mjs +176 -0
- package/dist/engineering-pa-core/src/scheduler/verify.mjs +435 -0
- package/dist/engineering-pa-core/src/session-boot/autonomy-injection.mjs +84 -0
- package/dist/engineering-pa-core/src/slice/cli.mjs +139 -0
- package/dist/engineering-pa-core/src/slice/inputs.mjs +174 -0
- package/dist/engineering-pa-core/src/slice/prompt.mjs +94 -0
- package/dist/engineering-pa-core/src/slice/prompts/dave-boot.md +91 -0
- package/dist/engineering-pa-core/src/slice/run.mjs +334 -0
- package/dist/engineering-pa-core-extensions-atlassian/README.md +31 -0
- package/dist/engineering-pa-core-extensions-atlassian/index.mjs +9 -0
- package/dist/engineering-pa-core-extensions-atlassian/package.json +19 -0
- package/dist/engineering-pa-core-extensions-n8n/README.md +29 -0
- package/dist/engineering-pa-core-extensions-n8n/index.mjs +8 -0
- package/dist/engineering-pa-core-extensions-n8n/package.json +19 -0
- package/dist/engineering-pa-librarian/README.md +38 -0
- package/dist/engineering-pa-librarian/index.mjs +12 -0
- package/dist/engineering-pa-librarian/package.json +19 -0
- package/dist/engineering-pa-migrate-inspect/README.md +131 -0
- package/dist/engineering-pa-migrate-inspect/bin/migrate-inspect +2 -0
- package/dist/engineering-pa-migrate-inspect/package.json +21 -0
- package/dist/engineering-pa-migrate-inspect/src/age-key-migrate.mjs +83 -0
- package/dist/engineering-pa-migrate-inspect/src/cli.mjs +97 -0
- package/dist/engineering-pa-migrate-inspect/src/inspector.mjs +237 -0
- package/dist/engineering-pa-migrate-inspect/src/platforms/linux.mjs +87 -0
- package/dist/engineering-pa-migrate-inspect/src/platforms/macos.mjs +105 -0
- package/dist/engineering-pa-migrate-inspect/src/runner.mjs +87 -0
- package/dist/engineering-pa-runbook/README.md +103 -0
- package/dist/engineering-pa-runbook/package.json +18 -0
- package/dist/engineering-pa-runbook/reference/dex-template.runbook.json +66 -0
- package/dist/engineering-pa-runbook/reference/hq-dave.runbook.json +69 -0
- package/dist/engineering-pa-runbook/reference/smarthome01.runbook.json +92 -0
- package/dist/engineering-pa-runbook/schema/inspection.schema.json +113 -0
- package/dist/engineering-pa-runbook/schema/runbook.schema.json +67 -0
- package/dist/engineering-pa-runbook/src/validator.mjs +167 -0
- package/dist/engineering-pa-scaffold/README.md +164 -0
- package/dist/engineering-pa-scaffold/bin/pa-init +2 -0
- package/dist/engineering-pa-scaffold/index.mjs +42 -0
- package/dist/engineering-pa-scaffold/package.json +22 -0
- package/dist/engineering-pa-scaffold/src/cli.mjs +115 -0
- package/dist/engineering-pa-scaffold/src/commands/init.mjs +169 -0
- package/dist/engineering-pa-scaffold/src/generator.mjs +354 -0
- package/dist/engineering-pa-scaffold/src/prompts.mjs +125 -0
- package/dist/engineering-pa-scaffold/src/runner.mjs +142 -0
- package/dist/engineering-pa-scaffold/templates/CLAUDE.md.template +196 -0
- package/dist/engineering-pa-scaffold/templates/operator-README.md.template +44 -0
- package/dist/engineering-pa-types-engineering/README.md +35 -0
- package/dist/engineering-pa-types-engineering/docs/commands/product-build.md +120 -0
- package/dist/engineering-pa-types-engineering/index.mjs +9 -0
- package/dist/engineering-pa-types-engineering/package.json +19 -0
- package/dist/engineering-pa-types-engineering/roles/product-engineer/definition.md +650 -0
- package/dist/engineering-pa-types-engineering/roles/product-engineer/templates/build-spec.md +82 -0
- package/dist/engineering-pa-types-engineering/roles/product-engineer/templates/preflight-checklist.md +158 -0
- package/dist/engineering-pa-types-engineering/roles/product-engineer/templates/worker-brief.md +130 -0
- package/dist/engineering-pa-workspace/README.md +197 -0
- package/dist/engineering-pa-workspace/app/assets/md.js +187 -0
- package/dist/engineering-pa-workspace/app/assets/modal.js +120 -0
- package/dist/engineering-pa-workspace/app/assets/theme.css +132 -0
- package/dist/engineering-pa-workspace/app/assets/theme.js +159 -0
- package/dist/engineering-pa-workspace/app/banner.js +320 -0
- package/dist/engineering-pa-workspace/app/delegations.html +345 -0
- package/dist/engineering-pa-workspace/app/home.html +1060 -0
- package/dist/engineering-pa-workspace/app/index.html +361 -0
- package/dist/engineering-pa-workspace/app/knowledge-map.html +163 -0
- package/dist/engineering-pa-workspace/app/knowledge.html +304 -0
- package/dist/engineering-pa-workspace/app/nav.json +75 -0
- package/dist/engineering-pa-workspace/app/notes.html +199 -0
- package/dist/engineering-pa-workspace/app/onboarding.html +592 -0
- package/dist/engineering-pa-workspace/app/profile.html +243 -0
- package/dist/engineering-pa-workspace/app/project-detail.html +432 -0
- package/dist/engineering-pa-workspace/app/projects.html +297 -0
- package/dist/engineering-pa-workspace/app/repos.html +598 -0
- package/dist/engineering-pa-workspace/app/schedules.html +486 -0
- package/dist/engineering-pa-workspace/app/secrets.html +164 -0
- package/dist/engineering-pa-workspace/app/staging.html +319 -0
- package/dist/engineering-pa-workspace/app/tasks.html +465 -0
- package/dist/engineering-pa-workspace/app/vendor/chart.umd.min.js +21 -0
- package/dist/engineering-pa-workspace/app/viewer.html +116 -0
- package/dist/engineering-pa-workspace/docs/DAEMON.md +104 -0
- package/dist/engineering-pa-workspace/docs/page-blueprint.md +286 -0
- package/dist/engineering-pa-workspace/docs/status-mon.md +168 -0
- package/dist/engineering-pa-workspace/index.mjs +12 -0
- package/dist/engineering-pa-workspace/nav.json.example +8 -0
- package/dist/engineering-pa-workspace/package.json +27 -0
- package/dist/engineering-pa-workspace/src/api.mjs +2086 -0
- package/dist/engineering-pa-workspace/src/install-daemon.mjs +573 -0
- package/dist/engineering-pa-workspace/src/nav.mjs +190 -0
- package/dist/engineering-pa-workspace/src/secrets-api.mjs +175 -0
- package/dist/engineering-pa-workspace/src/server.mjs +516 -0
- package/dist/engineering-pa-workspace/src/status-mon/poll.mjs +220 -0
- package/dist/engineering-pa-workspace/src/status-mon/poller.mjs +113 -0
- package/dist/engineering-pa-workspace/src/status-mon/run.mjs +133 -0
- package/dist/engineering-pa-workspace/src/supervisor.mjs +264 -0
- package/dist/engineering-pa-workspace/src/ws.mjs +633 -0
- package/index.mjs +60 -0
- package/package.json +58 -0
- package/templates/banned-ai-tells.md +102 -0
- package/templates/purpose.md +105 -0
- package/templates/voice-guide.md +98 -0
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* verify.mjs -- Verify a schedule's command runs under its installed environment
|
|
4
|
+
*
|
|
5
|
+
* Usage: node node_modules/@stravica-ai/engineering-pa-core/src/scheduler/verify.mjs <schedule.json> [backend] [--timeout N]
|
|
6
|
+
*
|
|
7
|
+
* Reads a schedule JSON file and spawns its command under the same environment
|
|
8
|
+
* the named backend would install (PATH/HOME/DAVE_ROOT auto-injection on launchd,
|
|
9
|
+
* the schedule's own environment block elsewhere). This catches the silent-failure
|
|
10
|
+
* class of bug where an explicit narrow PATH masks brew binaries on Apple Silicon.
|
|
11
|
+
*
|
|
12
|
+
* The verify deliberately does not require the schedule to be installed already —
|
|
13
|
+
* it derives the env the same way install.mjs does and runs the command once. A
|
|
14
|
+
* timeout (default 30s) bounds the run; verify is meant for "does this schedule
|
|
15
|
+
* even start?" not "does it complete its full work?".
|
|
16
|
+
*
|
|
17
|
+
* Backend defaults to the auto-detected backend for the host (launchd on macOS,
|
|
18
|
+
* systemd or cron on Linux, schtasks on Windows).
|
|
19
|
+
*
|
|
20
|
+
* Exit codes:
|
|
21
|
+
* 0 ok — command exited zero
|
|
22
|
+
* 1 usage error
|
|
23
|
+
* 2 command exited non-zero (operational failure)
|
|
24
|
+
* 3 spawn failure — command not found / ENOENT / EACCES / etc.
|
|
25
|
+
* 4 timeout — command did not finish within the timeout
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import { readFileSync, realpathSync } from 'node:fs';
|
|
29
|
+
import { spawn } from 'node:child_process';
|
|
30
|
+
import { resolve, dirname, join } from 'node:path';
|
|
31
|
+
import { homedir } from 'node:os';
|
|
32
|
+
import { fileURLToPath } from 'node:url';
|
|
33
|
+
|
|
34
|
+
import {
|
|
35
|
+
resolveWorkDir,
|
|
36
|
+
resolveEnvironment,
|
|
37
|
+
withLaunchdDefaults,
|
|
38
|
+
buildCronCommand,
|
|
39
|
+
detectNvm,
|
|
40
|
+
} from './install.mjs';
|
|
41
|
+
import { detect } from './detect.mjs';
|
|
42
|
+
|
|
43
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
44
|
+
const __dirname = dirname(__filename);
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The environment cron's crond process actually provides to a job — a
|
|
48
|
+
* small fixed set (SHELL, a narrow system PATH, HOME, LOGNAME/USER), NOT
|
|
49
|
+
* whatever the verifying shell happens to have. This is what `env -i`
|
|
50
|
+
* testing proved on 2026-07-15 (w-2026-07-15-003): a login shell's PATH
|
|
51
|
+
* (nvm, Homebrew, pnpm global bin, …) is invisible to cron, so a schedule
|
|
52
|
+
* that "worked" under a verify run inheriting the operator's full shell
|
|
53
|
+
* env could still fail silently once actually installed.
|
|
54
|
+
* @param {object} [opts]
|
|
55
|
+
* @param {string} [opts.home]
|
|
56
|
+
* @param {string} [opts.user]
|
|
57
|
+
* @returns {Record<string,string>}
|
|
58
|
+
*/
|
|
59
|
+
export function minimalCronEnv({ home = homedir(), user = process.env.USER || process.env.LOGNAME || '' } = {}) {
|
|
60
|
+
return {
|
|
61
|
+
SHELL: '/bin/sh',
|
|
62
|
+
PATH: '/usr/bin:/bin',
|
|
63
|
+
HOME: home,
|
|
64
|
+
LOGNAME: user,
|
|
65
|
+
USER: user,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Compute the env the named backend would install for this schedule.
|
|
71
|
+
*
|
|
72
|
+
* - launchd: explicit env merged over auto-injected defaults (PATH, HOME, DAVE_ROOT).
|
|
73
|
+
* Mirrors `withLaunchdDefaults(resolveEnvironment(sched))` from install.mjs.
|
|
74
|
+
* - cron: the schedule's own resolved environment layered over cron's
|
|
75
|
+
* actual MINIMAL environment (see minimalCronEnv) — NOT the verifying
|
|
76
|
+
* process's env. This is the honest-about-cron-reality fix: verify used
|
|
77
|
+
* to inherit `process.env`, which reliably masked the nvm/PATH bug this
|
|
78
|
+
* whole feature exists to catch (see module doc).
|
|
79
|
+
* - systemd / schtasks: the schedule's own resolved environment, with no
|
|
80
|
+
* auto-injection. Verify inherits the parent shell's env on top of these
|
|
81
|
+
* so spawn can find `node`, `bash`, etc. — matching how each backend
|
|
82
|
+
* actually executes commands at runtime (systemd user units inherit the
|
|
83
|
+
* user's systemd --user environment; schtasks inherits the interactive
|
|
84
|
+
* SYSTEM/USER env). The verify replicates the "explicit env wins"
|
|
85
|
+
* behaviour in each case.
|
|
86
|
+
*
|
|
87
|
+
* @param {object} sched
|
|
88
|
+
* @param {string} backend
|
|
89
|
+
* @returns {Record<string,string>}
|
|
90
|
+
*/
|
|
91
|
+
export function computeBackendEnv(sched, backend) {
|
|
92
|
+
const explicit = resolveEnvironment(sched);
|
|
93
|
+
if (backend === 'launchd') {
|
|
94
|
+
// launchd builds the agent env from EnvironmentVariables alone. Verify
|
|
95
|
+
// mirrors that: defaults + explicit, no parent-shell inheritance.
|
|
96
|
+
return withLaunchdDefaults(explicit);
|
|
97
|
+
}
|
|
98
|
+
if (backend === 'cron') {
|
|
99
|
+
return { ...minimalCronEnv(), ...explicit };
|
|
100
|
+
}
|
|
101
|
+
// systemd/schtasks: "parent env then explicit overrides". Replicate by
|
|
102
|
+
// layering explicit over process.env, dropping any keys the parent has
|
|
103
|
+
// but the schedule does not (we KEEP parent keys — explicit only
|
|
104
|
+
// narrows for keys it sets).
|
|
105
|
+
return { ...process.env, ...explicit };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Auto-detect the most-recommended backend for this host, falling back to the
|
|
110
|
+
* first available, then to 'cron' as a last resort.
|
|
111
|
+
*
|
|
112
|
+
* @returns {string}
|
|
113
|
+
*/
|
|
114
|
+
export function detectDefaultBackend() {
|
|
115
|
+
const { available } = detect();
|
|
116
|
+
if (available.length === 0) return 'cron';
|
|
117
|
+
const recommended = available.find(b => b.recommended);
|
|
118
|
+
return (recommended || available[0]).backend;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Read and parse a schedule JSON file.
|
|
123
|
+
* @param {string} filePath
|
|
124
|
+
* @returns {object}
|
|
125
|
+
*/
|
|
126
|
+
function readSchedule(filePath) {
|
|
127
|
+
const raw = readFileSync(filePath, 'utf8');
|
|
128
|
+
return JSON.parse(raw);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Spawn the configured command under the given env + workDir, with a timeout.
|
|
133
|
+
*
|
|
134
|
+
* Uses `spawn` (not `exec`) with shell:false on POSIX — the command is
|
|
135
|
+
* splittable by whitespace because schedule definitions are simple (a binary
|
|
136
|
+
* + args, no shell features). On Windows we use shell:true so `cmd.exe`
|
|
137
|
+
* handles the full string the same way schtasks would.
|
|
138
|
+
*
|
|
139
|
+
* Returns { kind, code, signal, error } where kind is one of:
|
|
140
|
+
* 'exit' — process exited; code is the exit code (0 = ok, !0 = fail)
|
|
141
|
+
* 'spawn' — spawn failed (ENOENT, EACCES, etc.)
|
|
142
|
+
* 'timeout' — process did not finish within timeoutMs; killed
|
|
143
|
+
*
|
|
144
|
+
* @param {string} command The schedule.command string (whitespace-split on POSIX)
|
|
145
|
+
* @param {string} workDir Working directory
|
|
146
|
+
* @param {Record<string,string>} env
|
|
147
|
+
* @param {number} timeoutMs
|
|
148
|
+
* @returns {Promise<{ kind: 'exit' | 'spawn' | 'timeout', code: number | null, signal: NodeJS.Signals | null, error: Error | null, stdout: string, stderr: string }>}
|
|
149
|
+
*/
|
|
150
|
+
// Shared settle/timeout/collect logic for an already-spawned child. Both
|
|
151
|
+
// runVerify (string-command path) and runVerifyArgv (exact-argv path,
|
|
152
|
+
// used to run the GENERATED cron line honestly — see below) fan into
|
|
153
|
+
// this so the timeout/kill/collect behaviour never drifts between them.
|
|
154
|
+
function waitForChild(child, timeoutMs) {
|
|
155
|
+
return new Promise(resolveOnce => {
|
|
156
|
+
let settled = false;
|
|
157
|
+
const settle = (value) => {
|
|
158
|
+
if (settled) return;
|
|
159
|
+
settled = true;
|
|
160
|
+
resolveOnce(value);
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
let stdout = '';
|
|
164
|
+
let stderr = '';
|
|
165
|
+
child.stdout.on('data', d => { stdout += d.toString(); });
|
|
166
|
+
child.stderr.on('data', d => { stderr += d.toString(); });
|
|
167
|
+
|
|
168
|
+
const timer = setTimeout(() => {
|
|
169
|
+
try { child.kill('SIGTERM'); } catch { /* already dead */ }
|
|
170
|
+
// Give it a grace window before SIGKILL.
|
|
171
|
+
setTimeout(() => { try { child.kill('SIGKILL'); } catch { /* gone */ } }, 1000).unref();
|
|
172
|
+
settle({ kind: 'timeout', code: null, signal: 'SIGTERM', error: null, stdout, stderr });
|
|
173
|
+
}, timeoutMs);
|
|
174
|
+
|
|
175
|
+
child.on('error', (err) => {
|
|
176
|
+
clearTimeout(timer);
|
|
177
|
+
settle({ kind: 'spawn', code: null, signal: null, error: err, stdout, stderr });
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
child.on('exit', (code, signal) => {
|
|
181
|
+
clearTimeout(timer);
|
|
182
|
+
// If we already settled (timeout), this exit fires later — settle is a no-op.
|
|
183
|
+
settle({ kind: 'exit', code, signal, error: null, stdout, stderr });
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function runVerify(command, workDir, env, timeoutMs) {
|
|
189
|
+
const onWindows = process.platform === 'win32';
|
|
190
|
+
let child;
|
|
191
|
+
try {
|
|
192
|
+
if (onWindows) {
|
|
193
|
+
child = spawn(command, {
|
|
194
|
+
cwd: workDir,
|
|
195
|
+
env,
|
|
196
|
+
shell: true,
|
|
197
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
198
|
+
});
|
|
199
|
+
} else {
|
|
200
|
+
const parts = command.trim().split(/\s+/);
|
|
201
|
+
const [bin, ...args] = parts;
|
|
202
|
+
child = spawn(bin, args, {
|
|
203
|
+
cwd: workDir,
|
|
204
|
+
env,
|
|
205
|
+
shell: false,
|
|
206
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
} catch (err) {
|
|
210
|
+
return Promise.resolve({ kind: 'spawn', code: null, signal: null, error: err, stdout: '', stderr: '' });
|
|
211
|
+
}
|
|
212
|
+
return waitForChild(child, timeoutMs);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Spawn an exact `bin` + `args` array — no string-splitting, no shell.
|
|
217
|
+
* Used to run the GENERATED cron inner script honestly: the script text
|
|
218
|
+
* (which may itself contain spaces, `&&`, quoting from env-var export
|
|
219
|
+
* statements, etc.) is passed as a single `-c` argv element to `bash`,
|
|
220
|
+
* never re-parsed by whitespace-splitting the way runVerify's string path
|
|
221
|
+
* would mangle it.
|
|
222
|
+
*
|
|
223
|
+
* @param {string} bin
|
|
224
|
+
* @param {string[]} args
|
|
225
|
+
* @param {string} workDir
|
|
226
|
+
* @param {Record<string,string>} env
|
|
227
|
+
* @param {number} timeoutMs
|
|
228
|
+
* @returns {Promise<{ kind: 'exit' | 'spawn' | 'timeout', code: number | null, signal: NodeJS.Signals | null, error: Error | null, stdout: string, stderr: string }>}
|
|
229
|
+
*/
|
|
230
|
+
export function runVerifyArgv(bin, args, workDir, env, timeoutMs) {
|
|
231
|
+
let child;
|
|
232
|
+
try {
|
|
233
|
+
child = spawn(bin, args, {
|
|
234
|
+
cwd: workDir,
|
|
235
|
+
env,
|
|
236
|
+
shell: false,
|
|
237
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
238
|
+
});
|
|
239
|
+
} catch (err) {
|
|
240
|
+
return Promise.resolve({ kind: 'spawn', code: null, signal: null, error: err, stdout: '', stderr: '' });
|
|
241
|
+
}
|
|
242
|
+
return waitForChild(child, timeoutMs);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Verify a schedule by running its command once under the resolved backend
|
|
247
|
+
* env.
|
|
248
|
+
*
|
|
249
|
+
* For backend === 'cron', this does NOT run `sched.command` directly — it
|
|
250
|
+
* builds the exact GENERATED inner cron script (via install.mjs's
|
|
251
|
+
* `buildCronCommand`, the same function `scheduler install` uses to write
|
|
252
|
+
* the actual crontab line) and runs THAT via `bash -c` with an exact argv
|
|
253
|
+
* array (never a re-split string). This is the "verification is honest
|
|
254
|
+
* about cron reality" fix: verifying `sched.command` alone, under an env
|
|
255
|
+
* that inherits the verifying process's PATH, never exercised the nvm
|
|
256
|
+
* preamble or the minimal-PATH reality a real cron invocation faces —
|
|
257
|
+
* exactly how the env -i-provable bug (w-2026-07-15-003) went undetected
|
|
258
|
+
* by the pre-existing verify path.
|
|
259
|
+
*
|
|
260
|
+
* @param {string} scheduleFile - Path to the schedule JSON
|
|
261
|
+
* @param {object} [opts]
|
|
262
|
+
* @param {string} [opts.backend] - Override backend (default: auto-detect)
|
|
263
|
+
* @param {number} [opts.timeoutMs] - Timeout in ms (default: 30000)
|
|
264
|
+
* @param {boolean} [opts.hasNvm] - Test-only override; defaults to a real
|
|
265
|
+
* filesystem check of $HOME/.nvm/nvm.sh, matching install-time detection.
|
|
266
|
+
* @param {string} [opts.cronLogPath] - Test-only override for the cron
|
|
267
|
+
* inner script's log redirect target (defaults to
|
|
268
|
+
* `/tmp/<agent>-<id>-verify.log` — distinct from the INSTALLED
|
|
269
|
+
* schedule's own `/tmp/<agent>-<id>.log`, so a verify run never
|
|
270
|
+
* clobbers/interleaves with real cron output).
|
|
271
|
+
* @returns {Promise<{ result: 'ok' | 'fail-exit' | 'fail-spawn' | 'fail-timeout', exitCode: number, sched: object, backend: string, env: Record<string,string>, workDir: string, run: object }>}
|
|
272
|
+
*/
|
|
273
|
+
export async function verify(scheduleFile, opts = {}) {
|
|
274
|
+
const sched = readSchedule(scheduleFile);
|
|
275
|
+
|
|
276
|
+
if (!sched.id || !sched.schedule || !sched.command) {
|
|
277
|
+
const err = new Error('Schedule file must have id, schedule, and command fields');
|
|
278
|
+
err.exitCode = 1;
|
|
279
|
+
throw err;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const backend = opts.backend || sched.backend || detectDefaultBackend();
|
|
283
|
+
const timeoutMs = opts.timeoutMs ?? 30000;
|
|
284
|
+
|
|
285
|
+
const workDir = resolveWorkDir(sched.workingDirectory);
|
|
286
|
+
const env = computeBackendEnv(sched, backend);
|
|
287
|
+
|
|
288
|
+
let run;
|
|
289
|
+
if (backend === 'cron') {
|
|
290
|
+
const explicit = resolveEnvironment(sched);
|
|
291
|
+
const hasNvm = opts.hasNvm ?? detectNvm();
|
|
292
|
+
const logPath = opts.cronLogPath ?? `/tmp/${sched.agent || 'dave'}-${sched.id}-verify.log`;
|
|
293
|
+
const { inner } = buildCronCommand(sched, workDir, explicit, { hasNvm, logPath });
|
|
294
|
+
run = await runVerifyArgv('bash', ['-c', inner], workDir, env, timeoutMs);
|
|
295
|
+
} else {
|
|
296
|
+
run = await runVerify(sched.command, workDir, env, timeoutMs);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
let result;
|
|
300
|
+
let exitCode;
|
|
301
|
+
if (run.kind === 'timeout') {
|
|
302
|
+
result = 'fail-timeout';
|
|
303
|
+
exitCode = 4;
|
|
304
|
+
} else if (run.kind === 'spawn') {
|
|
305
|
+
result = 'fail-spawn';
|
|
306
|
+
exitCode = 3;
|
|
307
|
+
} else if (run.code === 0) {
|
|
308
|
+
result = 'ok';
|
|
309
|
+
exitCode = 0;
|
|
310
|
+
} else {
|
|
311
|
+
result = 'fail-exit';
|
|
312
|
+
exitCode = 2;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return { result, exitCode, sched, backend, env, workDir, run };
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// ── CLI entry point ──────────────────────────────────────────────────
|
|
319
|
+
|
|
320
|
+
function printUsage(stream = process.stderr) {
|
|
321
|
+
stream.write(
|
|
322
|
+
`Usage: node verify.mjs <schedule.json> [backend] [--timeout <seconds>]
|
|
323
|
+
|
|
324
|
+
Spawns the schedule's command once under the same environment the named backend
|
|
325
|
+
would install. Useful as a post-install smoke test to catch silent-failure bugs
|
|
326
|
+
caused by env mismatches (e.g. a narrow PATH that masks Homebrew binaries).
|
|
327
|
+
|
|
328
|
+
Arguments:
|
|
329
|
+
<schedule.json> Path to the schedule definition file.
|
|
330
|
+
[backend] Backend whose env shape to simulate (cron, launchd,
|
|
331
|
+
systemd, schtasks). Defaults to auto-detected backend.
|
|
332
|
+
|
|
333
|
+
Flags:
|
|
334
|
+
--timeout <seconds> Kill the verify run after this many seconds (default: 30).
|
|
335
|
+
-h, --help Print this message and exit 0.
|
|
336
|
+
|
|
337
|
+
Exit codes:
|
|
338
|
+
0 command ran and exited zero
|
|
339
|
+
1 usage error
|
|
340
|
+
2 command exited non-zero
|
|
341
|
+
3 spawn failure (command not found, etc.)
|
|
342
|
+
4 timeout
|
|
343
|
+
`);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// BUG 3 fix — see install.mjs for the full rationale: realpath both sides
|
|
347
|
+
// instead of the previous realpath-vs-symlink endsWith comparison, which
|
|
348
|
+
// silently no-op'd under pnpm.
|
|
349
|
+
|
|
350
|
+
function isDirectlyInvoked() {
|
|
351
|
+
if (!process.argv[1]) return false;
|
|
352
|
+
try {
|
|
353
|
+
return fileURLToPath(import.meta.url) === realpathSync(resolve(process.argv[1]));
|
|
354
|
+
} catch {
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (isDirectlyInvoked()) {
|
|
360
|
+
const args = process.argv.slice(2);
|
|
361
|
+
|
|
362
|
+
if (args.includes('-h') || args.includes('--help')) {
|
|
363
|
+
printUsage(process.stdout);
|
|
364
|
+
process.exit(0);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Parse: positional <schedule.json>, optional positional <backend>, optional --timeout N.
|
|
368
|
+
let scheduleFile = null;
|
|
369
|
+
let backend = null;
|
|
370
|
+
let timeoutSeconds = 30;
|
|
371
|
+
|
|
372
|
+
for (let i = 0; i < args.length; i++) {
|
|
373
|
+
const a = args[i];
|
|
374
|
+
if (a === '--timeout') {
|
|
375
|
+
const v = args[++i];
|
|
376
|
+
const n = Number(v);
|
|
377
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
378
|
+
process.stderr.write(`Error: --timeout requires a positive number, got: ${v}\n`);
|
|
379
|
+
process.exit(1);
|
|
380
|
+
}
|
|
381
|
+
timeoutSeconds = n;
|
|
382
|
+
} else if (a.startsWith('--timeout=')) {
|
|
383
|
+
const v = a.slice('--timeout='.length);
|
|
384
|
+
const n = Number(v);
|
|
385
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
386
|
+
process.stderr.write(`Error: --timeout requires a positive number, got: ${v}\n`);
|
|
387
|
+
process.exit(1);
|
|
388
|
+
}
|
|
389
|
+
timeoutSeconds = n;
|
|
390
|
+
} else if (a.startsWith('--')) {
|
|
391
|
+
process.stderr.write(`Error: unknown flag: ${a}\n`);
|
|
392
|
+
printUsage();
|
|
393
|
+
process.exit(1);
|
|
394
|
+
} else if (scheduleFile === null) {
|
|
395
|
+
scheduleFile = a;
|
|
396
|
+
} else if (backend === null) {
|
|
397
|
+
backend = a;
|
|
398
|
+
} else {
|
|
399
|
+
process.stderr.write(`Error: unexpected argument: ${a}\n`);
|
|
400
|
+
printUsage();
|
|
401
|
+
process.exit(1);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (!scheduleFile) {
|
|
406
|
+
printUsage();
|
|
407
|
+
process.exit(1);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (backend && !['cron', 'launchd', 'systemd', 'schtasks'].includes(backend)) {
|
|
411
|
+
process.stderr.write(`Error: unknown backend: ${backend}. Supported: cron, launchd, systemd, schtasks\n`);
|
|
412
|
+
process.exit(1);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
try {
|
|
416
|
+
const out = await verify(scheduleFile, { backend, timeoutMs: timeoutSeconds * 1000 });
|
|
417
|
+
const label = `verify[${out.sched.id}@${out.backend}]`;
|
|
418
|
+
if (out.result === 'ok') {
|
|
419
|
+
process.stdout.write(`${label}: OK — command exited 0 in ${out.workDir}\n`);
|
|
420
|
+
} else if (out.result === 'fail-exit') {
|
|
421
|
+
process.stdout.write(`${label}: FAIL — command exited ${out.run.code}\n`);
|
|
422
|
+
if (out.run.stderr) process.stderr.write(out.run.stderr);
|
|
423
|
+
} else if (out.result === 'fail-spawn') {
|
|
424
|
+
const msg = out.run.error ? out.run.error.message : 'unknown spawn error';
|
|
425
|
+
process.stderr.write(`${label}: FAIL — could not spawn command: ${msg}\n`);
|
|
426
|
+
process.stderr.write(`Hint: verify the command's first token is on PATH (current PATH: ${out.env.PATH || '(unset)'})\n`);
|
|
427
|
+
} else if (out.result === 'fail-timeout') {
|
|
428
|
+
process.stderr.write(`${label}: FAIL — timed out after ${timeoutSeconds}s\n`);
|
|
429
|
+
}
|
|
430
|
+
process.exit(out.exitCode);
|
|
431
|
+
} catch (err) {
|
|
432
|
+
process.stderr.write(`Error: ${err.message}\n`);
|
|
433
|
+
process.exit(err.exitCode || 1);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// autonomy-injection.mjs — session-boot integration surface for the
|
|
2
|
+
// autonomy envelope.
|
|
3
|
+
//
|
|
4
|
+
// OQ-A1 recommendation: the core does NOT ship a Claude Code SessionStart
|
|
5
|
+
// hook — hook infrastructure is operator-side (typically an operator's
|
|
6
|
+
// boot-context tool). Core instead ships this reusable module that renders
|
|
7
|
+
// the envelope's current state as an `additionalContext`-shaped markdown
|
|
8
|
+
// block, and the `pa autonomy get <agent> --format json` verb that lets an
|
|
9
|
+
// operator's boot hook consume the state programmatically.
|
|
10
|
+
//
|
|
11
|
+
// The recommended operator wiring is: the operator's SessionStart hook
|
|
12
|
+
// tool spawns `pa autonomy get <agent> --format json`, imports this
|
|
13
|
+
// module, and calls `buildAutonomyContext({ envelope })` to produce the
|
|
14
|
+
// markdown block to inject alongside its other live-state blocks.
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Build a compact `additionalContext`-shaped markdown block for the given
|
|
18
|
+
* envelope. Same size class as a workState block — a summary of task-types
|
|
19
|
+
* grouped by state, not a full render of the envelope.
|
|
20
|
+
*
|
|
21
|
+
* Input shape (matches `pa autonomy get <agent> --format json` output):
|
|
22
|
+
* {
|
|
23
|
+
* agent, owner, updated,
|
|
24
|
+
* taskTypes: [{ id, label, state, stateSince, operatorNote? }, ...]
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* Returns a string suitable for the `additionalContext` field of a
|
|
28
|
+
* Claude Code SessionStart hook JSON envelope.
|
|
29
|
+
*/
|
|
30
|
+
export function buildAutonomyContext(envelope) {
|
|
31
|
+
if (!envelope || !envelope.agent) {
|
|
32
|
+
return '# autonomyEnvelope (live)\n\n_No envelope initialised — run `pa autonomy init <agent>` to seed one._\n';
|
|
33
|
+
}
|
|
34
|
+
const grouped = {
|
|
35
|
+
fullyApproved: [],
|
|
36
|
+
checkBeforeCommitting: [],
|
|
37
|
+
needsFullSupervision: [],
|
|
38
|
+
};
|
|
39
|
+
const taskTypes = envelope.taskTypes ?? [];
|
|
40
|
+
for (const t of taskTypes) {
|
|
41
|
+
if (grouped[t.state]) grouped[t.state].push(t);
|
|
42
|
+
}
|
|
43
|
+
const parts = [];
|
|
44
|
+
parts.push('# autonomyEnvelope (live)');
|
|
45
|
+
parts.push('');
|
|
46
|
+
parts.push(`Agent: **${envelope.agent}** | Updated: ${envelope.updated ?? '-'}`);
|
|
47
|
+
parts.push('');
|
|
48
|
+
parts.push('## fullyApproved (act, don\'t ask)');
|
|
49
|
+
parts.push('');
|
|
50
|
+
parts.push(renderGroup(grouped.fullyApproved));
|
|
51
|
+
parts.push('');
|
|
52
|
+
parts.push('## checkBeforeCommitting (draft, sign-off before commit / push / publish)');
|
|
53
|
+
parts.push('');
|
|
54
|
+
parts.push(renderGroup(grouped.checkBeforeCommitting));
|
|
55
|
+
parts.push('');
|
|
56
|
+
parts.push('## needsFullSupervision (do not act; escalate every step)');
|
|
57
|
+
parts.push('');
|
|
58
|
+
parts.push(renderGroup(grouped.needsFullSupervision));
|
|
59
|
+
parts.push('');
|
|
60
|
+
parts.push('_The envelope is the durable record. If a task-type is not listed above it defaults to needsFullSupervision — escalate._');
|
|
61
|
+
return parts.join('\n') + '\n';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function renderGroup(taskTypes) {
|
|
65
|
+
if (!taskTypes.length) return '_(none)_';
|
|
66
|
+
return taskTypes
|
|
67
|
+
.map((t) => `- **${t.label}** (\`${t.id}\`)${t.operatorNote ? ` — ${t.operatorNote}` : ''}`)
|
|
68
|
+
.join('\n');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Build the full Claude Code SessionStart hook envelope shape for the
|
|
73
|
+
* given autonomy envelope. Convenience wrapper — operator hook tools that
|
|
74
|
+
* want to emit the block directly can call this instead of composing the
|
|
75
|
+
* envelope themselves.
|
|
76
|
+
*/
|
|
77
|
+
export function buildAutonomyHookEnvelope(envelope) {
|
|
78
|
+
return {
|
|
79
|
+
hookSpecificOutput: {
|
|
80
|
+
hookEventName: 'SessionStart',
|
|
81
|
+
additionalContext: buildAutonomyContext(envelope),
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// slice — CLI.
|
|
2
|
+
//
|
|
3
|
+
// Arg parsing (node:util.parseArgs, strict:true), verb routing,
|
|
4
|
+
// exit-code translation per §5–§6 of the tooling standard.
|
|
5
|
+
|
|
6
|
+
import { parseArgs } from 'node:util';
|
|
7
|
+
|
|
8
|
+
import { runSlice } from './run.mjs';
|
|
9
|
+
import { defaultRunner } from '../distill/runner.mjs';
|
|
10
|
+
|
|
11
|
+
const USAGE = `slice — operator profile slice generator
|
|
12
|
+
|
|
13
|
+
Usage:
|
|
14
|
+
slice generate <name> --profile <path> [options]
|
|
15
|
+
slice -h, --help Show this help
|
|
16
|
+
|
|
17
|
+
Verbs:
|
|
18
|
+
generate <name> Generate a named slice (e.g. "dave-boot"). The name
|
|
19
|
+
selects a bundled prompt template under
|
|
20
|
+
src/slice/prompts/<name>.md. To use a custom template
|
|
21
|
+
pass --template <path> instead of a name.
|
|
22
|
+
|
|
23
|
+
Options for "generate":
|
|
24
|
+
--profile <path> Path to the operator's profile.md (required).
|
|
25
|
+
--learned-rules <path> Path to learned-rules.md (optional).
|
|
26
|
+
--observations <dir> Directory of recent observation .md files (optional).
|
|
27
|
+
--output <path> Where to write the slice (required).
|
|
28
|
+
--template <path> Override the bundled template path.
|
|
29
|
+
--runs-log <path> Append one JSON audit line per invocation to this
|
|
30
|
+
file (camelCase fields: ts, status, exitCode,
|
|
31
|
+
durationSec, dryRun, outputBytes, reason).
|
|
32
|
+
Consumed by the tasks-status monitor — when
|
|
33
|
+
slice runs on a schedule, point this at a
|
|
34
|
+
per-task runs.jsonl. Optional.
|
|
35
|
+
--dry-run Build the prompt and report; skip claude call + write.
|
|
36
|
+
-h, --help Show this help.
|
|
37
|
+
|
|
38
|
+
Exit codes:
|
|
39
|
+
0 ok
|
|
40
|
+
1 usage error
|
|
41
|
+
2 prerequisite missing / operational failure (incl. validation failure)
|
|
42
|
+
3 claude transport failure
|
|
43
|
+
|
|
44
|
+
Source of truth for behaviour: @stravica-ai/engineering-pa-core/docs/tools/slice.md
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
export async function main(
|
|
48
|
+
argv,
|
|
49
|
+
{ stderr = process.stderr, stdout = process.stdout, exit = process.exit } = {},
|
|
50
|
+
) {
|
|
51
|
+
try {
|
|
52
|
+
return await route(argv, { stderr, stdout, exit });
|
|
53
|
+
} catch (err) {
|
|
54
|
+
const code = err?.sliceExitCode ?? 2;
|
|
55
|
+
stderr.write(`[slice] ${err.message || err}\n`);
|
|
56
|
+
exit(code);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function route(argv, { stderr, stdout, exit }) {
|
|
61
|
+
if (argv.length === 0 || argv[0] === '-h' || argv[0] === '--help') {
|
|
62
|
+
stdout.write(USAGE);
|
|
63
|
+
exit(0);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const verb = argv[0];
|
|
68
|
+
const rest = argv.slice(1);
|
|
69
|
+
|
|
70
|
+
if (verb === 'generate') {
|
|
71
|
+
// First token after the verb is treated as the slice name (e.g. "dave-boot")
|
|
72
|
+
// IF it doesn't start with `-`. Otherwise the name is omitted and must be
|
|
73
|
+
// supplied via --template. Subsequent positionals are an error (caught by
|
|
74
|
+
// parseArgs strict mode).
|
|
75
|
+
let name = null;
|
|
76
|
+
let args = rest;
|
|
77
|
+
if (rest.length > 0 && !rest[0].startsWith('-')) {
|
|
78
|
+
name = rest[0];
|
|
79
|
+
args = rest.slice(1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const { values } = parseArgs({
|
|
83
|
+
args,
|
|
84
|
+
options: {
|
|
85
|
+
profile: { type: 'string' },
|
|
86
|
+
'learned-rules': { type: 'string' },
|
|
87
|
+
observations: { type: 'string' },
|
|
88
|
+
output: { type: 'string' },
|
|
89
|
+
template: { type: 'string' },
|
|
90
|
+
'runs-log': { type: 'string' },
|
|
91
|
+
'dry-run': { type: 'boolean', default: false },
|
|
92
|
+
help: { type: 'boolean', short: 'h', default: false },
|
|
93
|
+
},
|
|
94
|
+
strict: true,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
if (values.help) {
|
|
98
|
+
stdout.write(USAGE);
|
|
99
|
+
exit(0);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const template = values.template ?? name;
|
|
104
|
+
if (!template) {
|
|
105
|
+
stderr.write('[slice] generate: missing slice name or --template\n');
|
|
106
|
+
stderr.write(USAGE);
|
|
107
|
+
exit(1);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (!values.profile) {
|
|
111
|
+
stderr.write('[slice] generate: --profile is required\n');
|
|
112
|
+
exit(1);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (!values.output) {
|
|
116
|
+
stderr.write('[slice] generate: --output is required\n');
|
|
117
|
+
exit(1);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const code = await runSlice({
|
|
122
|
+
profilePath: values.profile,
|
|
123
|
+
learnedRulesPath: values['learned-rules'],
|
|
124
|
+
observationsDir: values.observations,
|
|
125
|
+
template,
|
|
126
|
+
outputPath: values.output,
|
|
127
|
+
runsLog: values['runs-log'],
|
|
128
|
+
dryRun: values['dry-run'],
|
|
129
|
+
runner: defaultRunner,
|
|
130
|
+
stderr,
|
|
131
|
+
});
|
|
132
|
+
exit(code ?? 0);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
stderr.write(`[slice] unknown command: ${verb}\n`);
|
|
137
|
+
stderr.write(USAGE);
|
|
138
|
+
exit(1);
|
|
139
|
+
}
|