@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,199 @@
|
|
|
1
|
+
// checks.mjs — domain definitions for the smoke suite.
|
|
2
|
+
import { PA_PACKAGE_NAME } from '../../../engineering-pa-core/src/config/pa-package-name.mjs';
|
|
3
|
+
|
|
4
|
+
//
|
|
5
|
+
// v2: the smoke suite validates a v2 operator-instance layout. There are
|
|
6
|
+
// two distinct shapes the operator repo can be in, each with different
|
|
7
|
+
// expectations:
|
|
8
|
+
//
|
|
9
|
+
// • fresh-scaffold — the post-`pa-init --mode=solo` shape. Operator
|
|
10
|
+
// content is empty except for `.gitkeep` markers; node_modules is
|
|
11
|
+
// present from `pnpm install`. This mode is exercised when an
|
|
12
|
+
// operator first stands up the platform on a new host.
|
|
13
|
+
//
|
|
14
|
+
// • live-repo — a populated operator repo with real work items,
|
|
15
|
+
// projects, profile content, etc. The `.gitkeep` markers may have
|
|
16
|
+
// been removed once real files exist in each directory. This is
|
|
17
|
+
// the day-to-day operator-machine shape.
|
|
18
|
+
//
|
|
19
|
+
// Mode selection is plumbed in cli.mjs (`--mode=fresh-scaffold|live-repo`,
|
|
20
|
+
// default `live-repo`). Each mode builds its own check plan via
|
|
21
|
+
// `buildCheckPlan(mode)`.
|
|
22
|
+
//
|
|
23
|
+
// Check classes:
|
|
24
|
+
//
|
|
25
|
+
// path — path exists (file or dir)
|
|
26
|
+
// dirExists — directory exists (alias of path for clarity)
|
|
27
|
+
// dirNotEmpty — directory exists AND contains at least one entry
|
|
28
|
+
// pkgInstalled — node_modules/@stravica-ai/digital-operator-pa* present
|
|
29
|
+
// serverReady — workspace server started on port N
|
|
30
|
+
// httpStatus — GET url returns a specific status code
|
|
31
|
+
// jsonValid — GET url returns parseable JSON
|
|
32
|
+
// cliExit — running `<bin> --help` exits 0
|
|
33
|
+
// vaultExit — `secrets` exits 0 or 1 (no vault yet is fine)
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Fresh-scaffold paths verified on disk. These are the v2 operator-instance
|
|
37
|
+
* shape produced by `pa-init --mode=solo`, with `.gitkeep` markers in every
|
|
38
|
+
* directory before the operator has populated them. Paths are
|
|
39
|
+
* operator-tree-relative.
|
|
40
|
+
*/
|
|
41
|
+
export const EXPECTED_PATHS_FRESH_SCAFFOLD = [
|
|
42
|
+
// Operator content scaffold.
|
|
43
|
+
'operator/.gitkeep',
|
|
44
|
+
'operator/profile/.gitkeep',
|
|
45
|
+
'operator/knowledge/.gitkeep',
|
|
46
|
+
'operator/notes/.gitkeep',
|
|
47
|
+
'operator/extensions/.gitkeep',
|
|
48
|
+
// Work and projects.
|
|
49
|
+
'work/.gitkeep',
|
|
50
|
+
'projects/.gitkeep',
|
|
51
|
+
// Schedules (gitkept folder, individual schedules created on demand).
|
|
52
|
+
'schedules/.gitkeep',
|
|
53
|
+
// Root files an operator repo always carries.
|
|
54
|
+
'CLAUDE.md',
|
|
55
|
+
'package.json',
|
|
56
|
+
'.gitignore',
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Backwards-compat alias — pre-v0.1.3 callers and tests reference
|
|
61
|
+
* EXPECTED_PATHS. Keep the alias pointing at the fresh-scaffold list since
|
|
62
|
+
* that's the shape the existing tests exercise.
|
|
63
|
+
*/
|
|
64
|
+
export const EXPECTED_PATHS = EXPECTED_PATHS_FRESH_SCAFFOLD;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Live-repo paths verified on disk. Same operator scaffold but expressed as
|
|
68
|
+
* directories (not `.gitkeep` markers) — operator activity may have removed
|
|
69
|
+
* the markers once real files arrived. The root files are unchanged.
|
|
70
|
+
*/
|
|
71
|
+
export const EXPECTED_PATHS_LIVE_REPO_DIRS = [
|
|
72
|
+
'operator',
|
|
73
|
+
'operator/profile',
|
|
74
|
+
'operator/knowledge',
|
|
75
|
+
'operator/notes',
|
|
76
|
+
'operator/extensions',
|
|
77
|
+
'work',
|
|
78
|
+
'projects',
|
|
79
|
+
'schedules',
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
export const EXPECTED_PATHS_LIVE_REPO_FILES = [
|
|
83
|
+
'CLAUDE.md',
|
|
84
|
+
'package.json',
|
|
85
|
+
'.gitignore',
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Bundled package install paths verified on disk. These point inside
|
|
90
|
+
* node_modules — the package is read-only on the operator's machine.
|
|
91
|
+
*/
|
|
92
|
+
export const EXPECTED_PACKAGE_PATHS = [
|
|
93
|
+
`node_modules/${PA_PACKAGE_NAME}/package.json`,
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
/** HTML pages verified over HTTP. Labels mirror the operator UX. */
|
|
97
|
+
export const HTML_PAGES = [
|
|
98
|
+
{ label: '/ (shell)', path: '/' },
|
|
99
|
+
{ label: '/home.html', path: '/home.html' },
|
|
100
|
+
{ label: '/onboarding.html', path: '/onboarding.html' },
|
|
101
|
+
{ label: '/tasks.html', path: '/tasks.html' },
|
|
102
|
+
{ label: '/knowledge.html', path: '/knowledge.html' },
|
|
103
|
+
{ label: '/secrets.html', path: '/secrets.html' },
|
|
104
|
+
{ label: '/viewer.html', path: '/viewer.html' },
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
/** JSON API endpoints exercised by the smoke suite. */
|
|
108
|
+
export const API_ENDPOINTS = [
|
|
109
|
+
'/__api/overview',
|
|
110
|
+
'/__api/projects',
|
|
111
|
+
'/__api/work',
|
|
112
|
+
];
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* CLI --help invocations. In v2 these are installed bin shims; the smoke
|
|
116
|
+
* runner resolves them via `node_modules/.bin/<name>` rather than absolute
|
|
117
|
+
* repo paths.
|
|
118
|
+
*/
|
|
119
|
+
export const CLI_HELP_TOOLS = [
|
|
120
|
+
{ name: 'desk --help', binName: 'desk' },
|
|
121
|
+
{ name: 'distill --help', binName: 'distill' },
|
|
122
|
+
{ name: 'memory-sync --help', binName: 'memory-sync' },
|
|
123
|
+
{ name: 'sync --help', binName: 'sync' },
|
|
124
|
+
{ name: 'scheduler --help', binName: 'scheduler' },
|
|
125
|
+
{ name: 'pa --help', binName: 'pa' },
|
|
126
|
+
{ name: 'slice --help', binName: 'slice' },
|
|
127
|
+
];
|
|
128
|
+
|
|
129
|
+
/** Test port for the workspace server. */
|
|
130
|
+
export const TEST_PORT = 4201;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Build the complete check plan. Returns an array of check descriptors in
|
|
134
|
+
* a stable order:
|
|
135
|
+
*
|
|
136
|
+
* 1. Operator-content paths
|
|
137
|
+
* 2. Package install paths
|
|
138
|
+
* 3. Server boot
|
|
139
|
+
* 4. HTML pages (gated on server)
|
|
140
|
+
* 5. JSON endpoints (gated on server)
|
|
141
|
+
* 6. CLI --help (one per bin shim)
|
|
142
|
+
* 7. Secrets exit-code probe
|
|
143
|
+
*
|
|
144
|
+
* @param {object} [opts]
|
|
145
|
+
* @param {'fresh-scaffold'|'live-repo'} [opts.mode] — defaults to fresh-scaffold
|
|
146
|
+
* for backwards compatibility with v0.1.2-era callers and tests. The
|
|
147
|
+
* CLI defaults to 'live-repo' for operator-machine usage.
|
|
148
|
+
*/
|
|
149
|
+
export function buildCheckPlan(opts = {}) {
|
|
150
|
+
const mode = opts.mode ?? 'fresh-scaffold';
|
|
151
|
+
const plan = [];
|
|
152
|
+
|
|
153
|
+
if (mode === 'live-repo') {
|
|
154
|
+
// In live-repo mode, directories must exist (any contents OK) and root
|
|
155
|
+
// files must exist. We never assert on `.gitkeep` markers because real
|
|
156
|
+
// operator content may have evicted them.
|
|
157
|
+
for (const p of EXPECTED_PATHS_LIVE_REPO_DIRS) {
|
|
158
|
+
plan.push({ id: `path-${p}`, class: 'path', path: p, label: `directory exists: ${p}` });
|
|
159
|
+
}
|
|
160
|
+
for (const p of EXPECTED_PATHS_LIVE_REPO_FILES) {
|
|
161
|
+
plan.push({ id: `path-${p}`, class: 'path', path: p, label: `path exists: ${p}` });
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
// fresh-scaffold (default for backwards compat).
|
|
165
|
+
for (const p of EXPECTED_PATHS_FRESH_SCAFFOLD) {
|
|
166
|
+
plan.push({ id: `path-${p}`, class: 'path', path: p, label: `path exists: ${p}` });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
for (const p of EXPECTED_PACKAGE_PATHS) {
|
|
171
|
+
plan.push({ id: `pkg-${p}`, class: 'pkgInstalled', path: p, label: `package installed: ${p}` });
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
plan.push({ id: 'server-ready', class: 'serverReady', port: TEST_PORT, label: `workspace server started on port ${TEST_PORT}` });
|
|
175
|
+
|
|
176
|
+
for (const page of HTML_PAGES) {
|
|
177
|
+
plan.push({ id: `http-${page.path}`, class: 'httpStatus', path: page.path, expect: 200, label: `HTTP 200: ${page.label}`, requires: 'server' });
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
for (const ep of API_ENDPOINTS) {
|
|
181
|
+
plan.push({ id: `json-${ep}`, class: 'jsonValid', path: ep, label: `valid JSON: ${ep}`, requires: 'server' });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
for (const tool of CLI_HELP_TOOLS) {
|
|
185
|
+
plan.push({ id: `cli-${tool.binName}`, class: 'cliExit', binName: tool.binName, label: `CLI exits 0: ${tool.name}` });
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
plan.push({ id: 'vault', class: 'vaultExit', binName: 'secrets', label: 'secrets runs' });
|
|
189
|
+
|
|
190
|
+
return plan;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Render the full JSON-endpoint URL for a given port and path.
|
|
195
|
+
* Centralised here so checks and tests see the same construction.
|
|
196
|
+
*/
|
|
197
|
+
export function apiUrl(port, path) {
|
|
198
|
+
return `http://localhost:${port}${path}`;
|
|
199
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// cli.mjs — arg parsing, exit-code translation, usage.
|
|
2
|
+
//
|
|
3
|
+
// The smoke tool has a single default verb: run. It is invoked via
|
|
4
|
+
// `npm run test:smoke` which resolves to `node core/tools/smoke/bin/smoke`.
|
|
5
|
+
//
|
|
6
|
+
// Exit codes (see README §Exit codes):
|
|
7
|
+
// 0 all checks passed
|
|
8
|
+
// 1 one or more checks failed
|
|
9
|
+
// 2 internal error (uncaught exception)
|
|
10
|
+
// 3 IO / transport failure during setup (tempdir, copy, server spawn)
|
|
11
|
+
|
|
12
|
+
import { parseArgs } from 'node:util';
|
|
13
|
+
import { fileURLToPath } from 'node:url';
|
|
14
|
+
import { dirname, resolve } from 'node:path';
|
|
15
|
+
import { PA_PACKAGE_NAME } from '../../../engineering-pa-core/src/config/pa-package-name.mjs';
|
|
16
|
+
import { runSmoke } from './commands/run.mjs';
|
|
17
|
+
|
|
18
|
+
const USAGE = `
|
|
19
|
+
smoke — operator-instance smoke suite for the v2 platform
|
|
20
|
+
|
|
21
|
+
Usage:
|
|
22
|
+
smoke Run the live-repo suite against the auto-detected root
|
|
23
|
+
smoke --mode <mode> 'live-repo' (default) or 'fresh-scaffold'
|
|
24
|
+
smoke --root <path> Repo root (default: auto-detect)
|
|
25
|
+
smoke --port <n> HTTP port for the workspace server (default: 4201)
|
|
26
|
+
smoke -h, --help Show this help
|
|
27
|
+
|
|
28
|
+
Modes:
|
|
29
|
+
live-repo Probe a populated operator repo in-place — no tempdir copy.
|
|
30
|
+
Asserts that operator/ subdirs exist (any contents), required
|
|
31
|
+
root files are present, the installed ${PA_PACKAGE_NAME}
|
|
32
|
+
package is reachable, the workspace server starts, the API
|
|
33
|
+
responds, and every published bin shim returns exit 0 on --help.
|
|
34
|
+
|
|
35
|
+
fresh-scaffold Verify the layout produced by 'pa-init --mode=solo' on a
|
|
36
|
+
freshly-scaffolded operator repo. Asserts the .gitkeep
|
|
37
|
+
markers, root files, the installed package, and the same
|
|
38
|
+
HTTP/CLI surfaces. Copies the source tree into a tempdir
|
|
39
|
+
to keep the original untouched.
|
|
40
|
+
|
|
41
|
+
Exit codes:
|
|
42
|
+
0 all checks passed
|
|
43
|
+
1 one or more checks failed
|
|
44
|
+
2 internal error
|
|
45
|
+
3 IO / transport failure (tempdir, copy, server launch)
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
const VALID_MODES = new Set(['live-repo', 'fresh-scaffold']);
|
|
49
|
+
|
|
50
|
+
export async function run(argv) {
|
|
51
|
+
let parsed;
|
|
52
|
+
try {
|
|
53
|
+
parsed = parseArgs({
|
|
54
|
+
args: argv,
|
|
55
|
+
options: {
|
|
56
|
+
help: { type: 'boolean', short: 'h' },
|
|
57
|
+
root: { type: 'string' },
|
|
58
|
+
port: { type: 'string' },
|
|
59
|
+
mode: { type: 'string' },
|
|
60
|
+
},
|
|
61
|
+
strict: true,
|
|
62
|
+
allowPositionals: false,
|
|
63
|
+
});
|
|
64
|
+
} catch (err) {
|
|
65
|
+
console.error(`smoke: ${err.message}`);
|
|
66
|
+
console.error('Run `smoke --help` for usage.');
|
|
67
|
+
return 1;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (parsed.values.help) {
|
|
71
|
+
console.log(USAGE.trim());
|
|
72
|
+
return 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const mode = parsed.values.mode ?? 'live-repo';
|
|
76
|
+
if (!VALID_MODES.has(mode)) {
|
|
77
|
+
console.error(`smoke: invalid --mode value: ${mode}. Must be one of: ${[...VALID_MODES].join(', ')}`);
|
|
78
|
+
return 1;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const repoRoot = parsed.values.root
|
|
82
|
+
? resolve(parsed.values.root)
|
|
83
|
+
: autoDetectRepoRoot();
|
|
84
|
+
|
|
85
|
+
const port = parsed.values.port ? Number(parsed.values.port) : undefined;
|
|
86
|
+
if (port != null && (!Number.isInteger(port) || port <= 0 || port > 65535)) {
|
|
87
|
+
console.error(`smoke: invalid port: ${parsed.values.port}`);
|
|
88
|
+
return 1;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const result = await runSmoke(repoRoot, { port, mode });
|
|
93
|
+
return result.exitCode;
|
|
94
|
+
} catch (err) {
|
|
95
|
+
console.error(`smoke: ${err.message || err}`);
|
|
96
|
+
return 3;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Auto-detect the repo root. The binary lives at
|
|
102
|
+
* `<root>/core/tools/smoke/bin/smoke`, so the root is four levels up
|
|
103
|
+
* from this module.
|
|
104
|
+
*/
|
|
105
|
+
function autoDetectRepoRoot() {
|
|
106
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
107
|
+
return resolve(here, '..', '..', '..', '..');
|
|
108
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
// commands/run.mjs — orchestrate the full smoke suite.
|
|
2
|
+
//
|
|
3
|
+
// Flow (mirrors test/smoke.sh):
|
|
4
|
+
// 1. mktemp and copy the repo (excluding .git, node_modules)
|
|
5
|
+
// 2. cd (conceptually) into the temp dir
|
|
6
|
+
// 3. Run path checks
|
|
7
|
+
// 4. Launch the workspace server, wait for ready
|
|
8
|
+
// 5. Run HTTP / JSON checks (gated on ready)
|
|
9
|
+
// 6. Run CLI --help checks
|
|
10
|
+
// 7. Run secrets check
|
|
11
|
+
// 8. Run dave.sh --help check
|
|
12
|
+
// 9. Cleanup (kill server, remove temp dir)
|
|
13
|
+
// 10. Print PASS/FAIL lines and summary, return exit code
|
|
14
|
+
|
|
15
|
+
import { resolve as pathResolve } from 'node:path';
|
|
16
|
+
import { existsSync } from 'node:fs';
|
|
17
|
+
import {
|
|
18
|
+
spawnProcess,
|
|
19
|
+
launchProcess,
|
|
20
|
+
killProcess,
|
|
21
|
+
makeTempDir,
|
|
22
|
+
removeDir,
|
|
23
|
+
copyTree,
|
|
24
|
+
pathExists,
|
|
25
|
+
pathExecutable,
|
|
26
|
+
waitForHttp,
|
|
27
|
+
httpGet,
|
|
28
|
+
} from '../runner.mjs';
|
|
29
|
+
import { PA_PACKAGE_NAME } from '../../../../engineering-pa-core/src/config/pa-package-name.mjs';
|
|
30
|
+
import { buildCheckPlan, apiUrl, TEST_PORT } from '../checks.mjs';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Run the full smoke suite against `repoRoot`.
|
|
34
|
+
* Returns { pass, fail, results, exitCode }.
|
|
35
|
+
*
|
|
36
|
+
* `opts.runner` (optional) injects a fake for unit tests.
|
|
37
|
+
* `opts.mode` ('live-repo' | 'fresh-scaffold') — default 'fresh-scaffold'
|
|
38
|
+
* to preserve the pre-v0.1.3 calling convention (the CLI overrides to
|
|
39
|
+
* 'live-repo'). Live-repo mode runs against the source root in-place
|
|
40
|
+
* (no tempdir copy) because copying excludes node_modules and breaks
|
|
41
|
+
* every CLI/cliExit probe against the destination.
|
|
42
|
+
*/
|
|
43
|
+
export async function runSmoke(repoRoot, opts = {}) {
|
|
44
|
+
const log = opts.log ?? ((line) => console.log(line));
|
|
45
|
+
const io = opts.runner ?? defaultRunner();
|
|
46
|
+
const port = opts.port ?? TEST_PORT;
|
|
47
|
+
const mode = opts.mode ?? 'fresh-scaffold';
|
|
48
|
+
|
|
49
|
+
const absRoot = pathResolve(repoRoot);
|
|
50
|
+
// Live-repo runs in-place; fresh-scaffold copies into a tempdir.
|
|
51
|
+
const useTempDir = mode !== 'live-repo';
|
|
52
|
+
const tempDir = useTempDir ? await io.makeTempDir() : null;
|
|
53
|
+
const workRoot = useTempDir ? tempDir : absRoot;
|
|
54
|
+
let serverChild = null;
|
|
55
|
+
const results = [];
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
if (useTempDir) {
|
|
59
|
+
await io.copyTree(absRoot, tempDir);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const plan = buildCheckPlan({ mode });
|
|
63
|
+
let serverReady = false;
|
|
64
|
+
|
|
65
|
+
for (const check of plan) {
|
|
66
|
+
// Lazy-launch the server the first time we hit a server-ready check.
|
|
67
|
+
if (check.class === 'serverReady') {
|
|
68
|
+
serverChild = io.launchWorkspace(workRoot, port);
|
|
69
|
+
const url = apiUrl(port, '/');
|
|
70
|
+
serverReady = await io.waitForHttp(url);
|
|
71
|
+
results.push(record(check, serverReady));
|
|
72
|
+
log(line(check, serverReady));
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// HTTP / JSON checks are skipped if the server never came up.
|
|
77
|
+
if (check.requires === 'server' && !serverReady) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const ok = await runCheck(check, workRoot, port, io);
|
|
82
|
+
results.push(record(check, ok));
|
|
83
|
+
log(line(check, ok));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const pass = results.filter((r) => r.ok).length;
|
|
87
|
+
const fail = results.filter((r) => !r.ok).length;
|
|
88
|
+
const total = pass + fail;
|
|
89
|
+
|
|
90
|
+
log('');
|
|
91
|
+
log('========================================');
|
|
92
|
+
log(`${pass}/${total} passed`);
|
|
93
|
+
if (fail > 0) {
|
|
94
|
+
log(`${fail} test(s) failed`);
|
|
95
|
+
return { pass, fail, results, exitCode: 1 };
|
|
96
|
+
}
|
|
97
|
+
log('All tests passed');
|
|
98
|
+
return { pass, fail, results, exitCode: 0 };
|
|
99
|
+
} finally {
|
|
100
|
+
if (serverChild) await io.killProcess(serverChild);
|
|
101
|
+
if (useTempDir) await io.removeDir(tempDir);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Execute a single check. Returns a boolean pass/fail.
|
|
107
|
+
*/
|
|
108
|
+
async function runCheck(check, root, port, io) {
|
|
109
|
+
switch (check.class) {
|
|
110
|
+
case 'execFile':
|
|
111
|
+
return io.pathExecutable(pathJoin(root, check.path));
|
|
112
|
+
|
|
113
|
+
case 'file':
|
|
114
|
+
case 'path':
|
|
115
|
+
return io.pathExists(pathJoin(root, check.path));
|
|
116
|
+
|
|
117
|
+
case 'httpStatus': {
|
|
118
|
+
const res = await io.httpGet(apiUrl(port, check.path));
|
|
119
|
+
return res.status === check.expect;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
case 'jsonValid': {
|
|
123
|
+
const res = await io.httpGet(apiUrl(port, check.path));
|
|
124
|
+
try { JSON.parse(res.body); return true; } catch { return false; }
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
case 'cliExit': {
|
|
128
|
+
// v2: invoke via the installed bin shim. Under pnpm's hoisted layout
|
|
129
|
+
// there is no `node_modules/.bin/<name>` symlink adjacent to the
|
|
130
|
+
// operator-repo root (the .bin lives off the @stravica-ai/digital-operator-pa
|
|
131
|
+
// package's own node_modules, not the operator repo's). Resolve to the
|
|
132
|
+
// package's `bin/<name>` shim instead — that is the canonical entry
|
|
133
|
+
// point for published commands.
|
|
134
|
+
const bin = await resolveBin(root, check.binName, io);
|
|
135
|
+
if (!bin) return false;
|
|
136
|
+
const res = await io.spawnProcess(bin, ['--help'], { cwd: root, timeoutMs: 15000 });
|
|
137
|
+
return res.code === 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
case 'vaultExit': {
|
|
141
|
+
const bin = await resolveBin(root, check.binName ?? 'secrets', io);
|
|
142
|
+
if (!bin) return false;
|
|
143
|
+
const res = await io.spawnProcess(bin, [], { cwd: root, timeoutMs: 15000 });
|
|
144
|
+
return res.code === 0 || res.code === 1;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
case 'pkgInstalled':
|
|
148
|
+
return io.pathExists(pathJoin(root, check.path));
|
|
149
|
+
|
|
150
|
+
case 'cliShell': {
|
|
151
|
+
// v1-compat — no v2 check uses this class but the runner remains
|
|
152
|
+
// backwards-compatible for operator-extension smoke suites that
|
|
153
|
+
// drop in their own check sets.
|
|
154
|
+
const res = await io.spawnProcess('bash', [check.path, '--help'], { cwd: root, timeoutMs: 15000 });
|
|
155
|
+
return res.code === 0;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
default:
|
|
159
|
+
throw new Error(`smoke: unknown check class: ${check.class}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function record(check, ok) {
|
|
164
|
+
return { id: check.id, class: check.class, label: check.label, ok };
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function line(check, ok) {
|
|
168
|
+
return `${ok ? 'PASS' : 'FAIL'}: ${check.label}`;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function pathJoin(root, p) {
|
|
172
|
+
return `${root}/${p}`;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Resolve a published bin shim for a given command. We try, in order:
|
|
177
|
+
*
|
|
178
|
+
* 1. node_modules/@stravica-ai/digital-operator-pa/bin/<name> — canonical v2 path
|
|
179
|
+
* 2. node_modules/.bin/<name> — pnpm-symlinked
|
|
180
|
+
*
|
|
181
|
+
* Returns the first absolute path that exists, or null if neither does.
|
|
182
|
+
* The lookup uses the injected runner so tests can fake it without
|
|
183
|
+
* touching disk.
|
|
184
|
+
*/
|
|
185
|
+
async function resolveBin(root, name, io) {
|
|
186
|
+
const candidates = [
|
|
187
|
+
pathJoin(root, `node_modules/${PA_PACKAGE_NAME}/bin/${name}`),
|
|
188
|
+
pathJoin(root, `node_modules/.bin/${name}`),
|
|
189
|
+
];
|
|
190
|
+
for (const candidate of candidates) {
|
|
191
|
+
// eslint-disable-next-line no-await-in-loop
|
|
192
|
+
if (await io.pathExists(candidate)) return candidate;
|
|
193
|
+
}
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Default runner — the production chokepoint bindings. Tests pass their
|
|
199
|
+
* own object matching this shape to avoid touching the filesystem / network.
|
|
200
|
+
*/
|
|
201
|
+
function defaultRunner() {
|
|
202
|
+
return {
|
|
203
|
+
makeTempDir,
|
|
204
|
+
removeDir,
|
|
205
|
+
copyTree,
|
|
206
|
+
pathExists,
|
|
207
|
+
pathExecutable,
|
|
208
|
+
waitForHttp,
|
|
209
|
+
httpGet,
|
|
210
|
+
spawnProcess,
|
|
211
|
+
killProcess,
|
|
212
|
+
launchWorkspace(cwd, port) {
|
|
213
|
+
// The workspace server lives in different places depending on
|
|
214
|
+
// install layout. In the published @stravica-ai/digital-operator-pa bundle
|
|
215
|
+
// it lives under `node_modules/@stravica-ai/digital-operator-pa/dist/
|
|
216
|
+
// engineering-pa-workspace/src/server.mjs`. In the dev monorepo
|
|
217
|
+
// (or any layout where workspace is installed as a separate
|
|
218
|
+
// package), it's at `node_modules/@stravica-ai/engineering-pa-workspace/
|
|
219
|
+
// src/server.mjs`. Try the bundled path first because that's the
|
|
220
|
+
// canonical operator-machine layout.
|
|
221
|
+
//
|
|
222
|
+
// Operators don't run server.mjs directly — the `pa workspace start`
|
|
223
|
+
// bin shim handles supervision in production — but the smoke suite
|
|
224
|
+
// bypasses that to keep the child PID easy to reap.
|
|
225
|
+
const candidates = [
|
|
226
|
+
`node_modules/${PA_PACKAGE_NAME}/dist/engineering-pa-workspace/src/server.mjs`,
|
|
227
|
+
'node_modules/@stravica-ai/engineering-pa-workspace/src/server.mjs',
|
|
228
|
+
];
|
|
229
|
+
const serverScript = candidates.find((rel) => existsSync(`${cwd}/${rel}`)) ?? candidates[0];
|
|
230
|
+
return launchProcess(
|
|
231
|
+
'node',
|
|
232
|
+
[serverScript, '--port', String(port), '--no-open', '--no-timeout'],
|
|
233
|
+
{ cwd, stdio: ['ignore', 'ignore', 'pipe'] },
|
|
234
|
+
);
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
}
|