godpowers 1.6.6 → 1.6.7

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 CHANGED
@@ -35,3 +35,13 @@ projects from raw idea to hardened production.
35
35
  - No emojis (use `+`, `-`, `x`, `!` for status indicators)
36
36
  - Every sentence in generated artifacts must be labeled: DECISION, HYPOTHESIS, or OPEN QUESTION
37
37
  - Every claim must fail the substitution test (swap in a competitor, sentence must break)
38
+
39
+ <!-- pillars:begin -->
40
+ ## Godpowers Pillars Protocol
41
+
42
+ - [DECISION] Load `agents/context.md` and `agents/repo.md` before Godpowers commands make durable project decisions.
43
+ - [DECISION] Load additional `agents/*.md` pillar files only when their frontmatter matches the task.
44
+ - [DECISION] Treat `.godpowers/state.json`, `.godpowers/PROGRESS.md`, and `.godpowers/CHECKPOINT.md` as workflow state.
45
+ - [DECISION] Treat Pillars files as portable project context for any coding agent that opens this repository.
46
+ - [DECISION] Disk state wins over conversation memory when these sources disagree.
47
+ <!-- pillars:end -->
package/CHANGELOG.md CHANGED
@@ -5,6 +5,45 @@ All notable changes to Godpowers will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.6.7] - 2026-05-16
9
+
10
+ Progress visibility patch. Makes Godpowers easier to follow while preserving
11
+ the stable 1.6 command surface.
12
+
13
+ ### Added
14
+ - Added `lib/state.progressSummary`, `orderedSubSteps`, and
15
+ `renderProgressLine` so commands can report percentage complete, completed
16
+ step count, total step count, and current step number from state.json.
17
+ - Added checkpoint frontmatter fields for `progress-pct`,
18
+ `progress-complete`, `progress-total`, and `current-step`.
19
+ - Added `CHECKPOINT.md` sections for recent work and what happens next.
20
+ - Added a Step Narration Protocol for `god-orchestrator` so visible
21
+ tier/sub-step work gets compact "Next step" and "Step result" cards.
22
+ - Added `/god-mode`, `/god-next`, `/god-status`, and `/god-locate` guidance
23
+ for progress, path-ahead, recent work, and next-action summaries.
24
+ - Added `PROGRESS.md` template sections for the current step plan and recent
25
+ step results.
26
+ - Added root `AGENTS.md` Pillars Protocol guidance so coding agents know which
27
+ project context and workflow-state files are authoritative.
28
+ - Added installer coverage for `--local` Codex installs.
29
+ - Added regression coverage for progress math, checkpoint progress rendering,
30
+ checkpoint progress preservation, and checkpoint step summaries.
31
+
32
+ ### Changed
33
+ - Package publication now allowlists `agents/god-*.md` instead of the entire
34
+ `agents/` directory so local Pillars files do not enter the npm payload.
35
+ - Package contents checks now fail when non-specialist files under `agents/`
36
+ would be included in the npm package.
37
+ - The installer now resolves local runtime destinations when `--local` is used
38
+ and only installs specialist agent files matching `god-*.md`.
39
+
40
+ ### Guardrails
41
+ - This patch does not add slash commands, specialist agents, workflows,
42
+ recipes, schemas, or public artifact formats.
43
+ - Progress percentages are derived from disk state, not conversation memory.
44
+ - Optional or intentionally skipped steps count as complete when their state
45
+ is `imported`, `skipped`, or `not-required`.
46
+
8
47
  ## [1.6.6] - 2026-05-16
9
48
 
10
49
  Non-God-Mode handoff privacy patch. Extends the display-safe handoff pattern
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![CI](https://github.com/aihxp/godpowers/actions/workflows/ci.yml/badge.svg)](https://github.com/aihxp/godpowers/actions/workflows/ci.yml)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
5
- [![Version](https://img.shields.io/badge/version-1.6.6-blue)](CHANGELOG.md)
5
+ [![Version](https://img.shields.io/badge/version-1.6.7-blue)](CHANGELOG.md)
6
6
  [![npm](https://img.shields.io/npm/v/godpowers.svg)](https://www.npmjs.com/package/godpowers)
7
7
 
8
8
  **Ship fast. Ship right. Ship everything. Ship accountably.**
@@ -12,11 +12,10 @@ idea to hardened production. It runs as **slash commands inside your AI coding
12
12
  tool** (Claude Code, Codex, Cursor, etc.) that orchestrate **specialist agents**
13
13
  in fresh contexts to do the work.
14
14
 
15
- Version 1.6.6 keeps the stable Godpowers surface while making more Codex
16
- orchestrator spawns transcript-safe: `/god-mode`, `/god-init`, and Mode D
17
- suite coordinator paths now use private handoff files with small display-safe
18
- pointers. Safe-sync and unresolved Critical harden findings still gate direct
19
- Tier 3 commands, `/god-mode`, and `/god-mode --yolo`.
15
+ Version 1.6.7 keeps the stable Godpowers surface while making the live arc
16
+ easier to follow: progress reports now show percent complete, current step,
17
+ recent work, and what happens next. The orchestrator also documents compact
18
+ "Next step" and "Step result" cards around visible tier/sub-step work.
20
19
 
21
20
  It fuses four disciplines into one unified workflow:
22
21
 
package/RELEASE.md CHANGED
@@ -1,11 +1,10 @@
1
- # Godpowers 1.6.6 Release
1
+ # Godpowers 1.6.7 Release
2
2
 
3
3
  Date: 2026-05-16
4
4
 
5
- Godpowers 1.6.6 extends transcript-safe spawn handling beyond `/god-mode`.
6
- The goal of this patch is to keep Codex-visible spawn messages small and safe
7
- for `/god-init` and Mode D suite coordination while preserving the same
8
- orchestrator and coordinator behavior.
5
+ Godpowers 1.6.7 makes the live workflow easier to track. The goal of this
6
+ patch is to answer "what is Godpowers doing, how far along is it, what just
7
+ happened, and what happens next" from disk state.
9
8
 
10
9
  ## What is stable
11
10
 
@@ -27,29 +26,36 @@ orchestrator and coordinator behavior.
27
26
 
28
27
  ## What is new
29
28
 
30
- - `/god-init` now writes detailed initialization context to
31
- `.godpowers/runs/<run-id>/INIT-ORCHESTRATOR-HANDOFF.md` before spawning
32
- `god-orchestrator`.
33
- - `/god-suite-init`, `/god-suite-release`, and `/god-suite-patch` now write
34
- suite coordination context to
35
- `.godpowers/runs/<run-id>/COORDINATOR-HANDOFF.md` before spawning
36
- `god-coordinator`.
37
- - `god-coordinator` now writes per-repo orchestrator context to
38
- `.godpowers/runs/<run-id>/COORDINATOR-ORCHESTRATOR-HANDOFF.md` before
39
- spawning a target repo's `god-orchestrator`.
40
- - `god-orchestrator` now treats handoff files as a general caller protocol,
41
- not only as a `/god-mode` protocol.
42
- - `/god-hygiene` routing no longer lists `god-orchestrator` as a secondary
43
- spawn because the skill only runs artifact, dependency, and documentation
44
- audits.
45
-
46
- ## What 1.6.6 means
47
-
48
- Godpowers 1.6.6 does not expand the public command surface. It fixes more
49
- Codex spawn integration paths so the right agent is still started, but the host
50
- UI only sees a small pointer to disk state instead of raw project description,
51
- suite metadata, release notes, patch directives, dependency graphs, routing
52
- rules, or local-file details.
29
+ - `lib/state.progressSummary` computes percentage complete, completed step
30
+ count, total step count, current step number, and current tier/sub-step from
31
+ `state.json`.
32
+ - `CHECKPOINT.md` can persist progress frontmatter and now includes
33
+ "What happened recently" and "What happens next" sections.
34
+ - `god-orchestrator` now has a Step Narration Protocol for compact
35
+ "Next step" and "Step result" cards around visible tier/sub-step work.
36
+ - `/god-mode`, `/god-next`, `/god-status`, and `/god-locate` now document
37
+ progress, path-ahead, recent-work, and next-action summaries.
38
+ - `templates/PROGRESS.md` now includes a current step plan and recent step
39
+ result shape.
40
+ - Package publication now allowlists `agents/god-*.md`, preventing local
41
+ Pillars files under `agents/` from entering the npm payload.
42
+ - Package contents checks now fail if non-specialist files under `agents/`
43
+ would be published.
44
+ - `AGENTS.md` now includes the Pillars Protocol for loading durable project
45
+ context and workflow-state files.
46
+ - Installer local mode now resolves runtime destinations under the current
47
+ directory and installs only `god-*.md` specialist agent files.
48
+
49
+ ## What 1.6.7 means
50
+
51
+ Godpowers 1.6.7 does not expand the public command surface. It makes the
52
+ existing arc more legible by showing a disk-derived progress report, a short
53
+ plan before visible work starts, and a short result after work completes or
54
+ pauses.
55
+
56
+ The release also tightens npm packaging around specialist agents. Local
57
+ project Pillars can live under `agents/` during development, but only
58
+ `agents/god-*.md` files are packaged as Godpowers specialist agents.
53
59
 
54
60
  Safe sync and unresolved Critical harden findings remain release-truth gates.
55
61
  Per-repo Quarterback ownership remains intact for Mode D suite work.
@@ -59,8 +65,8 @@ Per-repo Quarterback ownership remains intact for Mode D suite work.
59
65
  During the 1.x stability window, do not add broad new command families, change
60
66
  schema formats, or rename public artifacts without evidence from real use.
61
67
 
62
- The `v1.6.6` git tag points to the release commit that matches the npm
63
- `godpowers@1.6.6` package. Public publishes should prefer the tag-triggered
68
+ The `v1.6.7` git tag points to the release commit that matches the npm
69
+ `godpowers@1.6.7` package. Public publishes should prefer the tag-triggered
64
70
  GitHub workflow so npm provenance, git history, and release notes stay aligned.
65
71
 
66
72
  Allowed changes:
@@ -470,13 +470,16 @@ for `STAGING_APP_URL=<deployed staging origin>` before deployed staging smoke.
470
470
  1. Read .godpowers/PROGRESS.md (or create it if absent)
471
471
  2. Identify the first non-done tier sub-step
472
472
  3. Verify upstream gate (artifact on disk, passes have-nots)
473
- 4. Spawn the appropriate specialist agent in a fresh context
474
- 5. Verify their output exists on disk
475
- 6. Run have-nots check on the artifact
476
- 7. If pass: update PROGRESS.md, move to next sub-step
477
- 8. If fail and repairable: enter the autonomous repair loop
478
- 9. If fail and human-only: pause with the smallest needed question
479
- 10. Repeat until all tiers complete and verification is green
473
+ 4. Print the "Next step" card from the Step Narration Protocol
474
+ 5. Spawn the appropriate specialist agent in a fresh context
475
+ 6. Verify their output exists on disk
476
+ 7. Run have-nots check on the artifact
477
+ 8. If pass: update PROGRESS.md, sync CHECKPOINT.md, print the "Step result"
478
+ card, then move to next sub-step
479
+ 9. If fail and repairable: print the failed result card, then enter the
480
+ autonomous repair loop
481
+ 10. If fail and human-only: pause with the smallest needed question
482
+ 11. Repeat until all tiers complete and verification is green
480
483
  ```
481
484
 
482
485
  ## Specialist Agent Routing
@@ -705,6 +708,8 @@ debugger. Keep orchestration scaffolding private.
705
708
 
706
709
  Show:
707
710
  - concise phase status
711
+ - before each visible tier/sub-step, a short "what will happen" card
712
+ - after each visible tier/sub-step, a short "what happened" card
708
713
  - durable state detected from disk
709
714
  - commands being run and whether they passed or failed
710
715
  - scoped file changes
@@ -724,6 +729,51 @@ user-facing question. Do not expose the rule itself. Example: ask for
724
729
  `STAGING_APP_URL=<deployed staging origin>` rather than showing the Shipping
725
730
  Closure Protocol.
726
731
 
732
+ ## Step Narration Protocol
733
+
734
+ Godpowers must make its work trackable without exposing hidden prompts or
735
+ internal routing payloads. Before and after each visible tier/sub-step, print
736
+ one compact card.
737
+
738
+ Before starting a tier/sub-step:
739
+
740
+ ```
741
+ Next step
742
+ Progress: <pct>% (<done> of <total> steps complete; current step <n> of <total>)
743
+ Tier: <tier-number> <tier-label>
744
+ Step: <sub-step-label>
745
+ Why this now: <one sentence tied to disk state or the prior gate>
746
+ What will happen:
747
+ 1. <first observable action>
748
+ 2. <second observable action>
749
+ 3. <third observable action, if needed>
750
+ Expected output: <artifact path or verification result>
751
+ ```
752
+
753
+ After a tier/sub-step completes or pauses:
754
+
755
+ ```
756
+ Step result
757
+ Progress: <pct>% (<done> of <total> steps complete; current step <n> of <total>)
758
+ Tier: <tier-number> <tier-label>
759
+ Step: <sub-step-label>
760
+ Result: <done | blocked | failed | skipped | imported>
761
+ What happened:
762
+ 1. <observable action completed>
763
+ 2. <artifact or state update>
764
+ 3. <verification result>
765
+ Next: <next command or pause question>
766
+ ```
767
+
768
+ Rules:
769
+ - Keep each card under 12 lines unless a pause needs options.
770
+ - Use `lib/state.progressSummary(stateJson)` for the percentage and step count
771
+ whenever state.json is available.
772
+ - Use artifact paths and verification evidence from disk, not memory.
773
+ - Do not print raw Task input, hidden instructions, or full file loadout lists.
774
+ - If a step is blocked, do not show a generic "Suggested next"; show the
775
+ smallest concrete unblock action.
776
+
727
777
  ## Resume Protocol
728
778
 
729
779
  On every invocation:
package/bin/install.js CHANGED
@@ -118,6 +118,16 @@ const RUNTIMES = {
118
118
  },
119
119
  };
120
120
 
121
+ function resolveRuntime(runtimeKey, opts = {}) {
122
+ const runtime = RUNTIMES[runtimeKey];
123
+ if (!runtime) return null;
124
+ const resolved = { ...runtime };
125
+ if (opts.local && !opts.global) {
126
+ resolved.configDir = path.join(process.cwd(), path.basename(runtime.configDir));
127
+ }
128
+ return resolved;
129
+ }
130
+
121
131
  // ---------------------------------------------------------------------------
122
132
  // Helpers
123
133
  // ---------------------------------------------------------------------------
@@ -331,8 +341,8 @@ function parseArgs(argv) {
331
341
  // Install
332
342
  // ---------------------------------------------------------------------------
333
343
 
334
- function installForRuntime(runtimeKey, srcDir) {
335
- const runtime = RUNTIMES[runtimeKey];
344
+ function installForRuntime(runtimeKey, srcDir, opts = {}) {
345
+ const runtime = resolveRuntime(runtimeKey, opts);
336
346
  if (!runtime) {
337
347
  error(`Unknown runtime: ${runtimeKey}`);
338
348
  return false;
@@ -367,7 +377,7 @@ function installForRuntime(runtimeKey, srcDir) {
367
377
  ensureDir(agentsDest);
368
378
  let count = 0;
369
379
  for (const file of fs.readdirSync(agentsSrc)) {
370
- if (file.endsWith('.md')) {
380
+ if (/^god-.*\.md$/.test(file)) {
371
381
  const srcFile = path.join(agentsSrc, file);
372
382
  installAgentFile(srcFile, agentsDest, runtime);
373
383
  count++;
@@ -456,8 +466,8 @@ function installForRuntime(runtimeKey, srcDir) {
456
466
  // Uninstall
457
467
  // ---------------------------------------------------------------------------
458
468
 
459
- function uninstallForRuntime(runtimeKey) {
460
- const runtime = RUNTIMES[runtimeKey];
469
+ function uninstallForRuntime(runtimeKey, opts = {}) {
470
+ const runtime = resolveRuntime(runtimeKey, opts);
461
471
  if (!runtime) {
462
472
  error(`Unknown runtime: ${runtimeKey}`);
463
473
  return false;
@@ -580,16 +590,16 @@ function main() {
580
590
 
581
591
  const srcDir = path.resolve(__dirname, '..');
582
592
 
583
- // Detect non-interactive and default to claude global
593
+ // Detect non-interactive and default to Claude Code.
584
594
  if (opts.runtimes.length === 0 && !opts.all) {
585
595
  if (!process.stdin.isTTY) {
586
- warn('Non-interactive terminal detected, defaulting to Claude Code global install');
596
+ warn('Non-interactive terminal detected, defaulting to Claude Code install');
587
597
  opts.runtimes = ['claude'];
588
- opts.global = true;
598
+ if (!opts.local) opts.global = true;
589
599
  } else {
590
600
  // Interactive mode: default to claude
591
601
  opts.runtimes = ['claude'];
592
- opts.global = true;
602
+ if (!opts.local) opts.global = true;
593
603
  }
594
604
  }
595
605
 
@@ -601,7 +611,7 @@ function main() {
601
611
  if (opts.uninstall) {
602
612
  let removed = 0;
603
613
  for (const runtime of opts.runtimes) {
604
- if (uninstallForRuntime(runtime)) {
614
+ if (uninstallForRuntime(runtime, opts)) {
605
615
  removed++;
606
616
  }
607
617
  }
@@ -617,7 +627,7 @@ function main() {
617
627
 
618
628
  let installed = 0;
619
629
  for (const runtime of opts.runtimes) {
620
- if (installForRuntime(runtime, srcDir)) {
630
+ if (installForRuntime(runtime, srcDir, opts)) {
621
631
  installed++;
622
632
  }
623
633
  }
@@ -625,7 +635,7 @@ function main() {
625
635
  if (installed > 0) {
626
636
  // Count slash commands for verification message
627
637
  const skillsCount = fs.readdirSync(path.join(srcDir, 'skills')).filter(f => f.endsWith('.md')).length;
628
- const agentsCount = fs.readdirSync(path.join(srcDir, 'agents')).filter(f => f.endsWith('.md')).length;
638
+ const agentsCount = fs.readdirSync(path.join(srcDir, 'agents')).filter(f => /^god-.*\.md$/.test(f)).length;
629
639
 
630
640
  log('');
631
641
  log(`\x1b[32mDone!\x1b[0m Installed Godpowers v${VERSION} for ${installed} runtime(s).`);
package/lib/checkpoint.js CHANGED
@@ -22,6 +22,10 @@
22
22
  * lifecycle: {pre-init|in-arc|steady-state-active|...}
23
23
  * current-tier: {tier-N}
24
24
  * current-substep: {substep-key}
25
+ * progress-pct: {number}
26
+ * progress-complete: {number}
27
+ * progress-total: {number}
28
+ * current-step: {number}
25
29
  * last-action: {action-name}
26
30
  * last-actor: {agent or user}
27
31
  * last-update: {ISO8601}
@@ -123,6 +127,7 @@ function write(projectRoot, state) {
123
127
  const actions = (state.actions || []).slice(0, MAX_ACTIONS);
124
128
  const facts = (state.facts || []).slice(0, MAX_FACTS);
125
129
  const factsHash = sha256(JSON.stringify(facts));
130
+ const progress = state.progress || null;
126
131
 
127
132
  const fm = [
128
133
  '---',
@@ -133,13 +138,27 @@ function write(projectRoot, state) {
133
138
  `lifecycle: ${state.lifecycle || 'in-arc'}`,
134
139
  `current-tier: ${state.currentTier || 'tier-0'}`,
135
140
  `current-substep: ${state.currentSubstep || 'orchestration'}`,
141
+ progress ? `progress-pct: ${progress.percent}` : null,
142
+ progress ? `progress-complete: ${progress.completed}` : null,
143
+ progress ? `progress-total: ${progress.total}` : null,
144
+ progress ? `current-step: ${progress.currentStep}` : null,
136
145
  `last-action: ${state.lastAction || 'unknown'}`,
137
146
  `last-actor: ${state.lastActor || 'unknown'}`,
138
147
  `last-update: ${ts}`,
139
148
  `facts-hash: sha256:${factsHash}`,
140
149
  '---',
141
150
  ''
142
- ].join('\n');
151
+ ].filter(line => line !== null).join('\n');
152
+
153
+ const progressLine = progress
154
+ ? `- Progress: **${progress.percent}%** (${progress.completed} of ${progress.total} steps complete; current step ${progress.currentStep} of ${progress.total})`
155
+ : null;
156
+ const recentSummary = actions.length === 0
157
+ ? '_(no recent actions recorded yet)_'
158
+ : actions.slice(0, 3).map(a => `- ${a}`).join('\n');
159
+ const nextSummary = state.nextCommand
160
+ ? `- ${state.nextCommand}\n- ${state.nextReason || 'No reason recorded.'}`
161
+ : '- Run `/god-next` to compute the next command from disk state.';
143
162
 
144
163
  const body = [
145
164
  '# Checkpoint',
@@ -153,9 +172,18 @@ function write(projectRoot, state) {
153
172
  `- Project: **${state.project || 'unnamed'}**`,
154
173
  `- Mode: **${state.mode || '?'}**${state.modeDSuite ? ' (in multi-repo suite)' : ''}`,
155
174
  `- Lifecycle phase: **${state.lifecycle || 'in-arc'}**`,
175
+ progressLine,
156
176
  `- Current tier: **${state.currentTier || 'tier-0'}** / **${state.currentSubstep || 'orchestration'}**`,
157
177
  `- Last action: \`${state.lastAction || 'unknown'}\` by ${state.lastActor || 'unknown'} at ${ts}`,
158
178
  '',
179
+ '## What happened recently',
180
+ '',
181
+ recentSummary,
182
+ '',
183
+ '## What happens next',
184
+ '',
185
+ nextSummary,
186
+ '',
159
187
  '## Next suggested command',
160
188
  '',
161
189
  state.nextCommand
@@ -191,7 +219,7 @@ function write(projectRoot, state) {
191
219
  `- Authoritative state: \`.godpowers/state.json\``,
192
220
  `- Authoritative history: \`.godpowers/runs/<id>/events.jsonl\` + \`.godpowers/log\``,
193
221
  ''
194
- ].join('\n');
222
+ ].filter(line => line !== null).join('\n');
195
223
 
196
224
  fs.writeFileSync(file, fm + body);
197
225
  return file;
@@ -234,7 +262,7 @@ function recordFact(projectRoot, fact) {
234
262
  }
235
263
 
236
264
  function frontmatterToState(fm, facts) {
237
- return {
265
+ const result = {
238
266
  project: fm.project,
239
267
  mode: fm.mode,
240
268
  modeDSuite: fm['mode-d-suite'] === true || fm['mode-d-suite'] === 'true',
@@ -245,6 +273,15 @@ function frontmatterToState(fm, facts) {
245
273
  lastActor: fm['last-actor'],
246
274
  facts: facts || []
247
275
  };
276
+ if (fm['progress-total']) {
277
+ result.progress = {
278
+ percent: Number(fm['progress-pct'] || 0),
279
+ completed: Number(fm['progress-complete'] || 0),
280
+ total: Number(fm['progress-total'] || 0),
281
+ currentStep: Number(fm['current-step'] || 0)
282
+ };
283
+ }
284
+ return result;
248
285
  }
249
286
 
250
287
  /**
@@ -304,27 +341,26 @@ function syncFromState(projectRoot, opts = {}) {
304
341
 
305
342
  const s = state.read(projectRoot);
306
343
  if (!s) throw new Error('state.json not initialized');
344
+ const progress = state.progressSummary(s);
307
345
 
308
- // Find the current tier + sub-step: first one with status in-flight,
309
- // else last one done, else tier-0/orchestration.
346
+ // Find the current tier + sub-step from progressSummary, then keep a
347
+ // separate lastAction pointer to the newest completed step.
310
348
  let currentTier = 'tier-0';
311
349
  let currentSubstep = 'orchestration';
312
350
  let lastAction = 'init';
313
351
  let lastUpdate = null;
314
352
  let lastActor = 'unknown';
353
+ if (progress.current) {
354
+ currentTier = progress.current.tierKey;
355
+ currentSubstep = progress.current.subStepKey;
356
+ }
357
+
315
358
  if (s.tiers) {
316
- outer: for (const tierKey of Object.keys(s.tiers).sort()) {
359
+ for (const tierKey of Object.keys(s.tiers).sort()) {
317
360
  for (const [substepKey, sub] of Object.entries(s.tiers[tierKey])) {
318
- if (sub.status === 'in-flight') {
319
- currentTier = tierKey;
320
- currentSubstep = substepKey;
321
- break outer;
322
- }
323
361
  if (sub.status === 'done' && sub.updated) {
324
362
  if (!lastUpdate || sub.updated > lastUpdate) {
325
363
  lastUpdate = sub.updated;
326
- currentTier = tierKey;
327
- currentSubstep = substepKey;
328
364
  lastAction = `${tierKey}.${substepKey} done`;
329
365
  }
330
366
  }
@@ -372,6 +408,7 @@ function syncFromState(projectRoot, opts = {}) {
372
408
  lastActor,
373
409
  actions,
374
410
  facts,
411
+ progress,
375
412
  nextCommand: opts.nextCommand,
376
413
  nextReason: opts.nextReason
377
414
  });
package/lib/state.js CHANGED
@@ -10,11 +10,52 @@ const path = require('path');
10
10
  const crypto = require('crypto');
11
11
 
12
12
  const STATE_VERSION = '1.0.0';
13
+ const COMPLETE_STATUSES = new Set(['done', 'imported', 'skipped', 'not-required']);
14
+ const ACTIVE_STATUSES = new Set(['in-flight', 'failed', 're-invoked']);
15
+ const TIER_LABELS = {
16
+ 'tier-0': 'Orchestration',
17
+ 'tier-1': 'Planning',
18
+ 'tier-2': 'Building',
19
+ 'tier-3': 'Shipping'
20
+ };
21
+ const SUBSTEP_LABELS = {
22
+ orchestration: 'Orchestration',
23
+ prd: 'PRD',
24
+ arch: 'Architecture',
25
+ roadmap: 'Roadmap',
26
+ stack: 'Stack',
27
+ design: 'Design',
28
+ product: 'Product',
29
+ repo: 'Repo',
30
+ build: 'Build',
31
+ deploy: 'Deploy',
32
+ observe: 'Observe',
33
+ launch: 'Launch',
34
+ harden: 'Harden'
35
+ };
13
36
 
14
37
  function statePath(projectRoot) {
15
38
  return path.join(projectRoot, '.godpowers', 'state.json');
16
39
  }
17
40
 
41
+ function tierNumber(tierKey) {
42
+ const match = String(tierKey).match(/^tier-(\d+)$/);
43
+ return match ? Number(match[1]) : Number.MAX_SAFE_INTEGER;
44
+ }
45
+
46
+ function labelFromKey(key) {
47
+ return String(key)
48
+ .split(/[-_]/)
49
+ .filter(Boolean)
50
+ .map(part => part.charAt(0).toUpperCase() + part.slice(1))
51
+ .join(' ');
52
+ }
53
+
54
+ function tierComparator(a, b) {
55
+ const byNumber = tierNumber(a) - tierNumber(b);
56
+ return byNumber === 0 ? String(a).localeCompare(String(b)) : byNumber;
57
+ }
58
+
18
59
  /**
19
60
  * Read state.json from a project. Returns null if not initialized.
20
61
  */
@@ -139,4 +180,106 @@ function detectDrift(projectRoot) {
139
180
  return drift;
140
181
  }
141
182
 
142
- module.exports = { read, write, init, updateSubStep, hashFile, detectDrift, statePath };
183
+ function isCompleteStatus(status) {
184
+ return COMPLETE_STATUSES.has(status);
185
+ }
186
+
187
+ function isActiveStatus(status) {
188
+ return ACTIVE_STATUSES.has(status);
189
+ }
190
+
191
+ function orderedSubSteps(state) {
192
+ if (!state || !state.tiers) return [];
193
+ const steps = [];
194
+ for (const tierKey of Object.keys(state.tiers).sort(tierComparator)) {
195
+ const tier = state.tiers[tierKey] || {};
196
+ for (const [subStepKey, subStep] of Object.entries(tier)) {
197
+ const status = subStep && subStep.status ? subStep.status : 'pending';
198
+ steps.push({
199
+ tierKey,
200
+ tierNumber: tierNumber(tierKey),
201
+ tierLabel: TIER_LABELS[tierKey] || labelFromKey(tierKey),
202
+ subStepKey,
203
+ subStepLabel: SUBSTEP_LABELS[subStepKey] || labelFromKey(subStepKey),
204
+ status,
205
+ artifact: subStep && subStep.artifact,
206
+ updated: subStep && subStep.updated
207
+ });
208
+ }
209
+ }
210
+ return steps.map((step, index) => ({ ...step, ordinal: index + 1 }));
211
+ }
212
+
213
+ function progressSummary(state) {
214
+ const steps = orderedSubSteps(state);
215
+ const total = steps.length;
216
+ const completed = steps.filter(step => isCompleteStatus(step.status)).length;
217
+
218
+ let currentIndex = steps.findIndex(step => isActiveStatus(step.status));
219
+ if (currentIndex < 0) {
220
+ currentIndex = steps.findIndex(step => !isCompleteStatus(step.status));
221
+ }
222
+ if (currentIndex < 0 && total > 0) currentIndex = total - 1;
223
+
224
+ const current = currentIndex >= 0 ? steps[currentIndex] : null;
225
+ return {
226
+ percent: total === 0 ? 0 : Math.round((completed / total) * 100),
227
+ completed,
228
+ total,
229
+ remaining: Math.max(total - completed, 0),
230
+ currentStep: current ? current.ordinal : 0,
231
+ current,
232
+ tiers: summarizeTiers(steps)
233
+ };
234
+ }
235
+
236
+ function summarizeTiers(steps) {
237
+ const byTier = new Map();
238
+ for (const step of steps) {
239
+ if (!byTier.has(step.tierKey)) {
240
+ byTier.set(step.tierKey, {
241
+ tierKey: step.tierKey,
242
+ tierNumber: step.tierNumber,
243
+ tierLabel: step.tierLabel,
244
+ completed: 0,
245
+ total: 0,
246
+ current: false
247
+ });
248
+ }
249
+ const tier = byTier.get(step.tierKey);
250
+ tier.total += 1;
251
+ if (isCompleteStatus(step.status)) tier.completed += 1;
252
+ if (isActiveStatus(step.status)) tier.current = true;
253
+ }
254
+ return Array.from(byTier.values()).map(tier => ({
255
+ ...tier,
256
+ percent: tier.total === 0 ? 0 : Math.round((tier.completed / tier.total) * 100)
257
+ }));
258
+ }
259
+
260
+ function renderProgressLine(summary) {
261
+ const progress = summary && typeof summary.total === 'number' ? summary : progressSummary(summary);
262
+ if (!progress || progress.total === 0) {
263
+ return 'Progress: unavailable, no tracked Godpowers steps found';
264
+ }
265
+ const current = progress.current;
266
+ const currentLabel = current
267
+ ? `${current.tierLabel} / ${current.subStepLabel}`
268
+ : 'complete';
269
+ return `Progress: ${progress.percent}% (${progress.completed} of ${progress.total} steps complete; current step ${progress.currentStep} of ${progress.total}: ${currentLabel})`;
270
+ }
271
+
272
+ module.exports = {
273
+ read,
274
+ write,
275
+ init,
276
+ updateSubStep,
277
+ hashFile,
278
+ detectDrift,
279
+ statePath,
280
+ orderedSubSteps,
281
+ progressSummary,
282
+ renderProgressLine,
283
+ isCompleteStatus,
284
+ isActiveStatus
285
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "godpowers",
3
- "version": "1.6.6",
3
+ "version": "1.6.7",
4
4
  "description": "AI-powered development system: 106 slash commands and 39 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"
@@ -66,7 +66,7 @@
66
66
  "files": [
67
67
  "bin/",
68
68
  "skills/",
69
- "agents/",
69
+ "agents/god-*.md",
70
70
  "hooks/",
71
71
  "templates/",
72
72
  "references/",
@@ -40,6 +40,7 @@ GODPOWERS LOCATE
40
40
 
41
41
  Project: <name> Mode: <A/B/C/E> Suite: <yes/no>
42
42
  Lifecycle: <phase> Current: <tier>/<substep>
43
+ Progress: <pct>% (<complete> of <total> steps complete; current step <n> of <total>)
43
44
 
44
45
  Last action: <name> by <actor> at <ts>
45
46
  Last user instruction: <if available>
@@ -55,6 +56,14 @@ Recent events (last 5):
55
56
  - <event>
56
57
  - ...
57
58
 
59
+ What happened recently:
60
+ - <checkpoint action or event summary>
61
+ - <checkpoint action or event summary>
62
+
63
+ What happens next:
64
+ - <next command>
65
+ - <one-line reason>
66
+
58
67
  Next suggested: <command>
59
68
  Reason: <why>
60
69
 
@@ -73,8 +82,12 @@ Drift check:
73
82
  3. If state.json is missing: project is broken; run `/god-doctor`.
74
83
  4. Compute age of CHECKPOINT last-update; flag staleness if > 1 hour
75
84
  or > 100 events since last checkpoint write.
76
- 5. Produce single-screen orientation summary.
77
- 6. Append `op:locate` event to events.jsonl.
85
+ 5. Compute progress from `lib/state.progressSummary(stateJson)` and show
86
+ percentage, complete count, total count, and current step number.
87
+ 6. Summarize "what happened recently" from CHECKPOINT.md actions or recent
88
+ events, then summarize "what happens next" from routing.
89
+ 7. Produce single-screen orientation summary.
90
+ 8. Append `op:locate` event to events.jsonl.
78
91
 
79
92
  ## Difference from /god-status
80
93
 
@@ -164,6 +164,8 @@ The God Mode transcript is an operator console, not a prompt debugger.
164
164
 
165
165
  Show:
166
166
  - detected resume or project mode in plain language
167
+ - a compact "Next step" card before each visible phase or tier sub-step
168
+ - a compact "Step result" card after each visible phase or tier sub-step
167
169
  - short progress updates for phases, commands, validations, and file edits
168
170
  - concise validation summaries instead of full command noise when possible
169
171
  - final changed paths, validation results, and completion or pause status
@@ -182,6 +184,39 @@ smallest user-facing question. For example, ask for
182
184
  `STAGING_APP_URL=<deployed staging origin>` instead of exposing the full
183
185
  Shipping Closure Protocol.
184
186
 
187
+ ## Step Cards
188
+
189
+ Relay the orchestrator's step cards when present. If the orchestrator output is
190
+ missing them, synthesize them from disk state before continuing.
191
+
192
+ Before work starts:
193
+
194
+ ```
195
+ Next step
196
+ Progress: <pct>% (<done> of <total> steps complete; current step <n> of <total>)
197
+ Tier: <tier-number> <tier-label>
198
+ Step: <sub-step-label>
199
+ Why this now: <one sentence>
200
+ What will happen:
201
+ 1. <observable action>
202
+ 2. <observable action>
203
+ Expected output: <artifact path or verification result>
204
+ ```
205
+
206
+ After work completes or pauses:
207
+
208
+ ```
209
+ Step result
210
+ Progress: <pct>% (<done> of <total> steps complete; current step <n> of <total>)
211
+ Tier: <tier-number> <tier-label>
212
+ Step: <sub-step-label>
213
+ Result: <done | blocked | failed | skipped | imported>
214
+ What happened:
215
+ 1. <observable action completed>
216
+ 2. <artifact or verification result>
217
+ Next: <next command or pause question>
218
+ ```
219
+
185
220
  ## Pause Format (relay from orchestrator)
186
221
 
187
222
  ```
@@ -147,6 +147,17 @@ Display: "Suggested next: /god-arch
147
147
  Why: PRD is complete; architecture is the next gate"
148
148
  ```
149
149
 
150
+ When the suggestion is based on state.json, also show the immediate route:
151
+
152
+ ```
153
+ Path ahead:
154
+ 1. Current: <tier>/<substep> - <status>
155
+ 2. Next: /god-X - <why>
156
+ 3. Then: /god-Y - <next gate, if known>
157
+ ```
158
+
159
+ Keep the route to 3 lines unless the user asks for the full plan.
160
+
150
161
  ## Process for Mode 4 (intent-based)
151
162
 
152
163
  ```
@@ -280,10 +291,16 @@ recommending archaeology, reconstruction, arc-ready, pillars, or refactor work.
280
291
  Godpowers Next
281
292
 
282
293
  Current state: [where we are]
294
+ Progress: [pct]% ([done] of [total] steps complete; current step [n] of [total])
283
295
  Suggested next: [/god-X]
284
296
 
285
297
  Why: [one-line reason]
286
298
 
299
+ Path ahead:
300
+ 1. Current: [tier/substep] - [status]
301
+ 2. Next: [/god-X] - [why]
302
+ 3. Then: [/god-Y or "recompute after gate"]
303
+
287
304
  [If prereqs missing]:
288
305
  Pre-flight: missing [prereq]
289
306
  Auto-complete available: /god-Y
@@ -33,6 +33,9 @@ Re-derive state from disk. Your memory is not authoritative. The file system is.
33
33
  - If artifact exists but PROGRESS.md says "pending": FLAG as untracked work
34
34
  6. Report:
35
35
  - Current mode and scale
36
+ - Progress summary: percentage, completed step count, current step number
37
+ - What happened recently, using CHECKPOINT.md actions when available
38
+ - What happens next, using routing and disk state
36
39
  - Per-tier status (with disk verification)
37
40
  - Any inconsistencies between PROGRESS.md and disk
38
41
  - Suggested next action
@@ -45,6 +48,17 @@ Godpowers Status
45
48
 
46
49
  Mode: A (greenfield) Scale: medium
47
50
  Started: 2026-05-09
51
+ Progress: 15% (2 of 13 steps complete; current step 3 of 13)
52
+ Current: Tier 1 Planning / Architecture
53
+
54
+ What happened recently:
55
+ 1. PRD artifact verified on disk
56
+ 2. Tier state refreshed from state.json
57
+
58
+ What happens next:
59
+ 1. Run /god-arch
60
+ 2. Verify architecture artifact
61
+ 3. Recompute next gate with /god-next
48
62
 
49
63
  Tier 1: Planning
50
64
  + PRD done .godpowers/prd/PRD.md (lint clean: 0 errors)
@@ -7,11 +7,33 @@ Mode: [A: greenfield | B: gap-fill | C: audit | D: multi-repo]
7
7
  Scale: [trivial | small | medium | large | enterprise]
8
8
  Started: [ISO 8601 timestamp]
9
9
  Last updated: [ISO 8601 timestamp]
10
+ Progress: [0-100]% ([completed] of [total] steps complete; current step [n] of [total])
11
+ Current: [Tier N label] / [sub-step label]
10
12
 
11
13
  ## Project Description
12
14
 
13
15
  [One paragraph from /god-init]
14
16
 
17
+ ## Current Step
18
+
19
+ Why this now: [One sentence tied to disk state or the prior gate]
20
+
21
+ What will happen:
22
+ 1. [Observable action]
23
+ 2. [Observable action]
24
+ 3. [Observable action, if needed]
25
+
26
+ Expected output: [Artifact path or verification result]
27
+
28
+ ## Recent Step Results
29
+
30
+ What happened:
31
+ 1. [Observable action completed]
32
+ 2. [Artifact or state update]
33
+ 3. [Verification result]
34
+
35
+ Next: [Next command or pause question]
36
+
15
37
  ## Tier Status
16
38
 
17
39
  | Tier | Sub-step | Status | Artifact | Updated |