godpowers 0.15.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/AGENTS.md +37 -0
- package/CHANGELOG.md +639 -0
- package/INSPIRATION.md +52 -0
- package/LICENSE +21 -0
- package/README.md +232 -0
- package/SKILL.md +500 -0
- package/agents/god-archaeologist.md +139 -0
- package/agents/god-architect.md +92 -0
- package/agents/god-auditor.md +150 -0
- package/agents/god-browser-tester.md +144 -0
- package/agents/god-context-writer.md +137 -0
- package/agents/god-coordinator.md +138 -0
- package/agents/god-debt-assessor.md +132 -0
- package/agents/god-debugger.md +77 -0
- package/agents/god-deploy-engineer.md +87 -0
- package/agents/god-deps-auditor.md +111 -0
- package/agents/god-design-reviewer.md +137 -0
- package/agents/god-designer.md +171 -0
- package/agents/god-docs-writer.md +102 -0
- package/agents/god-executor.md +76 -0
- package/agents/god-explorer.md +110 -0
- package/agents/god-harden-auditor.md +163 -0
- package/agents/god-incident-investigator.md +144 -0
- package/agents/god-launch-strategist.md +103 -0
- package/agents/god-migration-strategist.md +126 -0
- package/agents/god-observability-engineer.md +76 -0
- package/agents/god-orchestrator.md +728 -0
- package/agents/god-org-context-loader.md +124 -0
- package/agents/god-planner.md +73 -0
- package/agents/god-pm.md +105 -0
- package/agents/god-quality-reviewer.md +74 -0
- package/agents/god-reconciler.md +230 -0
- package/agents/god-reconstructor.md +124 -0
- package/agents/god-repo-scaffolder.md +60 -0
- package/agents/god-retrospective.md +109 -0
- package/agents/god-roadmap-reconciler.md +123 -0
- package/agents/god-roadmap-updater.md +89 -0
- package/agents/god-roadmapper.md +82 -0
- package/agents/god-spec-reviewer.md +70 -0
- package/agents/god-spike-runner.md +119 -0
- package/agents/god-stack-selector.md +93 -0
- package/agents/god-standards-check.md +132 -0
- package/agents/god-storyteller.md +116 -0
- package/agents/god-updater.md +174 -0
- package/bin/install.js +514 -0
- package/extensions/data-pack/README.md +33 -0
- package/extensions/data-pack/agents/god-dashboard-builder.md +66 -0
- package/extensions/data-pack/agents/god-etl-engineer.md +64 -0
- package/extensions/data-pack/agents/god-ml-feature-engineer.md +66 -0
- package/extensions/data-pack/manifest.yaml +39 -0
- package/extensions/data-pack/package.json +42 -0
- package/extensions/data-pack/skills/god-dashboard.md +28 -0
- package/extensions/data-pack/skills/god-etl.md +28 -0
- package/extensions/data-pack/skills/god-ml-feature.md +28 -0
- package/extensions/data-pack/workflows/dashboard-arc.yaml +13 -0
- package/extensions/data-pack/workflows/etl-arc.yaml +13 -0
- package/extensions/data-pack/workflows/ml-feature-arc.yaml +13 -0
- package/extensions/launch-pack/README.md +36 -0
- package/extensions/launch-pack/agents/god-indie-hackers-strategist.md +128 -0
- package/extensions/launch-pack/agents/god-oss-release-strategist.md +125 -0
- package/extensions/launch-pack/agents/god-product-hunt-strategist.md +118 -0
- package/extensions/launch-pack/agents/god-show-hn-strategist.md +113 -0
- package/extensions/launch-pack/manifest.yaml +45 -0
- package/extensions/launch-pack/package.json +41 -0
- package/extensions/launch-pack/skills/god-indie-hackers.md +39 -0
- package/extensions/launch-pack/skills/god-oss-release.md +43 -0
- package/extensions/launch-pack/skills/god-product-hunt.md +41 -0
- package/extensions/launch-pack/skills/god-show-hn.md +40 -0
- package/extensions/launch-pack/workflows/indie-hackers.yaml +13 -0
- package/extensions/launch-pack/workflows/oss-release.yaml +13 -0
- package/extensions/launch-pack/workflows/product-hunt.yaml +13 -0
- package/extensions/launch-pack/workflows/show-hn.yaml +13 -0
- package/extensions/security-pack/README.md +48 -0
- package/extensions/security-pack/agents/god-hipaa-auditor.md +117 -0
- package/extensions/security-pack/agents/god-pci-auditor.md +100 -0
- package/extensions/security-pack/agents/god-soc2-auditor.md +107 -0
- package/extensions/security-pack/manifest.yaml +39 -0
- package/extensions/security-pack/package.json +42 -0
- package/extensions/security-pack/skills/god-hipaa-audit.md +41 -0
- package/extensions/security-pack/skills/god-pci-audit.md +40 -0
- package/extensions/security-pack/skills/god-soc2-audit.md +42 -0
- package/extensions/security-pack/workflows/hipaa-arc.yaml +15 -0
- package/extensions/security-pack/workflows/pci-arc.yaml +15 -0
- package/extensions/security-pack/workflows/soc2-arc.yaml +15 -0
- package/hooks/pre-tool-use.sh +40 -0
- package/hooks/session-start.sh +74 -0
- package/lib/README.md +28 -0
- package/lib/agent-browser-driver.js +215 -0
- package/lib/agent-cache.js +194 -0
- package/lib/agent-validator.js +275 -0
- package/lib/artifact-diff.js +168 -0
- package/lib/artifact-linter.js +142 -0
- package/lib/awesome-design.js +312 -0
- package/lib/browser-bridge.js +209 -0
- package/lib/budget.js +215 -0
- package/lib/checkpoint.js +390 -0
- package/lib/code-scanner.js +262 -0
- package/lib/context-budget.js +170 -0
- package/lib/context-writer.js +348 -0
- package/lib/cost-tracker.js +325 -0
- package/lib/cross-artifact-impact.js +162 -0
- package/lib/cross-repo-linkage.js +150 -0
- package/lib/design-detector.js +167 -0
- package/lib/design-spec.js +348 -0
- package/lib/drift-detector.js +212 -0
- package/lib/event-reader.js +174 -0
- package/lib/events.js +183 -0
- package/lib/extensions.js +257 -0
- package/lib/have-nots-validator.js +647 -0
- package/lib/impact.js +314 -0
- package/lib/impeccable-bridge.js +139 -0
- package/lib/intent.js +177 -0
- package/lib/linkage.js +232 -0
- package/lib/meta-linter.js +263 -0
- package/lib/multi-repo-detector.js +182 -0
- package/lib/otel-exporter.js +308 -0
- package/lib/recipes.js +186 -0
- package/lib/reverse-sync.js +332 -0
- package/lib/review-required.js +224 -0
- package/lib/router.js +278 -0
- package/lib/runtime-audit.js +455 -0
- package/lib/runtime-test.js +309 -0
- package/lib/skillui-bridge.js +216 -0
- package/lib/state-lock.js +201 -0
- package/lib/state.js +142 -0
- package/lib/story-validator.js +301 -0
- package/lib/suite-state.js +220 -0
- package/lib/workflow-parser.js +109 -0
- package/lib/workflow-runner.js +221 -0
- package/package.json +63 -0
- package/references/HAVE-NOTS.md +573 -0
- package/references/building/BUILD-ANTIPATTERNS.md +102 -0
- package/references/building/BUILD-VERTICAL-SLICES.md +75 -0
- package/references/building/BUILD-WAVES.md +61 -0
- package/references/building/README.md +17 -0
- package/references/design/COLOR.md +122 -0
- package/references/design/DESIGN-ANATOMY.md +121 -0
- package/references/design/DESIGN-ANTIPATTERNS.md +108 -0
- package/references/design/INTERACTION.md +148 -0
- package/references/design/MOTION.md +120 -0
- package/references/design/RESPONSIVE.md +157 -0
- package/references/design/SPATIAL.md +109 -0
- package/references/design/TYPOGRAPHY.md +121 -0
- package/references/design/UX-WRITING.md +135 -0
- package/references/orchestration/MODE-DETECTION.md +74 -0
- package/references/orchestration/README.md +18 -0
- package/references/orchestration/SCALE-DETECTION.md +81 -0
- package/references/planning/ARCH-ANATOMY.md +143 -0
- package/references/planning/ARCH-ANTIPATTERNS.md +52 -0
- package/references/planning/PRD-ANATOMY.md +117 -0
- package/references/planning/PRD-ANTIPATTERNS.md +138 -0
- package/references/planning/README.md +16 -0
- package/references/planning/ROADMAP-ANATOMY.md +43 -0
- package/references/planning/ROADMAP-ANTIPATTERNS.md +94 -0
- package/references/planning/STACK-ANATOMY.md +60 -0
- package/references/planning/STACK-ANTIPATTERNS.md +95 -0
- package/references/shared/GLOSSARY.md +80 -0
- package/references/shared/ORCHESTRATORS.md +76 -0
- package/references/shared/README.md +14 -0
- package/references/shipping/DEPLOY-ANTIPATTERNS.md +64 -0
- package/references/shipping/DEPLOY-PATTERNS.md +110 -0
- package/references/shipping/HARDEN-ANTIPATTERNS.md +66 -0
- package/references/shipping/HARDEN-OWASP-WORKSHEETS.md +89 -0
- package/references/shipping/LAUNCH-ANTIPATTERNS.md +68 -0
- package/references/shipping/OBSERVE-ANTIPATTERNS.md +62 -0
- package/references/shipping/OBSERVE-SLO-EXAMPLES.md +107 -0
- package/references/shipping/README.md +18 -0
- package/routing/god-add-backlog.yaml +24 -0
- package/routing/god-add-tests.yaml +27 -0
- package/routing/god-add-todo.yaml +24 -0
- package/routing/god-agent-audit.yaml +24 -0
- package/routing/god-arch.yaml +46 -0
- package/routing/god-archaeology.yaml +28 -0
- package/routing/god-audit.yaml +32 -0
- package/routing/god-budget.yaml +24 -0
- package/routing/god-build-agent.yaml +24 -0
- package/routing/god-build.yaml +46 -0
- package/routing/god-cache-clear.yaml +24 -0
- package/routing/god-check-todos.yaml +24 -0
- package/routing/god-context-scan.yaml +24 -0
- package/routing/god-context.yaml +44 -0
- package/routing/god-cost.yaml +24 -0
- package/routing/god-debug.yaml +28 -0
- package/routing/god-deploy.yaml +34 -0
- package/routing/god-design-impact.yaml +25 -0
- package/routing/god-design.yaml +67 -0
- package/routing/god-discuss.yaml +27 -0
- package/routing/god-docs.yaml +33 -0
- package/routing/god-doctor.yaml +27 -0
- package/routing/god-explore.yaml +27 -0
- package/routing/god-extension-add.yaml +24 -0
- package/routing/god-extension-info.yaml +24 -0
- package/routing/god-extension-list.yaml +24 -0
- package/routing/god-extension-remove.yaml +24 -0
- package/routing/god-extract-learnings.yaml +24 -0
- package/routing/god-fast.yaml +27 -0
- package/routing/god-feature.yaml +34 -0
- package/routing/god-graph.yaml +24 -0
- package/routing/god-harden.yaml +41 -0
- package/routing/god-help.yaml +27 -0
- package/routing/god-hotfix.yaml +34 -0
- package/routing/god-hygiene.yaml +28 -0
- package/routing/god-init.yaml +37 -0
- package/routing/god-intel.yaml +24 -0
- package/routing/god-launch.yaml +41 -0
- package/routing/god-lifecycle.yaml +27 -0
- package/routing/god-link.yaml +24 -0
- package/routing/god-lint.yaml +24 -0
- package/routing/god-list-assumptions.yaml +27 -0
- package/routing/god-locate.yaml +24 -0
- package/routing/god-logs.yaml +24 -0
- package/routing/god-map-codebase.yaml +24 -0
- package/routing/god-metrics.yaml +24 -0
- package/routing/god-mode.yaml +31 -0
- package/routing/god-next.yaml +27 -0
- package/routing/god-note.yaml +24 -0
- package/routing/god-observe.yaml +34 -0
- package/routing/god-org-context.yaml +28 -0
- package/routing/god-party.yaml +24 -0
- package/routing/god-pause-work.yaml +27 -0
- package/routing/god-plant-seed.yaml +24 -0
- package/routing/god-postmortem.yaml +34 -0
- package/routing/god-pr-branch.yaml +25 -0
- package/routing/god-prd.yaml +49 -0
- package/routing/god-quick.yaml +28 -0
- package/routing/god-reconcile.yaml +48 -0
- package/routing/god-reconstruct.yaml +36 -0
- package/routing/god-redo.yaml +27 -0
- package/routing/god-refactor.yaml +36 -0
- package/routing/god-repair.yaml +27 -0
- package/routing/god-repo.yaml +35 -0
- package/routing/god-restore.yaml +27 -0
- package/routing/god-resume-work.yaml +27 -0
- package/routing/god-review-changes.yaml +25 -0
- package/routing/god-review.yaml +28 -0
- package/routing/god-roadmap-check.yaml +39 -0
- package/routing/god-roadmap-update.yaml +37 -0
- package/routing/god-roadmap.yaml +42 -0
- package/routing/god-rollback.yaml +27 -0
- package/routing/god-scan.yaml +24 -0
- package/routing/god-set-profile.yaml +24 -0
- package/routing/god-settings.yaml +24 -0
- package/routing/god-skip.yaml +27 -0
- package/routing/god-smite.yaml +29 -0
- package/routing/god-spike.yaml +35 -0
- package/routing/god-sprint.yaml +25 -0
- package/routing/god-stack.yaml +41 -0
- package/routing/god-standards.yaml +24 -0
- package/routing/god-status.yaml +27 -0
- package/routing/god-stories.yaml +24 -0
- package/routing/god-story-build.yaml +25 -0
- package/routing/god-story-close.yaml +25 -0
- package/routing/god-story-verify.yaml +25 -0
- package/routing/god-story.yaml +24 -0
- package/routing/god-suite-init.yaml +24 -0
- package/routing/god-suite-patch.yaml +25 -0
- package/routing/god-suite-release.yaml +25 -0
- package/routing/god-suite-status.yaml +25 -0
- package/routing/god-suite-sync.yaml +25 -0
- package/routing/god-sync.yaml +33 -0
- package/routing/god-tech-debt.yaml +32 -0
- package/routing/god-test-extension.yaml +24 -0
- package/routing/god-test-runtime.yaml +25 -0
- package/routing/god-thread.yaml +24 -0
- package/routing/god-trace.yaml +24 -0
- package/routing/god-undo.yaml +27 -0
- package/routing/god-update-deps.yaml +39 -0
- package/routing/god-upgrade.yaml +33 -0
- package/routing/god-version.yaml +24 -0
- package/routing/god-workstream.yaml +24 -0
- package/routing/god.yaml +24 -0
- package/routing/recipes/add-feature-defer-current-milestone.yaml +21 -0
- package/routing/recipes/add-feature-future-conditional.yaml +21 -0
- package/routing/recipes/add-feature-mid-arc-pause.yaml +33 -0
- package/routing/recipes/add-feature-next-milestone.yaml +23 -0
- package/routing/recipes/add-feature-parallel.yaml +29 -0
- package/routing/recipes/add-feature-prd-update.yaml +21 -0
- package/routing/recipes/add-feature-small.yaml +24 -0
- package/routing/recipes/add-feature-tiny.yaml +24 -0
- package/routing/recipes/bluefield-org-aware.yaml +27 -0
- package/routing/recipes/broken-install.yaml +22 -0
- package/routing/recipes/brownfield-onboarding.yaml +32 -0
- package/routing/recipes/bug-no-urgency.yaml +21 -0
- package/routing/recipes/capture-idea.yaml +22 -0
- package/routing/recipes/capture-todo.yaml +21 -0
- package/routing/recipes/clean-pr.yaml +21 -0
- package/routing/recipes/code-cleanup.yaml +23 -0
- package/routing/recipes/docs-drift.yaml +21 -0
- package/routing/recipes/existing-codebase-onboarding.yaml +32 -0
- package/routing/recipes/extract-learnings.yaml +22 -0
- package/routing/recipes/greenfield-fast.yaml +25 -0
- package/routing/recipes/greenfield-manual.yaml +32 -0
- package/routing/recipes/greenfield-with-ideation.yaml +29 -0
- package/routing/recipes/incident-postmortem.yaml +24 -0
- package/routing/recipes/major-framework-upgrade.yaml +23 -0
- package/routing/recipes/monthly-deps.yaml +22 -0
- package/routing/recipes/multi-repo-suite.yaml +56 -0
- package/routing/recipes/parallel-engineers.yaml +26 -0
- package/routing/recipes/pause-handoff.yaml +21 -0
- package/routing/recipes/production-broken.yaml +26 -0
- package/routing/recipes/rerun-tier.yaml +21 -0
- package/routing/recipes/returning-after-break.yaml +31 -0
- package/routing/recipes/state-drift.yaml +21 -0
- package/routing/recipes/undo-last.yaml +21 -0
- package/routing/recipes/weekly-health-check.yaml +24 -0
- package/routing/recipes/whats-next.yaml +22 -0
- package/routing/recipes/where-am-i.yaml +21 -0
- package/schema/events.v1.json +63 -0
- package/schema/extension-manifest.v1.json +84 -0
- package/schema/intent.v1.yaml.json +116 -0
- package/schema/recipe.v1.json +120 -0
- package/schema/routing.v1.json +163 -0
- package/schema/state.v1.json +146 -0
- package/schema/workflow.v1.json +96 -0
- package/skills/god-add-backlog.md +40 -0
- package/skills/god-add-tests.md +53 -0
- package/skills/god-add-todo.md +32 -0
- package/skills/god-agent-audit.md +87 -0
- package/skills/god-arch.md +81 -0
- package/skills/god-archaeology.md +48 -0
- package/skills/god-audit.md +65 -0
- package/skills/god-budget.md +103 -0
- package/skills/god-build-agent.md +91 -0
- package/skills/god-build.md +90 -0
- package/skills/god-cache-clear.md +75 -0
- package/skills/god-check-todos.md +42 -0
- package/skills/god-context-scan.md +125 -0
- package/skills/god-context.md +147 -0
- package/skills/god-cost.md +118 -0
- package/skills/god-debug.md +30 -0
- package/skills/god-deploy.md +76 -0
- package/skills/god-design-impact.md +86 -0
- package/skills/god-design.md +275 -0
- package/skills/god-discuss.md +46 -0
- package/skills/god-docs.md +81 -0
- package/skills/god-doctor.md +94 -0
- package/skills/god-explore.md +50 -0
- package/skills/god-export-otel.md +87 -0
- package/skills/god-extension-add.md +79 -0
- package/skills/god-extension-info.md +75 -0
- package/skills/god-extension-list.md +55 -0
- package/skills/god-extension-remove.md +66 -0
- package/skills/god-extract-learnings.md +60 -0
- package/skills/god-fast.md +47 -0
- package/skills/god-feature.md +114 -0
- package/skills/god-graph.md +56 -0
- package/skills/god-harden.md +106 -0
- package/skills/god-help.md +66 -0
- package/skills/god-hotfix.md +139 -0
- package/skills/god-hygiene.md +104 -0
- package/skills/god-init.md +161 -0
- package/skills/god-intel.md +36 -0
- package/skills/god-launch.md +86 -0
- package/skills/god-lifecycle.md +119 -0
- package/skills/god-link.md +90 -0
- package/skills/god-lint.md +128 -0
- package/skills/god-list-assumptions.md +56 -0
- package/skills/god-locate.md +97 -0
- package/skills/god-logs.md +57 -0
- package/skills/god-map-codebase.md +45 -0
- package/skills/god-metrics.md +51 -0
- package/skills/god-mode.md +159 -0
- package/skills/god-next.md +257 -0
- package/skills/god-note.md +39 -0
- package/skills/god-observe.md +76 -0
- package/skills/god-org-context.md +81 -0
- package/skills/god-party.md +87 -0
- package/skills/god-pause-work.md +64 -0
- package/skills/god-plant-seed.md +59 -0
- package/skills/god-postmortem.md +103 -0
- package/skills/god-pr-branch.md +50 -0
- package/skills/god-prd.md +90 -0
- package/skills/god-quick.md +50 -0
- package/skills/god-reconcile.md +90 -0
- package/skills/god-reconstruct.md +72 -0
- package/skills/god-redo.md +73 -0
- package/skills/god-refactor.md +137 -0
- package/skills/god-repair.md +82 -0
- package/skills/god-repo.md +49 -0
- package/skills/god-restore.md +91 -0
- package/skills/god-resume-work.md +42 -0
- package/skills/god-review-changes.md +93 -0
- package/skills/god-review.md +52 -0
- package/skills/god-roadmap-check.md +66 -0
- package/skills/god-roadmap-update.md +64 -0
- package/skills/god-roadmap.md +77 -0
- package/skills/god-rollback.md +88 -0
- package/skills/god-scan.md +106 -0
- package/skills/god-set-profile.md +58 -0
- package/skills/god-settings.md +44 -0
- package/skills/god-skip.md +78 -0
- package/skills/god-smite.md +86 -0
- package/skills/god-spike.md +120 -0
- package/skills/god-sprint.md +77 -0
- package/skills/god-stack.md +74 -0
- package/skills/god-standards.md +62 -0
- package/skills/god-status.md +99 -0
- package/skills/god-stories.md +60 -0
- package/skills/god-story-build.md +76 -0
- package/skills/god-story-close.md +82 -0
- package/skills/god-story-verify.md +71 -0
- package/skills/god-story.md +55 -0
- package/skills/god-suite-init.md +75 -0
- package/skills/god-suite-patch.md +64 -0
- package/skills/god-suite-release.md +58 -0
- package/skills/god-suite-status.md +63 -0
- package/skills/god-suite-sync.md +49 -0
- package/skills/god-sync.md +102 -0
- package/skills/god-tech-debt.md +56 -0
- package/skills/god-test-extension.md +87 -0
- package/skills/god-test-runtime.md +144 -0
- package/skills/god-thread.md +39 -0
- package/skills/god-trace.md +50 -0
- package/skills/god-undo.md +68 -0
- package/skills/god-update-deps.md +134 -0
- package/skills/god-upgrade.md +139 -0
- package/skills/god-version.md +37 -0
- package/skills/god-workstream.md +61 -0
- package/skills/god.md +207 -0
- package/templates/ARCH.md +99 -0
- package/templates/DEPS-AUDIT.md +66 -0
- package/templates/DESIGN.md +71 -0
- package/templates/DOCS-UPDATE-LOG.md +64 -0
- package/templates/HARDEN-FINDINGS.md +69 -0
- package/templates/MIGRATION.md +86 -0
- package/templates/POSTMORTEM.md +88 -0
- package/templates/PRD.md +80 -0
- package/templates/PROGRESS.md +49 -0
- package/templates/ROADMAP.md +47 -0
- package/templates/SPIKE.md +72 -0
- package/templates/STACK-DECISION.md +61 -0
- package/workflows/audit-only.yaml +22 -0
- package/workflows/bluefield-arc.yaml +87 -0
- package/workflows/brownfield-arc.yaml +44 -0
- package/workflows/deps-audit.yaml +56 -0
- package/workflows/docs-arc.yaml +22 -0
- package/workflows/feature-arc.yaml +59 -0
- package/workflows/full-arc.yaml +84 -0
- package/workflows/hotfix-arc.yaml +59 -0
- package/workflows/hygiene.yaml +43 -0
- package/workflows/migration-arc.yaml +73 -0
- package/workflows/postmortem.yaml +31 -0
- package/workflows/refactor-arc.yaml +59 -0
- package/workflows/spike.yaml +23 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Suite State Manager
|
|
3
|
+
*
|
|
4
|
+
* Aggregates per-repo state.json into a suite-level view.
|
|
5
|
+
*
|
|
6
|
+
* Storage:
|
|
7
|
+
* <hub>/.godpowers/suite/state.json (machine-readable aggregate)
|
|
8
|
+
* <hub>/.godpowers/suite/STATE.md (human-readable summary)
|
|
9
|
+
* <hub>/.godpowers/suite/SYNC-LOG.md (append-only history)
|
|
10
|
+
*
|
|
11
|
+
* Public API:
|
|
12
|
+
* readSuiteState(hubPath) -> { repos, totals, lastSync }
|
|
13
|
+
* writeSuiteState(hubPath, data) -> void
|
|
14
|
+
* refreshFromRepos(hubPath) -> data (re-aggregate now)
|
|
15
|
+
* appendSyncLog(hubPath, entry) -> void
|
|
16
|
+
* format(hubPath) -> markdown summary
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const fs = require('fs');
|
|
20
|
+
const path = require('path');
|
|
21
|
+
|
|
22
|
+
const detector = require('./multi-repo-detector');
|
|
23
|
+
|
|
24
|
+
function suiteDir(hubPath) {
|
|
25
|
+
return path.join(hubPath, '.godpowers', 'suite');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function suiteStatePath(hubPath) {
|
|
29
|
+
return path.join(suiteDir(hubPath), 'state.json');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function suiteStateMdPath(hubPath) {
|
|
33
|
+
return path.join(suiteDir(hubPath), 'STATE.md');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function suiteSyncLogPath(hubPath) {
|
|
37
|
+
return path.join(suiteDir(hubPath), 'SYNC-LOG.md');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function ensureSuiteDir(hubPath) {
|
|
41
|
+
fs.mkdirSync(suiteDir(hubPath), { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Read the persisted suite state.
|
|
46
|
+
*/
|
|
47
|
+
function readSuiteState(hubPath) {
|
|
48
|
+
const file = suiteStatePath(hubPath);
|
|
49
|
+
if (!fs.existsSync(file)) return null;
|
|
50
|
+
try {
|
|
51
|
+
return JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
52
|
+
} catch (e) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Write the suite state JSON.
|
|
59
|
+
*/
|
|
60
|
+
function writeSuiteState(hubPath, data) {
|
|
61
|
+
ensureSuiteDir(hubPath);
|
|
62
|
+
fs.writeFileSync(suiteStatePath(hubPath), JSON.stringify(data, null, 2) + '\n');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Walk siblings, read each repo's state.json, build aggregate.
|
|
67
|
+
*/
|
|
68
|
+
function refreshFromRepos(hubPath) {
|
|
69
|
+
const config = detector.readSuiteConfig(hubPath);
|
|
70
|
+
if (!config) return null;
|
|
71
|
+
|
|
72
|
+
const siblings = (config.siblings || []).map(sib => {
|
|
73
|
+
if (typeof sib === 'string') return { name: sib, path: path.resolve(hubPath, sib) };
|
|
74
|
+
return { name: sib.name, path: path.resolve(hubPath, sib.path || sib.name) };
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const repos = [];
|
|
78
|
+
let totalArtifacts = 0;
|
|
79
|
+
let totalDrift = 0;
|
|
80
|
+
let totalReviews = 0;
|
|
81
|
+
let totalCoverage = 0;
|
|
82
|
+
let coverageCount = 0;
|
|
83
|
+
|
|
84
|
+
for (const sib of siblings) {
|
|
85
|
+
const statePath = path.join(sib.path, '.godpowers', 'state.json');
|
|
86
|
+
if (!fs.existsSync(statePath)) {
|
|
87
|
+
repos.push({ name: sib.name, path: sib.path, status: 'no-state' });
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
|
92
|
+
const tiers = state.tiers || {};
|
|
93
|
+
const linkage = state.linkage || {};
|
|
94
|
+
|
|
95
|
+
// Count completed artifacts
|
|
96
|
+
let completedArtifacts = 0;
|
|
97
|
+
for (const tier of Object.values(tiers)) {
|
|
98
|
+
for (const sub of Object.values(tier)) {
|
|
99
|
+
if (sub && sub.status === 'done') completedArtifacts++;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const repoSummary = {
|
|
104
|
+
name: sib.name,
|
|
105
|
+
path: sib.path,
|
|
106
|
+
mode: state.project && state.project.mode,
|
|
107
|
+
scale: state.project && state.project.scale,
|
|
108
|
+
lifecyclePhase: state['lifecycle-phase'],
|
|
109
|
+
completedArtifacts,
|
|
110
|
+
linkage: {
|
|
111
|
+
coveragePct: linkage['coverage-pct'] || 0,
|
|
112
|
+
orphanCount: linkage['orphan-count'] || 0,
|
|
113
|
+
driftCount: linkage['drift-count'] || 0,
|
|
114
|
+
reviewRequiredItems: linkage['review-required-items'] || 0
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
repos.push(repoSummary);
|
|
118
|
+
|
|
119
|
+
totalArtifacts += completedArtifacts;
|
|
120
|
+
totalDrift += repoSummary.linkage.driftCount;
|
|
121
|
+
totalReviews += repoSummary.linkage.reviewRequiredItems;
|
|
122
|
+
totalCoverage += repoSummary.linkage.coveragePct;
|
|
123
|
+
coverageCount++;
|
|
124
|
+
} catch (e) {
|
|
125
|
+
repos.push({ name: sib.name, path: sib.path, status: 'parse-error', error: e.message });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const data = {
|
|
130
|
+
version: '1.0.0',
|
|
131
|
+
hubPath,
|
|
132
|
+
refreshedAt: new Date().toISOString(),
|
|
133
|
+
repos,
|
|
134
|
+
totals: {
|
|
135
|
+
artifacts: totalArtifacts,
|
|
136
|
+
drift: totalDrift,
|
|
137
|
+
reviewRequired: totalReviews,
|
|
138
|
+
avgCoverage: coverageCount > 0 ? totalCoverage / coverageCount : 0
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
writeSuiteState(hubPath, data);
|
|
142
|
+
writeStateMd(hubPath, data);
|
|
143
|
+
return data;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Write a human-readable STATE.md from the aggregate.
|
|
148
|
+
*/
|
|
149
|
+
function writeStateMd(hubPath, data) {
|
|
150
|
+
ensureSuiteDir(hubPath);
|
|
151
|
+
const lines = [];
|
|
152
|
+
lines.push(`# Suite State`);
|
|
153
|
+
lines.push('');
|
|
154
|
+
lines.push(`Refreshed: ${data.refreshedAt}`);
|
|
155
|
+
lines.push(`Hub: ${data.hubPath}`);
|
|
156
|
+
lines.push('');
|
|
157
|
+
lines.push(`## Aggregate`);
|
|
158
|
+
lines.push('');
|
|
159
|
+
lines.push(`- Total artifacts complete: ${data.totals.artifacts}`);
|
|
160
|
+
lines.push(`- Total drift findings: ${data.totals.drift}`);
|
|
161
|
+
lines.push(`- Pending reviews: ${data.totals.reviewRequired}`);
|
|
162
|
+
lines.push(`- Average linkage coverage: ${(data.totals.avgCoverage * 100).toFixed(0)}%`);
|
|
163
|
+
lines.push('');
|
|
164
|
+
lines.push(`## Per-repo`);
|
|
165
|
+
lines.push('');
|
|
166
|
+
lines.push('| Repo | Mode | Phase | Artifacts | Coverage | Drift | Reviews |');
|
|
167
|
+
lines.push('|---|---|---|---|---|---|---|');
|
|
168
|
+
for (const repo of data.repos) {
|
|
169
|
+
if (repo.status) {
|
|
170
|
+
lines.push(`| ${repo.name} | (${repo.status}) | - | - | - | - | - |`);
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
const cov = repo.linkage.coveragePct ? `${(repo.linkage.coveragePct * 100).toFixed(0)}%` : '-';
|
|
174
|
+
lines.push(
|
|
175
|
+
`| ${repo.name} | ${repo.mode || '-'} | ${repo.lifecyclePhase || '-'} | ${repo.completedArtifacts} | ${cov} | ${repo.linkage.driftCount} | ${repo.linkage.reviewRequiredItems} |`
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
lines.push('');
|
|
179
|
+
fs.writeFileSync(suiteStateMdPath(hubPath), lines.join('\n'));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Append to SYNC-LOG.md.
|
|
184
|
+
*/
|
|
185
|
+
function appendSyncLog(hubPath, entry) {
|
|
186
|
+
ensureSuiteDir(hubPath);
|
|
187
|
+
const file = suiteSyncLogPath(hubPath);
|
|
188
|
+
const ts = new Date().toISOString();
|
|
189
|
+
const header = !fs.existsSync(file) ? `# Suite Sync Log\n\nAppend-only history of suite-level operations.\n\n` : '';
|
|
190
|
+
const block = `## ${ts}\n\n${entry}\n\n`;
|
|
191
|
+
if (header) {
|
|
192
|
+
fs.writeFileSync(file, header + block);
|
|
193
|
+
} else {
|
|
194
|
+
fs.appendFileSync(file, block);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Format the current suite state as a string (for /god-suite-status).
|
|
200
|
+
*/
|
|
201
|
+
function format(hubPath) {
|
|
202
|
+
const data = readSuiteState(hubPath);
|
|
203
|
+
if (!data) return 'No suite state. Run /god-suite-init first.';
|
|
204
|
+
if (fs.existsSync(suiteStateMdPath(hubPath))) {
|
|
205
|
+
return fs.readFileSync(suiteStateMdPath(hubPath), 'utf8');
|
|
206
|
+
}
|
|
207
|
+
return JSON.stringify(data, null, 2);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
module.exports = {
|
|
211
|
+
suiteDir,
|
|
212
|
+
suiteStatePath,
|
|
213
|
+
suiteStateMdPath,
|
|
214
|
+
suiteSyncLogPath,
|
|
215
|
+
readSuiteState,
|
|
216
|
+
writeSuiteState,
|
|
217
|
+
refreshFromRepos,
|
|
218
|
+
appendSyncLog,
|
|
219
|
+
format
|
|
220
|
+
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Parser
|
|
3
|
+
*
|
|
4
|
+
* Parse workflow YAML files into a structured DAG.
|
|
5
|
+
* Used by the workflow runner and by tests.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const { parseSimpleYaml } = require('./intent');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Parse a workflow YAML file into a structured object.
|
|
14
|
+
*/
|
|
15
|
+
function parseFile(filePath) {
|
|
16
|
+
if (!fs.existsSync(filePath)) {
|
|
17
|
+
throw new Error(`Workflow not found: ${filePath}`);
|
|
18
|
+
}
|
|
19
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
20
|
+
return parse(content);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Parse YAML content into a workflow object.
|
|
25
|
+
*/
|
|
26
|
+
function parse(yamlContent) {
|
|
27
|
+
const parsed = parseSimpleYaml(yamlContent);
|
|
28
|
+
validate(parsed);
|
|
29
|
+
return parsed;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Validate workflow structure. Throws on invalid.
|
|
34
|
+
*/
|
|
35
|
+
function validate(workflow) {
|
|
36
|
+
const errors = [];
|
|
37
|
+
if (workflow.apiVersion !== 'godpowers/v1') errors.push('apiVersion must be godpowers/v1');
|
|
38
|
+
if (workflow.kind !== 'Workflow') errors.push('kind must be Workflow');
|
|
39
|
+
if (!workflow.metadata || !workflow.metadata.name) errors.push('metadata.name required');
|
|
40
|
+
if (!workflow.metadata.version) errors.push('metadata.version required');
|
|
41
|
+
if (!workflow.on || !Array.isArray(workflow.on) || workflow.on.length === 0) {
|
|
42
|
+
errors.push('on must be a non-empty array');
|
|
43
|
+
}
|
|
44
|
+
if (!workflow.jobs || typeof workflow.jobs !== 'object') {
|
|
45
|
+
errors.push('jobs must be an object');
|
|
46
|
+
} else {
|
|
47
|
+
for (const [jobId, job] of Object.entries(workflow.jobs)) {
|
|
48
|
+
if (!job.uses) errors.push(`jobs.${jobId}.uses required`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (errors.length > 0) {
|
|
53
|
+
throw new Error(`Invalid workflow:\n - ${errors.join('\n - ')}`);
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Build a topological order of job IDs.
|
|
60
|
+
* Returns array of arrays; each inner array is a "wave" that can run in parallel.
|
|
61
|
+
*/
|
|
62
|
+
function buildWaves(workflow) {
|
|
63
|
+
const jobs = workflow.jobs;
|
|
64
|
+
const remaining = new Set(Object.keys(jobs));
|
|
65
|
+
const completed = new Set();
|
|
66
|
+
const waves = [];
|
|
67
|
+
|
|
68
|
+
while (remaining.size > 0) {
|
|
69
|
+
const wave = [];
|
|
70
|
+
for (const jobId of remaining) {
|
|
71
|
+
const needs = normalizeNeeds(jobs[jobId].needs);
|
|
72
|
+
if (needs.every(n => completed.has(n))) {
|
|
73
|
+
wave.push(jobId);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (wave.length === 0) {
|
|
77
|
+
throw new Error(`Cyclic dependency or unresolved needs in workflow ${workflow.metadata.name}`);
|
|
78
|
+
}
|
|
79
|
+
for (const jobId of wave) {
|
|
80
|
+
remaining.delete(jobId);
|
|
81
|
+
completed.add(jobId);
|
|
82
|
+
}
|
|
83
|
+
waves.push(wave);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return waves;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function normalizeNeeds(needs) {
|
|
90
|
+
if (!needs) return [];
|
|
91
|
+
if (typeof needs === 'string') return [needs];
|
|
92
|
+
return needs;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Load all workflows from a directory.
|
|
97
|
+
*/
|
|
98
|
+
function loadAll(dir) {
|
|
99
|
+
if (!fs.existsSync(dir)) return {};
|
|
100
|
+
const result = {};
|
|
101
|
+
for (const file of fs.readdirSync(dir)) {
|
|
102
|
+
if (!file.endsWith('.yaml') && !file.endsWith('.yml')) continue;
|
|
103
|
+
const workflow = parseFile(path.join(dir, file));
|
|
104
|
+
result[workflow.metadata.name] = workflow;
|
|
105
|
+
}
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
module.exports = { parse, parseFile, validate, buildWaves, loadAll, normalizeNeeds };
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Runner - v0.14 executable workflows.
|
|
3
|
+
*
|
|
4
|
+
* Reads a parsed workflow (from lib/workflow-parser.js), computes a
|
|
5
|
+
* plan (the agent dispatch order, with dependency waves), and either:
|
|
6
|
+
* - emits the plan only (--plan mode), writing
|
|
7
|
+
* .godpowers/runs/<id>/plan.yaml
|
|
8
|
+
* - emits a plan AND signals the orchestrator agent to execute it
|
|
9
|
+
* step by step
|
|
10
|
+
*
|
|
11
|
+
* For the pure-skill model, "execute" doesn't shell out; the
|
|
12
|
+
* orchestrator agent reads the plan and dispatches agents inside its
|
|
13
|
+
* AI context. The runner's contract is therefore:
|
|
14
|
+
*
|
|
15
|
+
* - parse + validate the YAML
|
|
16
|
+
* - compute waves (parallel groups)
|
|
17
|
+
* - emit a deterministic plan
|
|
18
|
+
* - return the plan for the orchestrator to follow
|
|
19
|
+
*
|
|
20
|
+
* Public API:
|
|
21
|
+
* loadByName(workflowName, opts?) -> workflow object
|
|
22
|
+
* plan(workflow, ctx?) -> { steps: [...], waves: [...], summary }
|
|
23
|
+
* writePlan(projectRoot, runId, plan) -> path
|
|
24
|
+
* readPlan(projectRoot, runId) -> plan | null
|
|
25
|
+
* listWorkflows(opts?) -> [{ name, version, description, file }]
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
const fs = require('fs');
|
|
29
|
+
const path = require('path');
|
|
30
|
+
|
|
31
|
+
const parser = require('./workflow-parser');
|
|
32
|
+
|
|
33
|
+
function workflowsDir(opts) {
|
|
34
|
+
if (opts && opts.dir) return opts.dir;
|
|
35
|
+
// Prefer project-local override, then repo workflows/
|
|
36
|
+
const candidates = [
|
|
37
|
+
path.join(process.cwd(), '.godpowers', 'workflows'),
|
|
38
|
+
path.join(__dirname, '..', 'workflows')
|
|
39
|
+
];
|
|
40
|
+
return candidates.find(d => fs.existsSync(d)) || candidates[1];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* List all available workflows. opts.dir overrides the default
|
|
45
|
+
* lookup chain.
|
|
46
|
+
*/
|
|
47
|
+
function listWorkflows(opts = {}) {
|
|
48
|
+
const dir = workflowsDir(opts);
|
|
49
|
+
if (!fs.existsSync(dir)) return [];
|
|
50
|
+
return fs.readdirSync(dir)
|
|
51
|
+
.filter(f => f.endsWith('.yaml'))
|
|
52
|
+
.map(f => {
|
|
53
|
+
try {
|
|
54
|
+
const wf = parser.parseFile(path.join(dir, f));
|
|
55
|
+
return {
|
|
56
|
+
name: wf.metadata && wf.metadata.name,
|
|
57
|
+
version: wf.metadata && wf.metadata.version,
|
|
58
|
+
description: wf.metadata && wf.metadata.description,
|
|
59
|
+
file: path.join(dir, f)
|
|
60
|
+
};
|
|
61
|
+
} catch (e) {
|
|
62
|
+
return { name: path.basename(f, '.yaml'), file: path.join(dir, f),
|
|
63
|
+
error: e.message };
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Load a workflow by name (looks up name in workflows/ dir).
|
|
70
|
+
* If `name` ends with .yaml, treats it as a path.
|
|
71
|
+
*/
|
|
72
|
+
function loadByName(name, opts = {}) {
|
|
73
|
+
if (name.endsWith('.yaml') && fs.existsSync(name)) {
|
|
74
|
+
return parser.parseFile(name);
|
|
75
|
+
}
|
|
76
|
+
const dir = workflowsDir(opts);
|
|
77
|
+
// Look up by metadata.name first; then by filename
|
|
78
|
+
for (const f of fs.readdirSync(dir).filter(f => f.endsWith('.yaml'))) {
|
|
79
|
+
const wf = parser.parseFile(path.join(dir, f));
|
|
80
|
+
if (wf.metadata && wf.metadata.name === name) return wf;
|
|
81
|
+
}
|
|
82
|
+
const filePath = path.join(dir, `${name}.yaml`);
|
|
83
|
+
if (fs.existsSync(filePath)) return parser.parseFile(filePath);
|
|
84
|
+
throw new Error(`workflow not found: ${name} (searched in ${dir})`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Compute an execution plan from a workflow. Uses parser.buildWaves
|
|
89
|
+
* for dependency ordering.
|
|
90
|
+
*
|
|
91
|
+
* Returns:
|
|
92
|
+
* {
|
|
93
|
+
* workflow: { name, version, description },
|
|
94
|
+
* steps: [{ jobKey, agent, tier, needs, uses, review?, on-pass?, on-fail? }],
|
|
95
|
+
* waves: [[jobKey, ...], ...],
|
|
96
|
+
* summary: '...'
|
|
97
|
+
* }
|
|
98
|
+
*/
|
|
99
|
+
function plan(workflow, ctx = {}) {
|
|
100
|
+
const waves = parser.buildWaves(workflow);
|
|
101
|
+
const steps = [];
|
|
102
|
+
for (const wave of waves) {
|
|
103
|
+
for (const jobKey of wave) {
|
|
104
|
+
const job = workflow.jobs[jobKey] || {};
|
|
105
|
+
steps.push({
|
|
106
|
+
jobKey,
|
|
107
|
+
agent: extractAgent(job.uses),
|
|
108
|
+
tier: job.tier != null ? `tier-${job.tier}` : null,
|
|
109
|
+
needs: parser.normalizeNeeds(job.needs),
|
|
110
|
+
uses: job.uses,
|
|
111
|
+
review: job.review || null,
|
|
112
|
+
'on-pass': job['on-pass'] || null,
|
|
113
|
+
'on-fail': job['on-fail'] || null,
|
|
114
|
+
with: job.with || null
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const summary = formatSummary(workflow, waves, steps);
|
|
119
|
+
return {
|
|
120
|
+
workflow: {
|
|
121
|
+
name: workflow.metadata && workflow.metadata.name,
|
|
122
|
+
version: workflow.metadata && workflow.metadata.version,
|
|
123
|
+
description: workflow.metadata && workflow.metadata.description
|
|
124
|
+
},
|
|
125
|
+
steps,
|
|
126
|
+
waves,
|
|
127
|
+
summary,
|
|
128
|
+
generatedAt: new Date().toISOString(),
|
|
129
|
+
context: ctx
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function extractAgent(uses) {
|
|
134
|
+
if (!uses) return null;
|
|
135
|
+
const m = String(uses).match(/^([a-z][a-z0-9-]*)/);
|
|
136
|
+
return m ? m[1] : uses;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function formatSummary(workflow, waves, steps) {
|
|
140
|
+
const lines = [];
|
|
141
|
+
lines.push(`Workflow: ${workflow.metadata && workflow.metadata.name} v${workflow.metadata && workflow.metadata.version}`);
|
|
142
|
+
if (workflow.metadata && workflow.metadata.description) {
|
|
143
|
+
lines.push(workflow.metadata.description.split('\n')[0]);
|
|
144
|
+
}
|
|
145
|
+
lines.push('');
|
|
146
|
+
lines.push(`Steps: ${steps.length} across ${waves.length} wave${waves.length === 1 ? '' : 's'}`);
|
|
147
|
+
lines.push('');
|
|
148
|
+
for (let i = 0; i < waves.length; i++) {
|
|
149
|
+
lines.push(`Wave ${i + 1}:`);
|
|
150
|
+
for (const jobKey of waves[i]) {
|
|
151
|
+
const step = steps.find(s => s.jobKey === jobKey);
|
|
152
|
+
const agent = step.agent || '(no agent)';
|
|
153
|
+
const tier = step.tier ? ` [${step.tier}]` : '';
|
|
154
|
+
lines.push(` - ${jobKey}${tier}: ${agent}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return lines.join('\n');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Write a plan to disk.
|
|
162
|
+
*/
|
|
163
|
+
function writePlan(projectRoot, runId, planObj) {
|
|
164
|
+
const dir = path.join(projectRoot, '.godpowers', 'runs', runId);
|
|
165
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
166
|
+
const file = path.join(dir, 'plan.yaml');
|
|
167
|
+
fs.writeFileSync(file, serializePlan(planObj));
|
|
168
|
+
return file;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function serializePlan(p) {
|
|
172
|
+
// YAML-ish hand-roll, paired with our minimal parser
|
|
173
|
+
const lines = [];
|
|
174
|
+
lines.push(`# Generated workflow plan`);
|
|
175
|
+
lines.push(`# Workflow: ${p.workflow.name} v${p.workflow.version}`);
|
|
176
|
+
lines.push(`# Generated: ${p.generatedAt}`);
|
|
177
|
+
lines.push('');
|
|
178
|
+
lines.push(`workflow: ${p.workflow.name}`);
|
|
179
|
+
lines.push(`version: ${p.workflow.version}`);
|
|
180
|
+
lines.push(`generated-at: ${p.generatedAt}`);
|
|
181
|
+
lines.push(`step-count: ${p.steps.length}`);
|
|
182
|
+
lines.push(`wave-count: ${p.waves.length}`);
|
|
183
|
+
lines.push('');
|
|
184
|
+
lines.push('waves:');
|
|
185
|
+
for (let i = 0; i < p.waves.length; i++) {
|
|
186
|
+
lines.push(` - index: ${i + 1}`);
|
|
187
|
+
lines.push(' steps:');
|
|
188
|
+
for (const jobKey of p.waves[i]) {
|
|
189
|
+
const step = p.steps.find(s => s.jobKey === jobKey);
|
|
190
|
+
lines.push(` - jobKey: ${jobKey}`);
|
|
191
|
+
if (step.tier) lines.push(` tier: ${step.tier}`);
|
|
192
|
+
if (step.agent) lines.push(` agent: ${step.agent}`);
|
|
193
|
+
if (step.uses) lines.push(` uses: ${step.uses}`);
|
|
194
|
+
if (step.needs && step.needs.length) {
|
|
195
|
+
lines.push(` needs: [${step.needs.join(', ')}]`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
lines.push('');
|
|
200
|
+
lines.push('summary: |');
|
|
201
|
+
for (const l of (p.summary || '').split('\n')) {
|
|
202
|
+
lines.push(` ${l}`);
|
|
203
|
+
}
|
|
204
|
+
return lines.join('\n') + '\n';
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function readPlan(projectRoot, runId) {
|
|
208
|
+
const file = path.join(projectRoot, '.godpowers', 'runs', runId, 'plan.yaml');
|
|
209
|
+
if (!fs.existsSync(file)) return null;
|
|
210
|
+
return fs.readFileSync(file, 'utf8');
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
module.exports = {
|
|
214
|
+
workflowsDir,
|
|
215
|
+
listWorkflows,
|
|
216
|
+
loadByName,
|
|
217
|
+
plan,
|
|
218
|
+
writePlan,
|
|
219
|
+
readPlan,
|
|
220
|
+
serializePlan
|
|
221
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "godpowers",
|
|
3
|
+
"version": "0.15.0",
|
|
4
|
+
"description": "Ship fast. Ship right. Ship everything. Ship accountably.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"godpowers": "./bin/install.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"test": "node scripts/validate-skills.js && bash scripts/smoke.sh && node scripts/test-runtime.js && node scripts/test-router.js && node scripts/test-recipes.js && node scripts/test-context-writer.js && node scripts/test-artifact-linter.js && node scripts/test-artifact-diff.js && node scripts/test-design-foundation.js && node scripts/test-linkage.js && node scripts/test-impact.js && node scripts/test-reverse-sync.js && node scripts/test-integration.js && node scripts/test-cross-artifact.js && node scripts/test-awesome-design.js && node scripts/test-skillui-bridge.js && node scripts/test-runtime-verification.js && node scripts/test-agent-browser.js && node scripts/test-mode-d.js && node scripts/test-runtime-heuristics.js && node scripts/test-agent-validator.js && node scripts/test-story-validator.js && node scripts/test-state.js && node scripts/test-intent.js && node scripts/test-events.js && node scripts/test-golden-artifacts.js && node scripts/test-install-smoke.js && node scripts/test-checkpoint.js && node scripts/test-extensions.js && node scripts/test-event-reader.js && node scripts/test-state-lock.js && node scripts/test-cost-saver.js && node scripts/test-budget-onoff.js && node scripts/test-workflow-runner.js && node scripts/test-otel-exporter.js && node scripts/test-extensions-publish.js",
|
|
10
|
+
"prepublishOnly": "npm test",
|
|
11
|
+
"validate-skills": "node scripts/validate-skills.js",
|
|
12
|
+
"smoke": "bash scripts/smoke.sh",
|
|
13
|
+
"test:runtime": "node scripts/test-runtime.js",
|
|
14
|
+
"test:router": "node scripts/test-router.js",
|
|
15
|
+
"test:recipes": "node scripts/test-recipes.js",
|
|
16
|
+
"test:context": "node scripts/test-context-writer.js",
|
|
17
|
+
"test:linter": "node scripts/test-artifact-linter.js",
|
|
18
|
+
"test:diff": "node scripts/test-artifact-diff.js"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"ai",
|
|
22
|
+
"coding",
|
|
23
|
+
"agent",
|
|
24
|
+
"claude",
|
|
25
|
+
"codex",
|
|
26
|
+
"cursor",
|
|
27
|
+
"tdd",
|
|
28
|
+
"orchestration",
|
|
29
|
+
"godmode",
|
|
30
|
+
"slash-commands"
|
|
31
|
+
],
|
|
32
|
+
"author": "Godpowers",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18.0.0"
|
|
36
|
+
},
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/aihxp/godpowers.git"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/aihxp/godpowers#readme",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/aihxp/godpowers/issues"
|
|
44
|
+
},
|
|
45
|
+
"files": [
|
|
46
|
+
"bin/",
|
|
47
|
+
"skills/",
|
|
48
|
+
"agents/",
|
|
49
|
+
"hooks/",
|
|
50
|
+
"templates/",
|
|
51
|
+
"references/",
|
|
52
|
+
"routing/",
|
|
53
|
+
"workflows/",
|
|
54
|
+
"schema/",
|
|
55
|
+
"lib/",
|
|
56
|
+
"extensions/",
|
|
57
|
+
"INSPIRATION.md",
|
|
58
|
+
"SKILL.md",
|
|
59
|
+
"AGENTS.md",
|
|
60
|
+
"CHANGELOG.md",
|
|
61
|
+
"LICENSE"
|
|
62
|
+
]
|
|
63
|
+
}
|