hive-lite 0.1.3 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/docs/cli-semantics.md +7 -7
- package/docs/skills/hive-lite-bootstrap/SKILL.md +28 -10
- package/docs/skills/hive-lite-finish/SKILL.md +18 -6
- package/docs/skills/hive-lite-map-maintainer/SKILL.md +21 -15
- package/docs/skills/hive-lite-map-maintainer/references/lifecycle.md +1 -1
- package/docs/skills/hive-lite-map-maintainer/references/repair-rules.md +4 -0
- package/docs/skills/hive-lite-start-prompt/SKILL.md +33 -12
- package/docs/skills/hive-lite-start-prompt/references/preflight.md +3 -3
- package/package.json +2 -2
- package/src/cli.js +43 -1
- package/src/lib/change.js +75 -1
- package/src/lib/context.js +418 -4
- package/src/lib/evidence.js +7 -0
- package/src/lib/health.js +1 -1
- package/src/lib/map.js +63 -0
- package/src/lib/next.js +10 -10
- package/src/lib/risk.js +5 -0
- package/src/lib/scope.js +117 -2
- package/src/lib/skills.js +6 -6
- package/src/lib/status.js +3 -3
package/src/lib/map.js
CHANGED
|
@@ -331,10 +331,14 @@ function summarizeFindContext(context) {
|
|
|
331
331
|
},
|
|
332
332
|
warnings: context.warnings || [],
|
|
333
333
|
reviewGated: context.reviewGated || (context.explain && context.explain.reviewGated) || [],
|
|
334
|
+
writePlan: context.writePlan || (context.explain && context.explain.writePlan) || null,
|
|
334
335
|
candidateAreas: context.candidateAreas || [],
|
|
335
336
|
areaScores: context.explain && context.explain.areaScores ? context.explain.areaScores : [],
|
|
336
337
|
scopeQuality: scope.quality || (context.explain ? context.explain.scopeQuality : 'unknown'),
|
|
337
338
|
writableDirect: scope.writableDirect || context.writableScope || [],
|
|
339
|
+
selectedWritableScope: context.writableScope || [],
|
|
340
|
+
writableExisting: scope.writableExisting || [],
|
|
341
|
+
writableCreatePatterns: scope.writableCreatePatterns || [],
|
|
338
342
|
writableConditional: scope.writableConditional || [],
|
|
339
343
|
writableBroadFallback: scope.writableBroadFallback || [],
|
|
340
344
|
forbidden: scope.forbidden || context.doNotTouch || [],
|
|
@@ -431,6 +435,12 @@ function repairFocusFromFind(findContext, userFocus) {
|
|
|
431
435
|
if (isGenericAreaId(area)) goals.push(`replace generic area id with a focused id such as ${suggestedArea}`);
|
|
432
436
|
if (warnings.includes('BROAD_WRITABLE_SCOPE')) goals.push('move broad writable scope to reviewed fallback');
|
|
433
437
|
if (warnings.includes('MISSING_DIRECT_WRITABLE_SCOPE')) goals.push('add narrow writable_direct files');
|
|
438
|
+
if (warnings.includes('MISSING_DIRECT_NEW_FILE_SCOPE')) goals.push('add narrow writable_direct patterns or exact paths for the new peer files this intent must create');
|
|
439
|
+
if (warnings.includes('DIRECT_ONLY_REFERENCE_PEERS')) goals.push('move peer examples out of selected direct scope and add target create capability');
|
|
440
|
+
if (warnings.includes('BROAD_FALLBACK_ONLY')) goals.push('replace broad fallback-only coverage with narrow direct create capability');
|
|
441
|
+
if (warnings.includes('TARGET_ENTITY_MISMATCH')) goals.push('add direct scope for the requested target identity or mark old peers as references');
|
|
442
|
+
if (warnings.includes('MISSING_ARTIFACT_FAMILY_SCOPE')) goals.push('add writable_create_patterns for required artifact families');
|
|
443
|
+
if (warnings.includes('MISSING_REQUIRED_HOOK_SCOPE')) goals.push('add writable_existing hook files required by the artifact family');
|
|
434
444
|
if (warnings.includes('MISSING_ENTRYPOINT')) goals.push('add durable entrypoints');
|
|
435
445
|
if (warnings.includes('MISSING_VALIDATION')) goals.push('add validation profile references');
|
|
436
446
|
if (warnings.includes('NO_CONFIDENT_AREA')) goals.push('create or refine a focused area');
|
|
@@ -464,6 +474,15 @@ function findContextPromptSection(findContext) {
|
|
|
464
474
|
'Review-gated scope from find:',
|
|
465
475
|
...listLines(findContext.reviewGated, (notice) => `- ${notice.code}: ${notice.message}`),
|
|
466
476
|
'',
|
|
477
|
+
...(findContext.writePlan ? [
|
|
478
|
+
'Write plan from find:',
|
|
479
|
+
...listLines(findContext.writePlan.hypotheses || [], (item) => `- ${item.action} ${item.artifactFamily}: ${item.operation}${item.targetIdentity ? ` for ${item.targetIdentity}` : ''}`),
|
|
480
|
+
'Write plan blocking warnings:',
|
|
481
|
+
...listLines(findContext.writePlan.blockingWarnings || [], (item) => `- ${item.code}: ${item.message}`),
|
|
482
|
+
'Reference files from write plan:',
|
|
483
|
+
...listLines(findContext.writePlan.referenceFiles || [], (file) => `- ${file.path}: ${file.reason || ''}`),
|
|
484
|
+
'',
|
|
485
|
+
] : []),
|
|
467
486
|
'Candidate/area scores:',
|
|
468
487
|
...listLines(findContext.areaScores.length ? findContext.areaScores : findContext.candidateAreas, (area) => {
|
|
469
488
|
const signals = area.signals && area.signals.length ? ` (${area.signals.slice(0, 3).join(', ')})` : '';
|
|
@@ -476,6 +495,15 @@ function findContextPromptSection(findContext) {
|
|
|
476
495
|
'Current direct writable scope:',
|
|
477
496
|
...listLines(findContext.writableDirect, patternLine),
|
|
478
497
|
'',
|
|
498
|
+
'Selected direct writable scope for this intent:',
|
|
499
|
+
...listLines(findContext.selectedWritableScope, patternLine),
|
|
500
|
+
'',
|
|
501
|
+
'Current writable existing scope:',
|
|
502
|
+
...listLines(findContext.writableExisting, patternLine),
|
|
503
|
+
'',
|
|
504
|
+
'Current writable create patterns:',
|
|
505
|
+
...listLines(findContext.writableCreatePatterns, patternLine),
|
|
506
|
+
'',
|
|
479
507
|
'Current conditional writable scope:',
|
|
480
508
|
...listLines(findContext.writableConditional, patternLine),
|
|
481
509
|
'',
|
|
@@ -541,6 +569,9 @@ function buildMapPrompt(result) {
|
|
|
541
569
|
'- Every `writable_conditional` and `writable_broad_fallback` item must set `requires_review: true`; never output `requires_review: false` for those tiers.',
|
|
542
570
|
'- Keep broad patterns like `apps/*/src/**` only under `writable_broad_fallback`, never under `writable_direct`.',
|
|
543
571
|
'- `writable_direct` should use exact existing files unless there is a very small, justified pattern.',
|
|
572
|
+
'- Prefer `writable_existing` for exact update targets and `writable_create_patterns` for new peer files when a repo has create/update distinctions.',
|
|
573
|
+
'- Put copy sources and peer examples under `readable_reference`, not under selected Direct Writable for new peer intents.',
|
|
574
|
+
'- Use `artifact_families` to declare required create artifacts and hook files for provider/adapter/endpoint families.',
|
|
544
575
|
'- Entrypoint roles must use this fixed taxonomy only: ' + roleListText() + '.',
|
|
545
576
|
'- Do not invent role names. If unsure, use `role: unknown` plus a TODO note.',
|
|
546
577
|
'- Add `source` and `confidence` to entrypoints when possible. Use `source: agent_draft` for your own draft and `confidence: low|medium|high`.',
|
|
@@ -594,8 +625,27 @@ function buildMapPrompt(result) {
|
|
|
594
625
|
' scope:',
|
|
595
626
|
' readable:',
|
|
596
627
|
' - path/to/read/**',
|
|
628
|
+
' readable_reference:',
|
|
629
|
+
' peer_examples:',
|
|
630
|
+
' - path: path/to/ExistingPeer.ts',
|
|
631
|
+
' artifact: service_impl',
|
|
632
|
+
' peer_identity: Existing',
|
|
597
633
|
' writable_direct:',
|
|
598
634
|
' - path/to/real/file.ts',
|
|
635
|
+
' writable_existing:',
|
|
636
|
+
' - path: path/to/Registry.ts',
|
|
637
|
+
' artifact: registry_hook',
|
|
638
|
+
' operations:',
|
|
639
|
+
' - update_existing',
|
|
640
|
+
' required_when:',
|
|
641
|
+
' - add_provider_proxy',
|
|
642
|
+
' writable_create_patterns:',
|
|
643
|
+
' - pattern: path/to/*Provider.ts',
|
|
644
|
+
' artifact: service_impl',
|
|
645
|
+
' operations:',
|
|
646
|
+
' - create_file',
|
|
647
|
+
' intent_kinds:',
|
|
648
|
+
' - add_provider_proxy',
|
|
599
649
|
' writable_conditional:',
|
|
600
650
|
' - pattern: path/to/shared/**',
|
|
601
651
|
' reason: only if shared model changes are required',
|
|
@@ -623,6 +673,19 @@ function buildMapPrompt(result) {
|
|
|
623
673
|
' default_level: low',
|
|
624
674
|
' tags:',
|
|
625
675
|
' - ui',
|
|
676
|
+
' artifact_families:',
|
|
677
|
+
' provider_proxy:',
|
|
678
|
+
' trigger_terms:',
|
|
679
|
+
' en:',
|
|
680
|
+
' - provider',
|
|
681
|
+
' - proxy',
|
|
682
|
+
' zh:',
|
|
683
|
+
' - 提供商',
|
|
684
|
+
' - 代理',
|
|
685
|
+
' create_requires:',
|
|
686
|
+
' - service_impl',
|
|
687
|
+
' hooks:',
|
|
688
|
+
' - registry_hook',
|
|
626
689
|
'```',
|
|
627
690
|
'',
|
|
628
691
|
'Validation profile schema example:',
|
package/src/lib/next.js
CHANGED
|
@@ -162,21 +162,21 @@ function applySkillPreflight(root, options, current) {
|
|
|
162
162
|
...current,
|
|
163
163
|
phaseGuess: 'skill_preflight',
|
|
164
164
|
primaryAction: action({
|
|
165
|
-
kind: '
|
|
166
|
-
label: `
|
|
167
|
-
command: preflight.
|
|
168
|
-
explanation: 'The recommended next operator step requires
|
|
165
|
+
kind: 'sync_operator_skill',
|
|
166
|
+
label: `Sync ${preflight.requiredSkill}`,
|
|
167
|
+
command: preflight.syncCommand,
|
|
168
|
+
explanation: 'The recommended next operator step requires a current Hive Lite skill in the selected agent target.',
|
|
169
169
|
}),
|
|
170
170
|
secondaryActions: [
|
|
171
171
|
action({
|
|
172
172
|
...blockedAction,
|
|
173
173
|
enabled: false,
|
|
174
|
-
disabledReason: `
|
|
174
|
+
disabledReason: `Sync ${preflight.requiredSkill} first for the selected agent target.`,
|
|
175
175
|
}),
|
|
176
176
|
...current.secondaryActions,
|
|
177
177
|
],
|
|
178
|
-
summaryForHuman:
|
|
179
|
-
summaryForAgent: `The selected agent target is missing ${preflight.requiredSkill}. Run skills
|
|
178
|
+
summaryForHuman: `需要先同步 ${preflight.requiredSkill},然后再继续 Hive Lite operator flow。`,
|
|
179
|
+
summaryForAgent: `The selected agent target is missing or has a stale ${preflight.requiredSkill}. Run skills sync before using the handoff skill.`,
|
|
180
180
|
operatorSkillPreflight: preflight,
|
|
181
181
|
};
|
|
182
182
|
}
|
|
@@ -238,10 +238,10 @@ function evaluateNextAction(cwd, options = {}) {
|
|
|
238
238
|
kind: 'run_bootstrap_skill',
|
|
239
239
|
label: 'Use hive-lite-bootstrap',
|
|
240
240
|
prompt: bootstrapPrompt(),
|
|
241
|
-
explanation: 'This git repository
|
|
241
|
+
explanation: 'This git repository is missing required Hive Lite setup files. Use the bootstrap skill to initialize or repair setup, build the first Project Map when needed, and prepare the setup/map commit before product work starts.',
|
|
242
242
|
});
|
|
243
|
-
summaryForHuman = '
|
|
244
|
-
summaryForAgent = 'Hive Lite is
|
|
243
|
+
summaryForHuman = '当前项目缺少 Hive Lite setup 文件。建议使用 hive-lite-bootstrap 完成首次接入或 setup 修复,并在开始第一个需求前准备 setup/map 提交。';
|
|
244
|
+
summaryForAgent = 'Hive Lite setup is missing or incomplete. Stop ordinary start/finish/map-maintainer workflows and hand off to hive-lite-bootstrap.';
|
|
245
245
|
} else if (!workspace.canStartNewRequirement) {
|
|
246
246
|
if (workspace.hive.state === 'in_progress') {
|
|
247
247
|
phaseGuess = 'finish';
|
package/src/lib/risk.js
CHANGED
|
@@ -54,6 +54,11 @@ function evaluateChangeRisk(change, map) {
|
|
|
54
54
|
if (change.scope.status === 'violation') {
|
|
55
55
|
blockingReasons.push(`scope violation: ${change.scope.violations.join(', ')}`);
|
|
56
56
|
}
|
|
57
|
+
if (change.writePlanStatus && change.writePlanStatus.status === 'blocked') {
|
|
58
|
+
for (const reason of change.writePlanStatus.blockingReasons || []) {
|
|
59
|
+
blockingReasons.push(`write plan blocked: ${reason}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
57
62
|
|
|
58
63
|
const status = validationStatus(change);
|
|
59
64
|
if (status === 'failed') blockingReasons.push('validation failed');
|
package/src/lib/scope.js
CHANGED
|
@@ -12,6 +12,12 @@ function patternFrom(value) {
|
|
|
12
12
|
return normalizePath((value.pattern || value.path || '').trim());
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
function arrayFrom(value) {
|
|
16
|
+
if (Array.isArray(value)) return value.map((item) => String(item || '')).filter(Boolean);
|
|
17
|
+
if (value == null || value === '') return [];
|
|
18
|
+
return [String(value)];
|
|
19
|
+
}
|
|
20
|
+
|
|
15
21
|
function normalizePattern(value, defaults = {}) {
|
|
16
22
|
const pattern = patternFrom(value);
|
|
17
23
|
if (!pattern) return null;
|
|
@@ -22,6 +28,13 @@ function normalizePattern(value, defaults = {}) {
|
|
|
22
28
|
requiresReview: defaults.requiresReview === true,
|
|
23
29
|
source: defaults.source || 'map',
|
|
24
30
|
matchCount: defaults.matchCount == null ? null : defaults.matchCount,
|
|
31
|
+
artifact: defaults.artifact || null,
|
|
32
|
+
artifactFamily: defaults.artifactFamily || null,
|
|
33
|
+
operations: arrayFrom(defaults.operations),
|
|
34
|
+
targetIdentity: defaults.targetIdentity || null,
|
|
35
|
+
targetSlot: defaults.targetSlot || null,
|
|
36
|
+
intentKinds: arrayFrom(defaults.intentKinds),
|
|
37
|
+
requiredWhen: arrayFrom(defaults.requiredWhen),
|
|
25
38
|
};
|
|
26
39
|
}
|
|
27
40
|
return {
|
|
@@ -30,6 +43,13 @@ function normalizePattern(value, defaults = {}) {
|
|
|
30
43
|
requiresReview: value.requires_review === true || value.requiresReview === true || defaults.requiresReview === true,
|
|
31
44
|
source: value.source || defaults.source || 'map',
|
|
32
45
|
matchCount: value.matchCount == null ? (defaults.matchCount == null ? null : defaults.matchCount) : value.matchCount,
|
|
46
|
+
artifact: value.artifact || defaults.artifact || null,
|
|
47
|
+
artifactFamily: value.artifact_family || value.artifactFamily || defaults.artifactFamily || null,
|
|
48
|
+
operations: arrayFrom(value.operations || value.operation || defaults.operations),
|
|
49
|
+
targetIdentity: value.target_identity || value.targetIdentity || value.peer_identity || value.peerIdentity || defaults.targetIdentity || null,
|
|
50
|
+
targetSlot: value.target_slot || value.targetSlot || defaults.targetSlot || null,
|
|
51
|
+
intentKinds: arrayFrom(value.intent_kinds || value.intentKinds || defaults.intentKinds),
|
|
52
|
+
requiredWhen: arrayFrom(value.required_when || value.requiredWhen || defaults.requiredWhen),
|
|
33
53
|
};
|
|
34
54
|
}
|
|
35
55
|
|
|
@@ -93,29 +113,119 @@ function splitDirectAndBroad(root, values, defaults = {}) {
|
|
|
93
113
|
return { direct, broad };
|
|
94
114
|
}
|
|
95
115
|
|
|
116
|
+
function splitItemsAndBroad(root, values, defaults = {}) {
|
|
117
|
+
const direct = [];
|
|
118
|
+
const broad = [];
|
|
119
|
+
for (const value of values || []) {
|
|
120
|
+
const pattern = patternFrom(value);
|
|
121
|
+
if (!pattern) continue;
|
|
122
|
+
const classification = isBroadPattern(root, pattern);
|
|
123
|
+
const item = normalizePattern(value, {
|
|
124
|
+
...defaults,
|
|
125
|
+
matchCount: classification.matchCount,
|
|
126
|
+
});
|
|
127
|
+
if (!item) continue;
|
|
128
|
+
if (classification.broad) {
|
|
129
|
+
broad.push({
|
|
130
|
+
...item,
|
|
131
|
+
reason: item.reason || classification.reason || 'broad writable scope',
|
|
132
|
+
requiresReview: true,
|
|
133
|
+
});
|
|
134
|
+
} else {
|
|
135
|
+
direct.push(item);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return { direct, broad };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function flattenReferenceValues(value) {
|
|
142
|
+
if (!value) return [];
|
|
143
|
+
if (Array.isArray(value)) return value;
|
|
144
|
+
if (typeof value === 'object' && (value.path || value.pattern)) return [value];
|
|
145
|
+
if (typeof value === 'object') {
|
|
146
|
+
return Object.values(value).flatMap((item) => flattenReferenceValues(item));
|
|
147
|
+
}
|
|
148
|
+
return [value];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function normalizeReference(value, defaults = {}) {
|
|
152
|
+
const pattern = patternFrom(value);
|
|
153
|
+
if (!pattern) return null;
|
|
154
|
+
if (typeof value === 'string') {
|
|
155
|
+
return {
|
|
156
|
+
path: pattern,
|
|
157
|
+
reason: defaults.reason || '',
|
|
158
|
+
role: defaults.role || 'reference',
|
|
159
|
+
artifact: defaults.artifact || null,
|
|
160
|
+
artifactFamily: defaults.artifactFamily || null,
|
|
161
|
+
peerIdentity: defaults.peerIdentity || null,
|
|
162
|
+
source: defaults.source || 'readable_reference',
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
path: pattern,
|
|
167
|
+
reason: value.reason || defaults.reason || '',
|
|
168
|
+
role: value.role || defaults.role || 'reference',
|
|
169
|
+
artifact: value.artifact || defaults.artifact || null,
|
|
170
|
+
artifactFamily: value.artifact_family || value.artifactFamily || defaults.artifactFamily || null,
|
|
171
|
+
peerIdentity: value.peer_identity || value.peerIdentity || value.provider || defaults.peerIdentity || null,
|
|
172
|
+
source: value.source || defaults.source || 'readable_reference',
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function normalizeReferenceList(value, defaults = {}) {
|
|
177
|
+
return flattenReferenceValues(value).map((item) => normalizeReference(item, defaults)).filter(Boolean);
|
|
178
|
+
}
|
|
179
|
+
|
|
96
180
|
function normalizeAreaScope(root, area = {}) {
|
|
97
181
|
const configured = area.scope || {};
|
|
98
182
|
const readable = (configured.readable || area.readable_scope || []).map(patternFrom).filter(Boolean);
|
|
183
|
+
const readableReference = normalizeReferenceList(configured.readable_reference || area.readable_reference || [], {
|
|
184
|
+
source: 'readable_reference',
|
|
185
|
+
});
|
|
99
186
|
const forbidden = (configured.forbidden || area.do_not_touch || []).map(patternFrom).filter(Boolean);
|
|
100
187
|
|
|
101
188
|
const directValues = configured.writable_direct || [];
|
|
189
|
+
const existingValues = configured.writable_existing || [];
|
|
190
|
+
const createValues = configured.writable_create_patterns || [];
|
|
102
191
|
const conditionalValues = configured.writable_conditional || [];
|
|
103
192
|
const broadValues = configured.writable_broad_fallback || [];
|
|
104
193
|
const legacyWritable = !area.scope ? (area.writable_scope || []) : [];
|
|
105
194
|
|
|
106
|
-
const directSplit =
|
|
195
|
+
const directSplit = splitItemsAndBroad(root, directValues, { source: 'writable_direct' });
|
|
196
|
+
const existingSplit = splitItemsAndBroad(root, existingValues, {
|
|
197
|
+
source: 'writable_existing',
|
|
198
|
+
operations: ['update_existing'],
|
|
199
|
+
});
|
|
200
|
+
const createSplit = splitItemsAndBroad(root, createValues, {
|
|
201
|
+
source: 'writable_create_patterns',
|
|
202
|
+
operations: ['create_file'],
|
|
203
|
+
});
|
|
107
204
|
const legacySplit = splitDirectAndBroad(root, legacyWritable, {
|
|
108
205
|
source: 'legacy_writable_scope',
|
|
109
206
|
reason: 'legacy writable_scope is broad; move this to scope.writable_broad_fallback or add writable_direct',
|
|
110
207
|
});
|
|
111
208
|
|
|
112
|
-
const
|
|
209
|
+
const legacyDirectItems = legacySplit.direct.map((pattern) => normalizePattern(pattern, {
|
|
210
|
+
source: 'legacy_writable_scope',
|
|
211
|
+
})).filter(Boolean);
|
|
212
|
+
const writableDirectItems = [
|
|
213
|
+
...directSplit.direct,
|
|
214
|
+
...existingSplit.direct,
|
|
215
|
+
...createSplit.direct,
|
|
216
|
+
...legacyDirectItems,
|
|
217
|
+
];
|
|
218
|
+
const writableDirect = writableDirectItems.map((item) => item.pattern);
|
|
219
|
+
const writableExisting = existingSplit.direct;
|
|
220
|
+
const writableCreatePatterns = createSplit.direct;
|
|
113
221
|
const writableConditional = normalizePatternList(conditionalValues, {
|
|
114
222
|
source: 'writable_conditional',
|
|
115
223
|
requiresReview: true,
|
|
116
224
|
});
|
|
117
225
|
const writableBroadFallback = [
|
|
118
226
|
...directSplit.broad,
|
|
227
|
+
...existingSplit.broad,
|
|
228
|
+
...createSplit.broad,
|
|
119
229
|
...normalizePatternList(broadValues, {
|
|
120
230
|
source: 'writable_broad_fallback',
|
|
121
231
|
requiresReview: true,
|
|
@@ -139,7 +249,11 @@ function normalizeAreaScope(root, area = {}) {
|
|
|
139
249
|
|
|
140
250
|
return {
|
|
141
251
|
readable,
|
|
252
|
+
readableReference,
|
|
142
253
|
writableDirect,
|
|
254
|
+
writableDirectItems,
|
|
255
|
+
writableExisting,
|
|
256
|
+
writableCreatePatterns,
|
|
143
257
|
writableConditional,
|
|
144
258
|
writableBroadFallback,
|
|
145
259
|
forbidden,
|
|
@@ -164,5 +278,6 @@ module.exports = {
|
|
|
164
278
|
itemPattern,
|
|
165
279
|
normalizeAreaScope,
|
|
166
280
|
normalizePatternList,
|
|
281
|
+
normalizeReferenceList,
|
|
167
282
|
patternDisplay,
|
|
168
283
|
};
|
package/src/lib/skills.js
CHANGED
|
@@ -215,11 +215,11 @@ function targetSelection(options = {}, command = 'doctor') {
|
|
|
215
215
|
};
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
function
|
|
219
|
-
if (options.path && options.path !== true) return `hive-lite skills
|
|
220
|
-
if (options.agent && options.agent !== true) return `hive-lite skills
|
|
221
|
-
if (options.all) return 'hive-lite skills
|
|
222
|
-
return 'hive-lite skills
|
|
218
|
+
function syncCommandForOptions(options = {}) {
|
|
219
|
+
if (options.path && options.path !== true) return `hive-lite skills sync --path ${options.path}`;
|
|
220
|
+
if (options.agent && options.agent !== true) return `hive-lite skills sync --agent ${options.agent}`;
|
|
221
|
+
if (options.all) return 'hive-lite skills sync --agent all';
|
|
222
|
+
return 'hive-lite skills sync --agent all';
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
function skillPreflight(cwd, skillName, options = {}) {
|
|
@@ -246,7 +246,7 @@ function skillPreflight(cwd, skillName, options = {}) {
|
|
|
246
246
|
requiredSkill: skillName,
|
|
247
247
|
targetSelection: targetSelection(options, 'doctor'),
|
|
248
248
|
ready: targets.length > 0 && targets.every((target) => target.status === 'current'),
|
|
249
|
-
|
|
249
|
+
syncCommand: syncCommandForOptions(options),
|
|
250
250
|
targets,
|
|
251
251
|
};
|
|
252
252
|
}
|
package/src/lib/status.js
CHANGED
|
@@ -226,8 +226,8 @@ function actionsFor(state, latestId, diffMatches) {
|
|
|
226
226
|
}
|
|
227
227
|
if (state === 'hive_init_required') {
|
|
228
228
|
return [
|
|
229
|
-
action('
|
|
230
|
-
action('stop', 'Stop', null, 'Do not run start, finish, or map-maintainer skills until Hive Lite
|
|
229
|
+
action('run_bootstrap_skill', 'Use hive-lite-bootstrap', '$hive-lite-bootstrap', 'Use the first-time setup or setup repair skill before ordinary start, finish, or map-maintainer workflows.'),
|
|
230
|
+
action('stop', 'Stop', null, 'Do not run start, finish, or map-maintainer skills until Hive Lite setup is complete.'),
|
|
231
231
|
];
|
|
232
232
|
}
|
|
233
233
|
if (state === 'clean') {
|
|
@@ -314,7 +314,7 @@ function evaluateWorkspaceStatus(cwd, options = {}) {
|
|
|
314
314
|
|
|
315
315
|
if (!initialized) {
|
|
316
316
|
state = 'hive_init_required';
|
|
317
|
-
reason = 'Hive Lite is
|
|
317
|
+
reason = 'Hive Lite setup is missing or incomplete in this git repository. Use $hive-lite-bootstrap for first-time setup or setup repair.';
|
|
318
318
|
} else if (dirty && latest.change) {
|
|
319
319
|
if (accepted(latest.change) && !committed(latest.change) && diffMatches) {
|
|
320
320
|
state = 'accepted_uncommitted';
|