hive-lite 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +443 -0
- package/bin/hive.js +6 -0
- package/docs/cli-semantics.md +386 -0
- package/docs/skills/hive-lite-finish/SKILL.md +282 -0
- package/docs/skills/hive-lite-finish/agents/openai.yaml +4 -0
- package/docs/skills/hive-lite-finish/references/safety.md +95 -0
- package/docs/skills/hive-lite-finish/references/verdicts.md +123 -0
- package/docs/skills/hive-lite-map-maintainer/SKILL.md +203 -0
- package/docs/skills/hive-lite-map-maintainer/agents/openai.yaml +7 -0
- package/docs/skills/hive-lite-map-maintainer/references/lifecycle.md +114 -0
- package/docs/skills/hive-lite-map-maintainer/references/repair-rules.md +201 -0
- package/docs/skills/hive-lite-start-prompt/SKILL.md +283 -0
- package/docs/skills/hive-lite-start-prompt/agents/openai.yaml +4 -0
- package/docs/skills/hive-lite-start-prompt/references/input-calibration.md +82 -0
- package/docs/skills/hive-lite-start-prompt/references/preflight.md +116 -0
- package/package.json +40 -0
- package/src/cli.js +910 -0
- package/src/lib/change.js +642 -0
- package/src/lib/context.js +1104 -0
- package/src/lib/evidence.js +230 -0
- package/src/lib/fsx.js +54 -0
- package/src/lib/git.js +128 -0
- package/src/lib/glob.js +47 -0
- package/src/lib/health.js +1012 -0
- package/src/lib/id.js +13 -0
- package/src/lib/map.js +713 -0
- package/src/lib/next.js +341 -0
- package/src/lib/risk.js +122 -0
- package/src/lib/roles.js +109 -0
- package/src/lib/scope.js +168 -0
- package/src/lib/skills.js +349 -0
- package/src/lib/status.js +344 -0
- package/src/lib/yaml.js +223 -0
package/src/cli.js
ADDED
|
@@ -0,0 +1,910 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { requireGitRepo } = require('./lib/git');
|
|
3
|
+
const { evaluateMapHealth } = require('./lib/health');
|
|
4
|
+
const { createMapPrompt, initProject, loadProjectMap, suggestMap, verifyProjectMap } = require('./lib/map');
|
|
5
|
+
const { createContextPacket } = require('./lib/context');
|
|
6
|
+
const { evaluateNextAction } = require('./lib/next');
|
|
7
|
+
const { installSkills, skillsDoctor, syncSkills } = require('./lib/skills');
|
|
8
|
+
const { patternDisplay } = require('./lib/scope');
|
|
9
|
+
const { evaluateWorkspaceStatus } = require('./lib/status');
|
|
10
|
+
const {
|
|
11
|
+
acceptChange,
|
|
12
|
+
allDeltas,
|
|
13
|
+
applyDelta,
|
|
14
|
+
createOrUpdateChange,
|
|
15
|
+
latestChangeId,
|
|
16
|
+
loadChange,
|
|
17
|
+
rejectDelta,
|
|
18
|
+
validateChange,
|
|
19
|
+
} = require('./lib/change');
|
|
20
|
+
|
|
21
|
+
function parseArgs(args) {
|
|
22
|
+
const positional = [];
|
|
23
|
+
const flags = {};
|
|
24
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
25
|
+
const arg = args[i];
|
|
26
|
+
if (!arg.startsWith('-')) {
|
|
27
|
+
positional.push(arg);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (arg === '--json' || arg === '--commit' || arg === '--reviewed' || arg === '--skip-validation' || arg === '--accept-risk' || arg === '--force' || arg === '--explain' || arg === '--all' || arg === '--dry-run') {
|
|
31
|
+
flags[arg.slice(2).replace(/-([a-z])/g, (_, ch) => ch.toUpperCase())] = true;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const key = arg === '-m' ? 'message' : arg.slice(2).replace(/-([a-z])/g, (_, ch) => ch.toUpperCase());
|
|
35
|
+
const next = args[i + 1];
|
|
36
|
+
if (next === undefined || next.startsWith('--')) {
|
|
37
|
+
flags[key] = true;
|
|
38
|
+
} else {
|
|
39
|
+
flags[key] = next;
|
|
40
|
+
i += 1;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { positional, flags };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function printHelp() {
|
|
47
|
+
console.log(`
|
|
48
|
+
Hive Lite - local Project Map + Change Control
|
|
49
|
+
|
|
50
|
+
Usage:
|
|
51
|
+
hive-lite init
|
|
52
|
+
hive-lite doctor
|
|
53
|
+
hive-lite status [--json] [--all]
|
|
54
|
+
hive-lite next [--json] [--agent codex|claude|gemini|all] [--path <skills-dir>]
|
|
55
|
+
hive-lite skills doctor [--agent codex|claude|gemini|all] [--path <skills-dir>] [--json]
|
|
56
|
+
hive-lite skills install --agent codex|claude|gemini|all [--force] [--dry-run] [--json]
|
|
57
|
+
hive-lite skills sync --agent codex|claude|gemini|all [--dry-run] [--json]
|
|
58
|
+
hive-lite find "<intent>" [--area <id>] [--max-files 8] [--explain] [--json]
|
|
59
|
+
hive-lite check [changeId] [--context ctx_id] [--json]
|
|
60
|
+
hive-lite validate [changeId] [--cmd "..."] [--profile <id>]
|
|
61
|
+
hive-lite validate [changeId] --manual <profile> --result passed --note "..."
|
|
62
|
+
hive-lite accept [changeId] [--commit -m "..."] [--reviewed --reason "..."] [--accept-risk --reason "..."] [--skip-validation --reason "..."]
|
|
63
|
+
hive-lite map verify [--json]
|
|
64
|
+
hive-lite map suggest
|
|
65
|
+
hive-lite map health [--area <id>] [--json]
|
|
66
|
+
hive-lite map prompt [--focus <path-or-topic>] [--from-find ctx_id] [--max-areas 8] [--json]
|
|
67
|
+
hive-lite map delta list
|
|
68
|
+
hive-lite map delta apply <deltaId>
|
|
69
|
+
hive-lite map delta reject <deltaId> --reason "..."
|
|
70
|
+
`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function relative(root, file) {
|
|
74
|
+
return path.relative(root, file).replace(/\\/g, '/');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function currentCliCommandArgv() {
|
|
78
|
+
if (!process.argv[1]) return ['hive-lite'];
|
|
79
|
+
return [process.execPath, path.resolve(process.argv[1])];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function printInit(result) {
|
|
83
|
+
console.log('Hive Lite initialized.');
|
|
84
|
+
console.log(`Repo: ${result.root}`);
|
|
85
|
+
if (result.created.length > 0) {
|
|
86
|
+
console.log('\nCreated:');
|
|
87
|
+
for (const file of result.created) console.log(` - ${file}`);
|
|
88
|
+
} else {
|
|
89
|
+
console.log('\nNo files created; Hive Lite was already initialized.');
|
|
90
|
+
}
|
|
91
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
92
|
+
console.log('\nWarnings:');
|
|
93
|
+
for (const warning of result.warnings) console.log(` - ${warning}`);
|
|
94
|
+
console.log(' Durable files should be committed: .hive/config.yaml and .hive/map/**');
|
|
95
|
+
console.log(' Ignore only runtime evidence: .hive/context/, .hive/changes/, .hive/patches/, .hive/state/');
|
|
96
|
+
}
|
|
97
|
+
console.log('\nNext:');
|
|
98
|
+
console.log(' 1. Edit .hive/map/areas.yaml');
|
|
99
|
+
console.log(' 2. Run: hive-lite find "<intent>"');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function printVerify(root, result) {
|
|
103
|
+
console.log(`Project Map: ${root}`);
|
|
104
|
+
if (result.problems.length === 0) console.log('Status: ok');
|
|
105
|
+
else {
|
|
106
|
+
console.log('Status: invalid');
|
|
107
|
+
console.log('\nProblems:');
|
|
108
|
+
for (const problem of result.problems) console.log(` - ${problem}`);
|
|
109
|
+
}
|
|
110
|
+
if (result.warnings.length > 0) {
|
|
111
|
+
console.log('\nWarnings:');
|
|
112
|
+
for (const warning of result.warnings) console.log(` - ${warning}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function verifyJson(root, result) {
|
|
117
|
+
return {
|
|
118
|
+
status: result.problems.length === 0 ? 'ok' : 'invalid',
|
|
119
|
+
mapDir: path.join(root, '.hive', 'map'),
|
|
120
|
+
problems: result.problems,
|
|
121
|
+
errors: result.problems,
|
|
122
|
+
warnings: result.warnings,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function printContext(result) {
|
|
127
|
+
const packet = result.packet;
|
|
128
|
+
const focus = JSON.stringify(packet.intent.raw);
|
|
129
|
+
console.log(`Context Packet: ${packet.id}`);
|
|
130
|
+
console.log('');
|
|
131
|
+
console.log('Mode:');
|
|
132
|
+
console.log(` ${packet.mode}`);
|
|
133
|
+
console.log('');
|
|
134
|
+
console.log('Intent:');
|
|
135
|
+
console.log(` ${packet.intent.summary}`);
|
|
136
|
+
console.log('');
|
|
137
|
+
console.log('Likely Area:');
|
|
138
|
+
if (packet.area) {
|
|
139
|
+
console.log(` ${packet.area.id}`);
|
|
140
|
+
console.log(` confidence: ${packet.area.confidence}`);
|
|
141
|
+
if (packet.area.matchedSignals.length > 0) {
|
|
142
|
+
console.log(' signals:');
|
|
143
|
+
for (const signal of packet.area.matchedSignals.slice(0, 8)) console.log(` - ${signal}`);
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
console.log(' unknown');
|
|
147
|
+
}
|
|
148
|
+
if (!packet.area) {
|
|
149
|
+
console.log('');
|
|
150
|
+
console.log('Candidate Areas:');
|
|
151
|
+
if (!packet.candidateAreas || packet.candidateAreas.length === 0) console.log(' - (none matched)');
|
|
152
|
+
for (const candidate of packet.candidateAreas || []) {
|
|
153
|
+
console.log(` - ${candidate.id} (score ${candidate.score})`);
|
|
154
|
+
if (candidate.signals.length > 0) {
|
|
155
|
+
console.log(` signals: ${candidate.signals.slice(0, 4).join(', ')}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
console.log('');
|
|
159
|
+
console.log('Map Guidance:');
|
|
160
|
+
console.log(' - Add aliases/concepts that match this intent wording.');
|
|
161
|
+
console.log(' - Add entrypoints for the files an agent should inspect first.');
|
|
162
|
+
console.log(` - Try: hive-lite map prompt --focus ${focus} --from-find ${packet.id}`);
|
|
163
|
+
}
|
|
164
|
+
if (packet.warnings && packet.warnings.length > 0) {
|
|
165
|
+
console.log('');
|
|
166
|
+
console.log('Warnings:');
|
|
167
|
+
for (const warning of packet.warnings) console.log(` - ${warning.code}: ${warning.message}`);
|
|
168
|
+
}
|
|
169
|
+
if (packet.reviewGated && packet.reviewGated.length > 0) {
|
|
170
|
+
console.log('');
|
|
171
|
+
console.log('Review-Gated Scope:');
|
|
172
|
+
for (const notice of packet.reviewGated) console.log(` - ${notice.code}: ${notice.message}`);
|
|
173
|
+
}
|
|
174
|
+
if (packet.decompositionSignals && packet.decompositionSignals.length > 0) {
|
|
175
|
+
console.log('');
|
|
176
|
+
console.log('Decomposition Signals:');
|
|
177
|
+
for (const item of packet.decompositionSignals) console.log(` - ${item.code}: ${item.message}`);
|
|
178
|
+
}
|
|
179
|
+
if (packet.splitNote) {
|
|
180
|
+
console.log('');
|
|
181
|
+
console.log('Split Note:');
|
|
182
|
+
console.log(` ${packet.splitNote.markdownPath}`);
|
|
183
|
+
}
|
|
184
|
+
if (packet.phaseDependencyStatus) {
|
|
185
|
+
console.log('');
|
|
186
|
+
console.log('Phase Dependency Status:');
|
|
187
|
+
console.log(` can start normally: ${packet.phaseDependencyStatus.canStartNormally ? 'yes' : 'no'}`);
|
|
188
|
+
console.log(` ${packet.phaseDependencyStatus.message}`);
|
|
189
|
+
if (packet.phaseDependencyStatus.missingRequiredAcceptedPhases && packet.phaseDependencyStatus.missingRequiredAcceptedPhases.length > 0) {
|
|
190
|
+
console.log(' missing required phases:');
|
|
191
|
+
for (const phaseId of packet.phaseDependencyStatus.missingRequiredAcceptedPhases) console.log(` - ${phaseId}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (packet.mode === 'needs_decomposition' && packet.candidatePhaseSeeds && packet.candidatePhaseSeeds.length > 0) {
|
|
195
|
+
console.log('');
|
|
196
|
+
console.log('Candidate Phase Seeds:');
|
|
197
|
+
for (const item of packet.candidatePhaseSeeds) {
|
|
198
|
+
console.log(` - ${item.id} (${item.areaId})`);
|
|
199
|
+
console.log(` find: ${item.findIntent}`);
|
|
200
|
+
if (item.evidenceClasses && item.evidenceClasses.length > 0) console.log(` evidence: ${item.evidenceClasses.join(', ')}`);
|
|
201
|
+
if (item.validationProfiles && item.validationProfiles.length > 0) console.log(` validation: ${item.validationProfiles.join(', ')}`);
|
|
202
|
+
console.log(` risk: ${item.risk}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
console.log('');
|
|
206
|
+
console.log('Relevant Files:');
|
|
207
|
+
if (packet.relevantFiles.length === 0) console.log(' - (none found)');
|
|
208
|
+
for (const file of packet.relevantFiles) console.log(` - ${file.path}\n reason: ${file.reason}`);
|
|
209
|
+
console.log('');
|
|
210
|
+
console.log('Writable Scope:');
|
|
211
|
+
if (packet.writableScope.length === 0) console.log(' - (none; this is not an edit permit)');
|
|
212
|
+
for (const item of packet.writableScope) console.log(` - ${item}`);
|
|
213
|
+
if (packet.scope) {
|
|
214
|
+
console.log('');
|
|
215
|
+
console.log(`Scope Quality: ${packet.scope.quality}`);
|
|
216
|
+
console.log('');
|
|
217
|
+
console.log('Conditional Writable Scope:');
|
|
218
|
+
if (packet.scope.writableConditional.length === 0) console.log(' - (none configured)');
|
|
219
|
+
for (const item of packet.scope.writableConditional) console.log(` - ${patternDisplay(item)}`);
|
|
220
|
+
console.log('');
|
|
221
|
+
console.log('Broad Fallback Scope:');
|
|
222
|
+
if (packet.scope.writableBroadFallback.length === 0) console.log(' - (none configured)');
|
|
223
|
+
for (const item of packet.scope.writableBroadFallback) console.log(` - ${patternDisplay(item)}`);
|
|
224
|
+
}
|
|
225
|
+
console.log('');
|
|
226
|
+
console.log('Do Not Touch:');
|
|
227
|
+
if (packet.doNotTouch.length === 0) console.log(' - (none configured)');
|
|
228
|
+
for (const item of packet.doNotTouch) console.log(` - ${item}`);
|
|
229
|
+
console.log('');
|
|
230
|
+
console.log('Validation:');
|
|
231
|
+
if (packet.validationPlan.length === 0) console.log(' - (none configured)');
|
|
232
|
+
for (const item of packet.validationPlan) {
|
|
233
|
+
if (item.command) console.log(` - ${item.command}`);
|
|
234
|
+
else console.log(` - manual: ${item.description || item.profile}`);
|
|
235
|
+
}
|
|
236
|
+
console.log('');
|
|
237
|
+
console.log('Risk:');
|
|
238
|
+
console.log(` ${packet.risk.level}`);
|
|
239
|
+
console.log('');
|
|
240
|
+
console.log('Saved:');
|
|
241
|
+
console.log(` ${relative(packet.repo.root, result.mdPath)}`);
|
|
242
|
+
console.log(` ${relative(packet.repo.root, result.jsonPath)}`);
|
|
243
|
+
console.log('');
|
|
244
|
+
if (packet.mode === 'edit_context') {
|
|
245
|
+
console.log(`Next: give ${relative(packet.repo.root, result.mdPath)} to your coding agent, then run hive-lite check --context ${packet.id}`);
|
|
246
|
+
} else if (packet.recommendedActions && packet.recommendedActions.length > 0) {
|
|
247
|
+
console.log('Next:');
|
|
248
|
+
for (const action of packet.recommendedActions) console.log(` - ${action}`);
|
|
249
|
+
} else {
|
|
250
|
+
console.log(`Next: refine .hive/map/areas.yaml, then run hive-lite find again.`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function printFindExplain(packet) {
|
|
255
|
+
console.log('');
|
|
256
|
+
console.log('Find Explain');
|
|
257
|
+
console.log('');
|
|
258
|
+
console.log('Area Scores:');
|
|
259
|
+
if (!packet.explain.areaScores.length) console.log(' - (no areas configured)');
|
|
260
|
+
for (const area of packet.explain.areaScores) {
|
|
261
|
+
console.log(` - ${area.id}: ${area.score}`);
|
|
262
|
+
for (const signal of area.signals) console.log(` + ${signal}`);
|
|
263
|
+
}
|
|
264
|
+
console.log('');
|
|
265
|
+
console.log(`Selected Area: ${packet.explain.selectedArea || '(none)'}`);
|
|
266
|
+
console.log(`Scope Quality: ${packet.explain.scopeQuality}`);
|
|
267
|
+
console.log(`Validation: ${packet.explain.validationQuality}`);
|
|
268
|
+
if (packet.explain.grepScope) console.log(`Grep Scope: ${packet.explain.grepScope}`);
|
|
269
|
+
console.log('');
|
|
270
|
+
console.log('Relevant File Sources:');
|
|
271
|
+
if (!packet.explain.relevantFileSources.length) console.log(' - (none)');
|
|
272
|
+
for (const file of packet.explain.relevantFileSources) {
|
|
273
|
+
console.log(` - ${file.path}`);
|
|
274
|
+
console.log(` source: ${file.source}`);
|
|
275
|
+
if (file.role) console.log(` role: ${file.role}`);
|
|
276
|
+
console.log(` reason: ${file.reason}`);
|
|
277
|
+
}
|
|
278
|
+
if (packet.explain.warnings.length > 0) {
|
|
279
|
+
console.log('');
|
|
280
|
+
console.log('Warnings:');
|
|
281
|
+
for (const warning of packet.explain.warnings) console.log(` - ${warning.code}: ${warning.message}`);
|
|
282
|
+
}
|
|
283
|
+
if (packet.explain.reviewGated && packet.explain.reviewGated.length > 0) {
|
|
284
|
+
console.log('');
|
|
285
|
+
console.log('Review-Gated Scope:');
|
|
286
|
+
for (const notice of packet.explain.reviewGated) console.log(` - ${notice.code}: ${notice.message}`);
|
|
287
|
+
}
|
|
288
|
+
if (packet.explain.decompositionSignals && packet.explain.decompositionSignals.length > 0) {
|
|
289
|
+
console.log('');
|
|
290
|
+
console.log('Decomposition Signals:');
|
|
291
|
+
for (const signal of packet.explain.decompositionSignals) console.log(` - ${signal.code}: ${signal.message}`);
|
|
292
|
+
}
|
|
293
|
+
if (packet.explain.recommendedActions.length > 0) {
|
|
294
|
+
console.log('');
|
|
295
|
+
console.log('Recommended:');
|
|
296
|
+
for (const action of packet.explain.recommendedActions) console.log(` - ${action}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function printCheck(root, result) {
|
|
301
|
+
if (result.clean) {
|
|
302
|
+
console.log('No current change: working tree is clean.');
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const change = result.change;
|
|
306
|
+
console.log(`Change: ${change.id}`);
|
|
307
|
+
console.log('');
|
|
308
|
+
console.log(`Branch: ${change.repo.branch || '(detached)'}`);
|
|
309
|
+
console.log(`Baseline: ${change.repo.baselineCommit || '(unknown)'}`);
|
|
310
|
+
console.log('');
|
|
311
|
+
console.log('Changed Files:');
|
|
312
|
+
for (const file of change.diff.changedFiles) console.log(` - ${file.path}`);
|
|
313
|
+
console.log('');
|
|
314
|
+
console.log('Scope:');
|
|
315
|
+
console.log(` ${change.scope.status}`);
|
|
316
|
+
console.log(` source: ${change.scope.source}`);
|
|
317
|
+
if (change.scope.quality) console.log(` quality: ${change.scope.quality}`);
|
|
318
|
+
if (change.scope.violations.length > 0) {
|
|
319
|
+
console.log(' violations:');
|
|
320
|
+
for (const violation of change.scope.violations) console.log(` - ${violation}`);
|
|
321
|
+
}
|
|
322
|
+
if (change.scope.review.length > 0) {
|
|
323
|
+
console.log(' needs review:');
|
|
324
|
+
for (const file of change.scope.review) console.log(` - ${file}`);
|
|
325
|
+
}
|
|
326
|
+
if (change.scope.reviewDetails && change.scope.reviewDetails.length > 0) {
|
|
327
|
+
console.log(' review reasons:');
|
|
328
|
+
for (const detail of change.scope.reviewDetails) console.log(` - ${detail}`);
|
|
329
|
+
}
|
|
330
|
+
if (change.scope.writableConditional && change.scope.writableConditional.length > 0) {
|
|
331
|
+
console.log(' conditional writable:');
|
|
332
|
+
for (const item of change.scope.writableConditional) console.log(` - ${patternDisplay(item)}`);
|
|
333
|
+
}
|
|
334
|
+
if (change.scope.writableBroadFallback && change.scope.writableBroadFallback.length > 0) {
|
|
335
|
+
console.log(' broad fallback:');
|
|
336
|
+
for (const item of change.scope.writableBroadFallback) console.log(` - ${patternDisplay(item)}`);
|
|
337
|
+
}
|
|
338
|
+
console.log('');
|
|
339
|
+
console.log('Validation:');
|
|
340
|
+
console.log(` ${change.validation.status}`);
|
|
341
|
+
const commands = (change.validation.plan || []).filter((item) => item.command).map((item) => item.command);
|
|
342
|
+
if (commands.length > 0) {
|
|
343
|
+
console.log(' suggested:');
|
|
344
|
+
for (const command of commands) console.log(` - ${command}`);
|
|
345
|
+
}
|
|
346
|
+
if (change.validation.results && change.validation.results.length > 0) {
|
|
347
|
+
console.log(' results:');
|
|
348
|
+
for (const item of change.validation.results) {
|
|
349
|
+
const label = item.command ? item.profile : `manual:${item.profile}`;
|
|
350
|
+
console.log(` - ${label}: ${item.status}`);
|
|
351
|
+
if (item.note) console.log(` note: ${item.note}`);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
if (change.evidencePolicy) {
|
|
355
|
+
console.log('');
|
|
356
|
+
console.log('Evidence Policy:');
|
|
357
|
+
console.log(` class: ${change.evidencePolicy.class}`);
|
|
358
|
+
console.log(` verdict: ${change.evidencePolicy.verdict}`);
|
|
359
|
+
if (change.evidencePolicy.changedRoles && change.evidencePolicy.changedRoles.length > 0) {
|
|
360
|
+
console.log(' changed roles:');
|
|
361
|
+
for (const item of change.evidencePolicy.changedRoles) console.log(` - ${item.role}: ${item.files.join(', ')}`);
|
|
362
|
+
}
|
|
363
|
+
if (change.evidencePolicy.required && change.evidencePolicy.required.length > 0) {
|
|
364
|
+
console.log(' required:');
|
|
365
|
+
for (const item of change.evidencePolicy.required) console.log(` - ${item}`);
|
|
366
|
+
}
|
|
367
|
+
if (change.evidencePolicy.recommended && change.evidencePolicy.recommended.length > 0) {
|
|
368
|
+
console.log(' recommended:');
|
|
369
|
+
for (const item of change.evidencePolicy.recommended) console.log(` - ${item}`);
|
|
370
|
+
}
|
|
371
|
+
if (change.evidencePolicy.missing && change.evidencePolicy.missing.length > 0) {
|
|
372
|
+
console.log(' missing:');
|
|
373
|
+
for (const item of change.evidencePolicy.missing) console.log(` - ${item}`);
|
|
374
|
+
}
|
|
375
|
+
if (change.evidencePolicy.reasons && change.evidencePolicy.reasons.length > 0) {
|
|
376
|
+
console.log(' reasons:');
|
|
377
|
+
for (const reason of change.evidencePolicy.reasons) console.log(` - ${reason}`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
console.log('');
|
|
381
|
+
console.log('Risk:');
|
|
382
|
+
console.log(` ${change.risk.level}`);
|
|
383
|
+
if (change.risk.blockingReasons.length > 0) {
|
|
384
|
+
console.log(' blockers:');
|
|
385
|
+
for (const reason of change.risk.blockingReasons) console.log(` - ${reason}`);
|
|
386
|
+
}
|
|
387
|
+
if (change.risk.reviewReasons.length > 0) {
|
|
388
|
+
console.log(' review:');
|
|
389
|
+
for (const reason of change.risk.reviewReasons) console.log(` - ${reason}`);
|
|
390
|
+
}
|
|
391
|
+
console.log('');
|
|
392
|
+
console.log(`Verdict: ${change.evidencePolicy ? change.evidencePolicy.verdict : change.risk.verdict}`);
|
|
393
|
+
console.log('');
|
|
394
|
+
console.log('Next Actions:');
|
|
395
|
+
for (const action of change.nextActions) console.log(` - ${action}`);
|
|
396
|
+
console.log('');
|
|
397
|
+
console.log(`Evidence: ${relative(root, path.join(root, '.hive', 'changes', change.id, 'change.json'))}`);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function printValidation(result) {
|
|
401
|
+
const validation = result.result;
|
|
402
|
+
console.log(`Validation: ${validation.id}`);
|
|
403
|
+
console.log('');
|
|
404
|
+
if (validation.command) console.log(`Command: ${validation.command}`);
|
|
405
|
+
else console.log(`Manual: ${validation.profile}`);
|
|
406
|
+
console.log(`Status: ${validation.status}`);
|
|
407
|
+
console.log(`Exit Code: ${validation.exitCode}`);
|
|
408
|
+
if (validation.stdoutPath) console.log(`Stdout: ${validation.stdoutPath}`);
|
|
409
|
+
if (validation.stderrPath) console.log(`Stderr: ${validation.stderrPath}`);
|
|
410
|
+
if (validation.note) console.log(`Note: ${validation.note}`);
|
|
411
|
+
console.log('');
|
|
412
|
+
console.log(`Updated Verdict: ${result.change.evidencePolicy ? result.change.evidencePolicy.verdict : result.change.risk.verdict}`);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function printAccept(result) {
|
|
416
|
+
console.log(`Accepted Change: ${result.change.id}`);
|
|
417
|
+
console.log('');
|
|
418
|
+
if (result.commit) console.log(`Commit: ${result.commit}`);
|
|
419
|
+
else console.log('Commit: (not created)');
|
|
420
|
+
console.log(`Evidence: .hive/changes/${result.change.id}/evidence.json`);
|
|
421
|
+
console.log('');
|
|
422
|
+
if (result.delta) {
|
|
423
|
+
console.log('Map Delta Candidate:');
|
|
424
|
+
console.log(` ${result.delta.id}`);
|
|
425
|
+
console.log(` ${result.delta.claim.text}`);
|
|
426
|
+
console.log('');
|
|
427
|
+
console.log(`Next: hive-lite map delta apply ${result.delta.id}`);
|
|
428
|
+
} else {
|
|
429
|
+
console.log('Map Delta Candidate: none');
|
|
430
|
+
}
|
|
431
|
+
if (result.postAcceptHint) {
|
|
432
|
+
console.log('');
|
|
433
|
+
console.log('Split Note Hint:');
|
|
434
|
+
console.log(` ${result.postAcceptHint.message}`);
|
|
435
|
+
if (result.postAcceptHint.readyPhases && result.postAcceptHint.readyPhases.length > 0) {
|
|
436
|
+
console.log(' Ready phases:');
|
|
437
|
+
for (const phase of result.postAcceptHint.readyPhases) console.log(` - ${phase.phaseId}: ${phase.title}`);
|
|
438
|
+
}
|
|
439
|
+
if (result.postAcceptHint.waitingPhases && result.postAcceptHint.waitingPhases.length > 0) {
|
|
440
|
+
console.log(' Waiting phases:');
|
|
441
|
+
for (const phase of result.postAcceptHint.waitingPhases) {
|
|
442
|
+
console.log(` - ${phase.phaseId}: waiting on ${phase.missingRequiredAcceptedPhases.join(', ')}`);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
if (result.postAcceptHint.suggestedNextPhase) {
|
|
446
|
+
console.log(` Suggested next phase: ${result.postAcceptHint.suggestedNextPhase.phaseId}`);
|
|
447
|
+
console.log(` Find: ${result.postAcceptHint.suggestedNextPhase.findIntent}`);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
function printDeltas(deltas) {
|
|
453
|
+
const pending = deltas.filter((delta) => delta.status !== 'applied' && delta.status !== 'rejected');
|
|
454
|
+
if (pending.length === 0) {
|
|
455
|
+
console.log('No pending map deltas.');
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
console.log('Pending Map Deltas:');
|
|
459
|
+
for (const delta of pending) {
|
|
460
|
+
console.log('');
|
|
461
|
+
console.log(delta.id);
|
|
462
|
+
console.log(` type: ${delta.type}`);
|
|
463
|
+
console.log(` status: ${delta.status}`);
|
|
464
|
+
console.log(` claim: ${delta.claim && delta.claim.text}`);
|
|
465
|
+
console.log(` source change: ${delta.source && delta.source.changeId}`);
|
|
466
|
+
console.log(` target area: ${delta.target && delta.target.areaId}`);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
function printMapPrompt(result) {
|
|
471
|
+
console.log(result.prompt);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
function printFindings(title, findings) {
|
|
475
|
+
if (findings.length === 0) return;
|
|
476
|
+
console.log('');
|
|
477
|
+
console.log(`${title}:`);
|
|
478
|
+
for (const finding of findings) {
|
|
479
|
+
const area = finding.areaId ? ` ${finding.areaId}` : '';
|
|
480
|
+
console.log(` - [${finding.code}]${area}`);
|
|
481
|
+
console.log(` ${finding.message}`);
|
|
482
|
+
if (finding.impact) console.log(` Impact: ${finding.impact}`);
|
|
483
|
+
if (finding.fix) console.log(` Fix: ${finding.fix}`);
|
|
484
|
+
if (finding.relatedCommand) console.log(` Try: ${finding.relatedCommand}`);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
function printMapHealth(result) {
|
|
489
|
+
console.log('Map Health');
|
|
490
|
+
console.log('');
|
|
491
|
+
console.log(`Status: ${result.status}`);
|
|
492
|
+
console.log(`Areas checked: ${result.summary.areasChecked}`);
|
|
493
|
+
console.log(`Critical: ${result.summary.critical}`);
|
|
494
|
+
console.log(`Warnings: ${result.summary.warnings}`);
|
|
495
|
+
console.log(`Info: ${result.summary.info}`);
|
|
496
|
+
|
|
497
|
+
if (result.areas.length > 0) {
|
|
498
|
+
console.log('');
|
|
499
|
+
console.log('Area Readiness:');
|
|
500
|
+
for (const area of result.areas) console.log(` - ${area.id}: ${area.readiness}`);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
printFindings('Critical', result.findings.filter((finding) => finding.severity === 'critical'));
|
|
504
|
+
printFindings('Warnings', result.findings.filter((finding) => finding.severity === 'warning'));
|
|
505
|
+
printFindings('Info', result.findings.filter((finding) => finding.severity === 'info'));
|
|
506
|
+
|
|
507
|
+
if (result.suggestions.length > 0) {
|
|
508
|
+
console.log('');
|
|
509
|
+
console.log('Suggestions:');
|
|
510
|
+
for (const suggestion of result.suggestions) console.log(` - ${suggestion.command}`);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
function printWorkspaceStatus(result) {
|
|
515
|
+
console.log('Hive Lite Status');
|
|
516
|
+
console.log('');
|
|
517
|
+
console.log(`Repo: ${result.root}`);
|
|
518
|
+
if (result.repo) console.log(`Git Repo: ${result.repo.isGitRepo ? 'yes' : 'no'}`);
|
|
519
|
+
console.log(`Branch: ${result.branch || '(detached)'}`);
|
|
520
|
+
console.log(`HEAD: ${result.head || '(unknown)'}`);
|
|
521
|
+
console.log('');
|
|
522
|
+
console.log(`Worktree: ${result.worktree.status}`);
|
|
523
|
+
console.log(`Hive State: ${result.hive.state}`);
|
|
524
|
+
console.log(`Can Start New Requirement: ${result.canStartNewRequirement ? 'yes' : 'no'}`);
|
|
525
|
+
console.log(`Reason: ${result.hive.reason}`);
|
|
526
|
+
if (result.hive.latestChange) {
|
|
527
|
+
console.log('');
|
|
528
|
+
console.log('Latest Change:');
|
|
529
|
+
console.log(` id: ${result.hive.latestChange.id}`);
|
|
530
|
+
if (result.hive.latestChange.verdict) console.log(` verdict: ${result.hive.latestChange.verdict}`);
|
|
531
|
+
if (result.hive.latestChange.validationStatus) console.log(` validation: ${result.hive.latestChange.validationStatus}`);
|
|
532
|
+
console.log(` current diff matches: ${result.hive.latestChange.currentDiffMatchesLatestChange ? 'yes' : 'no'}`);
|
|
533
|
+
if (result.hive.latestChange.humanDecision) {
|
|
534
|
+
console.log(` decision: ${result.hive.latestChange.humanDecision.status}`);
|
|
535
|
+
console.log(` commit: ${result.hive.latestChange.humanDecision.commit || '(not created)'}`);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
if (result.worktree.changedFiles.length > 0) {
|
|
539
|
+
console.log('');
|
|
540
|
+
console.log('Changed Files:');
|
|
541
|
+
for (const file of result.worktree.changedFiles) console.log(` - ${file.path} (${file.status})`);
|
|
542
|
+
}
|
|
543
|
+
if (result.recentSplitNotes && result.recentSplitNotes.length > 0) {
|
|
544
|
+
console.log('');
|
|
545
|
+
console.log('Recent Split Notes:');
|
|
546
|
+
const primarySplitId = result.splitNoteSummary && result.splitNoteSummary.primaryRecentSplitNote
|
|
547
|
+
? result.splitNoteSummary.primaryRecentSplitNote.id
|
|
548
|
+
: null;
|
|
549
|
+
for (const split of result.recentSplitNotes) {
|
|
550
|
+
console.log(` - ${split.id}${split.id === primarySplitId ? ' (primary)' : ''}`);
|
|
551
|
+
console.log(` intent: ${split.originalIntent}`);
|
|
552
|
+
if (split.suggestedNextPhase) {
|
|
553
|
+
console.log(` suggested next: ${split.suggestedNextPhase.phaseId}`);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
if (result.splitNoteSummary && result.splitNoteSummary.otherActiveSplitNotes.length > 0) {
|
|
557
|
+
console.log(` Other active split notes: ${result.splitNoteSummary.otherActiveSplitNotes.length}`);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
if (result.splitNoteSummary && result.splitNoteSummary.suppressed > 0) {
|
|
561
|
+
console.log('');
|
|
562
|
+
console.log(`Split Notes Hidden: ${result.splitNoteSummary.suppressed}`);
|
|
563
|
+
console.log(' Run: hive-lite status --all');
|
|
564
|
+
}
|
|
565
|
+
if (result.recommendedActions.length > 0) {
|
|
566
|
+
console.log('');
|
|
567
|
+
console.log('Recommended Actions:');
|
|
568
|
+
for (const item of result.recommendedActions) {
|
|
569
|
+
console.log(` - ${item.label}`);
|
|
570
|
+
if (item.command) console.log(` ${item.command}`);
|
|
571
|
+
if (item.description) console.log(` ${item.description}`);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
function printActionBlock(title, action) {
|
|
577
|
+
if (!action) return;
|
|
578
|
+
console.log(title);
|
|
579
|
+
console.log(` ${action.label}`);
|
|
580
|
+
if (action.explanation) console.log(` ${action.explanation}`);
|
|
581
|
+
if (action.command) {
|
|
582
|
+
console.log(' Command:');
|
|
583
|
+
console.log(` ${action.command}`);
|
|
584
|
+
}
|
|
585
|
+
if (action.prompt) {
|
|
586
|
+
console.log(' Prompt:');
|
|
587
|
+
for (const line of action.prompt.split(/\r?\n/)) console.log(` ${line}`);
|
|
588
|
+
}
|
|
589
|
+
if (action.disabledReason) console.log(` Disabled: ${action.disabledReason}`);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
function printNext(result) {
|
|
593
|
+
console.log('Hive Lite Next');
|
|
594
|
+
console.log('');
|
|
595
|
+
console.log('Current State:');
|
|
596
|
+
if (result.state.hive.state === 'repo_setup_required') console.log(' Git Repo: no');
|
|
597
|
+
console.log(` Worktree: ${result.state.worktree.status}`);
|
|
598
|
+
console.log(` Hive State: ${result.state.hive.state}`);
|
|
599
|
+
console.log(` Can Start New Requirement: ${result.state.canStartNewRequirement ? 'yes' : 'no'}`);
|
|
600
|
+
console.log(` Map Health: ${result.state.mapHealth.status} (${result.state.mapHealth.critical} critical, ${result.state.mapHealth.warnings} warnings)`);
|
|
601
|
+
if (result.state.latestChange) {
|
|
602
|
+
console.log(` Latest Change: ${result.state.latestChange.id}`);
|
|
603
|
+
if (result.state.latestChange.verdict) console.log(` Latest Verdict: ${result.state.latestChange.verdict}`);
|
|
604
|
+
}
|
|
605
|
+
console.log('');
|
|
606
|
+
console.log(`Phase Guess: ${result.phaseGuess}`);
|
|
607
|
+
console.log('');
|
|
608
|
+
console.log('Summary:');
|
|
609
|
+
console.log(` ${result.summaryForHuman}`);
|
|
610
|
+
console.log('');
|
|
611
|
+
printActionBlock('Recommended Next Action:', result.primaryAction);
|
|
612
|
+
|
|
613
|
+
if (result.operatorSkillPreflight) {
|
|
614
|
+
console.log('');
|
|
615
|
+
console.log('Operator Skill Preflight:');
|
|
616
|
+
console.log(` required: ${result.operatorSkillPreflight.requiredSkill}`);
|
|
617
|
+
console.log(` ready: ${result.operatorSkillPreflight.ready ? 'yes' : 'no'}`);
|
|
618
|
+
console.log(' agent detection: not performed');
|
|
619
|
+
for (const target of result.operatorSkillPreflight.targets) {
|
|
620
|
+
const scope = target.scope ? `, ${target.scope}` : '';
|
|
621
|
+
console.log(` - ${target.agent}: ${target.status} (${target.configuredPath}${scope})`);
|
|
622
|
+
if (target.note) console.log(` ${target.note}`);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
if (result.secondaryActions.length > 0) {
|
|
627
|
+
console.log('');
|
|
628
|
+
console.log('Secondary Actions:');
|
|
629
|
+
for (const action of result.secondaryActions) {
|
|
630
|
+
console.log(` - ${action.label}`);
|
|
631
|
+
if (action.command) console.log(` ${action.command}`);
|
|
632
|
+
if (action.prompt) {
|
|
633
|
+
console.log(' prompt:');
|
|
634
|
+
for (const line of action.prompt.split(/\r?\n/)) console.log(` ${line}`);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
if (result.state.recentSplitNotes.length > 0) {
|
|
640
|
+
console.log('');
|
|
641
|
+
console.log('Recent Split Notes:');
|
|
642
|
+
const primarySplitId = result.state.splitNoteSummary && result.state.splitNoteSummary.primaryRecentSplitNote
|
|
643
|
+
? result.state.splitNoteSummary.primaryRecentSplitNote.id
|
|
644
|
+
: null;
|
|
645
|
+
for (const split of result.state.recentSplitNotes.slice(0, 3)) {
|
|
646
|
+
console.log(` - ${split.id}${split.id === primarySplitId ? ' (primary)' : ''}`);
|
|
647
|
+
if (split.suggestedNextPhase) console.log(` suggested next: ${split.suggestedNextPhase.phaseId}`);
|
|
648
|
+
}
|
|
649
|
+
if (result.state.splitNoteSummary && result.state.splitNoteSummary.otherActiveSplitNotes.length > 0) {
|
|
650
|
+
console.log(` Other active split notes: ${result.state.splitNoteSummary.otherActiveSplitNotes.length}`);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
if (result.state.splitNoteSummary && result.state.splitNoteSummary.suppressed > 0) {
|
|
654
|
+
console.log('');
|
|
655
|
+
console.log(`Split Notes Hidden: ${result.state.splitNoteSummary.suppressed}`);
|
|
656
|
+
console.log(' Run: hive-lite status --all');
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
if (result.warnings.length > 0) {
|
|
660
|
+
console.log('');
|
|
661
|
+
console.log('Warnings:');
|
|
662
|
+
for (const warning of result.warnings) console.log(` - ${warning}`);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
function printSkillsDoctor(result) {
|
|
667
|
+
console.log('Hive Lite Skills Doctor');
|
|
668
|
+
console.log('');
|
|
669
|
+
console.log(`Source: ${result.sourceDir}`);
|
|
670
|
+
console.log(`Current: ${result.summary.current}`);
|
|
671
|
+
console.log(`Stale: ${result.summary.stale}`);
|
|
672
|
+
console.log(`Missing: ${result.summary.missing}`);
|
|
673
|
+
if (result.targetSelection) {
|
|
674
|
+
console.log(`Target Selection: ${result.targetSelection.mode}`);
|
|
675
|
+
console.log('Agent CLI Detection: not performed');
|
|
676
|
+
}
|
|
677
|
+
for (const target of result.targets) {
|
|
678
|
+
console.log('');
|
|
679
|
+
console.log(`${target.label}:`);
|
|
680
|
+
console.log(` path: ${target.path}`);
|
|
681
|
+
if (target.scope) console.log(` scope: ${target.scope}`);
|
|
682
|
+
if (target.note) console.log(` note: ${target.note}`);
|
|
683
|
+
console.log(` exists: ${target.exists ? 'yes' : 'no'}`);
|
|
684
|
+
for (const skill of target.skills) {
|
|
685
|
+
console.log(` - ${skill.name}: ${skill.status}`);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
if (result.summary.missing > 0 || result.summary.stale > 0) {
|
|
689
|
+
console.log('');
|
|
690
|
+
console.log('Next:');
|
|
691
|
+
console.log(' hive-lite skills install --agent <codex|claude|gemini|all>');
|
|
692
|
+
console.log(' hive-lite skills sync --agent <codex|claude|gemini|all>');
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
function printSkillsMutation(result) {
|
|
697
|
+
console.log(result.command === 'skills sync' ? 'Hive Lite Skills Sync' : 'Hive Lite Skills Install');
|
|
698
|
+
console.log('');
|
|
699
|
+
console.log(`Source: ${result.sourceDir}`);
|
|
700
|
+
for (const item of result.results) {
|
|
701
|
+
console.log('');
|
|
702
|
+
console.log(`${item.label}:`);
|
|
703
|
+
console.log(` path: ${item.path}`);
|
|
704
|
+
if (item.scope) console.log(` scope: ${item.scope}`);
|
|
705
|
+
if (item.note) console.log(` note: ${item.note}`);
|
|
706
|
+
if (item.dryRun) console.log(' dry run: yes');
|
|
707
|
+
if (item.installed.length > 0) console.log(` installed: ${item.installed.join(', ')}`);
|
|
708
|
+
if (item.updated.length > 0) console.log(` updated: ${item.updated.join(', ')}`);
|
|
709
|
+
if (item.unchanged.length > 0) console.log(` unchanged: ${item.unchanged.join(', ')}`);
|
|
710
|
+
if (item.skipped.length > 0) {
|
|
711
|
+
console.log(' skipped:');
|
|
712
|
+
for (const skipped of item.skipped) console.log(` - ${skipped.name}: ${skipped.reason}`);
|
|
713
|
+
}
|
|
714
|
+
if (!item.installed.length && !item.updated.length && !item.skipped.length) {
|
|
715
|
+
console.log(' status: already current');
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
async function main(argv) {
|
|
721
|
+
const [command, subcommand, subsubcommand, ...rest] = argv;
|
|
722
|
+
if (!command || command === 'help' || command === '--help' || command === '-h') {
|
|
723
|
+
printHelp();
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
if (command === 'init') {
|
|
728
|
+
requireGitRepo(process.cwd(), 'hive-lite init');
|
|
729
|
+
printInit(initProject(process.cwd()));
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
if (command === 'doctor') {
|
|
734
|
+
const root = requireGitRepo(process.cwd(), 'hive-lite doctor');
|
|
735
|
+
const result = verifyProjectMap(root);
|
|
736
|
+
printVerify(root, result);
|
|
737
|
+
if (result.problems.length > 0) process.exitCode = 1;
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
if (command === 'status') {
|
|
742
|
+
const parsed = parseArgs([subcommand, subsubcommand, ...rest].filter((item) => item !== undefined));
|
|
743
|
+
const result = evaluateWorkspaceStatus(process.cwd(), parsed.flags);
|
|
744
|
+
if (parsed.flags.json) console.log(JSON.stringify(result, null, 2));
|
|
745
|
+
else printWorkspaceStatus(result);
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
if (command === 'next') {
|
|
750
|
+
const parsed = parseArgs([subcommand, subsubcommand, ...rest].filter((item) => item !== undefined));
|
|
751
|
+
const result = evaluateNextAction(process.cwd(), parsed.flags);
|
|
752
|
+
if (parsed.flags.json) console.log(JSON.stringify(result, null, 2));
|
|
753
|
+
else printNext(result);
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
if (command === 'skills') {
|
|
758
|
+
const parsed = parseArgs([subsubcommand, ...rest].filter((item) => item !== undefined));
|
|
759
|
+
if (subcommand === 'doctor') {
|
|
760
|
+
const result = skillsDoctor(process.cwd(), parsed.flags);
|
|
761
|
+
if (parsed.flags.json) console.log(JSON.stringify(result, null, 2));
|
|
762
|
+
else printSkillsDoctor(result);
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
if (subcommand === 'install') {
|
|
766
|
+
const result = installSkills(process.cwd(), parsed.flags);
|
|
767
|
+
if (parsed.flags.json) console.log(JSON.stringify(result, null, 2));
|
|
768
|
+
else printSkillsMutation(result);
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
if (subcommand === 'sync') {
|
|
772
|
+
const result = syncSkills(process.cwd(), parsed.flags);
|
|
773
|
+
if (parsed.flags.json) console.log(JSON.stringify(result, null, 2));
|
|
774
|
+
else printSkillsMutation(result);
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
throw new Error('skills requires a subcommand: doctor, install, or sync');
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
if (command === 'find') {
|
|
781
|
+
const parsed = parseArgs([subcommand, subsubcommand, ...rest].filter((item) => item !== undefined));
|
|
782
|
+
const intent = parsed.positional.join(' ').trim();
|
|
783
|
+
if (!intent) throw new Error('find requires an intent string');
|
|
784
|
+
const root = requireGitRepo(process.cwd(), 'hive-lite find');
|
|
785
|
+
const result = createContextPacket(root, intent, {
|
|
786
|
+
...parsed.flags,
|
|
787
|
+
cliCommandArgv: currentCliCommandArgv(),
|
|
788
|
+
});
|
|
789
|
+
if (parsed.flags.json) console.log(JSON.stringify(result.packet, null, 2));
|
|
790
|
+
else {
|
|
791
|
+
printContext(result);
|
|
792
|
+
if (parsed.flags.explain) printFindExplain(result.packet);
|
|
793
|
+
}
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
if (command === 'check') {
|
|
798
|
+
requireGitRepo(process.cwd(), 'hive-lite check');
|
|
799
|
+
const parsed = parseArgs([subcommand, subsubcommand, ...rest].filter((item) => item !== undefined));
|
|
800
|
+
const changeId = parsed.positional[0] || null;
|
|
801
|
+
const result = createOrUpdateChange(process.cwd(), {
|
|
802
|
+
changeId,
|
|
803
|
+
context: parsed.flags.context,
|
|
804
|
+
});
|
|
805
|
+
if (parsed.flags.json) console.log(JSON.stringify(result.change || { clean: true }, null, 2));
|
|
806
|
+
else printCheck(result.root, result);
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
if (command === 'validate') {
|
|
811
|
+
requireGitRepo(process.cwd(), 'hive-lite validate');
|
|
812
|
+
const parsed = parseArgs([subcommand, subsubcommand, ...rest].filter((item) => item !== undefined));
|
|
813
|
+
if (!parsed.flags.json && !parsed.flags.manual) {
|
|
814
|
+
parsed.flags.onStart = (item) => {
|
|
815
|
+
console.log(`Running validation: ${item.profile}`);
|
|
816
|
+
console.log(`Command: ${item.command}`);
|
|
817
|
+
console.log('');
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
const result = validateChange(process.cwd(), parsed.positional[0] || null, parsed.flags);
|
|
821
|
+
if (parsed.flags.json) console.log(JSON.stringify(result, null, 2));
|
|
822
|
+
else printValidation(result);
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
if (command === 'accept') {
|
|
827
|
+
requireGitRepo(process.cwd(), 'hive-lite accept');
|
|
828
|
+
const parsed = parseArgs([subcommand, subsubcommand, ...rest].filter((item) => item !== undefined));
|
|
829
|
+
const result = acceptChange(process.cwd(), parsed.positional[0] || null, parsed.flags);
|
|
830
|
+
if (parsed.flags.json) console.log(JSON.stringify(result, null, 2));
|
|
831
|
+
else printAccept(result);
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
if (command === 'map') {
|
|
836
|
+
const root = requireGitRepo(process.cwd(), 'hive-lite map');
|
|
837
|
+
if (subcommand === 'verify') {
|
|
838
|
+
const parsed = parseArgs([subsubcommand, ...rest].filter((item) => item !== undefined));
|
|
839
|
+
const result = verifyProjectMap(root);
|
|
840
|
+
if (parsed.flags.json) console.log(JSON.stringify(verifyJson(root, result), null, 2));
|
|
841
|
+
else printVerify(root, result);
|
|
842
|
+
if (result.problems.length > 0) process.exitCode = 1;
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
if (subcommand === 'suggest') {
|
|
846
|
+
console.log(JSON.stringify(suggestMap(root), null, 2));
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
if (subcommand === 'health') {
|
|
850
|
+
const parsed = parseArgs([subsubcommand, ...rest].filter((item) => item !== undefined));
|
|
851
|
+
const result = evaluateMapHealth(root, parsed.flags);
|
|
852
|
+
if (parsed.flags.json) console.log(JSON.stringify(result, null, 2));
|
|
853
|
+
else printMapHealth(result);
|
|
854
|
+
process.exitCode = result.exitCode;
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
if (subcommand === 'prompt') {
|
|
858
|
+
const parsed = parseArgs([subsubcommand, ...rest].filter((item) => item !== undefined));
|
|
859
|
+
const result = createMapPrompt(root, parsed.flags);
|
|
860
|
+
if (parsed.flags.json) console.log(JSON.stringify(result, null, 2));
|
|
861
|
+
else printMapPrompt(result);
|
|
862
|
+
return;
|
|
863
|
+
}
|
|
864
|
+
if (subcommand === 'delta') {
|
|
865
|
+
if (subsubcommand === 'list') {
|
|
866
|
+
printDeltas(allDeltas(root));
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
if (subsubcommand === 'apply') {
|
|
870
|
+
const parsed = parseArgs(rest);
|
|
871
|
+
const id = parsed.positional[0];
|
|
872
|
+
if (!id) throw new Error('map delta apply requires a delta id');
|
|
873
|
+
const result = applyDelta(process.cwd(), id);
|
|
874
|
+
console.log(`Applied ${result.delta.id}`);
|
|
875
|
+
console.log(`Updated: .hive/map/areas.yaml`);
|
|
876
|
+
console.log(result.changed ? 'Status: changed' : 'Status: already present');
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
if (subsubcommand === 'reject') {
|
|
880
|
+
const parsed = parseArgs(rest);
|
|
881
|
+
const id = parsed.positional[0];
|
|
882
|
+
if (!id) throw new Error('map delta reject requires a delta id');
|
|
883
|
+
const result = rejectDelta(process.cwd(), id, parsed.flags.reason || '');
|
|
884
|
+
console.log(`Rejected ${result.delta.id}`);
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
if (command === 'show-change') {
|
|
891
|
+
const parsed = parseArgs([subcommand, subsubcommand, ...rest].filter((item) => item !== undefined));
|
|
892
|
+
const root = requireGitRepo(process.cwd(), 'hive-lite show-change');
|
|
893
|
+
const id = parsed.positional[0] || latestChangeId(root);
|
|
894
|
+
if (!id) throw new Error('no change id provided and no latest change exists');
|
|
895
|
+
console.log(JSON.stringify(loadChange(root, id), null, 2));
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
if (command === 'map-dump') {
|
|
900
|
+
console.log(JSON.stringify(loadProjectMap(requireGitRepo(process.cwd(), 'hive-lite map-dump')), null, 2));
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
throw new Error(`unknown command: ${command}`);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
module.exports = {
|
|
908
|
+
main,
|
|
909
|
+
parseArgs,
|
|
910
|
+
};
|