godpowers 2.3.0 → 2.3.1
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/CHANGELOG.md +32 -0
- package/README.md +16 -16
- package/RELEASE.md +30 -13
- package/agents/god-debugger.md +44 -8
- package/agents/god-executor.md +28 -0
- package/agents/god-quality-reviewer.md +23 -1
- package/agents/god-spec-reviewer.md +6 -0
- package/lib/README.md +2 -1
- package/lib/agent-cache.js +25 -3
- package/lib/code-intelligence.js +161 -0
- package/lib/dashboard.js +54 -20
- package/lib/extensions.js +6 -13
- package/lib/feature-awareness.js +1 -1
- package/lib/host-capabilities.js +4 -0
- package/lib/install-profiles.js +1 -0
- package/lib/planning-systems.js +7 -4
- package/lib/quick-proof.js +5 -2
- package/lib/route-quality-sync.js +2 -0
- package/package.json +2 -2
- package/routing/god-extension-scaffold.yaml +25 -0
- package/routing/god-stack.yaml +1 -1
- package/routing/recipes/add-feature-mid-arc-pause.yaml +6 -0
- package/routing/recipes/brownfield-onboarding.yaml +5 -2
- package/routing/recipes/extension-authoring.yaml +32 -0
- package/routing/recipes/greenfield-fast.yaml +3 -0
- package/routing/recipes/production-broken.yaml +4 -0
- package/routing/recipes/release-maintenance.yaml +3 -0
- package/routing/recipes/returning-after-break.yaml +3 -0
- package/routing/recipes/weekly-health-check.yaml +2 -0
- package/skills/god-discuss.md +10 -5
- package/skills/god-doctor.md +8 -2
- package/skills/god-extension-scaffold.md +66 -0
- package/skills/god-version.md +2 -2
- package/skills/god.md +8 -11
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.3.1] - 2026-06-08
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Added `/god-extension-scaffold` as the slash-command entry point for
|
|
14
|
+
extension pack authoring, with routing metadata, installer profile coverage,
|
|
15
|
+
package payload checks, and front-door recipe coverage.
|
|
16
|
+
- Added code-intelligence host capability detection for optional `ast-grep`,
|
|
17
|
+
`sg`, and LSP tooling without downgrading baseline host guarantees when those
|
|
18
|
+
tools are absent.
|
|
19
|
+
- Added public starter-path regression checks that verify README and Quick
|
|
20
|
+
Proof goal labels resolve through shipped `/god` recipes and routes.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- Updated public surface counts to 112 slash commands and 42 intent recipes
|
|
24
|
+
across release notes, reference docs, architecture maps, package metadata,
|
|
25
|
+
and project Pillars.
|
|
26
|
+
- Tightened public front-door recipe matching for starter phrases including
|
|
27
|
+
"start a product", "add a feature", "fix production", "maintain health",
|
|
28
|
+
"audit an existing repo", "ship a release", and extension authoring.
|
|
29
|
+
- Aligned the brownfield onboarding recipe to audit reconstructed artifacts
|
|
30
|
+
before tech-debt prioritization.
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
- Prevented maintainer-repository documentation drift from leaking into normal
|
|
34
|
+
user project dashboards.
|
|
35
|
+
- Corrected Quick Proof output so fixture-backed checks render
|
|
36
|
+
`--project=.` for the user project path.
|
|
37
|
+
- Hardened extension install, planning-system detection, and agent-cache cleanup
|
|
38
|
+
around symlinked directories that point outside the trusted source tree.
|
|
39
|
+
- Removed phantom `god-*` examples from the extension scaffold skill prose so
|
|
40
|
+
agent-reference validation stays clean.
|
|
41
|
+
|
|
10
42
|
## [2.3.0] - 2026-05-30
|
|
11
43
|
|
|
12
44
|
### Added
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/aihxp/godpowers/actions/workflows/ci.yml)
|
|
4
4
|
[](LICENSE)
|
|
5
|
-
[](CHANGELOG.md)
|
|
6
6
|
[](https://www.npmjs.com/package/godpowers)
|
|
7
7
|
|
|
8
8
|
**Ship fast. Ship right. Ship everything. Ship accountably.**
|
|
@@ -21,15 +21,15 @@ Godpowers makes AI coding accountable: every serious run should leave disk
|
|
|
21
21
|
state, artifacts, validation gates, host guarantees, and a next action. Code is
|
|
22
22
|
only one output. The project memory and proof trail matter too.
|
|
23
23
|
|
|
24
|
-
Version 2.3.
|
|
25
|
-
hardening.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
Version 2.3.1 keeps the proof loop executable and adds release-surface
|
|
25
|
+
hardening. Extension authors get `/god-extension-scaffold`, public starter
|
|
26
|
+
paths are regression-tested against the actual router, host capability reports
|
|
27
|
+
include optional code-intelligence tooling, clean user dashboards avoid
|
|
28
|
+
maintainer-repo drift, and symlink handling is hardened across extension,
|
|
29
|
+
planning-system, and cache paths.
|
|
30
30
|
|
|
31
|
-
Maintainer hardening continues on the 2.x line
|
|
32
|
-
|
|
31
|
+
Maintainer hardening continues on the 2.x line with small, audited public
|
|
32
|
+
surface updates when they close real workflow gaps. The 2.1.0 patch closes a command-injection vector in the
|
|
33
33
|
agent-browser driver, guards runtime file parsing against corrupt state,
|
|
34
34
|
makes data-directory installs a clean replace, and reconciles documentation
|
|
35
35
|
drift. The 2.0.3 patch range-checks workflow agent references,
|
|
@@ -187,13 +187,13 @@ learn the next command when Godpowers recommends it.
|
|
|
187
187
|
|
|
188
188
|
| Goal | Starter path |
|
|
189
189
|
|---|---|
|
|
190
|
-
| Start a product | `/god-init`, `/god-prd`, `/god-design`, `/god-arch`, `/god-roadmap`, `/god-stack`, `/god-build` |
|
|
191
|
-
| Add a feature | `/god-
|
|
192
|
-
| Fix production | `/god-hotfix`, `/god-
|
|
193
|
-
| Audit an existing repo | `/god-preflight`, `/god-
|
|
194
|
-
| Ship a release | `/god-
|
|
190
|
+
| Start a product | `/god-init`, `/god-prd`, `/god-design`, `/god-arch`, `/god-roadmap`, `/god-stack`, `/god-repo`, `/god-build` |
|
|
191
|
+
| Add a feature | `/god-reconcile`, `/god-feature`, `/god-sync`, `/god-review` |
|
|
192
|
+
| Fix production | `/god-hotfix`, `/god-postmortem`, `/god-status` |
|
|
193
|
+
| Audit an existing repo | `/god-preflight`, `/god-archaeology`, `/god-reconstruct`, `/god-audit`, `/god-tech-debt` |
|
|
194
|
+
| Ship a release | `/god-sync`, `/god-docs`, `/god-version`, `/god-automation-setup`, `npm run release:check` |
|
|
195
195
|
| Maintain project health | `/god-hygiene`, `/god-update-deps`, `/god-docs`, `/god-check-todos` |
|
|
196
|
-
| Extend Godpowers | `/god-extension-
|
|
196
|
+
| Extend Godpowers | `/god-extension-scaffold --name=@godpowers/my-pack --output=.`, `/god-test-extension`, `/god-extension-add`, `/god-extension-list` |
|
|
197
197
|
|
|
198
198
|
The same status engine is available from the installer CLI for humans, CI,
|
|
199
199
|
Codex, Claude, Cursor, Gemini, OpenCode, Windsurf, Antigravity, and any host
|
|
@@ -498,7 +498,7 @@ Pi. T3 Code inherits from the underlying agent (Codex / Claude / OpenCode).
|
|
|
498
498
|
- [Getting Started](docs/getting-started.md)
|
|
499
499
|
- [Quick Proof](docs/quick-proof.md)
|
|
500
500
|
- [Concepts](docs/concepts.md)
|
|
501
|
-
- [Command reference (all
|
|
501
|
+
- [Command reference (all 112 skills + 40 agents)](docs/reference.md)
|
|
502
502
|
- [Feature awareness](docs/feature-awareness.md)
|
|
503
503
|
- [Adoption Canary](docs/adoption-canary.md)
|
|
504
504
|
- [Repository documentation sync](docs/repo-doc-sync.md)
|
package/RELEASE.md
CHANGED
|
@@ -1,22 +1,35 @@
|
|
|
1
|
-
# Godpowers 2.3.
|
|
1
|
+
# Godpowers 2.3.1 Release
|
|
2
2
|
|
|
3
|
-
> Status: Ready for
|
|
4
|
-
> Date: 2026-
|
|
3
|
+
> Status: Ready for package verification
|
|
4
|
+
> Date: 2026-06-08
|
|
5
5
|
|
|
6
|
-
Godpowers 2.3.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
Godpowers 2.3.1 is an accountability and release-surface hardening release for
|
|
7
|
+
the 2.x line. It strengthens planning grounding, package legitimacy, install
|
|
8
|
+
profiles, atomic persistence, executor recovery, extension authoring,
|
|
9
|
+
front-door route coverage, host capability reporting, and dashboard behavior.
|
|
10
10
|
|
|
11
11
|
## What's in this release
|
|
12
12
|
|
|
13
|
-
-
|
|
13
|
+
- 112 slash commands
|
|
14
14
|
- 40 specialist agents
|
|
15
15
|
- 13 executable workflows
|
|
16
|
-
-
|
|
16
|
+
- 42 intent recipes
|
|
17
17
|
|
|
18
18
|
## Highlights
|
|
19
19
|
|
|
20
|
+
- `/god-extension-scaffold` gives extension authors a first-class
|
|
21
|
+
slash-command path before `/god-test-extension` and `/god-extension-add`.
|
|
22
|
+
- Public `/god` intent matching now covers the starter phrases users are most
|
|
23
|
+
likely to type: start a product, add a feature, fix production, audit an
|
|
24
|
+
existing repo, ship a release, maintain health, and extend Godpowers.
|
|
25
|
+
- Quick Proof and README starter paths are now regression-tested against the
|
|
26
|
+
actual router and recipe engine.
|
|
27
|
+
- User project dashboards no longer show maintainer-repository documentation
|
|
28
|
+
drift when a clean non-Godpowers project is inspected.
|
|
29
|
+
- Host capability reporting now includes optional code-intelligence tooling
|
|
30
|
+
without treating missing optional tools as a host degradation.
|
|
31
|
+
- Extension install, planning-system detection, and agent-cache cleanup are
|
|
32
|
+
hardened around symlinked paths that point outside trusted source trees.
|
|
20
33
|
- Source-grounded planning records existing files, existing symbols, planned new
|
|
21
34
|
artifacts, and unchecked references before build execution.
|
|
22
35
|
- Package legitimacy checks give stack and dependency decisions a concrete npm
|
|
@@ -29,23 +42,27 @@ executor recovery.
|
|
|
29
42
|
decompose, prune, or escalate.
|
|
30
43
|
- Public migration language now uses neutral legacy-planning terminology so
|
|
31
44
|
Godpowers is not confused with external workflow products.
|
|
45
|
+
- Architecture docs now include an executable audit map for disconnected
|
|
46
|
+
commands, actions, workflows, recipes, and package surfaces.
|
|
32
47
|
|
|
33
48
|
## Validation
|
|
34
49
|
|
|
35
50
|
- `npm test` green across the full suite
|
|
36
51
|
- `npm run lint` clean
|
|
37
52
|
- `npm run release:check` green (tests, audit, package contents)
|
|
53
|
+
- `npm pack` creates a local `godpowers-2.3.1.tgz` tarball for package
|
|
54
|
+
inspection
|
|
38
55
|
|
|
39
56
|
## Upgrade
|
|
40
57
|
|
|
41
|
-
- `npm install -g godpowers@2.3.
|
|
58
|
+
- `npm install -g godpowers@2.3.1` or `npx godpowers@2.3.1`
|
|
42
59
|
- Re-run `/god-context` in each project to refresh installed runtime metadata
|
|
43
60
|
- No breaking changes; existing `.godpowers/` state is compatible. Users who
|
|
44
61
|
want a compact install can run `npx godpowers --profile=core`.
|
|
45
62
|
|
|
46
63
|
## Notes
|
|
47
64
|
|
|
48
|
-
- GitHub release creation for `v2.3.
|
|
65
|
+
- GitHub release creation for `v2.3.1`
|
|
49
66
|
- The tag should match the npm package version
|
|
50
|
-
- The `v2.3.
|
|
51
|
-
`godpowers@2.3.
|
|
67
|
+
- The `v2.3.1` tag should point to the release commit that matches the npm
|
|
68
|
+
`godpowers@2.3.1` package.
|
package/agents/god-debugger.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: god-debugger
|
|
3
3
|
description: |
|
|
4
|
-
Systematic
|
|
5
|
-
guess-and-check. Evidence-driven root cause analysis with
|
|
4
|
+
Systematic debugger: Observe, Minimize, Instrument, Hypothesize, Test,
|
|
5
|
+
Conclude. No guess-and-check. Evidence-driven root cause analysis with
|
|
6
|
+
regression tests.
|
|
6
7
|
|
|
7
8
|
Spawned by: /god-debug, when build encounters failures
|
|
8
9
|
tools: Read, Edit, Bash, Grep, Glob, WebSearch
|
|
@@ -22,10 +23,44 @@ Gather evidence before forming any hypothesis:
|
|
|
22
23
|
- Can you reproduce it RELIABLY? (if not, find a reliable repro first)
|
|
23
24
|
- All error messages, stack traces, logs (full text, not paraphrased)
|
|
24
25
|
- What is NOT happening that should be? (sometimes the silence is the clue)
|
|
26
|
+
- When available, use `ast-grep`, `sg`, or LSP diagnostics/references to
|
|
27
|
+
narrow impacted symbols before forming a hypothesis.
|
|
25
28
|
|
|
26
29
|
Output an observation document. Don't proceed until observations are complete.
|
|
27
30
|
|
|
28
|
-
## Phase 2:
|
|
31
|
+
## Phase 2: Minimize
|
|
32
|
+
|
|
33
|
+
Reduce the failure to the smallest reliable reproduction before proposing a
|
|
34
|
+
root cause:
|
|
35
|
+
|
|
36
|
+
- Remove unrelated inputs, branches, services, files, data, and timing from the
|
|
37
|
+
reproduction while keeping the failure present.
|
|
38
|
+
- Identify the smallest command, test, request, or user flow that still fails.
|
|
39
|
+
- Record the exact boundary where removing one more thing makes the failure
|
|
40
|
+
disappear.
|
|
41
|
+
- If minimization is impossible, record why and name the remaining broad
|
|
42
|
+
dependency that keeps the repro large.
|
|
43
|
+
|
|
44
|
+
Do not proceed until the minimized reproduction is clear enough that another
|
|
45
|
+
agent could rerun it without guessing.
|
|
46
|
+
|
|
47
|
+
## Phase 3: Instrument
|
|
48
|
+
|
|
49
|
+
Add or use focused evidence probes before forming a hypothesis:
|
|
50
|
+
|
|
51
|
+
- Prefer existing logs, traces, diagnostics, failing assertions, and debugger
|
|
52
|
+
output when they already expose the state transition.
|
|
53
|
+
- Add temporary probes only when they answer a specific question, then remove
|
|
54
|
+
them before the final fix unless they become a useful permanent test or log.
|
|
55
|
+
- Instrument the boundary between expected and actual behavior, not every
|
|
56
|
+
nearby function.
|
|
57
|
+
- Capture the observed values and the point where reality diverges from the
|
|
58
|
+
expected path.
|
|
59
|
+
|
|
60
|
+
Do not proceed until the instrumentation either narrows the failure boundary or
|
|
61
|
+
proves that more observation is needed.
|
|
62
|
+
|
|
63
|
+
## Phase 4: Hypothesize
|
|
29
64
|
|
|
30
65
|
Based on observations, list 2-3 most likely root causes:
|
|
31
66
|
|
|
@@ -35,7 +70,7 @@ For each hypothesis:
|
|
|
35
70
|
- What evidence would REFUTE this hypothesis?
|
|
36
71
|
- Rank by probability (1-10) with rationale
|
|
37
72
|
|
|
38
|
-
## Phase
|
|
73
|
+
## Phase 5: Test
|
|
39
74
|
|
|
40
75
|
Take the highest-probability hypothesis. Design a SPECIFIC test:
|
|
41
76
|
- The test should produce different evidence depending on which hypothesis is true
|
|
@@ -43,11 +78,12 @@ Take the highest-probability hypothesis. Design a SPECIFIC test:
|
|
|
43
78
|
- Record the evidence
|
|
44
79
|
- Compare to predicted outcomes
|
|
45
80
|
|
|
46
|
-
If hypothesis confirmed: proceed to Phase
|
|
81
|
+
If hypothesis confirmed: proceed to Phase 6.
|
|
47
82
|
If hypothesis refuted: cross it off, move to next hypothesis.
|
|
48
|
-
If all hypotheses refuted: return to Phase 1,
|
|
83
|
+
If all hypotheses refuted: return to Phase 1, then revisit minimization and
|
|
84
|
+
instrumentation with the new evidence.
|
|
49
85
|
|
|
50
|
-
## Phase
|
|
86
|
+
## Phase 6: Conclude (Fix and Verify)
|
|
51
87
|
|
|
52
88
|
1. **Write the regression test FIRST**
|
|
53
89
|
- The test should reproduce the bug
|
|
@@ -74,4 +110,4 @@ If all hypotheses refuted: return to Phase 1, expand observation scope.
|
|
|
74
110
|
- **Never apply multiple fixes at once** (can't tell which one worked)
|
|
75
111
|
- **Always write the regression test first** (locks in the contract)
|
|
76
112
|
- **If the bug is in a dependency**: document the workaround, file upstream, link in commit
|
|
77
|
-
- **Time-boxing**: if Phase 1-
|
|
113
|
+
- **Time-boxing**: if Phase 1-5 takes >2 hours with no progress, ask for help (the observations are likely incomplete)
|
package/agents/god-executor.md
CHANGED
|
@@ -96,6 +96,34 @@ Every changed line must trace back to that contract, the failing test, or a
|
|
|
96
96
|
cleanup created by your own change. If you cannot explain the trace, revert
|
|
97
97
|
that line before returning control to the orchestrator.
|
|
98
98
|
|
|
99
|
+
## Optional Style Profile
|
|
100
|
+
|
|
101
|
+
If `CODEDNA.md` exists at the project root or appears in the provided context
|
|
102
|
+
loadout, read it before editing:
|
|
103
|
+
- Match the repo's naming, file organization, comment density, extraction
|
|
104
|
+
threshold, error handling style, and test idioms when they do not conflict
|
|
105
|
+
with the slice plan.
|
|
106
|
+
- Treat formatter, linter, tests, and explicit project conventions as
|
|
107
|
+
higher-priority evidence when they conflict with the profile.
|
|
108
|
+
- Do not invent or generate a `CODEDNA.md` profile in executor scope.
|
|
109
|
+
- If no profile exists, continue by matching the surrounding code directly.
|
|
110
|
+
- Preserve required `// Implements: P-...` annotations even when the profile
|
|
111
|
+
prefers fewer comments.
|
|
112
|
+
|
|
113
|
+
## Optional Code Intelligence
|
|
114
|
+
|
|
115
|
+
When host capabilities or local probing report `ast-grep`, `sg`, or LSP tools:
|
|
116
|
+
- Use `ast-grep` or `sg` for structural search before broad text rewrites.
|
|
117
|
+
- Use LSP diagnostics, definitions, references, or rename support when the
|
|
118
|
+
host exposes them for the touched language.
|
|
119
|
+
- Treat these tools as evidence helpers, not authority. Tests, source
|
|
120
|
+
grounding, and request trace still decide whether the slice is complete.
|
|
121
|
+
- Record the tool only when it shaped file selection, rewrite scope, or a
|
|
122
|
+
repair decision.
|
|
123
|
+
|
|
124
|
+
If optional code intelligence is unavailable, continue with Grep, Glob, and
|
|
125
|
+
Bash evidence. Absence of these tools is not a blocker.
|
|
126
|
+
|
|
99
127
|
## After All Behaviors Complete
|
|
100
128
|
|
|
101
129
|
1. Run the full test suite. All tests must pass.
|
|
@@ -63,6 +63,26 @@ Your job: would you ship this code in production?
|
|
|
63
63
|
- Flag missing or inaccurate annotations: the deliverable ledger derives
|
|
64
64
|
requirement status from them, so a gap here understates delivered work
|
|
65
65
|
|
|
66
|
+
### 8. Comment Quality and Style Fidelity
|
|
67
|
+
- Required traceability comments such as `// Implements: P-...` remain present
|
|
68
|
+
and accurate.
|
|
69
|
+
- Comments explain non-obvious why, constraints, hazards, or tradeoffs. Flag
|
|
70
|
+
comments that narrate obvious code, duplicate names, go stale, or use generic
|
|
71
|
+
AI-assistant prose.
|
|
72
|
+
- Avoid decorative section banners or chatty explanation unless the surrounding
|
|
73
|
+
codebase already uses that convention.
|
|
74
|
+
- If `CODEDNA.md` exists, compare naming, comment voice, extraction threshold,
|
|
75
|
+
error style, test style, and common idioms against the profile.
|
|
76
|
+
- Absence of `CODEDNA.md` is not a failure. When no profile exists, judge style
|
|
77
|
+
against nearby code and repository conventions.
|
|
78
|
+
|
|
79
|
+
### 9. Optional Code Intelligence
|
|
80
|
+
- When `ast-grep`, `sg`, or LSP tools are available, use them to support
|
|
81
|
+
maintainability review for structural matches, impacted references, or
|
|
82
|
+
diagnostics that plain grep can miss.
|
|
83
|
+
- Absence of these tools is not a failure. Treat them as extra evidence when
|
|
84
|
+
present.
|
|
85
|
+
|
|
66
86
|
## Output
|
|
67
87
|
|
|
68
88
|
Return verdict to orchestrator:
|
|
@@ -78,6 +98,8 @@ Return verdict to orchestrator:
|
|
|
78
98
|
- [PASS/FAIL] Maintainability: [evidence]
|
|
79
99
|
- [PASS/FAIL] Simplicity and surgicality: [evidence]
|
|
80
100
|
- [PASS/FAIL] Requirement traceability: [evidence]
|
|
101
|
+
- [PASS/FAIL] Comment quality and style fidelity: [evidence]
|
|
102
|
+
- [PASS/FAIL] Optional code intelligence: [evidence or not applicable]
|
|
81
103
|
|
|
82
104
|
### Verdict: PASS / FAIL
|
|
83
105
|
|
|
@@ -86,7 +108,7 @@ Return verdict to orchestrator:
|
|
|
86
108
|
|
|
87
109
|
## Pass Criteria
|
|
88
110
|
|
|
89
|
-
ALL
|
|
111
|
+
ALL nine dimensions must PASS. Any FAIL blocks the commit.
|
|
90
112
|
|
|
91
113
|
If FAIL: orchestrator returns the slice to god-executor.
|
|
92
114
|
If PASS: orchestrator commits the slice atomically.
|
|
@@ -65,6 +65,12 @@ Answer each with EVIDENCE from the code:
|
|
|
65
65
|
- If the slice added a dependency, is there package legitimacy evidence or
|
|
66
66
|
an explicit accepted-risk note?
|
|
67
67
|
|
|
68
|
+
8. **Did available code intelligence support the review?**
|
|
69
|
+
- If `ast-grep`, `sg`, or LSP tools are available, use them to verify
|
|
70
|
+
impacted references, structural matches, or diagnostics for the touched
|
|
71
|
+
language when relevant.
|
|
72
|
+
- If unavailable or irrelevant, do not fail the slice for absence alone.
|
|
73
|
+
|
|
68
74
|
## Output
|
|
69
75
|
|
|
70
76
|
Return verdict to orchestrator:
|
package/lib/README.md
CHANGED
|
@@ -13,7 +13,8 @@ package-level integrations.
|
|
|
13
13
|
| `intent.js` | Read and validate `intent.yaml` from project roots or `.godpowers/`. |
|
|
14
14
|
| `checkpoint.js` | Create and inspect resumable checkpoint artifacts. |
|
|
15
15
|
| `feature-awareness.js` | Detect and refresh existing-project awareness after runtime upgrades. |
|
|
16
|
-
| `
|
|
16
|
+
| `code-intelligence.js` | Detect optional `ast-grep`, `sg`, and LSP tooling for structural search, rewrite, and diagnostics guidance. |
|
|
17
|
+
| `host-capabilities.js` | Detect host guarantees for shell, git, npm, agent spawning, optional code intelligence, extension authoring, and suite dry-runs. |
|
|
17
18
|
| `repo-doc-sync.js` | Detect and refresh mechanical repository documentation surfaces. |
|
|
18
19
|
| `repo-surface-sync.js` | Detect structural drift across commands, routes, packages, agents, workflows, recipes, extensions, and release policy. |
|
|
19
20
|
| `route-quality-sync.js` | Detect symbolic route spawns, unresolved agent targets, and unapproved contextual route exits. |
|
package/lib/agent-cache.js
CHANGED
|
@@ -134,9 +134,29 @@ function clear(projectRoot, opts = {}) {
|
|
|
134
134
|
const now = Date.now();
|
|
135
135
|
for (const shard of fs.readdirSync(dir)) {
|
|
136
136
|
const shardPath = path.join(dir, shard);
|
|
137
|
-
|
|
137
|
+
const shardStat = fs.lstatSync(shardPath);
|
|
138
|
+
if (shardStat.isSymbolicLink()) {
|
|
139
|
+
if (opts.all) {
|
|
140
|
+
fs.unlinkSync(shardPath);
|
|
141
|
+
removed++;
|
|
142
|
+
} else {
|
|
143
|
+
kept++;
|
|
144
|
+
}
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (!shardStat.isDirectory()) continue;
|
|
138
148
|
for (const fname of fs.readdirSync(shardPath)) {
|
|
139
149
|
const fpath = path.join(shardPath, fname);
|
|
150
|
+
const fileStat = fs.lstatSync(fpath);
|
|
151
|
+
if (fileStat.isSymbolicLink()) {
|
|
152
|
+
if (opts.all) { fs.unlinkSync(fpath); removed++; }
|
|
153
|
+
else { kept++; }
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
if (!fileStat.isFile()) {
|
|
157
|
+
kept++;
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
140
160
|
let entry;
|
|
141
161
|
try { entry = JSON.parse(fs.readFileSync(fpath, 'utf8')); }
|
|
142
162
|
catch (e) {
|
|
@@ -173,10 +193,12 @@ function stats(projectRoot) {
|
|
|
173
193
|
let oldestTs = null;
|
|
174
194
|
for (const shard of fs.readdirSync(dir)) {
|
|
175
195
|
const shardPath = path.join(dir, shard);
|
|
176
|
-
|
|
196
|
+
const shardStat = fs.lstatSync(shardPath);
|
|
197
|
+
if (shardStat.isSymbolicLink() || !shardStat.isDirectory()) continue;
|
|
177
198
|
for (const fname of fs.readdirSync(shardPath)) {
|
|
178
199
|
const fpath = path.join(shardPath, fname);
|
|
179
|
-
const stat = fs.
|
|
200
|
+
const stat = fs.lstatSync(fpath);
|
|
201
|
+
if (stat.isSymbolicLink() || !stat.isFile()) continue;
|
|
180
202
|
totalBytes += stat.size;
|
|
181
203
|
count += 1;
|
|
182
204
|
try {
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional code intelligence capability detection.
|
|
3
|
+
*
|
|
4
|
+
* These tools sharpen refactors and reviews when present, but Godpowers must
|
|
5
|
+
* keep working through grep-backed workflows when they are absent.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const cp = require('child_process');
|
|
9
|
+
|
|
10
|
+
const AST_GREP_CANDIDATES = [
|
|
11
|
+
{ id: 'ast-grep', command: 'ast-grep', args: ['--version'], match: /ast-grep/i },
|
|
12
|
+
{ id: 'sg', command: 'sg', args: ['--version'], match: /\b(ast-grep|sg\s+\d)/i }
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const LSP_CANDIDATES = [
|
|
16
|
+
{ id: 'omo-lsp', command: 'omo-lsp', args: ['--version'], languages: ['multi'] },
|
|
17
|
+
{ id: 'typescript-language-server', command: 'typescript-language-server', args: ['--version'], languages: ['javascript', 'typescript'] },
|
|
18
|
+
{ id: 'vscode-json-language-server', command: 'vscode-json-language-server', args: ['--version'], languages: ['json'] },
|
|
19
|
+
{ id: 'yaml-language-server', command: 'yaml-language-server', args: ['--version'], languages: ['yaml'] },
|
|
20
|
+
{ id: 'pyright-langserver', command: 'pyright-langserver', args: ['--version'], languages: ['python'] },
|
|
21
|
+
{ id: 'pylsp', command: 'pylsp', args: ['--version'], languages: ['python'] },
|
|
22
|
+
{ id: 'gopls', command: 'gopls', args: ['version'], languages: ['go'] },
|
|
23
|
+
{ id: 'rust-analyzer', command: 'rust-analyzer', args: ['--version'], languages: ['rust'] },
|
|
24
|
+
{ id: 'clangd', command: 'clangd', args: ['--version'], languages: ['c', 'cpp'] },
|
|
25
|
+
{ id: 'jdtls', command: 'jdtls', args: ['--version'], languages: ['java'] },
|
|
26
|
+
{ id: 'ruby-lsp', command: 'ruby-lsp', args: ['--version'], languages: ['ruby'] },
|
|
27
|
+
{ id: 'solargraph', command: 'solargraph', args: ['--version'], languages: ['ruby'] },
|
|
28
|
+
{ id: 'terraform-ls', command: 'terraform-ls', args: ['version'], languages: ['terraform'] }
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
function firstLine(value) {
|
|
32
|
+
if (!value) return null;
|
|
33
|
+
const text = String(value).trim();
|
|
34
|
+
if (!text) return null;
|
|
35
|
+
return text.split(/\r?\n/)[0] || 'installed';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function commandVersion(command, args, opts = {}) {
|
|
39
|
+
try {
|
|
40
|
+
const out = cp.execFileSync(command, args, {
|
|
41
|
+
cwd: opts.cwd || process.cwd(),
|
|
42
|
+
encoding: 'utf8',
|
|
43
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
44
|
+
timeout: opts.timeout || 800
|
|
45
|
+
});
|
|
46
|
+
return firstLine(out) || 'installed';
|
|
47
|
+
} catch (err) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function checkCandidate(candidate, opts) {
|
|
53
|
+
const version = firstLine(opts.commandVersion(candidate.command, candidate.args, {
|
|
54
|
+
cwd: opts.cwd,
|
|
55
|
+
timeout: opts.timeout
|
|
56
|
+
}));
|
|
57
|
+
if (!version) return null;
|
|
58
|
+
if (candidate.match && !candidate.match.test(version)) return null;
|
|
59
|
+
return {
|
|
60
|
+
id: candidate.id,
|
|
61
|
+
command: candidate.command,
|
|
62
|
+
version,
|
|
63
|
+
languages: candidate.languages || []
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function detectFirst(candidates, opts) {
|
|
68
|
+
for (const candidate of candidates) {
|
|
69
|
+
const found = checkCandidate(candidate, opts);
|
|
70
|
+
if (found) return found;
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function detectAll(candidates, opts) {
|
|
76
|
+
const found = [];
|
|
77
|
+
const limit = opts.maxTools || 5;
|
|
78
|
+
for (const candidate of candidates) {
|
|
79
|
+
const result = checkCandidate(candidate, opts);
|
|
80
|
+
if (result) found.push(result);
|
|
81
|
+
if (found.length >= limit) break;
|
|
82
|
+
}
|
|
83
|
+
return found;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function detect(projectRoot, opts = {}) {
|
|
87
|
+
const root = projectRoot || process.cwd();
|
|
88
|
+
const probe = opts.commandVersion || commandVersion;
|
|
89
|
+
const probeOpts = {
|
|
90
|
+
cwd: root,
|
|
91
|
+
commandVersion: probe,
|
|
92
|
+
timeout: opts.timeout || 800,
|
|
93
|
+
maxTools: opts.maxTools || 5
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const astGrep = detectFirst(opts.astGrepCandidates || AST_GREP_CANDIDATES, probeOpts);
|
|
97
|
+
const lspTools = detectAll(opts.lspCandidates || LSP_CANDIDATES, probeOpts);
|
|
98
|
+
const gaps = [];
|
|
99
|
+
if (!astGrep) gaps.push('ast-grep not detected');
|
|
100
|
+
if (lspTools.length === 0) gaps.push('LSP tools not detected');
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
level: astGrep || lspTools.length > 0 ? 'available' : 'not-detected',
|
|
104
|
+
astGrep: astGrep
|
|
105
|
+
? { available: true, command: astGrep.command, version: astGrep.version }
|
|
106
|
+
: { available: false, command: null, version: null },
|
|
107
|
+
lsp: {
|
|
108
|
+
available: lspTools.length > 0,
|
|
109
|
+
primary: lspTools[0] || null,
|
|
110
|
+
tools: lspTools
|
|
111
|
+
},
|
|
112
|
+
gaps
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function lspSummary(lsp) {
|
|
117
|
+
if (!lsp || !lsp.available) return 'not detected';
|
|
118
|
+
return lsp.tools.map(tool => tool.command).join(', ');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function summary(report) {
|
|
122
|
+
if (!report) return 'not detected';
|
|
123
|
+
const parts = [];
|
|
124
|
+
if (report.astGrep && report.astGrep.available) {
|
|
125
|
+
parts.push(`ast-grep via ${report.astGrep.command}`);
|
|
126
|
+
}
|
|
127
|
+
if (report.lsp && report.lsp.available) {
|
|
128
|
+
parts.push(`LSP via ${lspSummary(report.lsp)}`);
|
|
129
|
+
}
|
|
130
|
+
return parts.length > 0 ? parts.join('; ') : 'not detected';
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function render(report) {
|
|
134
|
+
const ast = report && report.astGrep && report.astGrep.available
|
|
135
|
+
? `${report.astGrep.command} (${report.astGrep.version})`
|
|
136
|
+
: 'not detected';
|
|
137
|
+
const lsp = report && report.lsp && report.lsp.available
|
|
138
|
+
? lspSummary(report.lsp)
|
|
139
|
+
: 'not detected';
|
|
140
|
+
const gaps = report && report.gaps && report.gaps.length > 0
|
|
141
|
+
? report.gaps.join('; ')
|
|
142
|
+
: 'none';
|
|
143
|
+
return [
|
|
144
|
+
'Code intelligence:',
|
|
145
|
+
` Structural search: ${ast}`,
|
|
146
|
+
` LSP tools: ${lsp}`,
|
|
147
|
+
` Gaps: ${gaps}`
|
|
148
|
+
].join('\n');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
module.exports = {
|
|
152
|
+
detect,
|
|
153
|
+
summary,
|
|
154
|
+
render,
|
|
155
|
+
_private: {
|
|
156
|
+
AST_GREP_CANDIDATES,
|
|
157
|
+
LSP_CANDIDATES,
|
|
158
|
+
commandVersion,
|
|
159
|
+
firstLine
|
|
160
|
+
}
|
|
161
|
+
};
|
package/lib/dashboard.js
CHANGED
|
@@ -133,20 +133,43 @@ function hasRecentPath(projectRoot, relPath, maxAgeMs) {
|
|
|
133
133
|
return Date.now() - modified <= maxAgeMs;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
function
|
|
136
|
+
function isGodpowersRuntimeRepo(projectRoot) {
|
|
137
|
+
try {
|
|
138
|
+
const pkgPath = path.join(projectRoot, 'package.json');
|
|
139
|
+
if (!fs.existsSync(pkgPath)) return false;
|
|
140
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
141
|
+
return pkg.name === 'godpowers'
|
|
142
|
+
&& exists(projectRoot, 'skills')
|
|
143
|
+
&& exists(projectRoot, 'routing')
|
|
144
|
+
&& exists(projectRoot, 'agents');
|
|
145
|
+
} catch (e) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function proactiveChecks(projectRoot, changedFiles = [], opts = {}) {
|
|
137
151
|
const oneDay = 24 * 60 * 60 * 1000;
|
|
138
152
|
const thirtyDays = 30 * oneDay;
|
|
153
|
+
const initialized = opts.initialized !== false;
|
|
154
|
+
const runtimeRepo = opts.runtimeRepo !== undefined
|
|
155
|
+
? opts.runtimeRepo
|
|
156
|
+
: isGodpowersRuntimeRepo(projectRoot);
|
|
139
157
|
const reviews = reviewCount(projectRoot);
|
|
140
158
|
|
|
141
|
-
const checkpoint =
|
|
142
|
-
? (
|
|
143
|
-
|
|
159
|
+
const checkpoint = initialized
|
|
160
|
+
? (exists(projectRoot, CHECKPOINT_PATH)
|
|
161
|
+
? (hasRecentPath(projectRoot, CHECKPOINT_PATH, oneDay) ? 'fresh' : 'stale')
|
|
162
|
+
: 'missing')
|
|
163
|
+
: 'not-applicable';
|
|
144
164
|
|
|
145
|
-
const sync =
|
|
146
|
-
? (
|
|
147
|
-
|
|
165
|
+
const sync = initialized
|
|
166
|
+
? (exists(projectRoot, SYNC_LOG_PATH)
|
|
167
|
+
? (hasRecentPath(projectRoot, SYNC_LOG_PATH, oneDay) ? 'fresh' : 'stale, suggest /god-sync')
|
|
168
|
+
: 'missing, suggest /god-sync')
|
|
169
|
+
: 'not-applicable';
|
|
148
170
|
|
|
149
|
-
const hygieneFresh =
|
|
171
|
+
const hygieneFresh = initialized
|
|
172
|
+
&& exists(projectRoot, CHECKPOINT_PATH)
|
|
150
173
|
&& hasRecentPath(projectRoot, CHECKPOINT_PATH, thirtyDays);
|
|
151
174
|
|
|
152
175
|
const pkgChanged = changedFiles.some(file => [
|
|
@@ -162,14 +185,22 @@ function proactiveChecks(projectRoot, changedFiles = []) {
|
|
|
162
185
|
'auth',
|
|
163
186
|
'security'
|
|
164
187
|
]));
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
:
|
|
188
|
+
const repoDocsStatus = runtimeRepo
|
|
189
|
+
? (() => {
|
|
190
|
+
const repoDocs = repoDocSync.detect(projectRoot, { changedFiles });
|
|
191
|
+
return repoDocs.status === 'fresh'
|
|
192
|
+
? 'fresh'
|
|
193
|
+
: `${repoDocs.stale.length} stale, suggest /god-docs`;
|
|
194
|
+
})()
|
|
195
|
+
: 'not-applicable';
|
|
196
|
+
const repoSurfaceStatus = runtimeRepo
|
|
197
|
+
? (() => {
|
|
198
|
+
const repoSurface = repoSurfaceSync.detect(projectRoot);
|
|
199
|
+
return repoSurface.status === 'fresh'
|
|
200
|
+
? 'fresh'
|
|
201
|
+
: `${repoSurface.stale.length} stale, suggest /god-doctor`;
|
|
202
|
+
})()
|
|
203
|
+
: 'not-applicable';
|
|
173
204
|
const host = hostCapabilities.detect(projectRoot);
|
|
174
205
|
|
|
175
206
|
return {
|
|
@@ -183,7 +214,7 @@ function proactiveChecks(projectRoot, changedFiles = []) {
|
|
|
183
214
|
automation: automationSummary(projectRoot),
|
|
184
215
|
security: sensitiveChanged ? 'sensitive files changed, suggest /god-harden' : 'clear',
|
|
185
216
|
dependencies: pkgChanged ? 'dependency files changed, suggest /god-update-deps' : 'clear',
|
|
186
|
-
hygiene: hygieneFresh ? 'fresh' : 'stale, suggest /god-hygiene'
|
|
217
|
+
hygiene: initialized ? (hygieneFresh ? 'fresh' : 'stale, suggest /god-hygiene') : 'not-applicable'
|
|
187
218
|
};
|
|
188
219
|
}
|
|
189
220
|
|
|
@@ -237,7 +268,7 @@ function compute(projectRoot, opts = {}) {
|
|
|
237
268
|
completion: '0% workflow progress because .godpowers/state.json is missing',
|
|
238
269
|
completionBasis: 'missing .godpowers/state.json'
|
|
239
270
|
},
|
|
240
|
-
proactive: proactiveChecks(projectRoot, git.entries.map(statusPath)),
|
|
271
|
+
proactive: proactiveChecks(projectRoot, git.entries.map(statusPath), { initialized: false }),
|
|
241
272
|
host: hostCapabilities.detect(projectRoot, opts.host || {}),
|
|
242
273
|
next,
|
|
243
274
|
deliverables: { hasRequirements: false },
|
|
@@ -276,7 +307,7 @@ function compute(projectRoot, opts = {}) {
|
|
|
276
307
|
worktree: git.worktree,
|
|
277
308
|
index: git.index,
|
|
278
309
|
planning: planningVisibility(projectRoot, progress),
|
|
279
|
-
proactive: proactiveChecks(projectRoot, git.entries.map(statusPath)),
|
|
310
|
+
proactive: proactiveChecks(projectRoot, git.entries.map(statusPath), { initialized: true }),
|
|
280
311
|
host: hostCapabilities.detect(projectRoot, opts.host || {}),
|
|
281
312
|
next,
|
|
282
313
|
deliverables,
|
|
@@ -289,6 +320,7 @@ function compute(projectRoot, opts = {}) {
|
|
|
289
320
|
function actionBrief(dashboard) {
|
|
290
321
|
const proactive = dashboard.proactive || {};
|
|
291
322
|
const next = dashboard.next || {};
|
|
323
|
+
const recommended = next.command || 'describe the next intent';
|
|
292
324
|
const blockers = [];
|
|
293
325
|
for (const [label, value] of [
|
|
294
326
|
['Repo surface', proactive.repoSurface],
|
|
@@ -304,10 +336,11 @@ function actionBrief(dashboard) {
|
|
|
304
336
|
if (value === 'fresh' || value === 'none' || value === 'clear' || value === 'not-applicable') continue;
|
|
305
337
|
if (/^full on /.test(value)) continue;
|
|
306
338
|
if (/^available via /.test(value)) continue;
|
|
339
|
+
if (label === 'Sync' && recommended !== '/god-sync') continue;
|
|
340
|
+
if (label === 'Hygiene' && recommended !== '/god-hygiene') continue;
|
|
307
341
|
blockers.push(`${label}: ${value}`);
|
|
308
342
|
}
|
|
309
343
|
|
|
310
|
-
const recommended = next.command || 'describe the next intent';
|
|
311
344
|
return {
|
|
312
345
|
recommended,
|
|
313
346
|
reason: next.reason || 'No route was computed.',
|
|
@@ -414,6 +447,7 @@ module.exports = {
|
|
|
414
447
|
parseGitStatus,
|
|
415
448
|
proactiveChecks,
|
|
416
449
|
automationSummary,
|
|
450
|
+
isGodpowersRuntimeRepo,
|
|
417
451
|
actionBrief,
|
|
418
452
|
planningVisibility
|
|
419
453
|
};
|
package/lib/extensions.js
CHANGED
|
@@ -27,6 +27,7 @@ const fs = require('fs');
|
|
|
27
27
|
const path = require('path');
|
|
28
28
|
|
|
29
29
|
const intentLib = require('./intent'); // reuses parseSimpleYaml
|
|
30
|
+
const { copyRecursive } = require('./installer-files');
|
|
30
31
|
|
|
31
32
|
function extensionsDir(runtimeConfigDir) {
|
|
32
33
|
return path.join(runtimeConfigDir, 'godpowers-extensions');
|
|
@@ -159,11 +160,13 @@ function list(runtimeConfigDir) {
|
|
|
159
160
|
const results = [];
|
|
160
161
|
for (const scope of fs.readdirSync(dir)) {
|
|
161
162
|
const scopePath = path.join(dir, scope);
|
|
162
|
-
|
|
163
|
+
const scopeStat = fs.lstatSync(scopePath);
|
|
164
|
+
if (scopeStat.isSymbolicLink() || !scopeStat.isDirectory()) continue;
|
|
163
165
|
if (!scope.startsWith('@')) continue;
|
|
164
166
|
for (const name of fs.readdirSync(scopePath)) {
|
|
165
167
|
const packDir = path.join(scopePath, name);
|
|
166
|
-
|
|
168
|
+
const packStat = fs.lstatSync(packDir);
|
|
169
|
+
if (packStat.isSymbolicLink() || !packStat.isDirectory()) continue;
|
|
167
170
|
const manifestFile = path.join(packDir, 'manifest.yaml');
|
|
168
171
|
if (!fs.existsSync(manifestFile)) continue;
|
|
169
172
|
const { manifest } = parseManifest(fs.readFileSync(manifestFile, 'utf8'));
|
|
@@ -220,22 +223,12 @@ function install(runtimeConfigDir, sourceDir, godpowersVersion) {
|
|
|
220
223
|
for (const sub of ['agents', 'skills', 'workflows', 'references']) {
|
|
221
224
|
const src = path.join(sourceDir, sub);
|
|
222
225
|
if (fs.existsSync(src)) {
|
|
223
|
-
|
|
226
|
+
copyRecursive(src, path.join(destDir, sub));
|
|
224
227
|
}
|
|
225
228
|
}
|
|
226
229
|
return { installed: true, path: destDir, manifest };
|
|
227
230
|
}
|
|
228
231
|
|
|
229
|
-
function copyDirRecursive(src, dest) {
|
|
230
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
231
|
-
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
232
|
-
const s = path.join(src, entry.name);
|
|
233
|
-
const d = path.join(dest, entry.name);
|
|
234
|
-
if (entry.isDirectory()) copyDirRecursive(s, d);
|
|
235
|
-
else fs.copyFileSync(s, d);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
232
|
/**
|
|
240
233
|
* Remove an installed extension by name.
|
|
241
234
|
*/
|
package/lib/feature-awareness.js
CHANGED
|
@@ -110,7 +110,7 @@ const FEATURES = [
|
|
|
110
110
|
{
|
|
111
111
|
id: 'extension-authoring',
|
|
112
112
|
since: '1.6.22',
|
|
113
|
-
commands: ['/god-extension-
|
|
113
|
+
commands: ['/god-extension-scaffold', '/god-test-extension', '/god-extension-add'],
|
|
114
114
|
description: 'Scaffold and validate publishable Godpowers extension packs.'
|
|
115
115
|
},
|
|
116
116
|
{
|
package/lib/host-capabilities.js
CHANGED
|
@@ -10,6 +10,7 @@ const fs = require('fs');
|
|
|
10
10
|
const path = require('path');
|
|
11
11
|
const os = require('os');
|
|
12
12
|
const cp = require('child_process');
|
|
13
|
+
const codeIntelligence = require('./code-intelligence');
|
|
13
14
|
|
|
14
15
|
function exists(filePath) {
|
|
15
16
|
return fs.existsSync(filePath);
|
|
@@ -55,6 +56,7 @@ function detect(projectRoot, opts = {}) {
|
|
|
55
56
|
const git = commandVersion('git', ['--version'], { cwd: root });
|
|
56
57
|
const npm = commandVersion('npm', ['--version'], { cwd: root });
|
|
57
58
|
const gh = commandVersion('gh', ['--version'], { cwd: root });
|
|
59
|
+
const codeIntel = opts.codeIntelligence || codeIntelligence.detect(root, opts.codeIntelligenceOpts || {});
|
|
58
60
|
const shell = Boolean(env.SHELL || env.ComSpec);
|
|
59
61
|
const agentSpawn = Boolean(installedAgents.codex || installedAgents.claude || opts.agentSpawn);
|
|
60
62
|
const extensionAuthoring = exists(path.join(root, 'lib', 'extension-authoring.js'))
|
|
@@ -84,6 +86,7 @@ function detect(projectRoot, opts = {}) {
|
|
|
84
86
|
npm,
|
|
85
87
|
gh,
|
|
86
88
|
agentSpawn,
|
|
89
|
+
codeIntelligence: codeIntel,
|
|
87
90
|
extensionAuthoring,
|
|
88
91
|
suiteReleaseDryRun
|
|
89
92
|
},
|
|
@@ -109,6 +112,7 @@ function render(report) {
|
|
|
109
112
|
lines.push(` Git: ${report.guarantees.git || 'not detected'}`);
|
|
110
113
|
lines.push(` npm: ${report.guarantees.npm || 'not detected'}`);
|
|
111
114
|
lines.push(` GitHub CLI: ${report.guarantees.gh || 'not detected'}`);
|
|
115
|
+
lines.push(` Code intelligence: ${codeIntelligence.summary(report.guarantees.codeIntelligence)}`);
|
|
112
116
|
lines.push(` Gaps: ${report.gaps.length > 0 ? report.gaps.join('; ') : 'none'}`);
|
|
113
117
|
return lines.join('\n');
|
|
114
118
|
}
|
package/lib/install-profiles.js
CHANGED
package/lib/planning-systems.js
CHANGED
|
@@ -112,7 +112,7 @@ function hashFiles(projectRoot, files) {
|
|
|
112
112
|
for (const file of files.map((f) => f.path).sort()) {
|
|
113
113
|
const full = path.join(projectRoot, file);
|
|
114
114
|
h.update(file);
|
|
115
|
-
if (fs.existsSync(full) && fs.
|
|
115
|
+
if (fs.existsSync(full) && fs.lstatSync(full).isFile()) {
|
|
116
116
|
h.update(fs.readFileSync(full));
|
|
117
117
|
}
|
|
118
118
|
}
|
|
@@ -125,8 +125,10 @@ function isTextFile(filePath) {
|
|
|
125
125
|
|
|
126
126
|
function readText(projectRoot, relPath) {
|
|
127
127
|
const full = path.join(projectRoot, relPath);
|
|
128
|
-
if (!fs.existsSync(full)
|
|
129
|
-
const
|
|
128
|
+
if (!fs.existsSync(full)) return '';
|
|
129
|
+
const stat = fs.lstatSync(full);
|
|
130
|
+
if (!stat.isFile()) return '';
|
|
131
|
+
const size = stat.size;
|
|
130
132
|
const buffer = fs.readFileSync(full);
|
|
131
133
|
const raw = buffer.slice(0, Math.min(size, MAX_FILE_BYTES)).toString('utf8');
|
|
132
134
|
return raw.replace(/\r\n/g, '\n');
|
|
@@ -134,7 +136,8 @@ function readText(projectRoot, relPath) {
|
|
|
134
136
|
|
|
135
137
|
function walkFiles(rootDir, projectRoot, out = []) {
|
|
136
138
|
if (!fs.existsSync(rootDir) || out.length >= MAX_SYSTEM_FILES) return out;
|
|
137
|
-
const stat = fs.
|
|
139
|
+
const stat = fs.lstatSync(rootDir);
|
|
140
|
+
if (stat.isSymbolicLink()) return out;
|
|
138
141
|
if (stat.isFile()) {
|
|
139
142
|
if (isTextFile(rootDir)) out.push(rel(projectRoot, rootDir));
|
|
140
143
|
return out;
|
package/lib/quick-proof.js
CHANGED
|
@@ -93,6 +93,9 @@ function render(proof, opts = {}) {
|
|
|
93
93
|
const next = proof.dashboard.next || {};
|
|
94
94
|
const progress = proof.dashboard.progress || {};
|
|
95
95
|
const planning = proof.dashboard.planning || {};
|
|
96
|
+
const projectCommandRoot = path.resolve(proof.projectRoot) === path.resolve(proof.fixtureRoot)
|
|
97
|
+
? '.'
|
|
98
|
+
: proof.projectRoot;
|
|
96
99
|
|
|
97
100
|
if (opts.brief) {
|
|
98
101
|
return [
|
|
@@ -140,8 +143,8 @@ function render(proof, opts = {}) {
|
|
|
140
143
|
` npx godpowers next --project=${proof.fixtureRoot} --brief`,
|
|
141
144
|
'',
|
|
142
145
|
'Try it on your project:',
|
|
143
|
-
` npx godpowers status --project=${
|
|
144
|
-
` npx godpowers next --project=${
|
|
146
|
+
` npx godpowers status --project=${projectCommandRoot} --brief`,
|
|
147
|
+
` npx godpowers next --project=${projectCommandRoot} --brief`
|
|
145
148
|
].join('\n');
|
|
146
149
|
}
|
|
147
150
|
|
|
@@ -27,6 +27,7 @@ const CONTEXTUAL_NEXT_ALLOWED = new Set([
|
|
|
27
27
|
'/god-extension-info',
|
|
28
28
|
'/god-extension-list',
|
|
29
29
|
'/god-extension-remove',
|
|
30
|
+
'/god-extension-scaffold',
|
|
30
31
|
'/god-graph',
|
|
31
32
|
'/god-help',
|
|
32
33
|
'/god-lifecycle',
|
|
@@ -61,6 +62,7 @@ const STANDARDS_EXEMPT_COMMANDS = new Set([
|
|
|
61
62
|
'/god-progress',
|
|
62
63
|
'/god-reconstruct',
|
|
63
64
|
'/god-roadmap-check',
|
|
65
|
+
'/god-extension-scaffold',
|
|
64
66
|
'/god-smite',
|
|
65
67
|
'/god-tech-debt'
|
|
66
68
|
]);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "godpowers",
|
|
3
|
-
"version": "2.3.
|
|
4
|
-
"description": "AI-powered development system:
|
|
3
|
+
"version": "2.3.1",
|
|
4
|
+
"description": "AI-powered development system: 112 slash commands and 40 specialist agents that take a project from raw idea to hardened production. Runs inside Claude Code, Codex, Cursor, Windsurf, Gemini, and 10+ other AI coding tools.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"godpowers": "./bin/install.js"
|
|
7
7
|
},
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
apiVersion: godpowers/v1
|
|
2
|
+
kind: CommandRouting
|
|
3
|
+
metadata:
|
|
4
|
+
command: /god-extension-scaffold
|
|
5
|
+
description: Create a publishable extension pack skeleton
|
|
6
|
+
tier: 0
|
|
7
|
+
|
|
8
|
+
prerequisites:
|
|
9
|
+
required: []
|
|
10
|
+
|
|
11
|
+
execution:
|
|
12
|
+
spawns: [built-in]
|
|
13
|
+
context: fresh
|
|
14
|
+
writes:
|
|
15
|
+
- extension pack skeleton
|
|
16
|
+
|
|
17
|
+
success-path:
|
|
18
|
+
next-recommended: /god-test-extension
|
|
19
|
+
|
|
20
|
+
failure-path:
|
|
21
|
+
on-error: /god-doctor
|
|
22
|
+
|
|
23
|
+
endoff:
|
|
24
|
+
state-update: tier-0 updated for /god-extension-scaffold
|
|
25
|
+
events: [agent.start, artifact.created, agent.end]
|
package/routing/god-stack.yaml
CHANGED
|
@@ -11,6 +11,12 @@ triggers:
|
|
|
11
11
|
- "mid development"
|
|
12
12
|
- "pause arc"
|
|
13
13
|
- "feature during build"
|
|
14
|
+
- "add a feature"
|
|
15
|
+
- "feature addition"
|
|
16
|
+
- "add a feature during the current project run"
|
|
17
|
+
- "add a feature without breaking the current project run"
|
|
18
|
+
- "without breaking current project run"
|
|
19
|
+
- "do not disturb current work"
|
|
14
20
|
state-conditions:
|
|
15
21
|
- "lifecycle-phase == in-arc"
|
|
16
22
|
|
|
@@ -11,6 +11,9 @@ triggers:
|
|
|
11
11
|
- "inherit codebase"
|
|
12
12
|
- "legacy code"
|
|
13
13
|
- "understand existing"
|
|
14
|
+
- "audit an existing repo"
|
|
15
|
+
- "audit existing repo"
|
|
16
|
+
- "audit existing codebase"
|
|
14
17
|
state-conditions:
|
|
15
18
|
- "has-package-json"
|
|
16
19
|
|
|
@@ -24,10 +27,10 @@ sequences:
|
|
|
24
27
|
why: "Deep history, decisions, conventions, risks"
|
|
25
28
|
- command: "/god-reconstruct"
|
|
26
29
|
why: "Reverse-engineer PRD/ARCH/ROADMAP/STACK from code"
|
|
27
|
-
- command: "/god-tech-debt"
|
|
28
|
-
why: "Categorize and prioritize debt"
|
|
29
30
|
- command: "/god-audit"
|
|
30
31
|
why: "Score reconstructed artifacts"
|
|
32
|
+
- command: "/god-tech-debt"
|
|
33
|
+
why: "Categorize and prioritize debt"
|
|
31
34
|
- command: "/god-feature"
|
|
32
35
|
why: "Now safe to add new work with reconciliation"
|
|
33
36
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
apiVersion: godpowers/v1
|
|
2
|
+
kind: Recipe
|
|
3
|
+
metadata:
|
|
4
|
+
name: extension-authoring
|
|
5
|
+
category: extension
|
|
6
|
+
description: "Create, test, install, and verify a Godpowers extension pack"
|
|
7
|
+
|
|
8
|
+
triggers:
|
|
9
|
+
intent-keywords:
|
|
10
|
+
- "create extension pack"
|
|
11
|
+
- "create an extension pack"
|
|
12
|
+
- "author extension pack"
|
|
13
|
+
- "new extension pack"
|
|
14
|
+
- "scaffold extension"
|
|
15
|
+
- "build extension pack"
|
|
16
|
+
- "extend godpowers"
|
|
17
|
+
- "make a pack"
|
|
18
|
+
|
|
19
|
+
sequences:
|
|
20
|
+
default:
|
|
21
|
+
description: "Create, test, install, and verify a Godpowers extension pack"
|
|
22
|
+
steps:
|
|
23
|
+
- command: "/god-extension-scaffold --name=@godpowers/my-pack --output=."
|
|
24
|
+
why: "Create the manifest, package, README, skill, and optional agent or workflow skeleton"
|
|
25
|
+
- command: "/god-test-extension <pack-dir>"
|
|
26
|
+
why: "Run contract tests before install or publish"
|
|
27
|
+
- command: "/god-extension-add <pack-dir>"
|
|
28
|
+
why: "Install the passing pack into the active runtime"
|
|
29
|
+
- command: "/god-extension-list"
|
|
30
|
+
why: "Verify the installed pack appears with its provided commands"
|
|
31
|
+
|
|
32
|
+
default-sequence: default
|
package/skills/god-discuss.md
CHANGED
|
@@ -11,7 +11,7 @@ description: |
|
|
|
11
11
|
|
|
12
12
|
# /god-discuss
|
|
13
13
|
|
|
14
|
-
Pre-planning Socratic discussion with domain grilling.
|
|
14
|
+
Pre-planning Socratic discussion with domain and plan grilling.
|
|
15
15
|
|
|
16
16
|
## When to use
|
|
17
17
|
|
|
@@ -31,10 +31,15 @@ The agent:
|
|
|
31
31
|
4. Explores the codebase instead of asking when repo evidence can answer
|
|
32
32
|
5. Challenges vague, overloaded, or conflicting terms against the glossary
|
|
33
33
|
6. Stress-tests domain relationships with concrete scenarios and edge cases
|
|
34
|
-
7.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
7. Attempts to falsify the proposed plan before accepting it:
|
|
35
|
+
- What breaks if the smallest happy path is wrong?
|
|
36
|
+
- Which dependency, user behavior, or edge case could invalidate the plan?
|
|
37
|
+
- What would make this scope too broad for one safe slice?
|
|
38
|
+
- What evidence would change the recommended next command?
|
|
39
|
+
8. Surfaces 2-3 hidden assumptions
|
|
40
|
+
9. Identifies what's [DECISION] vs [HYPOTHESIS] vs [OPEN QUESTION]
|
|
41
|
+
10. Drafts a brief in `.godpowers/discussions/<topic>.md`
|
|
42
|
+
11. Updates `.godpowers/domain/GLOSSARY.md` when a term or ambiguity is resolved
|
|
38
43
|
|
|
39
44
|
The brief and glossary get passed to the next planning command. The glossary is
|
|
40
45
|
preparation context, not a replacement for PRD, ARCH, ROADMAP, STACK, or Pillars
|
package/skills/god-doctor.md
CHANGED
|
@@ -48,9 +48,9 @@ Plain-text report grouped by severity:
|
|
|
48
48
|
GODPOWERS DOCTOR
|
|
49
49
|
|
|
50
50
|
Install: claude (~/.claude/)
|
|
51
|
-
[OK]
|
|
51
|
+
[OK] 112 skills installed
|
|
52
52
|
[OK] 40 agents installed
|
|
53
|
-
[OK] VERSION matches (2.3.
|
|
53
|
+
[OK] VERSION matches (2.3.1)
|
|
54
54
|
[WARN] routing/god-doctor.yaml exists but skill file did not until now
|
|
55
55
|
|
|
56
56
|
Project: /Users/.../my-project/.godpowers/
|
|
@@ -114,6 +114,12 @@ as a read-only diagnostic. It reports:
|
|
|
114
114
|
`/god-doctor --fix` may call `lib/feature-awareness.run(projectRoot)` because
|
|
115
115
|
that helper writes only safe state metadata and managed context fences.
|
|
116
116
|
|
|
117
|
+
## Host Capability Reporting
|
|
118
|
+
|
|
119
|
+
`/god-doctor` reports optional code intelligence when `ast-grep`, `sg`, or LSP
|
|
120
|
+
tools are available. Missing code intelligence is diagnostic context only; it
|
|
121
|
+
does not make the host degraded.
|
|
122
|
+
|
|
117
123
|
## Repo Documentation Sync
|
|
118
124
|
|
|
119
125
|
For initialized projects, `/god-doctor` calls `lib/repo-doc-sync.detect` as a
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: god-extension-scaffold
|
|
3
|
+
description: |
|
|
4
|
+
Create a publishable Godpowers extension pack skeleton from inside the
|
|
5
|
+
slash-command UX. Wraps the same extension authoring helper exposed by
|
|
6
|
+
`npx godpowers extension-scaffold`, then routes to contract testing.
|
|
7
|
+
|
|
8
|
+
Triggers on: "god extension scaffold", "/god-extension-scaffold",
|
|
9
|
+
"create extension pack", "author extension pack", "new extension pack",
|
|
10
|
+
"extend godpowers"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# /god-extension-scaffold
|
|
14
|
+
|
|
15
|
+
Create a Godpowers extension pack skeleton.
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### `/god-extension-scaffold --name=@godpowers/my-pack --output=.`
|
|
20
|
+
|
|
21
|
+
Optional arguments:
|
|
22
|
+
|
|
23
|
+
- `--skill=custom-pack-command` sets the generated skill name.
|
|
24
|
+
- `--agent=custom-pack-agent` creates a generated agent contract.
|
|
25
|
+
- `--workflow=my-pack-workflow` creates a generated workflow YAML.
|
|
26
|
+
- `--overwrite` allows replacing existing scaffold files.
|
|
27
|
+
|
|
28
|
+
## Process
|
|
29
|
+
|
|
30
|
+
1. Parse the requested package name, output root, optional skill, optional
|
|
31
|
+
agent, and optional workflow.
|
|
32
|
+
2. Call `lib/extension-authoring.js scaffold(...)`.
|
|
33
|
+
3. Validate the generated `manifest.yaml` against the extension manifest
|
|
34
|
+
contract.
|
|
35
|
+
4. Report the created pack path and written files.
|
|
36
|
+
5. Suggest `/god-test-extension <pack-dir>` before install or publish.
|
|
37
|
+
|
|
38
|
+
## Output
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
Extension scaffold created: ./godpowers-my-pack
|
|
42
|
+
|
|
43
|
+
Written:
|
|
44
|
+
manifest.yaml
|
|
45
|
+
package.json
|
|
46
|
+
README.md
|
|
47
|
+
skills/custom-pack-command.md
|
|
48
|
+
|
|
49
|
+
Suggested next: /god-test-extension ./godpowers-my-pack
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Implementation
|
|
53
|
+
|
|
54
|
+
Built-in. Calls `lib/extension-authoring.js scaffold(...)`.
|
|
55
|
+
|
|
56
|
+
The terminal equivalent remains:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npx godpowers extension-scaffold --name=@godpowers/my-pack --output=.
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Related
|
|
63
|
+
|
|
64
|
+
- `/god-test-extension <path>` - contract test the pack before install or publish
|
|
65
|
+
- `/god-extension-add <path>` - install a passing pack
|
|
66
|
+
- `/god-extension-list` - verify the pack is visible in the runtime
|
package/skills/god-version.md
CHANGED
|
@@ -14,9 +14,9 @@ Print version and a short capability summary.
|
|
|
14
14
|
## Output
|
|
15
15
|
|
|
16
16
|
```
|
|
17
|
-
Godpowers v2.3.
|
|
17
|
+
Godpowers v2.3.1
|
|
18
18
|
Install: /Users/.../.claude/ (matches package.json)
|
|
19
|
-
Surface:
|
|
19
|
+
Surface: 112 skills, 40 agents, 13 workflows, 42 recipes
|
|
20
20
|
Schema: intent.v1, state.v1, events.v1, workflow.v1, routing.v1, recipe.v1
|
|
21
21
|
External integrations available: impeccable, agent-browser (others lazy)
|
|
22
22
|
Feature awareness: planning-system migration, source-system sync-back, context refresh, dashboard status labels, repo documentation sync, repo surface sync, quick proof, request trace, release hardening, maintenance hardening
|
package/skills/god.md
CHANGED
|
@@ -160,13 +160,11 @@ any destructive sequence executes.
|
|
|
160
160
|
```
|
|
161
161
|
User: /god production is broken
|
|
162
162
|
|
|
163
|
-
Match: production-broken (score:
|
|
164
|
-
What this does:
|
|
163
|
+
Match: production-broken (score: 20)
|
|
164
|
+
What this does: Production is broken now
|
|
165
165
|
|
|
166
166
|
Sequence:
|
|
167
|
-
1. /god-hotfix
|
|
168
|
-
2. /god-deploy Push the fix once green
|
|
169
|
-
3. /god-postmortem Schedule the incident review
|
|
167
|
+
1. /god-hotfix Skip planning, debug, fix with TDD, expedited deploy, schedule postmortem
|
|
170
168
|
|
|
171
169
|
Run this sequence? (yes / show others / cancel)
|
|
172
170
|
```
|
|
@@ -174,15 +172,14 @@ Run this sequence? (yes / show others / cancel)
|
|
|
174
172
|
### Example 2: ambiguous intent (multiple matches)
|
|
175
173
|
|
|
176
174
|
```
|
|
177
|
-
User: /god
|
|
175
|
+
User: /god parallel feature during build
|
|
178
176
|
|
|
179
|
-
Top matches for "
|
|
177
|
+
Top matches for "parallel feature during build":
|
|
180
178
|
|
|
181
|
-
1. add-feature-mid-arc-pause (
|
|
182
|
-
2. add-feature-
|
|
183
|
-
3. add-feature-next-milestone (10) Defer to next milestone
|
|
179
|
+
1. add-feature-mid-arc-pause (10) Bigger feature during the current project run; reconcile with roadmap, pause, do feature, update roadmap, resume
|
|
180
|
+
2. add-feature-parallel (10) Parallel feature, do not disrupt main work
|
|
184
181
|
|
|
185
|
-
Pick one (1/2
|
|
182
|
+
Pick one (1/2) or describe more specifically.
|
|
186
183
|
```
|
|
187
184
|
|
|
188
185
|
### Example 3: state-driven (no text)
|