@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,369 @@
|
|
|
1
|
+
// pa — operator-facing top-level CLI.
|
|
2
|
+
//
|
|
3
|
+
// Status: minimal v0.1.0 surface. The verbs landing here are the ones the
|
|
4
|
+
// scaffolder (`pa-init`) and the operator runbook rely on. Each verb routes
|
|
5
|
+
// to a specialist CLI or library.
|
|
6
|
+
|
|
7
|
+
import { spawn } from 'node:child_process';
|
|
8
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
9
|
+
import { dirname, join, resolve } from 'node:path';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
11
|
+
import { run as runDesk } from '../../../engineering-pa-core/src/desk/cli.mjs';
|
|
12
|
+
import { PA_PACKAGE_NAME } from '../../../engineering-pa-core/src/config/pa-package-name.mjs';
|
|
13
|
+
import { main as runMigrateInspect } from '../../../engineering-pa-migrate-inspect/src/cli.mjs';
|
|
14
|
+
|
|
15
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
|
|
17
|
+
const USAGE = `pa — operator personal-assistant CLI
|
|
18
|
+
|
|
19
|
+
Usage:
|
|
20
|
+
pa session Start a PA session — chdir to agent dir, exec \`claude\`
|
|
21
|
+
pa status Probe operator content, installed package, and workspace reachability, then print a desk overview
|
|
22
|
+
pa workspace <verb> Workspace server lifecycle (start | stop | status | open)
|
|
23
|
+
pa project <verb> Project state writes (create | status | doc add/rm | list)
|
|
24
|
+
pa work <verb> Work-item state writes (create | status | list)
|
|
25
|
+
pa gsc <verb> Google Search Console automation (add-property | verify-via-cf-dns | submit-sitemap | pull-analytics | list-properties)
|
|
26
|
+
pa knowledge <verb> Query the operator's knowledge graph (related | search | domain | orphans | path)
|
|
27
|
+
pa research <verb> Deep-research session store (run | list | show | gates | prune | mark | paths)
|
|
28
|
+
pa autonomy <verb> Per-agent per-task-type approval state (init | get | set | list)
|
|
29
|
+
pa environment [verb] Session-boot environment cache (default | refresh | extended)
|
|
30
|
+
pa staging-alias <verb> Canonical staging.<site> alias for CF Workers sites (set | unset | status | list)
|
|
31
|
+
pa lint <verb> Lint operator text against voice rules (linkedin)
|
|
32
|
+
pa migrate-inspect [options] Host inspection for migration planning
|
|
33
|
+
pa launch --agent=<n> --task=<id> [--dry-run]
|
|
34
|
+
Boot a scoped agent instance bound to an identity and task
|
|
35
|
+
pa -h, --help Show this help
|
|
36
|
+
|
|
37
|
+
Routed sub-CLIs (also available as standalone bins):
|
|
38
|
+
desk Task and project queries (read-side complement of \`pa project\` / \`pa work\`)
|
|
39
|
+
secrets Vault management
|
|
40
|
+
sync Per-host single-writer git sync
|
|
41
|
+
scheduler Scheduling primitives
|
|
42
|
+
memory-sync PA-memory cache mirror
|
|
43
|
+
distill Librarian distillation sweep
|
|
44
|
+
|
|
45
|
+
Exit codes (tooling standard §6):
|
|
46
|
+
0 ok | 1 usage error | 2 operational failure | 3 transport/IO failure
|
|
47
|
+
`;
|
|
48
|
+
|
|
49
|
+
export async function main(argv) {
|
|
50
|
+
if (argv.length === 0 || argv[0] === '-h' || argv[0] === '--help') {
|
|
51
|
+
process.stdout.write(USAGE);
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const verb = argv[0];
|
|
56
|
+
const rest = argv.slice(1);
|
|
57
|
+
|
|
58
|
+
switch (verb) {
|
|
59
|
+
case 'session':
|
|
60
|
+
return await doSession(rest);
|
|
61
|
+
case 'status':
|
|
62
|
+
return await doStatus();
|
|
63
|
+
case 'workspace':
|
|
64
|
+
return await doWorkspace(rest);
|
|
65
|
+
case 'project':
|
|
66
|
+
return await doProject(rest);
|
|
67
|
+
case 'work':
|
|
68
|
+
return await doWork(rest);
|
|
69
|
+
case 'gsc':
|
|
70
|
+
return await doGsc(rest);
|
|
71
|
+
case 'knowledge':
|
|
72
|
+
return await doKnowledge(rest);
|
|
73
|
+
case 'research':
|
|
74
|
+
return await doResearch(rest);
|
|
75
|
+
case 'autonomy':
|
|
76
|
+
return await doAutonomy(rest);
|
|
77
|
+
case 'environment':
|
|
78
|
+
return await doEnvironment(rest);
|
|
79
|
+
case 'lint':
|
|
80
|
+
return await doLint(rest);
|
|
81
|
+
case 'staging-alias':
|
|
82
|
+
return await doStagingAlias(rest);
|
|
83
|
+
case 'migrate-inspect':
|
|
84
|
+
return await runMigrateInspect(rest);
|
|
85
|
+
case 'launch':
|
|
86
|
+
return await doLaunch(rest);
|
|
87
|
+
default:
|
|
88
|
+
process.stderr.write(`[pa] unknown verb: ${verb}\n`);
|
|
89
|
+
process.stderr.write(USAGE);
|
|
90
|
+
return 1;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function doStatus(opts = {}) {
|
|
95
|
+
// Three structured probes followed by a desk overview snapshot.
|
|
96
|
+
//
|
|
97
|
+
// 1. Operator content present — does the cwd look like an operator repo?
|
|
98
|
+
// Reports each well-known path as "present" or "missing".
|
|
99
|
+
// 2. Package install integrity — is `@stravica-ai/digital-operator-pa` installed
|
|
100
|
+
// under node_modules/? If so, report its version.
|
|
101
|
+
// 3. Workspace reachability — try GET /__api/identity on the configured
|
|
102
|
+
// workspace port (default 4200). Reports "reachable", "not running",
|
|
103
|
+
// or "error: …". Workspace-not-running is informational, not failure.
|
|
104
|
+
//
|
|
105
|
+
// After the probes, run `desk overview` in-process and emit its output as
|
|
106
|
+
// the final section. Exit 0 if all structural prerequisites are present
|
|
107
|
+
// (operator/, installed package), 2 if any are missing.
|
|
108
|
+
//
|
|
109
|
+
// Why `desk` runs in-process rather than spawning `node_modules/.bin/desk`:
|
|
110
|
+
// under pnpm's hoisted install layout, no `node_modules/.bin/desk` is
|
|
111
|
+
// adjacent to this package; the bin shim lives off the operator-repo root.
|
|
112
|
+
// Subpath import via `@stravica-ai/engineering-pa-core/src/desk/cli.mjs` is
|
|
113
|
+
// permitted by the widened `exports` map in the core package.
|
|
114
|
+
const out = opts.stdout ?? process.stdout;
|
|
115
|
+
const err = opts.stderr ?? process.stderr;
|
|
116
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
117
|
+
const repoRoot = opts.repoRoot
|
|
118
|
+
?? process.env.DAVE_REPO_ROOT
|
|
119
|
+
?? process.env.PA_REPO_ROOT
|
|
120
|
+
?? cwd;
|
|
121
|
+
const workspacePort = resolveWorkspacePort(repoRoot, opts);
|
|
122
|
+
|
|
123
|
+
let allOk = true;
|
|
124
|
+
|
|
125
|
+
// 1. Operator content probes.
|
|
126
|
+
out.write('Operator content:\n');
|
|
127
|
+
const operatorPaths = [
|
|
128
|
+
'operator/',
|
|
129
|
+
'operator/profile/profile.md',
|
|
130
|
+
'agents/',
|
|
131
|
+
'work/',
|
|
132
|
+
'projects/',
|
|
133
|
+
];
|
|
134
|
+
const operatorMissing = [];
|
|
135
|
+
for (const rel of operatorPaths) {
|
|
136
|
+
const present = existsSync(join(repoRoot, rel));
|
|
137
|
+
out.write(` ${rel.padEnd(36)} ${present ? 'present' : 'missing'}\n`);
|
|
138
|
+
if (!present) operatorMissing.push(rel);
|
|
139
|
+
}
|
|
140
|
+
// Treat absence of `operator/` itself as a structural failure — the other
|
|
141
|
+
// paths are recommended but not all are required on every operator repo
|
|
142
|
+
// (e.g. a brand-new scaffold may not yet have a profile.md).
|
|
143
|
+
if (operatorMissing.includes('operator/')) allOk = false;
|
|
144
|
+
|
|
145
|
+
// 2. Package install probe. Informational: a missing
|
|
146
|
+
// node_modules/@stravica-ai/digital-operator-pa is reported in the output so the
|
|
147
|
+
// operator can see it, but does not flip the exit code. Rationale: this
|
|
148
|
+
// verb is exercised against scenarios (CI fixtures, pre-install operator
|
|
149
|
+
// repos, pa-init dry-runs) where the package is intentionally absent.
|
|
150
|
+
// The pa-cli is sometimes invoked directly from the dev monorepo against
|
|
151
|
+
// an operator-shape repo before `pnpm install` has populated
|
|
152
|
+
// node_modules; treating that as a structural failure would block
|
|
153
|
+
// legitimate diagnostic use. Operator content remains the load-bearing
|
|
154
|
+
// exit-code probe (#1 above).
|
|
155
|
+
out.write('\nInstalled package:\n');
|
|
156
|
+
const pkgJson = join(repoRoot, 'node_modules', PA_PACKAGE_NAME, 'package.json');
|
|
157
|
+
if (existsSync(pkgJson)) {
|
|
158
|
+
try {
|
|
159
|
+
const meta = JSON.parse(readFileSync(pkgJson, 'utf8'));
|
|
160
|
+
out.write(` ${PA_PACKAGE_NAME} ${meta.version ?? '(no version)'}\n`);
|
|
161
|
+
} catch (e) {
|
|
162
|
+
out.write(` ${PA_PACKAGE_NAME} error reading package.json: ${e.message}\n`);
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
out.write(` ${PA_PACKAGE_NAME} missing (informational)\n`);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// 3. Workspace reachability probe.
|
|
169
|
+
out.write('\nWorkspace:\n');
|
|
170
|
+
const probeUrl = `http://localhost:${workspacePort}/__api/identity`;
|
|
171
|
+
const reachability = await probeWorkspace(probeUrl, opts.fetchImpl);
|
|
172
|
+
out.write(` ${probeUrl}\n`);
|
|
173
|
+
out.write(` status: ${reachability.status}`);
|
|
174
|
+
if (reachability.detail) out.write(` (${reachability.detail})`);
|
|
175
|
+
out.write('\n');
|
|
176
|
+
// Workspace-not-running is OK — operators may run pa status before
|
|
177
|
+
// starting the workspace server.
|
|
178
|
+
|
|
179
|
+
// 4. Desk overview snapshot.
|
|
180
|
+
out.write('\nOverview:\n');
|
|
181
|
+
try {
|
|
182
|
+
const code = await runDesk(['overview']);
|
|
183
|
+
if (typeof code === 'number' && code !== 0) {
|
|
184
|
+
// Desk reported a non-zero — propagate as operational failure.
|
|
185
|
+
return 2;
|
|
186
|
+
}
|
|
187
|
+
} catch (e) {
|
|
188
|
+
err.write(`[pa status] ${e?.message || e}\n`);
|
|
189
|
+
return 2;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return allOk ? 0 : 2;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function resolveWorkspacePort(repoRoot, opts = {}) {
|
|
196
|
+
if (opts.workspacePort) return opts.workspacePort;
|
|
197
|
+
try {
|
|
198
|
+
const prefsPath = join(repoRoot, 'operator', 'config', 'preferences.json');
|
|
199
|
+
if (existsSync(prefsPath)) {
|
|
200
|
+
const prefs = JSON.parse(readFileSync(prefsPath, 'utf8'));
|
|
201
|
+
if (typeof prefs.workspacePort === 'number') return prefs.workspacePort;
|
|
202
|
+
}
|
|
203
|
+
} catch { /* fall through to default */ }
|
|
204
|
+
return 4200;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async function probeWorkspace(url, fetchImpl) {
|
|
208
|
+
const fetchFn = fetchImpl ?? globalThis.fetch;
|
|
209
|
+
if (typeof fetchFn !== 'function') {
|
|
210
|
+
return { status: 'error', detail: 'fetch unavailable' };
|
|
211
|
+
}
|
|
212
|
+
const controller = new AbortController();
|
|
213
|
+
const timer = setTimeout(() => controller.abort(), 1500);
|
|
214
|
+
try {
|
|
215
|
+
const res = await fetchFn(url, { signal: controller.signal });
|
|
216
|
+
if (res.status >= 200 && res.status < 500) {
|
|
217
|
+
return { status: 'reachable', detail: `HTTP ${res.status}` };
|
|
218
|
+
}
|
|
219
|
+
return { status: 'error', detail: `HTTP ${res.status}` };
|
|
220
|
+
} catch (e) {
|
|
221
|
+
// ECONNREFUSED / abort / DNS — server is not running.
|
|
222
|
+
const code = e && (e.cause?.code || e.code);
|
|
223
|
+
if (code === 'ECONNREFUSED' || code === 'ENOTFOUND' || e?.name === 'AbortError') {
|
|
224
|
+
return { status: 'not running', detail: null };
|
|
225
|
+
}
|
|
226
|
+
return { status: 'error', detail: e?.message || String(e) };
|
|
227
|
+
} finally {
|
|
228
|
+
clearTimeout(timer);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export { doStatus, probeWorkspace, resolveWorkspacePort };
|
|
233
|
+
|
|
234
|
+
async function doLaunch(rest) {
|
|
235
|
+
const { run } = await import('../launch/cli.mjs');
|
|
236
|
+
return await run(rest);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async function doProject(rest) {
|
|
240
|
+
const { run } = await import('./project-cli.mjs');
|
|
241
|
+
return await run(rest);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async function doWork(rest) {
|
|
245
|
+
const { run } = await import('./work-cli.mjs');
|
|
246
|
+
return await run(rest);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async function doGsc(rest) {
|
|
250
|
+
const { run } = await import('../gsc/cli.mjs');
|
|
251
|
+
return await run(rest);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
async function doLint(rest) {
|
|
255
|
+
const { main } = await import('../lint/cli.mjs');
|
|
256
|
+
return await main(rest);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
async function doKnowledge(rest) {
|
|
260
|
+
const { run } = await import('../knowledge/cli.mjs');
|
|
261
|
+
return await run(rest);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
async function doResearch(rest) {
|
|
265
|
+
const { main } = await import('../research/cli.mjs');
|
|
266
|
+
return await main(rest);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
async function doAutonomy(rest) {
|
|
270
|
+
const { run } = await import('../autonomy/cli.mjs');
|
|
271
|
+
return await run(rest);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
async function doEnvironment(rest) {
|
|
275
|
+
const { run } = await import('../environment/cli.mjs');
|
|
276
|
+
return await run(rest);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
async function doStagingAlias(rest) {
|
|
280
|
+
const { main } = await import('../staging-alias/cli.mjs');
|
|
281
|
+
return await main(rest);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
async function doSession(rest) {
|
|
285
|
+
// `pa session` takes no arguments today. Reject anything to make typos
|
|
286
|
+
// (`pa session help`, `pa session start`) surface fast rather than
|
|
287
|
+
// silently boot a Claude session.
|
|
288
|
+
if (rest.length > 0) {
|
|
289
|
+
if (rest[0] === '-h' || rest[0] === '--help') {
|
|
290
|
+
process.stdout.write(SESSION_USAGE);
|
|
291
|
+
return 0;
|
|
292
|
+
}
|
|
293
|
+
process.stderr.write(`[pa session] unexpected arguments: ${rest.join(' ')}\n`);
|
|
294
|
+
process.stderr.write(SESSION_USAGE);
|
|
295
|
+
return 1;
|
|
296
|
+
}
|
|
297
|
+
const { executeSession } = await import('./session.mjs');
|
|
298
|
+
return await executeSession();
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const SESSION_USAGE = `pa session — start a PA session
|
|
302
|
+
|
|
303
|
+
Usage:
|
|
304
|
+
pa session Chdir to the agent dir for the configured PA and exec \`claude\`
|
|
305
|
+
pa session -h, --help Show this help
|
|
306
|
+
|
|
307
|
+
Resolution order for the operator repo root:
|
|
308
|
+
1. \$DAVE_REPO_ROOT (if set)
|
|
309
|
+
2. \$PA_REPO_ROOT (if set)
|
|
310
|
+
3. Walk upward from CWD looking for a \`.git\` directory
|
|
311
|
+
4. Fall back to CWD (with a warning)
|
|
312
|
+
|
|
313
|
+
Reads \`operator/config/preferences.json\`; the \`paName\` field selects
|
|
314
|
+
which \`agents/<paName>/\` directory the session runs in.
|
|
315
|
+
|
|
316
|
+
Exit codes (tooling standard §6):
|
|
317
|
+
0 ok | 1 usage/config error | 2 operational failure
|
|
318
|
+
`;
|
|
319
|
+
|
|
320
|
+
const WORKSPACE_USAGE = `pa workspace — workspace server lifecycle
|
|
321
|
+
|
|
322
|
+
Usage:
|
|
323
|
+
pa workspace start [--port N] [--no-open] Start the workspace server
|
|
324
|
+
pa workspace stop Stop the running server (refuses if supervised)
|
|
325
|
+
pa workspace restart [--port N] [--no-open] Restart (supervisor-aware: launchctl kickstart / systemctl restart)
|
|
326
|
+
pa workspace status Show server status (supervisor-aware)
|
|
327
|
+
pa workspace open Open the workspace URL in a browser
|
|
328
|
+
pa workspace -h, --help Show this help
|
|
329
|
+
|
|
330
|
+
When the workspace is supervised by launchd (~/Library/LaunchAgents/com.dave.workspace.plist)
|
|
331
|
+
or systemd (~/.config/systemd/user/dave-workspace.service), \`stop\` is refused and \`restart\`
|
|
332
|
+
delegates to the supervisor — this is the in-place version-pickup path after \`pnpm update\`.
|
|
333
|
+
|
|
334
|
+
Exit codes (tooling standard §6):
|
|
335
|
+
0 ok | 1 usage error | 2 operational failure | 3 transport/IO failure
|
|
336
|
+
`;
|
|
337
|
+
|
|
338
|
+
async function doWorkspace(rest) {
|
|
339
|
+
// Intercept --help / -h before routing — keeps the verb consistent with
|
|
340
|
+
// every other `pa` verb and avoids surfacing "Unknown command: --help"
|
|
341
|
+
// from the underlying ws.mjs.
|
|
342
|
+
if (rest.length > 0 && (rest[0] === '--help' || rest[0] === '-h' || rest[0] === 'help')) {
|
|
343
|
+
process.stdout.write(WORKSPACE_USAGE);
|
|
344
|
+
return 0;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Defer to @stravica-ai/engineering-pa-workspace/src/ws.mjs by argv proxy.
|
|
348
|
+
// ws.mjs handles start/stop/status/open/restart.
|
|
349
|
+
try {
|
|
350
|
+
const wsPath = await import('../../../engineering-pa-workspace/src/ws.mjs');
|
|
351
|
+
// ws.mjs is currently a CLI script with its own main() — execute via
|
|
352
|
+
// argv when imported. The runtime emits an exit code that we propagate.
|
|
353
|
+
// Implementation detail: when imported (not executed) ws.mjs exposes a
|
|
354
|
+
// run() function in v2; here we just invoke its top-level for the
|
|
355
|
+
// common verbs.
|
|
356
|
+
if (typeof wsPath.run === 'function') {
|
|
357
|
+
return await wsPath.run(rest);
|
|
358
|
+
}
|
|
359
|
+
// Fallback: spawn ws.mjs as a child process.
|
|
360
|
+
const child = spawn(process.execPath, [
|
|
361
|
+
resolve(__dirname, '..', '..', '..', 'engineering-pa-workspace', 'src', 'ws.mjs'),
|
|
362
|
+
...rest,
|
|
363
|
+
], { stdio: 'inherit' });
|
|
364
|
+
return await new Promise((res) => child.on('close', (code) => res(code ?? 0)));
|
|
365
|
+
} catch (err) {
|
|
366
|
+
process.stderr.write(`[pa workspace] ${err.message || err}\n`);
|
|
367
|
+
return 2;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// doc-groups.mjs — schema migration + write helpers for project.json:docs.
|
|
2
|
+
//
|
|
3
|
+
// `docs` historically was a flat array of {label, path}. The new shape is
|
|
4
|
+
// an object keyed by group name; each value is an array of {label, path}.
|
|
5
|
+
//
|
|
6
|
+
// Legacy: "docs": [ { "label": "README", "path": "..." } ]
|
|
7
|
+
// New: "docs": { "Documents": [ { "label": "README", "path": "..." } ] }
|
|
8
|
+
//
|
|
9
|
+
// Backwards-compat is strict: a flat array means a single "Documents"
|
|
10
|
+
// group. The first write through `addDoc` migrates the project to the
|
|
11
|
+
// grouped shape; reads via `readGroups` work for both shapes.
|
|
12
|
+
//
|
|
13
|
+
// Group order is preserved as insertion order — JavaScript Map / plain
|
|
14
|
+
// object semantics are sufficient. "Documents" stays first when it exists.
|
|
15
|
+
//
|
|
16
|
+
// Doc entries may carry an optional `status` field:
|
|
17
|
+
// "draft" | "review" | "approved" | undefined
|
|
18
|
+
// The field is preserved through normalisation and addDoc; setDocStatus
|
|
19
|
+
// provides a dedicated write path.
|
|
20
|
+
|
|
21
|
+
export const DEFAULT_GROUP = 'Documents';
|
|
22
|
+
|
|
23
|
+
export const VALID_DOC_STATUSES = new Set(['draft', 'review', 'approved']);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Normalise a project's `docs` field into the new {group: entry[]} shape.
|
|
27
|
+
*
|
|
28
|
+
* - undefined / null → {}
|
|
29
|
+
* - flat array → { [DEFAULT_GROUP]: array }
|
|
30
|
+
* - object → returned as-is (defensive copy, arrays cloned)
|
|
31
|
+
*
|
|
32
|
+
* Defensive copy so callers can mutate without leaking back to the input.
|
|
33
|
+
*/
|
|
34
|
+
export function normaliseDocs(docs) {
|
|
35
|
+
if (docs == null) return {};
|
|
36
|
+
if (Array.isArray(docs)) {
|
|
37
|
+
if (docs.length === 0) return {};
|
|
38
|
+
return { [DEFAULT_GROUP]: docs.map((d) => ({ ...d })) };
|
|
39
|
+
}
|
|
40
|
+
if (typeof docs === 'object') {
|
|
41
|
+
const out = {};
|
|
42
|
+
for (const [k, v] of Object.entries(docs)) {
|
|
43
|
+
if (!Array.isArray(v)) continue;
|
|
44
|
+
out[k] = v.map((d) => ({ ...d }));
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
return {};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* True iff the project's docs field is already in the grouped shape
|
|
53
|
+
* (object of arrays). Empty objects count as grouped.
|
|
54
|
+
*/
|
|
55
|
+
export function isGrouped(docs) {
|
|
56
|
+
return docs != null && !Array.isArray(docs) && typeof docs === 'object';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Add a doc entry to a group. Returns a new docs object — pure, does
|
|
61
|
+
* not mutate the input.
|
|
62
|
+
*
|
|
63
|
+
* - Migrates flat-array shape to grouped shape under DEFAULT_GROUP.
|
|
64
|
+
* - Creates the group if missing.
|
|
65
|
+
* - Idempotent: if {label, path} already exists in the target group,
|
|
66
|
+
* returns the input unchanged (still normalised to grouped shape).
|
|
67
|
+
*/
|
|
68
|
+
export function addDoc(docs, group, entry) {
|
|
69
|
+
if (!entry || typeof entry !== 'object') {
|
|
70
|
+
throw new Error('addDoc: entry must be { label, path }');
|
|
71
|
+
}
|
|
72
|
+
if (!entry.label || !entry.path) {
|
|
73
|
+
throw new Error('addDoc: entry must have label and path');
|
|
74
|
+
}
|
|
75
|
+
const groupKey = group || DEFAULT_GROUP;
|
|
76
|
+
const next = normaliseDocs(docs);
|
|
77
|
+
const existing = next[groupKey] || [];
|
|
78
|
+
const dup = existing.find((d) => d.path === entry.path && d.label === entry.label);
|
|
79
|
+
if (dup) {
|
|
80
|
+
// Already present — return the normalised-but-unchanged shape so
|
|
81
|
+
// callers writing it back still benefit from the migration even on
|
|
82
|
+
// a no-op add.
|
|
83
|
+
next[groupKey] = existing;
|
|
84
|
+
return next;
|
|
85
|
+
}
|
|
86
|
+
const newEntry = { label: entry.label, path: entry.path };
|
|
87
|
+
if (entry.status) newEntry.status = entry.status;
|
|
88
|
+
next[groupKey] = [...existing, newEntry];
|
|
89
|
+
return next;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Remove all entries with `path` from every group. Returns:
|
|
94
|
+
* { docs: <new docs>, removed: <number> }
|
|
95
|
+
*
|
|
96
|
+
* Empty groups are dropped so the project doesn't accumulate dead
|
|
97
|
+
* headings.
|
|
98
|
+
*/
|
|
99
|
+
export function removeDocByPath(docs, path) {
|
|
100
|
+
const next = normaliseDocs(docs);
|
|
101
|
+
let removed = 0;
|
|
102
|
+
for (const [group, entries] of Object.entries(next)) {
|
|
103
|
+
const kept = entries.filter((d) => {
|
|
104
|
+
if (d.path === path) {
|
|
105
|
+
removed += 1;
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
return true;
|
|
109
|
+
});
|
|
110
|
+
if (kept.length === 0) {
|
|
111
|
+
delete next[group];
|
|
112
|
+
} else {
|
|
113
|
+
next[group] = kept;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return { docs: next, removed };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Iterate groups in display order. Returns [{group, entries}] with
|
|
121
|
+
* DEFAULT_GROUP first (if present), then the rest in insertion order.
|
|
122
|
+
*/
|
|
123
|
+
export function listGroups(docs) {
|
|
124
|
+
const normalised = normaliseDocs(docs);
|
|
125
|
+
const keys = Object.keys(normalised);
|
|
126
|
+
const ordered = [];
|
|
127
|
+
if (Object.prototype.hasOwnProperty.call(normalised, DEFAULT_GROUP)) {
|
|
128
|
+
ordered.push(DEFAULT_GROUP);
|
|
129
|
+
}
|
|
130
|
+
for (const k of keys) {
|
|
131
|
+
if (k !== DEFAULT_GROUP) ordered.push(k);
|
|
132
|
+
}
|
|
133
|
+
return ordered.map((g) => ({ group: g, entries: normalised[g] }));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Set or remove the status field on doc entries matching `path`.
|
|
138
|
+
*
|
|
139
|
+
* - `status` must be one of VALID_DOC_STATUSES, or falsy to remove.
|
|
140
|
+
* - Searches across all groups.
|
|
141
|
+
* - Returns { docs, matched } where matched is the count of entries updated.
|
|
142
|
+
*/
|
|
143
|
+
export function setDocStatus(docs, path, status) {
|
|
144
|
+
if (status && !VALID_DOC_STATUSES.has(status)) {
|
|
145
|
+
throw new Error(
|
|
146
|
+
`invalid doc status: ${status} (expected one of: ${[...VALID_DOC_STATUSES].join(', ')})`,
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
const next = normaliseDocs(docs);
|
|
150
|
+
let matched = 0;
|
|
151
|
+
for (const entries of Object.values(next)) {
|
|
152
|
+
for (const entry of entries) {
|
|
153
|
+
if (entry.path === path) {
|
|
154
|
+
if (status) {
|
|
155
|
+
entry.status = status;
|
|
156
|
+
} else {
|
|
157
|
+
delete entry.status;
|
|
158
|
+
}
|
|
159
|
+
matched += 1;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return { docs: next, matched };
|
|
164
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// io.mjs — shared JSON read/write helpers for the pa write-side CLIs.
|
|
2
|
+
//
|
|
3
|
+
// The operator-repo convention is 2-space-indented JSON with a trailing
|
|
4
|
+
// newline. We always honour that on write so diffs stay clean.
|
|
5
|
+
//
|
|
6
|
+
// Read helpers are intentionally thin — node:fs/promises already throws
|
|
7
|
+
// sensible errors for ENOENT/EACCES; callers translate to exit codes.
|
|
8
|
+
|
|
9
|
+
import { readFile, writeFile, mkdir, readdir } from 'node:fs/promises';
|
|
10
|
+
import { dirname, join } from 'node:path';
|
|
11
|
+
|
|
12
|
+
export async function readJson(path) {
|
|
13
|
+
const raw = await readFile(path, 'utf8');
|
|
14
|
+
return JSON.parse(raw);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Write a JSON file with the operator-repo convention: 2-space indent and a
|
|
19
|
+
* trailing newline. Creates parent directories if needed.
|
|
20
|
+
*/
|
|
21
|
+
export async function writeJson(path, value) {
|
|
22
|
+
await mkdir(dirname(path), { recursive: true });
|
|
23
|
+
const body = JSON.stringify(value, null, 2) + '\n';
|
|
24
|
+
await writeFile(path, body, 'utf8');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Ensure a directory exists. Returns the absolute path.
|
|
29
|
+
*/
|
|
30
|
+
export async function ensureDir(path) {
|
|
31
|
+
await mkdir(path, { recursive: true });
|
|
32
|
+
return path;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* List the directories inside `dir`. Returns an empty array if `dir`
|
|
37
|
+
* does not exist; throws on other errors.
|
|
38
|
+
*/
|
|
39
|
+
export async function listSubdirs(dir) {
|
|
40
|
+
let entries;
|
|
41
|
+
try {
|
|
42
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
43
|
+
} catch (err) {
|
|
44
|
+
if (err.code === 'ENOENT') return [];
|
|
45
|
+
throw err;
|
|
46
|
+
}
|
|
47
|
+
return entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* List the .json files in `dir`. Returns an empty array if `dir`
|
|
52
|
+
* does not exist; throws on other errors.
|
|
53
|
+
*/
|
|
54
|
+
export async function listJsonFiles(dir) {
|
|
55
|
+
let entries;
|
|
56
|
+
try {
|
|
57
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
58
|
+
} catch (err) {
|
|
59
|
+
if (err.code === 'ENOENT') return [];
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
return entries
|
|
63
|
+
.filter((e) => e.isFile() && e.name.endsWith('.json'))
|
|
64
|
+
.map((e) => e.name);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Build an absolute path inside the repo. Convenience wrapper for callers
|
|
69
|
+
* that already have the repo root resolved.
|
|
70
|
+
*/
|
|
71
|
+
export function repoPath(repoRoot, ...parts) {
|
|
72
|
+
return join(repoRoot, ...parts);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Today's date in YYYY-MM-DD (UTC).
|
|
77
|
+
*/
|
|
78
|
+
export function today() {
|
|
79
|
+
return new Date().toISOString().slice(0, 10);
|
|
80
|
+
}
|