@ngockhoale/ukit 1.1.7 → 1.1.8
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 +11 -0
- package/README.md +9 -6
- package/manifests/platform.full.yaml +42 -0
- package/package.json +1 -1
- package/src/cli/commands/doctor.js +2 -0
- package/src/cli/commands/install.js +3 -2
- package/src/cli/commands/uninstall.js +1 -1
- package/src/core/runtimeConfig.js +1 -1
- package/src/core/uninstall.js +1 -1
- package/src/index/routeCatalog.js +24 -2
- package/src/index/taskRouting.js +137 -1
- package/templates/.claude/skills/docs-quality/SKILL.md +9 -1
- package/templates/.claude/skills/next-step/SKILL.md +78 -0
- package/templates/.claude/skills/update-status/SKILL.md +88 -0
- package/templates/.claude/ukit/index/route-catalog.mjs +24 -2
- package/templates/.claude/ukit/index/route-task.mjs +137 -1
- package/templates/.codex/README.md +6 -1
- package/templates/.codex/settings.json +8 -1
- package/templates/AGENTS.md +12 -1
- package/templates/CLAUDE.md +12 -1
- package/templates/docs/INSTALL.md +2 -0
- package/templates/docs/PROJECT.md +5 -4
- package/templates/docs/STATUS.md +81 -0
- package/templates/docs/UKIT_USAGE_GUIDE.md +16 -0
- package/templates/ukit/README.md +1 -1
- package/templates/ukit/storage/config.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@ All notable changes to UKit are documented here.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 1.1.8 - 2026-05-05
|
|
8
|
+
|
|
9
|
+
### Living Project Status
|
|
10
|
+
|
|
11
|
+
- Added `docs/STATUS.md` as a compact living project-state baseline for active work, debug threads, blockers, verification, and next candidates.
|
|
12
|
+
- Added `next-step` and `update-status` skills so Claude/Codex/OpenCode can use project status automatically without adding any user-facing commands beyond `ukit install`.
|
|
13
|
+
- Made next-step routing freshness-aware: stale or missing status must be treated as orientation only and verified against source/index before recommendations.
|
|
14
|
+
- Added concrete-task precedence so prompts like “fix login bug but not sure next step” stay on the debug/implementation/review workflow instead of being hijacked by global roadmap suggestions.
|
|
15
|
+
- Registered status docs/skills in the manifest with skip semantics for the living doc, and kept source route catalogs aligned with installed helper mirrors.
|
|
16
|
+
- Updated install/routing/manifest regression coverage for open-ended status prompts, explicit handoff updates, concrete debug edge cases, and default skill installation.
|
|
17
|
+
|
|
7
18
|
## 1.1.7 - 2026-04-25
|
|
8
19
|
|
|
9
20
|
### Impact Confidence
|
package/README.md
CHANGED
|
@@ -32,6 +32,7 @@ ukit install
|
|
|
32
32
|
4. Fill in the generated docs baseline:
|
|
33
33
|
- `docs/PROJECT.md`
|
|
34
34
|
- `docs/MEMORY.md`
|
|
35
|
+
- `docs/STATUS.md`
|
|
35
36
|
- `docs/WORKLOG.md`
|
|
36
37
|
5. Open your AI tool and work in natural language.
|
|
37
38
|
|
|
@@ -64,9 +65,9 @@ If maintainers roll out a newer CLI build, the in-project workflow still stays t
|
|
|
64
65
|
**Project support files**
|
|
65
66
|
- `.claude/ukit/.ukit/` — installer manifests, metadata, backups
|
|
66
67
|
- `.ukit/` — hidden shared runtime storage for config, cache, and cross-agent memory
|
|
67
|
-
- `docs/` — PROJECT / MEMORY / WORKLOG baseline
|
|
68
|
+
- `docs/` — PROJECT / MEMORY / STATUS / WORKLOG baseline
|
|
68
69
|
|
|
69
|
-
## UKit v1.1.
|
|
70
|
+
## UKit v1.1.8 Runtime
|
|
70
71
|
|
|
71
72
|
UKit now installs a hidden shared local runtime at `.ukit/` for production-oriented state that should survive across agent sessions:
|
|
72
73
|
|
|
@@ -83,15 +84,17 @@ When long sessions approach the compact threshold, UKit now uses a conservative
|
|
|
83
84
|
- compact only safe-zone history/noise
|
|
84
85
|
- preserve active task, rules, decisions, and current code focus
|
|
85
86
|
|
|
86
|
-
UKit v1.1.
|
|
87
|
+
UKit v1.1.8 keeps the same shared runtime contract while adding living project status routing for continuity-safe AI sessions:
|
|
87
88
|
|
|
88
89
|
- install globally with `npm install -g @ngockhoale/ukit`
|
|
89
90
|
- keep using the exact same human workflow inside projects: `ukit install`
|
|
90
91
|
- preserve the same `ukit` binary, hooks, and install-first orchestration while standardizing the runtime root as hidden `.ukit/`
|
|
91
|
-
-
|
|
92
|
-
-
|
|
92
|
+
- install `docs/STATUS.md` as a compact living state file for active work, debug threads, blockers, verification, and next candidates
|
|
93
|
+
- auto-route open-ended “what next?” / “continue” prompts to the `next-step` skill with a visible freshness cue when status may be stale
|
|
94
|
+
- auto-route explicit handoff/wrap-up requests to the `update-status` skill while skipping trivial/no-state-change tasks
|
|
95
|
+
- keep concrete debug/implementation/review prompts primary, so project status never replaces source/index-first task work
|
|
93
96
|
|
|
94
|
-
UKit v1.1.
|
|
97
|
+
UKit v1.1.8 also keeps the fast path improvements from the recent runtime releases:
|
|
95
98
|
|
|
96
99
|
- Vietnamese prompts now normalize more effectively for English-heavy code symbols and paths
|
|
97
100
|
- localized simple direct-target lanes skip extra previous-context / recent-output work when it would not change the next action
|
|
@@ -143,6 +143,22 @@ items:
|
|
|
143
143
|
packs:
|
|
144
144
|
- core
|
|
145
145
|
|
|
146
|
+
- id: docs-status
|
|
147
|
+
type: config
|
|
148
|
+
sourceTemplate: docs/STATUS.md
|
|
149
|
+
targetPath: docs/STATUS.md
|
|
150
|
+
requires:
|
|
151
|
+
- docs-project
|
|
152
|
+
- docs-memory
|
|
153
|
+
- docs-worklog
|
|
154
|
+
- docs-code-map
|
|
155
|
+
mergeStrategy: skip
|
|
156
|
+
variables:
|
|
157
|
+
- project.name
|
|
158
|
+
enabledByDefault: true
|
|
159
|
+
packs:
|
|
160
|
+
- core
|
|
161
|
+
|
|
146
162
|
- id: docs-bugfix
|
|
147
163
|
type: config
|
|
148
164
|
sourceTemplate: docs/BUGFIX.md
|
|
@@ -460,6 +476,32 @@ items:
|
|
|
460
476
|
packs:
|
|
461
477
|
- core
|
|
462
478
|
|
|
479
|
+
- id: next-step-skill
|
|
480
|
+
type: skill
|
|
481
|
+
sourceTemplate: .claude/skills/next-step/SKILL.md
|
|
482
|
+
targetPath: .claude/skills/next-step/SKILL.md
|
|
483
|
+
requires:
|
|
484
|
+
- docs-quality-skill
|
|
485
|
+
- docs-status
|
|
486
|
+
mergeStrategy: overwrite_with_backup
|
|
487
|
+
variables: []
|
|
488
|
+
enabledByDefault: true
|
|
489
|
+
packs:
|
|
490
|
+
- core
|
|
491
|
+
|
|
492
|
+
- id: update-status-skill
|
|
493
|
+
type: skill
|
|
494
|
+
sourceTemplate: .claude/skills/update-status/SKILL.md
|
|
495
|
+
targetPath: .claude/skills/update-status/SKILL.md
|
|
496
|
+
requires:
|
|
497
|
+
- docs-quality-skill
|
|
498
|
+
- docs-status
|
|
499
|
+
mergeStrategy: overwrite_with_backup
|
|
500
|
+
variables: []
|
|
501
|
+
enabledByDefault: true
|
|
502
|
+
packs:
|
|
503
|
+
- core
|
|
504
|
+
|
|
463
505
|
- id: docs-manager-skill
|
|
464
506
|
type: skill
|
|
465
507
|
sourceTemplate: .claude/skills/docs-manager
|
package/package.json
CHANGED
|
@@ -62,6 +62,7 @@ export async function runDoctor({ packageRoot, projectRoot, argv = [] }) {
|
|
|
62
62
|
sessionMemoryDirExists: await pathExists(runtimePaths.sessionsDir),
|
|
63
63
|
docsProjectExists: await pathExists(path.join(projectRoot, 'docs', 'PROJECT.md')),
|
|
64
64
|
docsMemoryExists: await pathExists(path.join(projectRoot, 'docs', 'MEMORY.md')),
|
|
65
|
+
docsStatusExists: await pathExists(path.join(projectRoot, 'docs', 'STATUS.md')),
|
|
65
66
|
docsWorklogExists: await pathExists(path.join(projectRoot, 'docs', 'WORKLOG.md')),
|
|
66
67
|
allProvidersConfigured: providers.allSupported,
|
|
67
68
|
...(codexAdapterTracked
|
|
@@ -103,6 +104,7 @@ export async function runDoctor({ packageRoot, projectRoot, argv = [] }) {
|
|
|
103
104
|
console.log(`[UKit] ${ok(checks.sessionMemoryDirExists)} .ukit/storage/memory/sessions/`);
|
|
104
105
|
console.log(`[UKit] ${ok(checks.docsProjectExists)} docs/PROJECT.md`);
|
|
105
106
|
console.log(`[UKit] ${ok(checks.docsMemoryExists)} docs/MEMORY.md`);
|
|
107
|
+
console.log(`[UKit] ${ok(checks.docsStatusExists)} docs/STATUS.md`);
|
|
106
108
|
console.log(`[UKit] ${ok(checks.docsWorklogExists)} docs/WORKLOG.md`);
|
|
107
109
|
if (codexAdapterTracked) {
|
|
108
110
|
console.log(`[UKit] ${ok(checks.codexReadmeExists)} .codex/README.md`);
|
|
@@ -244,9 +244,10 @@ export async function runInstall({ packageRoot, projectRoot, packageVersion, arg
|
|
|
244
244
|
const docsPaths = [
|
|
245
245
|
path.join(projectRoot, 'docs', 'PROJECT.md'),
|
|
246
246
|
path.join(projectRoot, 'docs', 'MEMORY.md'),
|
|
247
|
+
path.join(projectRoot, 'docs', 'STATUS.md'),
|
|
247
248
|
path.join(projectRoot, 'docs', 'WORKLOG.md'),
|
|
248
249
|
];
|
|
249
|
-
const docsLabels = ['docs/PROJECT.md', 'docs/MEMORY.md', 'docs/WORKLOG.md'];
|
|
250
|
+
const docsLabels = ['docs/PROJECT.md', 'docs/MEMORY.md', 'docs/STATUS.md', 'docs/WORKLOG.md'];
|
|
250
251
|
const missingDocs = [];
|
|
251
252
|
for (let i = 0; i < docsPaths.length; i++) {
|
|
252
253
|
if (!(await pathExists(docsPaths[i]))) {
|
|
@@ -257,7 +258,7 @@ export async function runInstall({ packageRoot, projectRoot, packageVersion, arg
|
|
|
257
258
|
if (missingDocs.length > 0) {
|
|
258
259
|
console.log(`[UKit] Missing docs — fill these in before first use: ${missingDocs.join(', ')}`);
|
|
259
260
|
} else {
|
|
260
|
-
console.log('[UKit] Docs baseline ready: docs/PROJECT.md, docs/MEMORY.md, docs/WORKLOG.md');
|
|
261
|
+
console.log('[UKit] Docs baseline ready: docs/PROJECT.md, docs/MEMORY.md, docs/STATUS.md, docs/WORKLOG.md');
|
|
261
262
|
console.log('[UKit] Fill them once with real project context for the best results.');
|
|
262
263
|
}
|
|
263
264
|
|
|
@@ -47,5 +47,5 @@ export async function runUninstall({ projectRoot, argv = [] }) {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
console.log(`[UKit] Uninstall complete. Removed ${result.removed}/${result.attempted} managed paths.`);
|
|
50
|
-
console.log('[UKit] Note: docs/PROJECT.md, docs/MEMORY.md, docs/WORKLOG.md contain user content and were preserved. Delete manually if needed.');
|
|
50
|
+
console.log('[UKit] Note: docs/PROJECT.md, docs/MEMORY.md, docs/STATUS.md, docs/WORKLOG.md contain user content and were preserved. Delete manually if needed.');
|
|
51
51
|
}
|
package/src/core/uninstall.js
CHANGED
|
@@ -200,7 +200,7 @@ export async function uninstallUkit({ projectRoot, dryRun = false }) {
|
|
|
200
200
|
}
|
|
201
201
|
} else {
|
|
202
202
|
// Old format (no files list): fall back to hardcoded managed paths.
|
|
203
|
-
// NOTE: docs/PROJECT.md, MEMORY.md, WORKLOG.md are intentionally excluded.
|
|
203
|
+
// NOTE: docs/PROJECT.md, MEMORY.md, STATUS.md, WORKLOG.md are intentionally excluded.
|
|
204
204
|
// These are user-created content (mergeStrategy: skip) — deleting them
|
|
205
205
|
// would cause data loss. Users must remove them manually if desired.
|
|
206
206
|
const fallback = buildFallbackPaths(projectRoot);
|
|
@@ -223,8 +223,30 @@ export const ROUTE_CATALOG = [
|
|
|
223
223
|
path: '.claude/skills/docs-quality/SKILL.md',
|
|
224
224
|
order: 12,
|
|
225
225
|
signals: [
|
|
226
|
-
{ type: 'prompt', regex: /\b(docs|documentation|readme|changelog|handoff|worklog|memory|code map)\b/i, score: 4 },
|
|
227
|
-
{ type: 'file', regex: /\bdocs\/|readme\.md$|project\.md$|memory\.md$|worklog\.md$|code_map\.md$/i, score: 4 },
|
|
226
|
+
{ type: 'prompt', regex: /\b(docs|documentation|readme|changelog|handoff|worklog|memory|code map|status\.md)\b/i, score: 4 },
|
|
227
|
+
{ type: 'file', regex: /\bdocs\/|readme\.md$|project\.md$|memory\.md$|status\.md$|worklog\.md$|code_map\.md$/i, score: 4 },
|
|
228
|
+
],
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
id: 'next-step',
|
|
232
|
+
path: '.claude/skills/next-step/SKILL.md',
|
|
233
|
+
order: 12.1,
|
|
234
|
+
contextMode: 'standalone',
|
|
235
|
+
signals: [
|
|
236
|
+
{ type: 'prompt', regex: /\b(what(?:'s| is)? next|next steps?|project status|current status|where are we|continue(?: from)?(?: last session)?|roadmap|status\.md)\b/i, score: 7 },
|
|
237
|
+
{ type: 'prompt', regex: /\b(làm gì tiếp|bước tiếp theo|tiếp theo làm gì|làm tiếp|đang ở đâu|trạng thái project|tình trạng project)\b/i, score: 7 },
|
|
238
|
+
],
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
id: 'update-status',
|
|
242
|
+
path: '.claude/skills/update-status/SKILL.md',
|
|
243
|
+
order: 12.2,
|
|
244
|
+
contextMode: 'standalone',
|
|
245
|
+
signals: [
|
|
246
|
+
{ type: 'prompt', regex: /\b(update|refresh|write|sync|record|capture|summari[sz]e).{0,48}\b(status\.md|project status|current state|next candidates?|session state)\b/i, score: 9 },
|
|
247
|
+
{ type: 'prompt', regex: /\b(status\.md|project status).{0,48}\b(update|refresh|write|sync|record|capture|summari[sz]e)\b/i, score: 9 },
|
|
248
|
+
{ type: 'prompt', regex: /\b(wrap up|handoff|end(?:ing)? this session|session summary|before final)\b/i, score: 7 },
|
|
249
|
+
{ type: 'prompt', regex: /\b(cập nhật|ghi lại|tổng kết|chốt session|bàn giao).{0,48}\b(status|trạng thái|việc tiếp theo)\b/i, score: 9 },
|
|
228
250
|
],
|
|
229
251
|
},
|
|
230
252
|
{
|
package/src/index/taskRouting.js
CHANGED
|
@@ -22,11 +22,17 @@ export async function deriveTaskRoute({
|
|
|
22
22
|
const normalizedPrompt = String(promptText || '').trim();
|
|
23
23
|
const normalizedCommand = String(commandText || '').trim();
|
|
24
24
|
const normalizedTarget = normalizeRelativeFile(absoluteRoot, targetFile);
|
|
25
|
+
const intentMode = deriveIntentMode({
|
|
26
|
+
promptText: normalizedPrompt,
|
|
27
|
+
commandText: normalizedCommand,
|
|
28
|
+
targetFile: normalizedTarget,
|
|
29
|
+
});
|
|
25
30
|
const activeSkills = await selectActiveSkills({
|
|
26
31
|
rootDir: absoluteRoot,
|
|
27
32
|
promptText: normalizedPrompt,
|
|
28
33
|
commandText: normalizedCommand,
|
|
29
34
|
targetFile: normalizedTarget,
|
|
35
|
+
intentMode,
|
|
30
36
|
});
|
|
31
37
|
const useIndexedContext = shouldUseIndexedContext({
|
|
32
38
|
activeSkills,
|
|
@@ -102,6 +108,7 @@ export async function deriveTaskRoute({
|
|
|
102
108
|
targetFile: normalizedTarget,
|
|
103
109
|
contextIntent,
|
|
104
110
|
taskType: inferredTaskType,
|
|
111
|
+
intentMode,
|
|
105
112
|
},
|
|
106
113
|
contextRecommendation,
|
|
107
114
|
verificationRecommendation,
|
|
@@ -117,6 +124,7 @@ export async function deriveTaskRoute({
|
|
|
117
124
|
targetFile: normalizedTarget,
|
|
118
125
|
contextIntent,
|
|
119
126
|
taskType: inferredTaskType,
|
|
127
|
+
intentMode,
|
|
120
128
|
},
|
|
121
129
|
contextRecommendation,
|
|
122
130
|
verificationRecommendation,
|
|
@@ -175,6 +183,7 @@ export function buildRouteSummary({
|
|
|
175
183
|
fallbackCommands,
|
|
176
184
|
preferredOrder,
|
|
177
185
|
policyMode,
|
|
186
|
+
intentMode: routingContext.intentMode ?? null,
|
|
178
187
|
delegateHint: delegationRecommendation?.hint ?? null,
|
|
179
188
|
nextActionType: nextAction?.type ?? null,
|
|
180
189
|
nextActionCommand,
|
|
@@ -183,7 +192,7 @@ export function buildRouteSummary({
|
|
|
183
192
|
};
|
|
184
193
|
}
|
|
185
194
|
|
|
186
|
-
async function selectActiveSkills({ rootDir, promptText, commandText, targetFile }) {
|
|
195
|
+
async function selectActiveSkills({ rootDir, promptText, commandText, targetFile, intentMode = null }) {
|
|
187
196
|
const routeSignals = {
|
|
188
197
|
promptRawText: String(promptText || '').toLowerCase(),
|
|
189
198
|
promptNormalizedText: buildRouteSignalText(promptText),
|
|
@@ -194,6 +203,7 @@ async function selectActiveSkills({ rootDir, promptText, commandText, targetFile
|
|
|
194
203
|
const scoredEntries = ROUTE_CATALOG
|
|
195
204
|
.map((entry) => scoreSkillRouteEntry(entry, routeSignals))
|
|
196
205
|
.filter((entry) => entry.score > 0)
|
|
206
|
+
.filter((entry) => shouldKeepRouteEntryForIntent(entry, intentMode))
|
|
197
207
|
.sort((a, b) => b.score - a.score || a.order - b.order);
|
|
198
208
|
const active = [];
|
|
199
209
|
|
|
@@ -209,6 +219,22 @@ async function selectActiveSkills({ rootDir, promptText, commandText, targetFile
|
|
|
209
219
|
return active.map(({ order, ...rest }) => rest);
|
|
210
220
|
}
|
|
211
221
|
|
|
222
|
+
function shouldKeepRouteEntryForIntent(entry, intentMode) {
|
|
223
|
+
if (entry.id === 'next-step' && ['scoped-advice', 'docs-specific'].includes(intentMode)) {
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (entry.id === 'update-status' && intentMode === 'docs-specific') {
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (entry.id === 'docs-quality' && ['open-ended-status', 'status-update'].includes(intentMode)) {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
|
|
212
238
|
function scoreSkillRouteEntry(entry, routeSignals = {}) {
|
|
213
239
|
let score = 0;
|
|
214
240
|
const reasons = [];
|
|
@@ -282,6 +308,116 @@ function getSignalTexts(signalType, routeSignals = {}) {
|
|
|
282
308
|
};
|
|
283
309
|
}
|
|
284
310
|
|
|
311
|
+
function deriveIntentMode({ promptText = '', commandText = '', targetFile = null } = {}) {
|
|
312
|
+
const lower = buildRouteSignalText(promptText, commandText);
|
|
313
|
+
const raw = `${promptText ?? ''}\n${commandText ?? ''}`.toLowerCase();
|
|
314
|
+
const docsSpecific = hasDocsSpecificTaskSignal(lower, raw, targetFile);
|
|
315
|
+
const statusUpdate = hasStatusUpdateSignal(lower, raw);
|
|
316
|
+
const openEndedStatus = hasOpenEndedStatusSignal(lower, raw);
|
|
317
|
+
const concreteTask = hasConcreteTaskSignal(lower, raw, targetFile);
|
|
318
|
+
|
|
319
|
+
if (docsSpecific) {
|
|
320
|
+
return 'docs-specific';
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (statusUpdate) {
|
|
324
|
+
return 'status-update';
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (concreteTask && openEndedStatus) {
|
|
328
|
+
return 'scoped-advice';
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (openEndedStatus) {
|
|
332
|
+
return 'open-ended-status';
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (concreteTask) {
|
|
336
|
+
if (/\b(bug|debug|error|crash|broken|failing|stack trace|triage|fix|login|timeout)\b/.test(lower)) {
|
|
337
|
+
return 'debug-specific';
|
|
338
|
+
}
|
|
339
|
+
if (/\b(review|audit|diff|pr feedback|code review|kiem tra|soat)\b/.test(lower)) {
|
|
340
|
+
return 'review-specific';
|
|
341
|
+
}
|
|
342
|
+
if (/\b(implement|build|create|add|ship|deliver|refactor|integrate|integration|scaffold|feature)\b/.test(lower)) {
|
|
343
|
+
return 'implement-specific';
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function hasStatusUpdateSignal(lower, raw) {
|
|
351
|
+
return /\b(update|refresh|write|sync|record|capture|summarize|summarise).{0,64}\b(status\.md|project status|current state|next candidates|session state)\b/.test(lower)
|
|
352
|
+
|| /\b(status\.md|project status).{0,64}\b(update|refresh|write|sync|record|capture|summarize|summarise)\b/.test(lower)
|
|
353
|
+
|| /\b(wrap up|handoff|end this session|ending this session|session summary|before final)\b/.test(lower)
|
|
354
|
+
|| /\b(cap nhat|ghi lai|tong ket|chot session|ban giao).{0,64}\b(status|trang thai|viec tiep theo)\b/.test(lower)
|
|
355
|
+
|| /\b(cập nhật|ghi lại|tổng kết|chốt session|bàn giao).{0,64}\b(status|trạng thái|việc tiếp theo)\b/.test(raw);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function hasOpenEndedStatusSignal(lower, raw) {
|
|
359
|
+
return /\b(what next|what is next|what's next|next step|next steps|project status|current status|where are we|continue|continue from last session|roadmap|status\.md)\b/.test(lower)
|
|
360
|
+
|| /\b(lam gi tiep|buoc tiep theo|tiep theo lam gi|lam tiep|dang o dau|trang thai project|tinh trang project)\b/.test(lower)
|
|
361
|
+
|| /\b(làm gì tiếp|bước tiếp theo|tiếp theo làm gì|làm tiếp|đang ở đâu|trạng thái project|tình trạng project)\b/.test(raw);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function hasConcreteTaskSignal(lower, raw, targetFile) {
|
|
365
|
+
if (targetFile && !isStatusFileTarget(targetFile)) {
|
|
366
|
+
return true;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return /\b(bug|debug|error|crash|broken|failing|stack trace|triage|fix|implement|build|create|add|ship|deliver|refactor|integrate|integration|scaffold|feature|review|audit|diff|pr feedback|code review|auth|login|api|endpoint|test|spec)\b/.test(lower)
|
|
370
|
+
|| /\b(sửa|fix|lỗi|bug|debug|implement|cài|thêm|review|kiểm tra|soát|đăng nhập)\b/.test(raw);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function hasDocsSpecificTaskSignal(lower, raw, targetFile) {
|
|
374
|
+
if (!targetFile || !isDocsTarget(targetFile)) {
|
|
375
|
+
return false;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const targetName = path.posix.basename(String(targetFile || '').replaceAll('\\', '/')).toLowerCase();
|
|
379
|
+
const explicitStatusUpdate = hasExplicitStatusUpdateSignal(lower, raw);
|
|
380
|
+
|
|
381
|
+
if (!isStatusFileTarget(targetFile)) {
|
|
382
|
+
if (explicitStatusUpdate && !mentionsTargetDoc(lower, targetName)) {
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return mentionsTargetDoc(lower, targetName)
|
|
387
|
+
|| /\b(edit|write|improve|document|docs?|readme|changelog|worklog|memory|code map|template|wording|copy|grammar|format|structure|heading|section|handoff notes?)\b/.test(lower)
|
|
388
|
+
|| /\b(câu chữ|chỉnh|sửa chữ|ngữ pháp|định dạng|cấu trúc|tài liệu|ghi chú bàn giao)\b/.test(raw);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
return /\b(template|wording|edit|copy|grammar|format|structure|heading|section|docs?)\b/.test(lower)
|
|
392
|
+
|| /\b(mẫu|câu chữ|chỉnh|sửa chữ|ngữ pháp|định dạng|cấu trúc|tài liệu)\b/.test(raw);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function hasExplicitStatusUpdateSignal(lower, raw) {
|
|
396
|
+
return /\b(update|refresh|write|sync|record|capture|summarize|summarise).{0,64}\b(status\.md|project status|current state|next candidates|session state)\b/.test(lower)
|
|
397
|
+
|| /\b(status\.md|project status).{0,64}\b(update|refresh|write|sync|record|capture|summarize|summarise)\b/.test(lower)
|
|
398
|
+
|| /\b(cap nhat|ghi lai|tong ket|chot session|ban giao).{0,64}\b(status|trang thai|viec tiep theo)\b/.test(lower)
|
|
399
|
+
|| /\b(cập nhật|ghi lại|tổng kết|chốt session|bàn giao).{0,64}\b(status|trạng thái|việc tiếp theo)\b/.test(raw);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function mentionsTargetDoc(lower, targetName) {
|
|
403
|
+
if (!targetName) {
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const escaped = targetName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
408
|
+
const withoutExt = escaped.replace(/\\\.md$/i, '');
|
|
409
|
+
return new RegExp(`\\b(?:${escaped}|${withoutExt})\\b`, 'i').test(lower);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
function isStatusFileTarget(targetFile) {
|
|
413
|
+
return /(?:^|\/)docs\/STATUS\.md$|(?:^|\/)STATUS\.md$/i.test(String(targetFile || ''));
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function isDocsTarget(targetFile) {
|
|
417
|
+
const normalized = String(targetFile || '').replaceAll('\\', '/');
|
|
418
|
+
return /(?:^|\/)docs\/.+\.md$|(?:^|\/)(?:README|CHANGELOG|AGENTS|CLAUDE|STATUS)\.md$/i.test(normalized);
|
|
419
|
+
}
|
|
420
|
+
|
|
285
421
|
function shouldUseIndexedContext({ activeSkills = [], targetFile = null } = {}) {
|
|
286
422
|
if (activeSkills.length === 0) {
|
|
287
423
|
return Boolean(targetFile);
|
|
@@ -61,7 +61,7 @@ Docs should **not** become:
|
|
|
61
61
|
|
|
62
62
|
- update README / docs after code changes
|
|
63
63
|
- fix source-vs-doc drift
|
|
64
|
-
- improve `docs/PROJECT.md`, `docs/MEMORY.md`, `docs/WORKLOG.md`, `docs/CODE_MAP.md`
|
|
64
|
+
- improve `docs/PROJECT.md`, `docs/MEMORY.md`, `docs/STATUS.md`, `docs/WORKLOG.md`, `docs/CODE_MAP.md`
|
|
65
65
|
- prepare durable handoff notes
|
|
66
66
|
- tighten or remove stale setup instructions
|
|
67
67
|
- document newly discovered module boundaries, dangerous areas, or bug patterns
|
|
@@ -97,6 +97,14 @@ Use for durable knowledge:
|
|
|
97
97
|
|
|
98
98
|
Prefer short entries that future sessions can scan in seconds.
|
|
99
99
|
|
|
100
|
+
#### `docs/STATUS.md`
|
|
101
|
+
Use for compact current state:
|
|
102
|
+
- current focus / active work
|
|
103
|
+
- live debug threads, blockers, and verification status
|
|
104
|
+
- next candidates for open-ended continuation
|
|
105
|
+
|
|
106
|
+
Do **not** treat it as source truth or duplicate full session history here.
|
|
107
|
+
|
|
100
108
|
#### `docs/WORKLOG.md`
|
|
101
109
|
Use for session-level execution history:
|
|
102
110
|
- what changed
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: next-step
|
|
3
|
+
description: Use when the user asks what to do next, asks for project status, says continue/làm tiếp without a concrete target, or needs a lightweight session-start orientation from docs/STATUS.md. Do not use as the primary skill for concrete debug, implementation, review, or docs tasks.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Next Step
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
Suggest the next useful project action without scanning the whole repository.
|
|
11
|
+
|
|
12
|
+
This skill is for open-ended continuity prompts such as:
|
|
13
|
+
- "what next?", "project status?", "where are we?"
|
|
14
|
+
- "continue", "continue from last session"
|
|
15
|
+
- "làm gì tiếp?", "làm tiếp", "project đang ở đâu?"
|
|
16
|
+
|
|
17
|
+
It is **not** a replacement for concrete workflows. If the user names a bug, feature, file, test, PR, or review target, keep the concrete workflow primary and use this skill only as background if useful.
|
|
18
|
+
|
|
19
|
+
## Hard Guardrails
|
|
20
|
+
|
|
21
|
+
- End users should not need to know this skill name.
|
|
22
|
+
- Do not ask users to run a `next-step` command. The human workflow remains `ukit install` + natural language.
|
|
23
|
+
- `docs/STATUS.md` is orientation, not truth. Source code, tests, and the UKit index win.
|
|
24
|
+
- Concrete task beats open-ended wording. Example: "I'm fixing login bug but unsure next step" is a debug approach question, not a global roadmap request.
|
|
25
|
+
- Do not scan the whole repo unless `docs/STATUS.md` is missing/stale and the user still wants project-level direction.
|
|
26
|
+
|
|
27
|
+
## Freshness Check
|
|
28
|
+
|
|
29
|
+
Before relying on status content, check both:
|
|
30
|
+
1. filesystem modified time for `docs/STATUS.md` (fallback: root `STATUS.md` if present)
|
|
31
|
+
2. the `Last meaningful update` field inside the file
|
|
32
|
+
|
|
33
|
+
Use this cue in your response:
|
|
34
|
+
|
|
35
|
+
- 🟢 fresh: modified within 24h
|
|
36
|
+
- 🟡 possibly stale: 24-72h old
|
|
37
|
+
- 🔴 stale: older than 72h
|
|
38
|
+
- ⚪ missing: no status file yet
|
|
39
|
+
|
|
40
|
+
If stale or missing, downgrade confidence and verify with the smallest current tree/index/context signal before recommending work.
|
|
41
|
+
|
|
42
|
+
## Input Order
|
|
43
|
+
|
|
44
|
+
Read only what is needed:
|
|
45
|
+
1. `docs/STATUS.md` (or existing root `STATUS.md` fallback)
|
|
46
|
+
2. `docs/CODE_MAP.md` only when navigation is needed
|
|
47
|
+
3. `docs/MEMORY.md` only when constraints/decisions affect the suggestion
|
|
48
|
+
4. routed index/tree summary only if status is stale, missing, or contradicted
|
|
49
|
+
|
|
50
|
+
## Output Shape
|
|
51
|
+
|
|
52
|
+
Keep output compact:
|
|
53
|
+
|
|
54
|
+
```md
|
|
55
|
+
STATUS freshness: 🟡 possibly stale
|
|
56
|
+
- last modified: YYYY-MM-DD HH:mm
|
|
57
|
+
- confidence: medium-low
|
|
58
|
+
|
|
59
|
+
Suggested next steps:
|
|
60
|
+
1. Candidate — why now — likely files — verification — risk
|
|
61
|
+
2. Candidate — why now — likely files — verification — risk
|
|
62
|
+
|
|
63
|
+
Recommended: ...
|
|
64
|
+
Why: ...
|
|
65
|
+
First check: ...
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Intent Handling
|
|
69
|
+
|
|
70
|
+
- `open-ended-status`: read status and suggest 1-3 candidates.
|
|
71
|
+
- `continue-existing-work`: prefer Active Work / Current Debug Threads, then Next Candidates.
|
|
72
|
+
- `scoped-advice`: do not produce a global roadmap; hand off to the concrete skill and suggest the immediate approach only.
|
|
73
|
+
- `debug-specific`, `implement-specific`, `review-specific`: do not use this skill as primary.
|
|
74
|
+
|
|
75
|
+
## Missing or Stale Status
|
|
76
|
+
|
|
77
|
+
If missing, suggest creating/updating `docs/STATUS.md` after the current task, but do not block the user.
|
|
78
|
+
If stale, say so visibly and treat old Next Candidates as hypotheses, not fact.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: update-status
|
|
3
|
+
description: Use near the end of a meaningful session or explicit handoff/status request to update docs/STATUS.md with compact current state, verification, blockers, and next candidates. Skip trivial/no-state-change tasks.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Update Status
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
Keep `docs/STATUS.md` useful as a compact living state document for future AI sessions.
|
|
11
|
+
|
|
12
|
+
This skill should run when:
|
|
13
|
+
- the user explicitly asks to update status / handoff / wrap up
|
|
14
|
+
- meaningful source/docs/tests/package state changed
|
|
15
|
+
- a task is paused, blocked, completed, or has a new verified next action
|
|
16
|
+
- a bug root cause, verification result, or durable blocker was discovered
|
|
17
|
+
|
|
18
|
+
Do **not** run for trivial typo-only edits, pure Q&A, or exploration with no durable finding.
|
|
19
|
+
|
|
20
|
+
## Hard Guardrails
|
|
21
|
+
|
|
22
|
+
- End users should not need to know this skill name.
|
|
23
|
+
- Do not ask users to run a `update-status` command. The human workflow remains `ukit install` + natural language.
|
|
24
|
+
- Keep `docs/STATUS.md` compact. It is not `docs/WORKLOG.md` and not a raw session transcript.
|
|
25
|
+
- Source code and tests are truth. If status conflicts with source, update status to match source or mark uncertainty.
|
|
26
|
+
- Do not invent verification. Record only commands actually run and their outcome.
|
|
27
|
+
- Preserve user edits and rewrite the smallest relevant section.
|
|
28
|
+
|
|
29
|
+
## Update Decision
|
|
30
|
+
|
|
31
|
+
Before editing, ask internally:
|
|
32
|
+
|
|
33
|
+
1. Did project state actually change?
|
|
34
|
+
2. Is any work still active/blocked?
|
|
35
|
+
3. Was a root cause, decision, blocker, or next action confirmed?
|
|
36
|
+
4. What verification ran?
|
|
37
|
+
5. Will future sessions be faster if this is recorded?
|
|
38
|
+
|
|
39
|
+
If all answers are no, skip the update and mention that no status change was needed.
|
|
40
|
+
|
|
41
|
+
## Freshness Fields
|
|
42
|
+
|
|
43
|
+
When updating meaningful state, update the header:
|
|
44
|
+
|
|
45
|
+
```md
|
|
46
|
+
## Freshness
|
|
47
|
+
|
|
48
|
+
- Last meaningful update: YYYY-MM-DD HH:mm
|
|
49
|
+
- Updated by: Claude / Codex / OpenCode / human
|
|
50
|
+
- Status confidence: high / medium / low
|
|
51
|
+
- Stale after: 72h
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Confidence guide:
|
|
55
|
+
- `high`: implementation/fix verified by targeted tests or stronger
|
|
56
|
+
- `medium`: state changed but verification was partial or docs-only
|
|
57
|
+
- `low`: investigation/hypothesis only, blocked, or stale recovery
|
|
58
|
+
|
|
59
|
+
## Section Rules
|
|
60
|
+
|
|
61
|
+
- `Snapshot`: only current focus, health, branch/state, release/version.
|
|
62
|
+
- `Active Work`: only live unfinished work.
|
|
63
|
+
- `Current Debug Threads`: compact bug state; detailed context should link to future `docs/context/<slug>.md` files when available.
|
|
64
|
+
- `Decisions Pending`: unresolved choices only.
|
|
65
|
+
- `Next Candidates`: max 3-5 actionable candidates.
|
|
66
|
+
- `Recently Completed`: max 10 compact lines; detailed session history belongs in `docs/WORKLOG.md`.
|
|
67
|
+
|
|
68
|
+
## What to Record
|
|
69
|
+
|
|
70
|
+
Prefer concrete bullets:
|
|
71
|
+
|
|
72
|
+
- files changed or likely involved
|
|
73
|
+
- verification commands and pass/fail/blocked result
|
|
74
|
+
- current blocker
|
|
75
|
+
- next action that can be started immediately
|
|
76
|
+
- uncertainty labels (`unknown`, `unverified`, `suspected`) when needed
|
|
77
|
+
|
|
78
|
+
Avoid:
|
|
79
|
+
|
|
80
|
+
- raw command output
|
|
81
|
+
- every file opened/read
|
|
82
|
+
- speculative TODO spam
|
|
83
|
+
- duplicate history already better suited for WORKLOG
|
|
84
|
+
- global roadmap changes caused by a concrete one-file task
|
|
85
|
+
|
|
86
|
+
## Future Context Note
|
|
87
|
+
|
|
88
|
+
Do not create task-scoped `CONTEXT.md` as part of v1.1.8 unless the project already has that convention. If detailed bug/feature context is needed, note it as a v1.2 candidate or link to an existing `docs/context/<slug>.md` file.
|
|
@@ -223,8 +223,30 @@ export const ROUTE_CATALOG = [
|
|
|
223
223
|
path: '.claude/skills/docs-quality/SKILL.md',
|
|
224
224
|
order: 12,
|
|
225
225
|
signals: [
|
|
226
|
-
{ type: 'prompt', regex: /\b(docs|documentation|readme|changelog|handoff|worklog|memory|code map)\b/i, score: 4 },
|
|
227
|
-
{ type: 'file', regex: /\bdocs\/|readme\.md$|project\.md$|memory\.md$|worklog\.md$|code_map\.md$/i, score: 4 },
|
|
226
|
+
{ type: 'prompt', regex: /\b(docs|documentation|readme|changelog|handoff|worklog|memory|code map|status\.md)\b/i, score: 4 },
|
|
227
|
+
{ type: 'file', regex: /\bdocs\/|readme\.md$|project\.md$|memory\.md$|status\.md$|worklog\.md$|code_map\.md$/i, score: 4 },
|
|
228
|
+
],
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
id: 'next-step',
|
|
232
|
+
path: '.claude/skills/next-step/SKILL.md',
|
|
233
|
+
order: 12.1,
|
|
234
|
+
contextMode: 'standalone',
|
|
235
|
+
signals: [
|
|
236
|
+
{ type: 'prompt', regex: /\b(what(?:'s| is)? next|next steps?|project status|current status|where are we|continue(?: from)?(?: last session)?|roadmap|status\.md)\b/i, score: 7 },
|
|
237
|
+
{ type: 'prompt', regex: /\b(làm gì tiếp|bước tiếp theo|tiếp theo làm gì|làm tiếp|đang ở đâu|trạng thái project|tình trạng project)\b/i, score: 7 },
|
|
238
|
+
],
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
id: 'update-status',
|
|
242
|
+
path: '.claude/skills/update-status/SKILL.md',
|
|
243
|
+
order: 12.2,
|
|
244
|
+
contextMode: 'standalone',
|
|
245
|
+
signals: [
|
|
246
|
+
{ type: 'prompt', regex: /\b(update|refresh|write|sync|record|capture|summari[sz]e).{0,48}\b(status\.md|project status|current state|next candidates?|session state)\b/i, score: 9 },
|
|
247
|
+
{ type: 'prompt', regex: /\b(status\.md|project status).{0,48}\b(update|refresh|write|sync|record|capture|summari[sz]e)\b/i, score: 9 },
|
|
248
|
+
{ type: 'prompt', regex: /\b(wrap up|handoff|end(?:ing)? this session|session summary|before final)\b/i, score: 7 },
|
|
249
|
+
{ type: 'prompt', regex: /\b(cập nhật|ghi lại|tổng kết|chốt session|bàn giao).{0,48}\b(status|trạng thái|việc tiếp theo)\b/i, score: 9 },
|
|
228
250
|
],
|
|
229
251
|
},
|
|
230
252
|
{
|
|
@@ -230,11 +230,17 @@ async function prepareTaskRoute({
|
|
|
230
230
|
const normalizedPrompt = String(promptText || '').trim();
|
|
231
231
|
const normalizedCommand = String(commandText || '').trim();
|
|
232
232
|
const normalizedTarget = normalizeRelativeFile(absoluteRoot, targetFile);
|
|
233
|
+
const intentMode = deriveIntentMode({
|
|
234
|
+
promptText: normalizedPrompt,
|
|
235
|
+
commandText: normalizedCommand,
|
|
236
|
+
targetFile: normalizedTarget,
|
|
237
|
+
});
|
|
233
238
|
const activeSkills = await selectActiveSkills({
|
|
234
239
|
rootDir: absoluteRoot,
|
|
235
240
|
promptText: normalizedPrompt,
|
|
236
241
|
commandText: normalizedCommand,
|
|
237
242
|
targetFile: normalizedTarget,
|
|
243
|
+
intentMode,
|
|
238
244
|
});
|
|
239
245
|
const selectedIds = activeSkills.map((entry) => entry.id);
|
|
240
246
|
const contextIntent = deriveContextIntent({
|
|
@@ -262,6 +268,7 @@ async function prepareTaskRoute({
|
|
|
262
268
|
targetFile: normalizedTarget,
|
|
263
269
|
contextIntent,
|
|
264
270
|
taskType: inferredTaskType,
|
|
271
|
+
intentMode,
|
|
265
272
|
},
|
|
266
273
|
};
|
|
267
274
|
}
|
|
@@ -624,7 +631,7 @@ async function readHelperCacheSnapshot({
|
|
|
624
631
|
};
|
|
625
632
|
}
|
|
626
633
|
|
|
627
|
-
async function selectActiveSkills({ rootDir, promptText, commandText, targetFile }) {
|
|
634
|
+
async function selectActiveSkills({ rootDir, promptText, commandText, targetFile, intentMode = null }) {
|
|
628
635
|
const routeSignals = {
|
|
629
636
|
promptRawText: String(promptText || '').toLowerCase(),
|
|
630
637
|
promptNormalizedText: buildNormalizedRouteSignalText(promptText),
|
|
@@ -635,6 +642,7 @@ async function selectActiveSkills({ rootDir, promptText, commandText, targetFile
|
|
|
635
642
|
const scoredEntries = ROUTE_CATALOG
|
|
636
643
|
.map((entry) => scoreSkillRouteEntry(entry, routeSignals))
|
|
637
644
|
.filter((entry) => entry.score > 0)
|
|
645
|
+
.filter((entry) => shouldKeepRouteEntryForIntent(entry, intentMode))
|
|
638
646
|
.sort((a, b) => b.score - a.score || a.order - b.order);
|
|
639
647
|
const active = [];
|
|
640
648
|
|
|
@@ -650,6 +658,22 @@ async function selectActiveSkills({ rootDir, promptText, commandText, targetFile
|
|
|
650
658
|
return active.map(({ order, ...rest }) => rest);
|
|
651
659
|
}
|
|
652
660
|
|
|
661
|
+
function shouldKeepRouteEntryForIntent(entry, intentMode) {
|
|
662
|
+
if (entry.id === 'next-step' && ['scoped-advice', 'docs-specific'].includes(intentMode)) {
|
|
663
|
+
return false;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
if (entry.id === 'update-status' && intentMode === 'docs-specific') {
|
|
667
|
+
return false;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
if (entry.id === 'docs-quality' && ['open-ended-status', 'status-update'].includes(intentMode)) {
|
|
671
|
+
return false;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
return true;
|
|
675
|
+
}
|
|
676
|
+
|
|
653
677
|
function scoreSkillRouteEntry(entry, routeSignals = {}) {
|
|
654
678
|
let score = 0;
|
|
655
679
|
const reasons = [];
|
|
@@ -718,6 +742,116 @@ function getSignalTexts(signalType, routeSignals = {}) {
|
|
|
718
742
|
};
|
|
719
743
|
}
|
|
720
744
|
|
|
745
|
+
function deriveIntentMode({ promptText = '', commandText = '', targetFile = null } = {}) {
|
|
746
|
+
const lower = buildNormalizedRouteSignalText(promptText, commandText);
|
|
747
|
+
const raw = `${promptText ?? ''}\n${commandText ?? ''}`.toLowerCase();
|
|
748
|
+
const docsSpecific = hasDocsSpecificTaskSignal(lower, raw, targetFile);
|
|
749
|
+
const statusUpdate = hasStatusUpdateSignal(lower, raw);
|
|
750
|
+
const openEndedStatus = hasOpenEndedStatusSignal(lower, raw);
|
|
751
|
+
const concreteTask = hasConcreteTaskSignal(lower, raw, targetFile);
|
|
752
|
+
|
|
753
|
+
if (docsSpecific) {
|
|
754
|
+
return 'docs-specific';
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
if (statusUpdate) {
|
|
758
|
+
return 'status-update';
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
if (concreteTask && openEndedStatus) {
|
|
762
|
+
return 'scoped-advice';
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
if (openEndedStatus) {
|
|
766
|
+
return 'open-ended-status';
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
if (concreteTask) {
|
|
770
|
+
if (/\b(bug|debug|error|crash|broken|failing|stack trace|triage|fix|login|timeout)\b/.test(lower)) {
|
|
771
|
+
return 'debug-specific';
|
|
772
|
+
}
|
|
773
|
+
if (/\b(review|audit|diff|pr feedback|code review|kiem tra|soat)\b/.test(lower)) {
|
|
774
|
+
return 'review-specific';
|
|
775
|
+
}
|
|
776
|
+
if (/\b(implement|build|create|add|ship|deliver|refactor|integrate|integration|scaffold|feature)\b/.test(lower)) {
|
|
777
|
+
return 'implement-specific';
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
return null;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
function hasStatusUpdateSignal(lower, raw) {
|
|
785
|
+
return /\b(update|refresh|write|sync|record|capture|summarize|summarise).{0,64}\b(status\.md|project status|current state|next candidates|session state)\b/.test(lower)
|
|
786
|
+
|| /\b(status\.md|project status).{0,64}\b(update|refresh|write|sync|record|capture|summarize|summarise)\b/.test(lower)
|
|
787
|
+
|| /\b(wrap up|handoff|end this session|ending this session|session summary|before final)\b/.test(lower)
|
|
788
|
+
|| /\b(cap nhat|ghi lai|tong ket|chot session|ban giao).{0,64}\b(status|trang thai|viec tiep theo)\b/.test(lower)
|
|
789
|
+
|| /\b(cập nhật|ghi lại|tổng kết|chốt session|bàn giao).{0,64}\b(status|trạng thái|việc tiếp theo)\b/.test(raw);
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
function hasOpenEndedStatusSignal(lower, raw) {
|
|
793
|
+
return /\b(what next|what is next|what's next|next step|next steps|project status|current status|where are we|continue|continue from last session|roadmap|status\.md)\b/.test(lower)
|
|
794
|
+
|| /\b(lam gi tiep|buoc tiep theo|tiep theo lam gi|lam tiep|dang o dau|trang thai project|tinh trang project)\b/.test(lower)
|
|
795
|
+
|| /\b(làm gì tiếp|bước tiếp theo|tiếp theo làm gì|làm tiếp|đang ở đâu|trạng thái project|tình trạng project)\b/.test(raw);
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
function hasConcreteTaskSignal(lower, raw, targetFile) {
|
|
799
|
+
if (targetFile && !isStatusFileTarget(targetFile)) {
|
|
800
|
+
return true;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
return /\b(bug|debug|error|crash|broken|failing|stack trace|triage|fix|implement|build|create|add|ship|deliver|refactor|integrate|integration|scaffold|feature|review|audit|diff|pr feedback|code review|auth|login|api|endpoint|test|spec)\b/.test(lower)
|
|
804
|
+
|| /\b(sửa|fix|lỗi|bug|debug|implement|cài|thêm|review|kiểm tra|soát|đăng nhập)\b/.test(raw);
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
function hasDocsSpecificTaskSignal(lower, raw, targetFile) {
|
|
808
|
+
if (!targetFile || !isDocsTarget(targetFile)) {
|
|
809
|
+
return false;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
const targetName = path.posix.basename(String(targetFile || '').replaceAll('\\', '/')).toLowerCase();
|
|
813
|
+
const explicitStatusUpdate = hasExplicitStatusUpdateSignal(lower, raw);
|
|
814
|
+
|
|
815
|
+
if (!isStatusFileTarget(targetFile)) {
|
|
816
|
+
if (explicitStatusUpdate && !mentionsTargetDoc(lower, targetName)) {
|
|
817
|
+
return false;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
return mentionsTargetDoc(lower, targetName)
|
|
821
|
+
|| /\b(edit|write|improve|document|docs?|readme|changelog|worklog|memory|code map|template|wording|copy|grammar|format|structure|heading|section|handoff notes?)\b/.test(lower)
|
|
822
|
+
|| /\b(câu chữ|chỉnh|sửa chữ|ngữ pháp|định dạng|cấu trúc|tài liệu|ghi chú bàn giao)\b/.test(raw);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
return /\b(template|wording|edit|copy|grammar|format|structure|heading|section|docs?)\b/.test(lower)
|
|
826
|
+
|| /\b(mẫu|câu chữ|chỉnh|sửa chữ|ngữ pháp|định dạng|cấu trúc|tài liệu)\b/.test(raw);
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
function hasExplicitStatusUpdateSignal(lower, raw) {
|
|
830
|
+
return /\b(update|refresh|write|sync|record|capture|summarize|summarise).{0,64}\b(status\.md|project status|current state|next candidates|session state)\b/.test(lower)
|
|
831
|
+
|| /\b(status\.md|project status).{0,64}\b(update|refresh|write|sync|record|capture|summarize|summarise)\b/.test(lower)
|
|
832
|
+
|| /\b(cap nhat|ghi lai|tong ket|chot session|ban giao).{0,64}\b(status|trang thai|viec tiep theo)\b/.test(lower)
|
|
833
|
+
|| /\b(cập nhật|ghi lại|tổng kết|chốt session|bàn giao).{0,64}\b(status|trạng thái|việc tiếp theo)\b/.test(raw);
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
function mentionsTargetDoc(lower, targetName) {
|
|
837
|
+
if (!targetName) {
|
|
838
|
+
return false;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
const escaped = targetName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
842
|
+
const withoutExt = escaped.replace(/\\\.md$/i, '');
|
|
843
|
+
return new RegExp(`\\b(?:${escaped}|${withoutExt})\\b`, 'i').test(lower);
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
function isStatusFileTarget(targetFile) {
|
|
847
|
+
return /(?:^|\/)docs\/STATUS\.md$|(?:^|\/)STATUS\.md$/i.test(String(targetFile || ''));
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
function isDocsTarget(targetFile) {
|
|
851
|
+
const normalized = String(targetFile || '').replaceAll('\\', '/');
|
|
852
|
+
return /(?:^|\/)docs\/.+\.md$|(?:^|\/)(?:README|CHANGELOG|AGENTS|CLAUDE|STATUS)\.md$/i.test(normalized);
|
|
853
|
+
}
|
|
854
|
+
|
|
721
855
|
function shouldUseIndexedContext({ activeSkills = [], targetFile = null } = {}) {
|
|
722
856
|
if (activeSkills.length === 0) {
|
|
723
857
|
return Boolean(targetFile);
|
|
@@ -1063,6 +1197,7 @@ function buildRouteSummary({
|
|
|
1063
1197
|
fallbackCommands,
|
|
1064
1198
|
preferredOrder,
|
|
1065
1199
|
policyMode,
|
|
1200
|
+
intentMode: routingContext.intentMode ?? null,
|
|
1066
1201
|
delegateHint: delegationRecommendation?.hint ?? null,
|
|
1067
1202
|
nextActionType: nextAction?.type ?? null,
|
|
1068
1203
|
nextActionCommand,
|
|
@@ -1580,6 +1715,7 @@ function compactRoutingContext(routingContext = {}) {
|
|
|
1580
1715
|
adapter: routingContext.adapter ?? 'claude',
|
|
1581
1716
|
lastExplicitUserPromptText: routingContext.lastExplicitUserPromptText ?? '',
|
|
1582
1717
|
taskType: routingContext.taskType ?? null,
|
|
1718
|
+
intentMode: routingContext.intentMode ?? null,
|
|
1583
1719
|
};
|
|
1584
1720
|
}
|
|
1585
1721
|
|
|
@@ -12,7 +12,7 @@ Auto-generated by UKit for OpenAI Codex.
|
|
|
12
12
|
- Do not make end users memorize skill names, helper scripts, or routing internals unless they are debugging UKit itself.
|
|
13
13
|
- **Treat helper commands as internal orchestration. Do not ask end users to run them.**
|
|
14
14
|
|
|
15
|
-
## UKit v1.1.
|
|
15
|
+
## UKit v1.1.8 Shared Runtime
|
|
16
16
|
|
|
17
17
|
- Shared runtime state lives in `.ukit/storage/`.
|
|
18
18
|
- Treat `.ukit/storage/config.json` as the source of compact, token-pipeline, router, memory, and validation toggles.
|
|
@@ -29,6 +29,7 @@ Auto-generated by UKit for OpenAI Codex.
|
|
|
29
29
|
- **Trivial**: no docs.
|
|
30
30
|
- **Simple**: `docs/MEMORY.md` only.
|
|
31
31
|
- **Non-trivial**: `docs/MEMORY.md` + `docs/PROJECT.md` + `docs/CODE_MAP.md`.
|
|
32
|
+
- `docs/STATUS.md`: read for open-ended status/continue prompts or meaningful continuation context; stale status is orientation only.
|
|
32
33
|
- Read `docs/WORKLOG.md` only when recent continuation/debug context matters.
|
|
33
34
|
- Source is truth; if docs are stale, update docs and continue.
|
|
34
35
|
|
|
@@ -52,6 +53,9 @@ For clearly non-code specialist lanes, avoid dragging the source-code index into
|
|
|
52
53
|
- Match from prompt wording plus tool/file evidence.
|
|
53
54
|
- Use the smallest useful set, usually 1-2 skills.
|
|
54
55
|
- If docs work is detected, prefer `.codex/skills/docs-quality/SKILL.md`.
|
|
56
|
+
- For open-ended “what next?” / “continue” / project-status prompts, prefer `.codex/skills/next-step/SKILL.md` and show a status freshness cue.
|
|
57
|
+
- For explicit handoff/wrap-up/status updates, prefer `.codex/skills/update-status/SKILL.md`.
|
|
58
|
+
- Concrete debug/implementation/review prompts beat open-ended wording; do not let `next-step` replace the concrete workflow.
|
|
55
59
|
- If routing is complex or ambiguous, prefer `node .codex/ukit/index/route-task.mjs "<prompt>" [--tool-command <cmd>] [--target <file>]`.
|
|
56
60
|
- That helper should keep shared route memory in `.claude/ukit/skill-router-state.json` so Claude and Codex continue from the same compact route state.
|
|
57
61
|
- When route memory already includes `previous-context` or `recent-output`, reuse it before widening reads or logs.
|
|
@@ -68,6 +72,7 @@ For clearly non-code specialist lanes, avoid dragging the source-code index into
|
|
|
68
72
|
## Docs Discipline
|
|
69
73
|
|
|
70
74
|
After significant work, update only what changed:
|
|
75
|
+
- `docs/STATUS.md` — compact current state, blockers, verification, next candidates
|
|
71
76
|
- `docs/WORKLOG.md`
|
|
72
77
|
- `docs/MEMORY.md`
|
|
73
78
|
- `docs/CODE_MAP.md`
|
|
@@ -65,6 +65,12 @@
|
|
|
65
65
|
],
|
|
66
66
|
"maintenance": [
|
|
67
67
|
"repo-maintenance"
|
|
68
|
+
],
|
|
69
|
+
"nextStep": [
|
|
70
|
+
"next-step"
|
|
71
|
+
],
|
|
72
|
+
"statusUpdate": [
|
|
73
|
+
"update-status"
|
|
68
74
|
]
|
|
69
75
|
},
|
|
70
76
|
"toolSignals": {
|
|
@@ -89,7 +95,8 @@
|
|
|
89
95
|
},
|
|
90
96
|
"routingRule": {
|
|
91
97
|
"endUserShouldNotNeedSkillNames": true,
|
|
92
|
-
"selectSmallestUsefulSkillSet": true
|
|
98
|
+
"selectSmallestUsefulSkillSet": true,
|
|
99
|
+
"concreteTaskBeatsOpenEndedStatus": true
|
|
93
100
|
},
|
|
94
101
|
"delegationBridge": {
|
|
95
102
|
"enabled": true,
|
package/templates/AGENTS.md
CHANGED
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
- bug / error / crash / triage / failing path → `.claude/skills/debugging-toolkit/SKILL.md`
|
|
32
32
|
- test / spec / coverage / fixture → `.claude/skills/testing-quality/SKILL.md`
|
|
33
33
|
- docs / README / changelog / handoff / editing `docs/` → `.claude/skills/docs-quality/SKILL.md`
|
|
34
|
+
- open-ended next step / project status / continue with no concrete target → `.claude/skills/next-step/SKILL.md`
|
|
35
|
+
- explicit handoff / wrap up / update `docs/STATUS.md` → `.claude/skills/update-status/SKILL.md`
|
|
34
36
|
- auth / security / token / permission / validation / risky shell-path-delete-db work → `.claude/skills/discover-security/SKILL.md`
|
|
35
37
|
- stale workspace / reinstall / cleanup / maintenance → `.claude/skills/repo-maintenance/SKILL.md`
|
|
36
38
|
|
|
@@ -41,7 +43,7 @@
|
|
|
41
43
|
- If a concrete verification lane is needed, prefer `node .claude/ukit/index/verify-context.mjs ...`.
|
|
42
44
|
- These helper/index commands are internal orchestration. Run them yourself when needed; never turn them into required end-user workflow.
|
|
43
45
|
|
|
44
|
-
## UKit v1.1.
|
|
46
|
+
## UKit v1.1.8 Shared Runtime
|
|
45
47
|
|
|
46
48
|
- Shared runtime state lives in `.ukit/storage/`.
|
|
47
49
|
- Treat `.ukit/storage/config.json` as the source of runtime toggles for compact, token pipeline, router, memory, and validation behavior.
|
|
@@ -59,9 +61,18 @@
|
|
|
59
61
|
- **Trivial**: no docs, no index query unless the file target is unclear.
|
|
60
62
|
- **Simple**: default to `docs/MEMORY.md` only; pull related files/tests with the resolver.
|
|
61
63
|
- **Non-trivial**: read `docs/MEMORY.md` + `docs/PROJECT.md` + `docs/CODE_MAP.md`.
|
|
64
|
+
- `docs/STATUS.md`: read for open-ended status/continue prompts or meaningful continuation context; treat stale status as orientation only and verify against source/index.
|
|
62
65
|
- `docs/WORKLOG.md`: only recent, relevant entries for continuation/debugging.
|
|
63
66
|
- Follow routed verification policy: targeted first when localized, widen in order for shared/risky scope, ask before blanket broad runs when no related-test evidence exists.
|
|
64
67
|
|
|
68
|
+
## Living Status Workflow
|
|
69
|
+
|
|
70
|
+
- `docs/STATUS.md` is compact current state, not a transcript and not source truth.
|
|
71
|
+
- When the user asks “what next?”, “continue”, or “project đang ở đâu?” without a concrete target, use the `next-step` skill and show a freshness cue (fresh / possibly stale / stale / missing).
|
|
72
|
+
- Concrete debug/implementation/review prompts beat open-ended wording; use the concrete skill first and only use status as background.
|
|
73
|
+
- After meaningful work, use `update-status` to record state, verification, blockers, and next candidates; skip trivial/no-state-change tasks.
|
|
74
|
+
- Detailed task context files such as `docs/context/<slug>.md` are a future extension, not required baseline workflow.
|
|
75
|
+
|
|
65
76
|
## Subagent Policy (internal only)
|
|
66
77
|
|
|
67
78
|
- Default to direct execution for trivial/simple work.
|
package/templates/CLAUDE.md
CHANGED
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
- bug / error / crash / triage → `.claude/skills/debugging-toolkit/SKILL.md`
|
|
30
30
|
- test / spec / coverage → `.claude/skills/testing-quality/SKILL.md`
|
|
31
31
|
- docs / README / changelog / handoff / editing `docs/` → `.claude/skills/docs-quality/SKILL.md`
|
|
32
|
+
- open-ended next step / project status / continue with no concrete target → `.claude/skills/next-step/SKILL.md`
|
|
33
|
+
- explicit handoff / wrap up / update `docs/STATUS.md` → `.claude/skills/update-status/SKILL.md`
|
|
32
34
|
- auth / security / token / permission / validation → `.claude/skills/discover-security/SKILL.md`
|
|
33
35
|
- stale workspace / reinstall / cleanup → `.claude/skills/repo-maintenance/SKILL.md`
|
|
34
36
|
|
|
@@ -40,7 +42,7 @@
|
|
|
40
42
|
- **Do not ask normal contributors to run internal helper commands**; run them yourself or tell them to rerun `ukit install`.
|
|
41
43
|
- Do not ask normal contributors to memorize `ukit doctor`, `ukit diff`, `ukit uninstall`, or `ukit index ...` unless they explicitly need maintainer/debug help.
|
|
42
44
|
|
|
43
|
-
## UKit v1.1.
|
|
45
|
+
## UKit v1.1.8 Shared Runtime
|
|
44
46
|
|
|
45
47
|
- Shared runtime state lives in `.ukit/storage/`.
|
|
46
48
|
- Treat `.ukit/storage/config.json` as the source of runtime toggles for compact, token pipeline, router, memory, and validation behavior.
|
|
@@ -56,9 +58,18 @@
|
|
|
56
58
|
- **Trivial**: no docs.
|
|
57
59
|
- **Simple**: `docs/MEMORY.md` only, plus resolver-selected files/tests.
|
|
58
60
|
- **Non-trivial**: `docs/MEMORY.md` + `docs/PROJECT.md` + `docs/CODE_MAP.md`.
|
|
61
|
+
- `docs/STATUS.md`: use for open-ended status/continue prompts or meaningful continuation context; stale status is orientation only.
|
|
59
62
|
- `docs/WORKLOG.md`: only recent relevant entries.
|
|
60
63
|
- Follow routed verification policy: targeted first, widen only when risk/shared scope justifies it, ask before blanket broad runs.
|
|
61
64
|
|
|
65
|
+
## Living Status Workflow
|
|
66
|
+
|
|
67
|
+
- `docs/STATUS.md` captures compact current state, active work, debug threads, blockers, verification, and next candidates.
|
|
68
|
+
- It is not source truth and must not replace source/index-first investigation.
|
|
69
|
+
- For “what next?” / “continue” prompts without a concrete target, use `next-step` and show a freshness cue before relying on the status file.
|
|
70
|
+
- For concrete debug/implementation/review prompts, keep the concrete workflow primary even if the user asks for an approach or next step.
|
|
71
|
+
- After meaningful work, use `update-status`; skip trivial/no-state-change tasks and avoid transcript-style noise.
|
|
72
|
+
|
|
62
73
|
## Selective Subagent Policy (internal only)
|
|
63
74
|
|
|
64
75
|
- Keep direct execution as the default for trivial/simple work.
|
|
@@ -47,6 +47,7 @@ End users do not need to manage any of that manually.
|
|
|
47
47
|
Complete these files before first serious use:
|
|
48
48
|
- `docs/PROJECT.md`
|
|
49
49
|
- `docs/MEMORY.md`
|
|
50
|
+
- `docs/STATUS.md`
|
|
50
51
|
- `docs/WORKLOG.md`
|
|
51
52
|
|
|
52
53
|
### 4) Open your AI tool
|
|
@@ -96,6 +97,7 @@ ukit install
|
|
|
96
97
|
Check that the docs baseline files exist and are filled in:
|
|
97
98
|
- `docs/PROJECT.md`
|
|
98
99
|
- `docs/MEMORY.md`
|
|
100
|
+
- `docs/STATUS.md`
|
|
99
101
|
- `docs/WORKLOG.md`
|
|
100
102
|
|
|
101
103
|
---
|
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
|
|
45
45
|
1. Run `ukit memory recall "<current task>"` for non-trivial work; reuse relevant `## Previous Context` before asking the user to restate prior decisions
|
|
46
46
|
2. Read `docs/MEMORY.md` — architecture decisions, active constraints, known bugs
|
|
47
|
-
3. Read `docs/
|
|
48
|
-
4.
|
|
49
|
-
5.
|
|
50
|
-
6.
|
|
47
|
+
3. Read `docs/STATUS.md` for open-ended status/continue prompts or meaningful continuation context; treat stale status as orientation only
|
|
48
|
+
4. Read `docs/CODE_MAP.md` if it exists — structural navigation index
|
|
49
|
+
5. Use the installed source-code index / routed helpers to localize the smallest relevant file + test set first
|
|
50
|
+
6. Scan recent `docs/WORKLOG.md` entries if continuing prior work
|
|
51
|
+
7. Verify understanding against source before acting — **docs orient, source is truth; keep the index-first workflow intact**
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Project Status — {{project.name}}
|
|
2
|
+
|
|
3
|
+
> Living project state for AI sessions.
|
|
4
|
+
> Keep this compact: current state only, not a session transcript.
|
|
5
|
+
> Source code, tests, and the UKit index remain ground truth.
|
|
6
|
+
|
|
7
|
+
## Freshness
|
|
8
|
+
|
|
9
|
+
- Last meaningful update: TODO YYYY-MM-DD HH:mm
|
|
10
|
+
- Updated by: TODO
|
|
11
|
+
- Status confidence: low
|
|
12
|
+
- Stale after: 72h
|
|
13
|
+
|
|
14
|
+
If this file is stale, AI must treat it as orientation only and verify against source/index before recommending or editing.
|
|
15
|
+
|
|
16
|
+
## Snapshot
|
|
17
|
+
|
|
18
|
+
- Current focus: TODO
|
|
19
|
+
- Health: unknown
|
|
20
|
+
- Branch/state: TODO
|
|
21
|
+
- Release/version: TODO
|
|
22
|
+
|
|
23
|
+
## Active Work
|
|
24
|
+
|
|
25
|
+
<!-- Keep only live work. Move finished work to Recently Completed or WORKLOG.md. -->
|
|
26
|
+
|
|
27
|
+
### TODO work item
|
|
28
|
+
|
|
29
|
+
- Status: planned / in-progress / blocked / done
|
|
30
|
+
- Goal: TODO
|
|
31
|
+
- Done: TODO
|
|
32
|
+
- Remaining: TODO
|
|
33
|
+
- Files involved: TODO
|
|
34
|
+
- Verification: TODO
|
|
35
|
+
- Next action: TODO
|
|
36
|
+
|
|
37
|
+
## Current Debug Threads
|
|
38
|
+
|
|
39
|
+
<!-- Detailed bug context belongs in docs/context/<task>.md when that exists. STATUS should only link/summarize. -->
|
|
40
|
+
|
|
41
|
+
### TODO debug thread
|
|
42
|
+
|
|
43
|
+
- Status: investigating / root cause found / fixed / blocked
|
|
44
|
+
- Symptom: TODO
|
|
45
|
+
- Root cause: unknown
|
|
46
|
+
- Evidence: TODO
|
|
47
|
+
- Changed files: TODO
|
|
48
|
+
- Verification: TODO
|
|
49
|
+
- Remaining risk: TODO
|
|
50
|
+
- Next action: TODO
|
|
51
|
+
|
|
52
|
+
## Decisions Pending
|
|
53
|
+
|
|
54
|
+
- [ ] TODO decision
|
|
55
|
+
- Context: TODO
|
|
56
|
+
- Options: TODO
|
|
57
|
+
- Recommended: TODO
|
|
58
|
+
|
|
59
|
+
## Next Candidates
|
|
60
|
+
|
|
61
|
+
1. TODO candidate
|
|
62
|
+
- Why now: TODO
|
|
63
|
+
- Expected files: TODO
|
|
64
|
+
- Verification: TODO
|
|
65
|
+
- Risk: TODO
|
|
66
|
+
|
|
67
|
+
## Recently Completed
|
|
68
|
+
|
|
69
|
+
<!-- Max 10 compact lines. Use docs/WORKLOG.md for session history. -->
|
|
70
|
+
|
|
71
|
+
- TODO YYYY-MM-DD — summary — verification
|
|
72
|
+
|
|
73
|
+
## Notes for Next AI Session
|
|
74
|
+
|
|
75
|
+
- Read first: docs/STATUS.md, then docs/CODE_MAP.md only if navigation is needed.
|
|
76
|
+
- Avoid: treating this file as source truth when it is stale or contradicted by code/tests.
|
|
77
|
+
- Known traps: keep concrete debug/implementation prompts on their specific workflow; do not turn them into global roadmap suggestions.
|
|
78
|
+
|
|
79
|
+
## Future Candidate: Task Context Files
|
|
80
|
+
|
|
81
|
+
v1.2 candidate: task-scoped `docs/context/<slug>.md` files for granular bug/feature context. Keep this out of v1.1.8 scope unless a project already uses that folder.
|
|
@@ -14,6 +14,7 @@ UKit should handle:
|
|
|
14
14
|
- hidden skill selection
|
|
15
15
|
- source-code indexing
|
|
16
16
|
- compact context selection
|
|
17
|
+
- living project status for open-ended continuation prompts
|
|
17
18
|
- targeted verification
|
|
18
19
|
- optional internal delegation when it is actually useful
|
|
19
20
|
|
|
@@ -127,6 +128,21 @@ Expected UKit behavior:
|
|
|
127
128
|
2. use DuraOne references only when the repo actually matches that domain/shape
|
|
128
129
|
3. keep the user away from manual skill selection
|
|
129
130
|
|
|
131
|
+
### F) Continue / what next
|
|
132
|
+
|
|
133
|
+
User says:
|
|
134
|
+
|
|
135
|
+
```text
|
|
136
|
+
Project đang ở đâu, làm gì tiếp?
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Expected UKit behavior:
|
|
140
|
+
1. auto-load the hidden next-step lane
|
|
141
|
+
2. read `docs/STATUS.md` first and show whether it is fresh, possibly stale, stale, or missing
|
|
142
|
+
3. suggest only a few actionable next candidates
|
|
143
|
+
4. if status is stale, verify with source/index before treating any candidate as authoritative
|
|
144
|
+
5. if the prompt names a concrete bug/feature/review target, keep the concrete workflow primary instead of producing a global roadmap
|
|
145
|
+
|
|
130
146
|
---
|
|
131
147
|
|
|
132
148
|
## What users should NOT need to do
|
package/templates/ukit/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# UKit Shared Runtime
|
|
2
2
|
|
|
3
|
-
This folder stores shared UKit runtime state for v1.1.
|
|
3
|
+
This folder stores shared UKit runtime state for v1.1.8 features.
|
|
4
4
|
|
|
5
5
|
- `storage/config.json` — runtime feature flags and defaults
|
|
6
6
|
- `storage/cache/` — prompt-cache, compact history, compact pressure state, output summaries, and preserved raw tool outputs under `storage/cache/tee/`
|