godpowers 3.0.1 → 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/CHANGELOG.md +255 -2
  2. package/README.md +31 -14
  3. package/RELEASE.md +21 -33
  4. package/SKILL.md +71 -112
  5. package/bin/install.js +44 -0
  6. package/fixtures/gate/harden-pass/.godpowers/state.json +26 -0
  7. package/lib/README.md +1 -0
  8. package/lib/artifact-map.js +2 -1
  9. package/lib/cli-dispatch.js +449 -3
  10. package/lib/command-families.js +10 -2
  11. package/lib/evidence/.provenance.json +45 -0
  12. package/lib/evidence-import.js +147 -0
  13. package/lib/evidence.js +908 -0
  14. package/lib/gate.js +26 -15
  15. package/lib/install-profiles.js +4 -1
  16. package/lib/installer-args.js +241 -1
  17. package/lib/quarterback.js +183 -0
  18. package/lib/surface-profile.js +168 -0
  19. package/lib/work-report.js +137 -0
  20. package/package.json +2 -2
  21. package/references/orchestration/GOD-MODE-RUNBOOK.md +9 -14
  22. package/references/orchestration/GOD-ORCHESTRATOR-RUNBOOK.md +40 -82
  23. package/references/shared/DASHBOARD-CONTRACT.md +66 -29
  24. package/references/shared/README.md +1 -1
  25. package/routing/god-demo.yaml +35 -0
  26. package/routing/god-first-run.yaml +34 -0
  27. package/routing/god-surface.yaml +39 -0
  28. package/routing/recipes/try-safely.yaml +26 -0
  29. package/skills/god-agent-audit.md +5 -6
  30. package/skills/god-archaeology.md +5 -6
  31. package/skills/god-audit.md +6 -7
  32. package/skills/god-automation-setup.md +6 -7
  33. package/skills/god-automation-status.md +6 -7
  34. package/skills/god-context-scan.md +7 -8
  35. package/skills/god-demo.md +53 -0
  36. package/skills/god-design-impact.md +5 -6
  37. package/skills/god-discuss.md +5 -6
  38. package/skills/god-docs.md +5 -10
  39. package/skills/god-doctor.md +8 -9
  40. package/skills/god-dogfood.md +7 -10
  41. package/skills/god-explore.md +5 -7
  42. package/skills/god-first-run.md +64 -0
  43. package/skills/god-harden.md +5 -2
  44. package/skills/god-help.md +77 -51
  45. package/skills/god-hygiene.md +5 -6
  46. package/skills/god-lifecycle.md +11 -13
  47. package/skills/god-list-assumptions.md +7 -8
  48. package/skills/god-locate.md +7 -8
  49. package/skills/god-map-codebase.md +5 -6
  50. package/skills/god-migrate.md +6 -15
  51. package/skills/god-next.md +16 -17
  52. package/skills/god-preflight.md +7 -8
  53. package/skills/god-progress.md +7 -8
  54. package/skills/god-reconcile.md +5 -6
  55. package/skills/god-reconstruct.md +5 -7
  56. package/skills/god-refactor.md +6 -7
  57. package/skills/god-roadmap-check.md +6 -7
  58. package/skills/god-scan.md +5 -9
  59. package/skills/god-spike.md +5 -6
  60. package/skills/god-standards.md +5 -6
  61. package/skills/god-status.md +12 -10
  62. package/skills/god-surface.md +61 -0
  63. package/skills/god-sync.md +4 -8
  64. package/skills/god-tech-debt.md +5 -6
  65. package/skills/god-test-runtime.md +4 -8
  66. package/skills/god-version.md +1 -1
  67. package/skills/god.md +53 -52
@@ -0,0 +1,147 @@
1
+ /**
2
+ * One-time importer for existing Mythify .mythify/ ledgers.
3
+ *
4
+ * Optional, best-effort, additive: it copies an existing Mythify state dir into
5
+ * the Godpowers ledger, rebinding the Mythify plan/step context to Godpowers'
6
+ * arc/substep on each record. It appends to the ledger and does NOT roll up into
7
+ * state.json or emit gate events; this is a historical import, not a re-run.
8
+ *
9
+ * See docs/FUSION-ARCHITECTURE.md (Phase 3, optional importer).
10
+ */
11
+
12
+ const fs = require('fs');
13
+ const path = require('path');
14
+
15
+ const atomic = require('./atomic-write');
16
+ const evidence = require('./evidence');
17
+
18
+ function readJson(file) {
19
+ try {
20
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
21
+ } catch (_) {
22
+ return null;
23
+ }
24
+ }
25
+
26
+ /**
27
+ * Rebind a Mythify record's plan/step context to Godpowers' arc/substep.
28
+ * Records that already carry arc/substep pass through unchanged.
29
+ */
30
+ function rebindRecord(record) {
31
+ if (!record || typeof record !== 'object') return record;
32
+ const hasMythifyContext = 'plan' in record || 'step_id' in record
33
+ || 'step_title' in record || 'step_status' in record;
34
+ if (!hasMythifyContext) return { ...record };
35
+ const out = { ...record };
36
+ out.arc = record.arc !== undefined ? record.arc : (record.plan !== undefined ? record.plan : null);
37
+ out.substep = record.substep !== undefined ? record.substep : (record.step_id !== undefined ? record.step_id : null);
38
+ out.substep_status = record.substep_status !== undefined
39
+ ? record.substep_status
40
+ : (record.step_status !== undefined ? record.step_status : null);
41
+ delete out.plan;
42
+ delete out.step_id;
43
+ delete out.step_title;
44
+ delete out.step_status;
45
+ return out;
46
+ }
47
+
48
+ /**
49
+ * Import an existing .mythify/ ledger into the Godpowers ledger.
50
+ *
51
+ * @param {{ source?: string, projectRoot?: string }} [opts]
52
+ * @returns {{ source: string, projectRoot: string, found: boolean,
53
+ * imported: { verifications: number, reflections: number, memory: number, lessons: number, outcomes: number },
54
+ * error?: string }}
55
+ */
56
+ function importMythify(opts = {}) {
57
+ const projectRoot = path.resolve(opts.projectRoot || process.cwd());
58
+ const source = path.resolve(opts.source || path.join(projectRoot, '.mythify'));
59
+ const result = {
60
+ source,
61
+ projectRoot,
62
+ found: false,
63
+ imported: { verifications: 0, reflections: 0, memory: 0, lessons: 0, outcomes: 0 }
64
+ };
65
+ if (!fs.existsSync(source)) {
66
+ result.error = 'source-not-found';
67
+ return result;
68
+ }
69
+ result.found = true;
70
+
71
+ // Verifications (rebind plan/step -> arc/substep).
72
+ for (const record of evidence.readJsonl(path.join(source, 'verifications.jsonl'))) {
73
+ evidence.appendJsonlAtomic(evidence.verificationsPath(projectRoot), rebindRecord(record));
74
+ result.imported.verifications += 1;
75
+ }
76
+
77
+ // Reflections (rebind for any bound context; mostly pass-through).
78
+ for (const record of evidence.readJsonl(path.join(source, 'reflections.jsonl'))) {
79
+ evidence.appendJsonlAtomic(evidence.reflectionsPath(projectRoot), rebindRecord(record));
80
+ result.imported.reflections += 1;
81
+ }
82
+
83
+ // Memory (merge entries by key).
84
+ const sourceMemory = readJson(path.join(source, 'memory.json'));
85
+ if (sourceMemory && Array.isArray(sourceMemory.entries) && sourceMemory.entries.length > 0) {
86
+ const dest = readJson(evidence.memoryPath(projectRoot)) || { entries: [], metadata: {} };
87
+ if (!Array.isArray(dest.entries)) dest.entries = [];
88
+ for (const entry of sourceMemory.entries) {
89
+ if (!entry || typeof entry.key !== 'string') continue;
90
+ const idx = dest.entries.findIndex((existing) => existing && existing.key === entry.key);
91
+ if (idx >= 0) dest.entries[idx] = entry;
92
+ else dest.entries.push(entry);
93
+ result.imported.memory += 1;
94
+ }
95
+ dest.metadata = dest.metadata || {};
96
+ dest.metadata.total_entries = dest.entries.length;
97
+ fs.mkdirSync(evidence.ledgerDir(projectRoot), { recursive: true });
98
+ atomic.writeJsonAtomic(evidence.memoryPath(projectRoot), dest);
99
+ }
100
+
101
+ // Lessons (Mythify lessons/*.json -> our lessons.jsonl).
102
+ const lessonsDir = path.join(source, 'lessons');
103
+ if (fs.existsSync(lessonsDir)) {
104
+ for (const name of fs.readdirSync(lessonsDir).filter((n) => n.endsWith('.json'))) {
105
+ const lesson = readJson(path.join(lessonsDir, name));
106
+ if (lesson) {
107
+ evidence.appendJsonlAtomic(evidence.lessonsPath(projectRoot, 'project'), lesson);
108
+ result.imported.lessons += 1;
109
+ }
110
+ }
111
+ }
112
+
113
+ // Outcomes (copy goal.json + iterations.jsonl per slug).
114
+ const outcomesDir = path.join(source, 'outcomes');
115
+ if (fs.existsSync(outcomesDir)) {
116
+ for (const slug of fs.readdirSync(outcomesDir)) {
117
+ const srcGoal = path.join(outcomesDir, slug, 'goal.json');
118
+ if (!fs.existsSync(srcGoal)) continue;
119
+ const destDir = path.join(evidence.ledgerDir(projectRoot), 'outcomes', slug);
120
+ fs.mkdirSync(destDir, { recursive: true });
121
+ atomic.writeFileAtomic(path.join(destDir, 'goal.json'), fs.readFileSync(srcGoal, 'utf8'));
122
+ const srcIters = path.join(outcomesDir, slug, 'iterations.jsonl');
123
+ if (fs.existsSync(srcIters)) {
124
+ atomic.writeFileAtomic(path.join(destDir, 'iterations.jsonl'), fs.readFileSync(srcIters, 'utf8'));
125
+ }
126
+ result.imported.outcomes += 1;
127
+ }
128
+ }
129
+
130
+ return result;
131
+ }
132
+
133
+ function render(result) {
134
+ const lines = ['Godpowers Ledger Import', ''];
135
+ lines.push(`Source: ${result.source}`);
136
+ if (!result.found) {
137
+ lines.push('');
138
+ lines.push('No .mythify/ ledger found at the source. Pass --from <path>.');
139
+ return lines.join('\n');
140
+ }
141
+ const i = result.imported;
142
+ lines.push(`Imported: ${i.verifications} verification(s), ${i.reflections} reflection(s), ${i.memory} memory entr(ies), ${i.lessons} lesson(s), ${i.outcomes} outcome(s)`);
143
+ lines.push('Records were appended to the Godpowers ledger (no state rollup, no gate events).');
144
+ return lines.join('\n');
145
+ }
146
+
147
+ module.exports = { importMythify, rebindRecord, render };