godpowers 1.6.15 → 1.6.17
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 +55 -0
- package/README.md +19 -9
- package/RELEASE.md +41 -53
- package/SKILL.md +19 -2
- package/lib/README.md +4 -0
- package/lib/context-writer.js +3 -4
- package/lib/dashboard.js +6 -1
- package/lib/feature-awareness.js +226 -0
- package/lib/pillars.js +9 -0
- package/lib/repo-doc-sync.js +392 -0
- package/package.json +2 -2
- package/routing/god-export-otel.yaml +24 -0
- package/schema/state.v1.json +26 -0
- package/skills/god-context.md +15 -5
- package/skills/god-docs.md +7 -0
- package/skills/god-doctor.md +33 -0
- package/skills/god-mode.md +14 -0
- package/skills/god-status.md +2 -2
- package/skills/god-sync.md +17 -4
- package/skills/god-version.md +2 -1
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository documentation sync.
|
|
3
|
+
*
|
|
4
|
+
* Keeps mechanical public repository claims aligned with the actual runtime
|
|
5
|
+
* surface. Narrative docs remain human or specialist-agent owned.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const crypto = require('crypto');
|
|
11
|
+
|
|
12
|
+
const pillars = require('./pillars');
|
|
13
|
+
|
|
14
|
+
const LOG_PATH = '.godpowers/docs/REPO-DOC-SYNC.md';
|
|
15
|
+
|
|
16
|
+
function read(projectRoot, relPath) {
|
|
17
|
+
const file = path.join(projectRoot, relPath);
|
|
18
|
+
if (!fs.existsSync(file)) return '';
|
|
19
|
+
return fs.readFileSync(file, 'utf8');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function write(projectRoot, relPath, text) {
|
|
23
|
+
const file = path.join(projectRoot, relPath);
|
|
24
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
25
|
+
fs.writeFileSync(file, text);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function exists(projectRoot, relPath) {
|
|
29
|
+
return fs.existsSync(path.join(projectRoot, relPath));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function countFiles(projectRoot, dir, pattern) {
|
|
33
|
+
const full = path.join(projectRoot, dir);
|
|
34
|
+
if (!fs.existsSync(full)) return 0;
|
|
35
|
+
return fs.readdirSync(full).filter((name) => pattern.test(name)).length;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function readPackage(projectRoot) {
|
|
39
|
+
const file = path.join(projectRoot, 'package.json');
|
|
40
|
+
if (!fs.existsSync(file)) return {};
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
43
|
+
} catch (err) {
|
|
44
|
+
return {};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function packageVersion(projectRoot) {
|
|
49
|
+
return readPackage(projectRoot).version || 'unknown';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function counts(projectRoot) {
|
|
53
|
+
return {
|
|
54
|
+
skills: countFiles(projectRoot, 'skills', /^god.*\.md$/),
|
|
55
|
+
agents: countFiles(projectRoot, 'agents', /^god.*\.md$/),
|
|
56
|
+
workflows: countFiles(projectRoot, 'workflows', /\.yaml$/),
|
|
57
|
+
recipes: countFiles(projectRoot, path.join('routing', 'recipes'), /\.yaml$/)
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function expectedSurface(projectRoot) {
|
|
62
|
+
const version = packageVersion(projectRoot);
|
|
63
|
+
const surfaceCounts = counts(projectRoot);
|
|
64
|
+
return {
|
|
65
|
+
version,
|
|
66
|
+
counts: surfaceCounts,
|
|
67
|
+
surface: `${surfaceCounts.skills} skills, ${surfaceCounts.agents} agents`,
|
|
68
|
+
commandSurface: `${surfaceCounts.skills} slash commands`,
|
|
69
|
+
workflowSurface: `${surfaceCounts.workflows} workflows`,
|
|
70
|
+
recipeSurface: `${surfaceCounts.recipes} recipes`,
|
|
71
|
+
minorSeries: version.split('.').slice(0, 2).join('.')
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function includes(projectRoot, relPath, expected) {
|
|
76
|
+
const text = read(projectRoot, relPath);
|
|
77
|
+
return text.includes(expected);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function makeCheck(id, relPath, expected, opts = {}) {
|
|
81
|
+
return {
|
|
82
|
+
id,
|
|
83
|
+
path: relPath,
|
|
84
|
+
expected,
|
|
85
|
+
safeFix: opts.safeFix === true,
|
|
86
|
+
owner: opts.owner || (opts.safeFix ? 'local runtime' : 'god-docs-writer'),
|
|
87
|
+
reason: opts.reason || ''
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function checkDefinitions(projectRoot) {
|
|
92
|
+
const expected = expectedSurface(projectRoot);
|
|
93
|
+
return [
|
|
94
|
+
makeCheck('package-description-surface', 'package.json',
|
|
95
|
+
`${expected.counts.skills} slash commands and ${expected.counts.agents} specialist agents`,
|
|
96
|
+
{ safeFix: true, reason: 'package metadata is a mechanical count claim' }),
|
|
97
|
+
makeCheck('readme-version-badge', 'README.md', `version-${expected.version}-blue`,
|
|
98
|
+
{ safeFix: true, reason: 'README badge mirrors package version' }),
|
|
99
|
+
makeCheck('readme-reference-counts', 'README.md',
|
|
100
|
+
`all ${expected.counts.skills} skills + ${expected.counts.agents} agents`,
|
|
101
|
+
{ safeFix: true, reason: 'README command reference count mirrors files on disk' }),
|
|
102
|
+
makeCheck('users-version', 'USERS.md', `Godpowers is at v${expected.version}. Stable release.`,
|
|
103
|
+
{ safeFix: true, reason: 'user support version mirrors package version' }),
|
|
104
|
+
makeCheck('architecture-version', 'ARCHITECTURE.md', `STABLE v${expected.version}`,
|
|
105
|
+
{ safeFix: true, reason: 'architecture release marker mirrors package version' }),
|
|
106
|
+
makeCheck('architecture-surface', 'ARCHITECTURE.md',
|
|
107
|
+
`Core: ${expected.surface}, ${expected.workflowSurface}`,
|
|
108
|
+
{ safeFix: true, reason: 'architecture surface mirrors repository counts' }),
|
|
109
|
+
makeCheck('roadmap-version', 'docs/ROADMAP.md', `Current shipped: v${expected.version}`,
|
|
110
|
+
{ safeFix: true, reason: 'roadmap current shipped marker mirrors package version' }),
|
|
111
|
+
makeCheck('roadmap-command-count', 'docs/ROADMAP.md', `**${expected.commandSurface}**`,
|
|
112
|
+
{ safeFix: true, reason: 'roadmap command count mirrors skills directory' }),
|
|
113
|
+
makeCheck('roadmap-agent-count', 'docs/ROADMAP.md',
|
|
114
|
+
`**${expected.counts.agents} specialist agents**`,
|
|
115
|
+
{ safeFix: true, reason: 'roadmap agent count mirrors agents directory' }),
|
|
116
|
+
makeCheck('reference-version', 'docs/reference.md', `reference for v${expected.version}`,
|
|
117
|
+
{ safeFix: true, reason: 'reference docs version mirrors package version' }),
|
|
118
|
+
makeCheck('reference-command-count', 'docs/reference.md',
|
|
119
|
+
`Slash commands (${expected.counts.skills} total)`,
|
|
120
|
+
{ safeFix: true, reason: 'reference command count mirrors skills directory' }),
|
|
121
|
+
makeCheck('reference-agent-count', 'docs/reference.md',
|
|
122
|
+
`Specialist agents (${expected.counts.agents} total)`,
|
|
123
|
+
{ safeFix: true, reason: 'reference agent count mirrors agents directory' }),
|
|
124
|
+
makeCheck('god-version-surface', 'skills/god-version.md',
|
|
125
|
+
`Surface: ${expected.surface}, ${expected.workflowSurface}, ${expected.recipeSurface}`,
|
|
126
|
+
{ safeFix: true, reason: '/god-version output mirrors repository counts' }),
|
|
127
|
+
makeCheck('god-doctor-skill-count', 'skills/god-doctor.md',
|
|
128
|
+
`[OK] ${expected.counts.skills} skills installed`,
|
|
129
|
+
{ safeFix: true, reason: '/god-doctor sample output mirrors skills directory' }),
|
|
130
|
+
makeCheck('god-doctor-agent-count', 'skills/god-doctor.md',
|
|
131
|
+
`[OK] ${expected.counts.agents} agents installed`,
|
|
132
|
+
{ safeFix: true, reason: '/god-doctor sample output mirrors agents directory' }),
|
|
133
|
+
makeCheck('release-notes-version', 'RELEASE.md', `Godpowers ${expected.version}`,
|
|
134
|
+
{ reason: 'release notes are narrative and should be reviewed before publish' }),
|
|
135
|
+
makeCheck('changelog-version', 'CHANGELOG.md', `## [${expected.version}]`,
|
|
136
|
+
{ reason: 'changelog entries are narrative and should be curated' }),
|
|
137
|
+
makeCheck('security-supported-series', 'SECURITY.md', `${expected.minorSeries}.x`,
|
|
138
|
+
{ reason: 'supported versions are release policy and should be reviewed' }),
|
|
139
|
+
makeCheck('contributing-release-sync', 'CONTRIBUTING.md', 'repo documentation sync',
|
|
140
|
+
{ reason: 'contributor release guidance is narrative policy' })
|
|
141
|
+
];
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function detect(projectRoot, opts = {}) {
|
|
145
|
+
const expected = expectedSurface(projectRoot);
|
|
146
|
+
const checks = checkDefinitions(projectRoot).map((check) => {
|
|
147
|
+
const present = exists(projectRoot, check.path);
|
|
148
|
+
const fresh = present && includes(projectRoot, check.path, check.expected);
|
|
149
|
+
return {
|
|
150
|
+
...check,
|
|
151
|
+
status: !present ? 'missing' : (fresh ? 'fresh' : 'stale')
|
|
152
|
+
};
|
|
153
|
+
});
|
|
154
|
+
const stale = checks.filter((check) => check.status !== 'fresh');
|
|
155
|
+
const safeFixes = stale.filter((check) => check.safeFix);
|
|
156
|
+
const prose = stale.filter((check) => !check.safeFix);
|
|
157
|
+
const changedFiles = opts.changedFiles || [];
|
|
158
|
+
const touchedDocs = changedFiles.filter((file) => isRepoDocPath(file));
|
|
159
|
+
const pillarSyncPlan = touchedDocs.length > 0
|
|
160
|
+
? pillars.planArtifactSync(projectRoot, touchedDocs, opts)
|
|
161
|
+
: [];
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
version: expected.version,
|
|
165
|
+
counts: expected.counts,
|
|
166
|
+
status: stale.length === 0 ? 'fresh' : 'stale',
|
|
167
|
+
checks,
|
|
168
|
+
stale,
|
|
169
|
+
safeFixes,
|
|
170
|
+
prose,
|
|
171
|
+
touchedDocs,
|
|
172
|
+
pillarSyncPlan,
|
|
173
|
+
adjacentOpportunities: adjacentOpportunities(),
|
|
174
|
+
spawnRecommendation: prose.length > 0
|
|
175
|
+
? {
|
|
176
|
+
agent: 'god-docs-writer',
|
|
177
|
+
reason: 'Repo documentation has narrative release, contribution, or security policy drift.',
|
|
178
|
+
paths: [...new Set(prose.map((check) => check.path))].sort()
|
|
179
|
+
}
|
|
180
|
+
: null
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function replaceOnce(text, regex, replacement) {
|
|
185
|
+
if (!regex.test(text)) return text;
|
|
186
|
+
return text.replace(regex, replacement);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function safeFixContent(relPath, text, expected) {
|
|
190
|
+
switch (relPath) {
|
|
191
|
+
case 'package.json':
|
|
192
|
+
return fixPackageDescription(text, expected);
|
|
193
|
+
case 'README.md':
|
|
194
|
+
return replaceOnce(
|
|
195
|
+
replaceOnce(text, /version-[0-9]+\.[0-9]+\.[0-9]+-blue/g, `version-${expected.version}-blue`),
|
|
196
|
+
/all [0-9]+ skills \+ [0-9]+ agents/g,
|
|
197
|
+
`all ${expected.counts.skills} skills + ${expected.counts.agents} agents`
|
|
198
|
+
);
|
|
199
|
+
case 'USERS.md':
|
|
200
|
+
return replaceOnce(text, /Godpowers is at v[0-9]+\.[0-9]+\.[0-9]+\. Stable release\./g,
|
|
201
|
+
`Godpowers is at v${expected.version}. Stable release.`);
|
|
202
|
+
case 'ARCHITECTURE.md':
|
|
203
|
+
return replaceOnce(
|
|
204
|
+
replaceOnce(text, /STABLE v[0-9]+\.[0-9]+\.[0-9]+/g, `STABLE v${expected.version}`),
|
|
205
|
+
/Core: [0-9]+ skills, [0-9]+ agents, [0-9]+ workflows/g,
|
|
206
|
+
`Core: ${expected.surface}, ${expected.workflowSurface}`
|
|
207
|
+
);
|
|
208
|
+
case 'docs/ROADMAP.md':
|
|
209
|
+
return replaceOnce(
|
|
210
|
+
replaceOnce(
|
|
211
|
+
replaceOnce(text, /Current shipped: v[0-9]+\.[0-9]+\.[0-9]+/g,
|
|
212
|
+
`Current shipped: v${expected.version}`),
|
|
213
|
+
/\*\*[0-9]+ slash commands\*\*/g,
|
|
214
|
+
`**${expected.commandSurface}**`
|
|
215
|
+
),
|
|
216
|
+
/\*\*[0-9]+ specialist agents\*\*/g,
|
|
217
|
+
`**${expected.counts.agents} specialist agents**`
|
|
218
|
+
);
|
|
219
|
+
case 'docs/reference.md':
|
|
220
|
+
return replaceOnce(
|
|
221
|
+
replaceOnce(
|
|
222
|
+
replaceOnce(text, /reference for v[0-9]+\.[0-9]+\.[0-9]+/g,
|
|
223
|
+
`reference for v${expected.version}`),
|
|
224
|
+
/Slash commands \([0-9]+ total\)/g,
|
|
225
|
+
`Slash commands (${expected.counts.skills} total)`
|
|
226
|
+
),
|
|
227
|
+
/Specialist agents \([0-9]+ total\)/g,
|
|
228
|
+
`Specialist agents (${expected.counts.agents} total)`
|
|
229
|
+
);
|
|
230
|
+
case 'skills/god-version.md':
|
|
231
|
+
return replaceOnce(text,
|
|
232
|
+
/Surface: [0-9]+ skills, [0-9]+ agents, [0-9]+ workflows, [0-9]+ recipes/g,
|
|
233
|
+
`Surface: ${expected.surface}, ${expected.workflowSurface}, ${expected.recipeSurface}`);
|
|
234
|
+
case 'skills/god-doctor.md':
|
|
235
|
+
return replaceOnce(
|
|
236
|
+
replaceOnce(text, /\[OK\] [0-9]+ skills installed/g,
|
|
237
|
+
`[OK] ${expected.counts.skills} skills installed`),
|
|
238
|
+
/\[OK\] [0-9]+ agents installed/g,
|
|
239
|
+
`[OK] ${expected.counts.agents} agents installed`
|
|
240
|
+
);
|
|
241
|
+
default:
|
|
242
|
+
return text;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function fixPackageDescription(text, expected) {
|
|
247
|
+
try {
|
|
248
|
+
const parsed = JSON.parse(text);
|
|
249
|
+
if (typeof parsed.description === 'string') {
|
|
250
|
+
parsed.description = parsed.description.replace(
|
|
251
|
+
/[0-9]+ slash commands and [0-9]+ specialist agents/g,
|
|
252
|
+
`${expected.counts.skills} slash commands and ${expected.counts.agents} specialist agents`
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
return `${JSON.stringify(parsed, null, 2)}\n`;
|
|
256
|
+
} catch (err) {
|
|
257
|
+
return text;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function isRepoDocPath(file) {
|
|
262
|
+
return [
|
|
263
|
+
'README.md',
|
|
264
|
+
'CHANGELOG.md',
|
|
265
|
+
'RELEASE.md',
|
|
266
|
+
'CONTRIBUTING.md',
|
|
267
|
+
'SECURITY.md',
|
|
268
|
+
'SUPPORT.md',
|
|
269
|
+
'AGENTS.md'
|
|
270
|
+
].includes(file) || file.startsWith('docs/');
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function appendLog(projectRoot, before, after, applied) {
|
|
274
|
+
const now = new Date().toISOString();
|
|
275
|
+
const lines = [];
|
|
276
|
+
if (exists(projectRoot, LOG_PATH)) {
|
|
277
|
+
lines.push(read(projectRoot, LOG_PATH).replace(/\s*$/, ''));
|
|
278
|
+
lines.push('');
|
|
279
|
+
} else {
|
|
280
|
+
lines.push('# Repo Documentation Sync Log');
|
|
281
|
+
lines.push('');
|
|
282
|
+
lines.push('- [DECISION] This file records mechanical repository documentation syncs run by Godpowers.');
|
|
283
|
+
lines.push('- [DECISION] Narrative release, contribution, support, and security policy prose remains owned by humans or `god-docs-writer`.');
|
|
284
|
+
lines.push('');
|
|
285
|
+
}
|
|
286
|
+
lines.push(`## ${now}`);
|
|
287
|
+
lines.push('');
|
|
288
|
+
lines.push(`- [DECISION] Repo documentation sync status before apply was ${before.status}.`);
|
|
289
|
+
lines.push(`- [DECISION] Repo documentation sync status after apply is ${after.status}.`);
|
|
290
|
+
if (applied.length === 0) {
|
|
291
|
+
lines.push('- [DECISION] No mechanical repo documentation files were changed.');
|
|
292
|
+
} else {
|
|
293
|
+
for (const item of applied) {
|
|
294
|
+
lines.push(`- [DECISION] Refreshed ${item.path} for ${item.checks.join(', ')}.`);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
if (after.spawnRecommendation) {
|
|
298
|
+
lines.push(`- [HYPOTHESIS] ${after.spawnRecommendation.agent} should review ${after.spawnRecommendation.paths.join(', ')}.`);
|
|
299
|
+
}
|
|
300
|
+
lines.push('');
|
|
301
|
+
write(projectRoot, LOG_PATH, lines.join('\n'));
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function run(projectRoot, opts = {}) {
|
|
305
|
+
const before = detect(projectRoot, opts);
|
|
306
|
+
const expected = expectedSurface(projectRoot);
|
|
307
|
+
const byPath = new Map();
|
|
308
|
+
const applied = [];
|
|
309
|
+
|
|
310
|
+
for (const check of before.safeFixes) {
|
|
311
|
+
if (!byPath.has(check.path)) byPath.set(check.path, []);
|
|
312
|
+
byPath.get(check.path).push(check);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
for (const [relPath, checks] of byPath.entries()) {
|
|
316
|
+
const original = read(projectRoot, relPath);
|
|
317
|
+
if (!original) continue;
|
|
318
|
+
const next = safeFixContent(relPath, original, expected);
|
|
319
|
+
if (next !== original) {
|
|
320
|
+
write(projectRoot, relPath, next);
|
|
321
|
+
applied.push({
|
|
322
|
+
path: relPath,
|
|
323
|
+
checks: checks.map((check) => check.id)
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const touched = applied.map((item) => item.path);
|
|
329
|
+
const pillarResults = opts.applyPillars && touched.length > 0
|
|
330
|
+
? pillars.applyArtifactSync(projectRoot, touched, opts)
|
|
331
|
+
: pillars.planArtifactSync(projectRoot, touched, opts);
|
|
332
|
+
|
|
333
|
+
const after = detect(projectRoot, { ...opts, changedFiles: touched });
|
|
334
|
+
if (opts.log !== false) appendLog(projectRoot, before, after, applied);
|
|
335
|
+
|
|
336
|
+
return {
|
|
337
|
+
before,
|
|
338
|
+
after,
|
|
339
|
+
applied,
|
|
340
|
+
pillarResults,
|
|
341
|
+
logPath: opts.log === false ? null : LOG_PATH,
|
|
342
|
+
hash: sha(JSON.stringify({ before: before.status, after: after.status, applied }))
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function sha(input) {
|
|
347
|
+
return `sha256:${crypto.createHash('sha256').update(input).digest('hex')}`;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function adjacentOpportunities() {
|
|
351
|
+
return [
|
|
352
|
+
{
|
|
353
|
+
id: 'routing-surface-sync',
|
|
354
|
+
trigger: '/god-doctor, /god-help, /god-next, /god-sync',
|
|
355
|
+
behavior: 'detect missing routing YAML for installed slash-command skills',
|
|
356
|
+
escalation: 'suggest fix by default, auto-apply only under fix mode'
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
id: 'package-installer-sync',
|
|
360
|
+
trigger: '/god-doctor, /god-sync, release checks',
|
|
361
|
+
behavior: 'detect package file allowlist and installer smoke drift when runtime files are added',
|
|
362
|
+
escalation: 'suggest fix because package contents affect release'
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
id: 'agent-contract-sync',
|
|
366
|
+
trigger: '/god-agent-audit, /god-doctor, /god-sync',
|
|
367
|
+
behavior: 'compare route spawns, skill docs, agent files, and agent specs',
|
|
368
|
+
escalation: 'spawn god-auditor when ownership or handoff conflicts need judgment'
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
id: 'workflow-recipe-graph-sync',
|
|
372
|
+
trigger: '/god-next, /god-mode, /god-doctor',
|
|
373
|
+
behavior: 'compare workflow YAML, recipes, command flows, and orchestrator guidance',
|
|
374
|
+
escalation: 'spawn god-roadmap-reconciler when lifecycle intent is ambiguous'
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
id: 'extension-pack-sync',
|
|
378
|
+
trigger: '/god-extension-info, /god-extension-list, /god-doctor',
|
|
379
|
+
behavior: 'compare first-party extension manifests, READMEs, skills, agents, and workflows',
|
|
380
|
+
escalation: 'spawn god-coordinator for multi-pack release prep'
|
|
381
|
+
}
|
|
382
|
+
];
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
module.exports = {
|
|
386
|
+
LOG_PATH,
|
|
387
|
+
counts,
|
|
388
|
+
expectedSurface,
|
|
389
|
+
detect,
|
|
390
|
+
run,
|
|
391
|
+
adjacentOpportunities
|
|
392
|
+
};
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "godpowers",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.17",
|
|
4
4
|
"description": "AI-powered development system: 109 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
|
},
|
|
8
8
|
"scripts": {
|
|
9
|
-
"test": "node scripts/validate-skills.js && node scripts/test-doc-surface-counts.js && bash scripts/smoke.sh && node scripts/test-runtime.js && node scripts/test-router.js && node scripts/test-recipes.js && node scripts/test-context-writer.js && node scripts/test-pillars.js && node scripts/test-artifact-linter.js && node scripts/test-artifact-diff.js && node scripts/test-design-foundation.js && node scripts/test-linkage.js && node scripts/test-impact.js && node scripts/test-reverse-sync.js && node scripts/test-planning-systems.js && node scripts/test-integration.js && node scripts/test-cross-artifact.js && node scripts/test-awesome-design.js && node scripts/test-skillui-bridge.js && node scripts/test-runtime-verification.js && node scripts/test-agent-browser.js && node scripts/test-mode-d.js && node scripts/test-runtime-heuristics.js && node scripts/test-agent-validator.js && node scripts/test-story-validator.js && node scripts/test-state.js && node scripts/test-dashboard.js && node scripts/test-automation-providers.js && node scripts/test-intent.js && node scripts/test-events.js && node scripts/test-golden-artifacts.js && node scripts/test-install-smoke.js && node scripts/test-checkpoint.js && node scripts/test-extensions.js && node scripts/test-event-reader.js && node scripts/test-state-lock.js && node scripts/test-cost-saver.js && node scripts/test-budget-onoff.js && node scripts/test-workflow-runner.js && npm run test:e2e && node scripts/test-otel-exporter.js && node scripts/test-extensions-publish.js",
|
|
9
|
+
"test": "node scripts/validate-skills.js && node scripts/test-doc-surface-counts.js && bash scripts/smoke.sh && node scripts/test-runtime.js && node scripts/test-router.js && node scripts/test-recipes.js && node scripts/test-context-writer.js && node scripts/test-pillars.js && node scripts/test-artifact-linter.js && node scripts/test-artifact-diff.js && node scripts/test-design-foundation.js && node scripts/test-linkage.js && node scripts/test-impact.js && node scripts/test-reverse-sync.js && node scripts/test-planning-systems.js && node scripts/test-feature-awareness.js && node scripts/test-repo-doc-sync.js && node scripts/test-integration.js && node scripts/test-cross-artifact.js && node scripts/test-awesome-design.js && node scripts/test-skillui-bridge.js && node scripts/test-runtime-verification.js && node scripts/test-agent-browser.js && node scripts/test-mode-d.js && node scripts/test-runtime-heuristics.js && node scripts/test-agent-validator.js && node scripts/test-story-validator.js && node scripts/test-state.js && node scripts/test-dashboard.js && node scripts/test-automation-providers.js && node scripts/test-intent.js && node scripts/test-events.js && node scripts/test-golden-artifacts.js && node scripts/test-install-smoke.js && node scripts/test-checkpoint.js && node scripts/test-extensions.js && node scripts/test-event-reader.js && node scripts/test-state-lock.js && node scripts/test-cost-saver.js && node scripts/test-budget-onoff.js && node scripts/test-workflow-runner.js && npm run test:e2e && node scripts/test-otel-exporter.js && node scripts/test-extensions-publish.js",
|
|
10
10
|
"prepublishOnly": "npm test",
|
|
11
11
|
"validate-skills": "node scripts/validate-skills.js",
|
|
12
12
|
"test:surface": "node scripts/test-doc-surface-counts.js",
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
apiVersion: godpowers/v1
|
|
2
|
+
kind: CommandRouting
|
|
3
|
+
metadata:
|
|
4
|
+
command: /god-export-otel
|
|
5
|
+
description: Export Godpowers events to OpenTelemetry OTLP JSON traces
|
|
6
|
+
tier: 0
|
|
7
|
+
|
|
8
|
+
prerequisites:
|
|
9
|
+
required: []
|
|
10
|
+
|
|
11
|
+
execution:
|
|
12
|
+
spawns: [built-in]
|
|
13
|
+
context: fresh
|
|
14
|
+
writes: []
|
|
15
|
+
|
|
16
|
+
success-path:
|
|
17
|
+
next-recommended: /god-status
|
|
18
|
+
|
|
19
|
+
failure-path:
|
|
20
|
+
on-error: /god-doctor
|
|
21
|
+
|
|
22
|
+
endoff:
|
|
23
|
+
state-update: none
|
|
24
|
+
events: [agent.start, agent.end]
|
package/schema/state.v1.json
CHANGED
|
@@ -131,6 +131,32 @@
|
|
|
131
131
|
"additionalProperties": false
|
|
132
132
|
}
|
|
133
133
|
},
|
|
134
|
+
"godpowers-features": {
|
|
135
|
+
"type": "object",
|
|
136
|
+
"description": "Installed Godpowers feature awareness recorded for this project.",
|
|
137
|
+
"required": ["feature-set-version", "runtime-version", "known"],
|
|
138
|
+
"properties": {
|
|
139
|
+
"feature-set-version": {
|
|
140
|
+
"type": "integer",
|
|
141
|
+
"minimum": 1
|
|
142
|
+
},
|
|
143
|
+
"runtime-version": {
|
|
144
|
+
"type": "string",
|
|
145
|
+
"pattern": "^(unknown|\\d+\\.\\d+\\.\\d+)$"
|
|
146
|
+
},
|
|
147
|
+
"known": {
|
|
148
|
+
"type": "array",
|
|
149
|
+
"items": {
|
|
150
|
+
"type": "string"
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
"last-awareness-refresh-at": {
|
|
154
|
+
"type": "string",
|
|
155
|
+
"format": "date-time"
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
"additionalProperties": false
|
|
159
|
+
},
|
|
134
160
|
"yolo-decisions": {
|
|
135
161
|
"type": "array",
|
|
136
162
|
"description": "Auto-decisions made under --yolo. Mirrored to YOLO-DECISIONS.md.",
|
package/skills/god-context.md
CHANGED
|
@@ -33,10 +33,12 @@ the Godpowers fences off, check status, or refresh on demand.
|
|
|
33
33
|
|
|
34
34
|
1. Verify `.godpowers/` exists. If not, suggest `/god-init` first.
|
|
35
35
|
2. Read `.godpowers/state.json`.
|
|
36
|
-
3. Call `lib/
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
3. Call `lib/feature-awareness.run(projectRoot)` to record current runtime
|
|
37
|
+
features and refresh managed AI-tool awareness safely.
|
|
38
|
+
4. Call `lib/pillars.detect(projectRoot)`.
|
|
39
|
+
5. If Pillars is absent or partial, call `lib/pillars.init(projectRoot)`.
|
|
40
|
+
6. Spawn `god-context-writer` agent with the requested mode.
|
|
41
|
+
7. Report results.
|
|
40
42
|
|
|
41
43
|
## What gets written
|
|
42
44
|
|
|
@@ -136,6 +138,14 @@ When `/god-sync` runs (after a project run, or any sync), `god-updater` calls th
|
|
|
136
138
|
with `refresh` to keep `AGENTS.md` content aligned with the latest project
|
|
137
139
|
state (mode, scale, completed tiers, active artifacts).
|
|
138
140
|
|
|
141
|
+
For existing projects after a Godpowers upgrade, `/god-context refresh`
|
|
142
|
+
auto-invokes `lib/feature-awareness.run(projectRoot)`. Report it as:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
Agent: none, local runtime only
|
|
146
|
+
Why: this path records current runtime features and refreshes managed context fences
|
|
147
|
+
```
|
|
148
|
+
|
|
139
149
|
You can disable the Godpowers fences by running `/god-context off`. Pillars
|
|
140
150
|
remains because it is the native context contract for Godpowers projects.
|
|
141
151
|
|
|
@@ -146,7 +156,7 @@ The fenced content contains:
|
|
|
146
156
|
- Mode (greenfield/brownfield/audit) and scale
|
|
147
157
|
- A short list of completed-tier artifact paths
|
|
148
158
|
- Quarterback rule reminder
|
|
149
|
-
-
|
|
159
|
+
- Short useful slash command list
|
|
150
160
|
|
|
151
161
|
It does NOT contain:
|
|
152
162
|
- Secrets, credentials, API keys
|
package/skills/god-docs.md
CHANGED
|
@@ -23,6 +23,11 @@ Documentation work. Docs that don't lie.
|
|
|
23
23
|
|
|
24
24
|
## Orchestration
|
|
25
25
|
|
|
26
|
+
First call `lib/repo-doc-sync.run(projectRoot)` for mechanical repository
|
|
27
|
+
documentation claims such as README badges, version references, public surface
|
|
28
|
+
counts, and `/god-doctor` sample counts. Report this as `Agent: none, local
|
|
29
|
+
runtime only`.
|
|
30
|
+
|
|
26
31
|
Spawn **god-docs-writer** in fresh context.
|
|
27
32
|
|
|
28
33
|
The agent:
|
|
@@ -56,6 +61,7 @@ Godpowers may invoke docs work proactively in two ways:
|
|
|
56
61
|
|---|---|---|
|
|
57
62
|
| Docs changed after code changed | Spawn `god-docs-writer` in drift-check mode when current workflow owns docs | Do not invent new docs scope |
|
|
58
63
|
| Code changed after docs that claim current behavior | Suggest `/god-docs` or spawn drift-check inside `/god-mode`, `/god-feature`, `/god-refactor`, or `/god-sync` closeout | Verify claims against code before editing |
|
|
64
|
+
| Repo docs surface drift | Run `lib/repo-doc-sync.run` for safe mechanical fixes, then spawn `god-docs-writer` for prose | Do not auto-invent changelog or release notes |
|
|
59
65
|
| `REVIEW-REQUIRED.md` contains docs drift items | Suggest `/god-review-changes` first | Do not auto-clear review items |
|
|
60
66
|
|
|
61
67
|
When auto-invoked, show:
|
|
@@ -65,6 +71,7 @@ Auto-invoked:
|
|
|
65
71
|
Trigger: docs and code changed in the same workflow
|
|
66
72
|
Agent: god-docs-writer
|
|
67
73
|
Local syncs:
|
|
74
|
+
+ repo-doc-sync: <safe mechanical fixes, prose review needed, or no-op>
|
|
68
75
|
+ docs-drift-check: <N claims checked, N drift items>
|
|
69
76
|
Artifacts: .godpowers/docs/UPDATE-LOG.md or no-op
|
|
70
77
|
Log: .godpowers/docs/UPDATE-LOG.md
|
package/skills/god-doctor.md
CHANGED
|
@@ -32,6 +32,8 @@ Run a system-state diagnostic. Build nothing. Touch nothing. Report only.
|
|
|
32
32
|
5. Is the reflog (`.godpowers/log`) parseable?
|
|
33
33
|
6. Are there entries in `.godpowers/.trash/`?
|
|
34
34
|
7. Do declared linkage entries point at real code files?
|
|
35
|
+
8. Does `state.json` know the current Godpowers feature set?
|
|
36
|
+
9. Are managed AI-tool context fences present when tools are detected?
|
|
35
37
|
|
|
36
38
|
### External integration health
|
|
37
39
|
1. Is impeccable present? `node_modules/impeccable` or `~/.claude/skills/impeccable`?
|
|
@@ -53,6 +55,7 @@ Install: claude (~/.claude/)
|
|
|
53
55
|
|
|
54
56
|
Project: /Users/.../my-project/.godpowers/
|
|
55
57
|
[OK] state.json valid
|
|
58
|
+
[WARN] feature awareness stale -> run /god-context refresh
|
|
56
59
|
[WARN] PRD declared but .godpowers/prd/PRD.md missing -> run /god-prd
|
|
57
60
|
[INFO] 2 entries in .trash/; run /god-restore to review
|
|
58
61
|
|
|
@@ -96,12 +99,42 @@ Skip install checks. Useful inside the project.
|
|
|
96
99
|
### `/god-doctor --fix`
|
|
97
100
|
Attempt to repair detected issues automatically (only for safe categories: regenerate missing routing YAMLs, repair PROGRESS.md from state.json, etc.). Pauses before any destructive change.
|
|
98
101
|
|
|
102
|
+
## Feature Awareness
|
|
103
|
+
|
|
104
|
+
For initialized projects, `/god-doctor` calls `lib/feature-awareness.detect`
|
|
105
|
+
as a read-only diagnostic. It reports:
|
|
106
|
+
- runtime version recorded in `state.json`
|
|
107
|
+
- missing current Godpowers feature IDs
|
|
108
|
+
- missing managed AI-tool context fences
|
|
109
|
+
- unimported GSD, BMAD, or Superpowers evidence that should route to
|
|
110
|
+
`/god-migrate`
|
|
111
|
+
- `god-greenfieldifier` recommendation when migration evidence is low
|
|
112
|
+
confidence or conflicting
|
|
113
|
+
|
|
114
|
+
`/god-doctor --fix` may call `lib/feature-awareness.run(projectRoot)` because
|
|
115
|
+
that helper writes only safe state metadata and managed context fences.
|
|
116
|
+
|
|
117
|
+
## Repo Documentation Sync
|
|
118
|
+
|
|
119
|
+
For initialized projects, `/god-doctor` calls `lib/repo-doc-sync.detect` as a
|
|
120
|
+
read-only diagnostic. It reports stale README badges, public surface counts,
|
|
121
|
+
release notes, changelog entries, contribution guidance, security policy, and
|
|
122
|
+
Pillars sync planning for changed repo docs.
|
|
123
|
+
|
|
124
|
+
`/god-doctor --fix` may call `lib/repo-doc-sync.run(projectRoot)` because that
|
|
125
|
+
helper writes only safe mechanical version, badge, and count claims. It should
|
|
126
|
+
recommend `god-docs-writer` when narrative release, contribution, support, or
|
|
127
|
+
security prose needs judgment.
|
|
128
|
+
|
|
99
129
|
## Implementation
|
|
100
130
|
|
|
101
131
|
Built-in, no spawned agent. Reads:
|
|
102
132
|
- `<runtime>/GODPOWERS_VERSION` (compare to package.json)
|
|
103
133
|
- `<runtime>/skills/` and `<runtime>/agents/` listings
|
|
104
134
|
- `.godpowers/state.json`, `intent.yaml`, `log`, `linkage.json`
|
|
135
|
+
- `lib/feature-awareness.detect(projectRoot)` for existing-project upgrade
|
|
136
|
+
awareness
|
|
137
|
+
- `lib/repo-doc-sync.detect(projectRoot)` for repo documentation freshness
|
|
105
138
|
- `bin/install.js` VERSION constant
|
|
106
139
|
|
|
107
140
|
## Exit codes
|
package/skills/god-mode.md
CHANGED
|
@@ -304,7 +304,9 @@ Sync status:
|
|
|
304
304
|
Trigger: /god-mode final sync
|
|
305
305
|
Agent: god-updater spawned
|
|
306
306
|
Local syncs:
|
|
307
|
+
+ feature-awareness: <recorded runtime features, refreshed context, or no-op>
|
|
307
308
|
+ reverse-sync: <counts and result>
|
|
309
|
+
+ repo-doc-sync: <refreshed repo docs, recommended god-docs-writer, or no-op>
|
|
308
310
|
+ pillars-sync: <counts and result>
|
|
309
311
|
+ checkpoint-sync: <created, updated, no-op, or skipped>
|
|
310
312
|
+ context-refresh: <spawned, no-op, or skipped>
|
|
@@ -318,6 +320,16 @@ to relevant pillar files through `lib/pillars.planArtifactSync`. Default mode
|
|
|
318
320
|
proposes pillar updates for review. `--yolo` applies them immediately and logs
|
|
319
321
|
the action to `.godpowers/YOLO-DECISIONS.md`.
|
|
320
322
|
|
|
323
|
+
When `/god-mode` resumes an existing `.godpowers` project, it auto-invokes
|
|
324
|
+
`lib/feature-awareness.run(projectRoot)` before the final sync report. This
|
|
325
|
+
keeps upgraded projects aware of new runtime features, current context fences,
|
|
326
|
+
and migration routes without rewriting user artifacts.
|
|
327
|
+
|
|
328
|
+
The mandatory final sync also receives repo documentation sync through
|
|
329
|
+
`/god-sync`. This keeps README badges, release surfaces, contribution guidance,
|
|
330
|
+
security policy checks, and Pillars context planning arc-ready before the
|
|
331
|
+
project run is declared complete.
|
|
332
|
+
|
|
321
333
|
If `/god-mode` resumes an existing `.godpowers` project that lacks Pillars,
|
|
322
334
|
it Pillar-izes the project before continuing. Existing `.godpowers` artifacts
|
|
323
335
|
become managed source references in the relevant `agents/*.md` files.
|
|
@@ -337,7 +349,9 @@ Sync status:
|
|
|
337
349
|
Trigger: /god-mode final sync
|
|
338
350
|
Agent: god-updater spawned
|
|
339
351
|
Local syncs:
|
|
352
|
+
+ feature-awareness: <recorded runtime features, refreshed context, or no-op>
|
|
340
353
|
+ reverse-sync: <counts and result>
|
|
354
|
+
+ repo-doc-sync: <refreshed repo docs, recommended god-docs-writer, or no-op>
|
|
341
355
|
+ pillars-sync: <counts and result>
|
|
342
356
|
+ checkpoint-sync: <created, updated, no-op, or skipped>
|
|
343
357
|
+ context-refresh: <spawned, no-op, or skipped>
|
package/skills/god-status.md
CHANGED
|
@@ -171,8 +171,8 @@ Report:
|
|
|
171
171
|
- Checkpoint: `fresh`, `missing`, `stale`, or `conflicts with state.json`
|
|
172
172
|
- Reviews: `none` or `<N> pending, suggest /god-review-changes`
|
|
173
173
|
- Sync: `fresh`, `missing`, `stale`, or `suggest /god-sync`
|
|
174
|
-
- Docs: `fresh`,
|
|
175
|
-
|
|
174
|
+
- Docs: `fresh`, `<N> stale, suggest /god-docs`, `possible drift, suggest
|
|
175
|
+
/god-docs`, or `repo-doc-sync ran`
|
|
176
176
|
- Runtime: `not-applicable`, `known URL, suggest /god-test-runtime`, or
|
|
177
177
|
`no known URL, defer deployed verification`
|
|
178
178
|
- Automation: `not configured`, `<N> active`, or
|