skillwiki 0.10.35 → 0.10.37
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/dist/{chunk-MIQOBEOW.js → chunk-BS556WUE.js} +2 -2
- package/dist/{chunk-K4OGG5KJ.js → chunk-E3JBAURS.js} +1 -1
- package/dist/{chunk-XYGGDGHR.js → chunk-IFMHQETQ.js} +1 -1
- package/dist/{chunk-GXT5WTSE.js → chunk-JUUZJJIF.js} +2 -2
- package/dist/{chunk-BY7V7QPU.js → chunk-LACQJ6RD.js} +2 -2
- package/dist/{chunk-SNCFIJ5E.js → chunk-QVO332CT.js} +2 -2
- package/dist/{chunk-2X2TCLHR.js → chunk-WJVG3DD5.js} +6 -6
- package/dist/{chunk-JJ654NVJ.js → chunk-XRBUABGE.js} +3 -3
- package/dist/cli.js +143 -54
- package/dist/{index-projection-WUAKRTAE.js → index-projection-ZXFN5DT4.js} +3 -3
- package/dist/{managed-write-preflight-4YCJVF64.js → managed-write-preflight-ANQPMOF4.js} +5 -5
- package/dist/skillwiki-mcp.js +6 -6
- package/dist/sources-LIJAUXFU.js +9 -0
- package/package.json +1 -1
- package/skills/.claude-plugin/plugin.json +1 -1
- package/skills/.codex-plugin/plugin.json +1 -1
- package/skills/hooks/session-context +226 -27
- package/skills/package.json +1 -1
- package/skills/skills/using-skillwiki/SKILL.md +44 -18
- package/skills/skills/using-skillwiki/activation.md +13 -0
- package/skills/using-skillwiki/SKILL.md +44 -18
- package/skills/using-skillwiki/activation.md +13 -0
- package/templates/SCHEMA.md +7 -0
- package/dist/sources-FCZCPOYB.js +0 -9
|
@@ -484,7 +484,7 @@ var MATCHERS = [
|
|
|
484
484
|
},
|
|
485
485
|
{
|
|
486
486
|
kind: "password",
|
|
487
|
-
re: /\b(?:
|
|
487
|
+
re: /\b(?:password|passwd)["']?\s*[:=]\s*["']?([^\s`"']{8,})["']?/gi,
|
|
488
488
|
valueGroup: 1
|
|
489
489
|
},
|
|
490
490
|
{
|
|
@@ -512,7 +512,7 @@ function isSyntheticPlaceholder(value) {
|
|
|
512
512
|
}
|
|
513
513
|
function isNonSecretTokenCapture(value) {
|
|
514
514
|
if (value.startsWith("//")) return true;
|
|
515
|
-
if (/^[a-
|
|
515
|
+
if (/^[a-z0-9.]+(?:-[a-z0-9.]+)+$/.test(value) && !/^[0-9a-f]+(?:-[0-9a-f]+)+$/.test(value)) return true;
|
|
516
516
|
return false;
|
|
517
517
|
}
|
|
518
518
|
function collectMatches(text) {
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
readLogEvents,
|
|
9
9
|
resolveExistingRegularFileInsideVault,
|
|
10
10
|
writeLogEvent
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-E3JBAURS.js";
|
|
12
12
|
import {
|
|
13
13
|
ExitCode,
|
|
14
14
|
RawSourceSchema,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
scanSensitiveContent,
|
|
20
20
|
scanVault,
|
|
21
21
|
splitFrontmatter
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-BS556WUE.js";
|
|
23
23
|
|
|
24
24
|
// src/utils/source-lifecycle.ts
|
|
25
25
|
import { basename } from "path";
|
|
@@ -22,12 +22,12 @@ import {
|
|
|
22
22
|
runSyncLintDelta,
|
|
23
23
|
runVaultSyncPullHelper,
|
|
24
24
|
supersedeStaleReviewRequiredJournals
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-XRBUABGE.js";
|
|
26
26
|
import {
|
|
27
27
|
ExitCode,
|
|
28
28
|
err,
|
|
29
29
|
ok
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-BS556WUE.js";
|
|
31
31
|
|
|
32
32
|
// src/utils/managed-write-preflight.ts
|
|
33
33
|
import { existsSync as existsSync3 } from "fs";
|
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
ROOT_INDEX_SECTION_ORDER,
|
|
4
4
|
atomicWriteText,
|
|
5
5
|
buildRootIndexUniverse
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-IFMHQETQ.js";
|
|
7
7
|
import {
|
|
8
8
|
err,
|
|
9
9
|
ok
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-BS556WUE.js";
|
|
11
11
|
|
|
12
12
|
// src/utils/index-projection.ts
|
|
13
13
|
import { readFile } from "fs/promises";
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
renderRootIndex,
|
|
8
8
|
writeRootIndexProjection
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-QVO332CT.js";
|
|
10
10
|
import {
|
|
11
11
|
CONFIG_KEYS,
|
|
12
12
|
acquireOwnedSyncLock,
|
|
@@ -34,15 +34,15 @@ import {
|
|
|
34
34
|
snapshotterAliasForLocalHost,
|
|
35
35
|
toUndirectedWeighted,
|
|
36
36
|
writeDotenv
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-XRBUABGE.js";
|
|
38
38
|
import {
|
|
39
39
|
atomicWriteText,
|
|
40
40
|
prepareTypedPage
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-IFMHQETQ.js";
|
|
42
42
|
import {
|
|
43
43
|
eventPathFor,
|
|
44
44
|
writeLogEvent
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-E3JBAURS.js";
|
|
46
46
|
import {
|
|
47
47
|
CompoundSchema,
|
|
48
48
|
ExitCode,
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
scanVault,
|
|
64
64
|
splitFrontmatter,
|
|
65
65
|
systemdPropertyFor
|
|
66
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-BS556WUE.js";
|
|
67
67
|
|
|
68
68
|
// src/commands/log-append.ts
|
|
69
69
|
import { readFile, stat } from "fs/promises";
|
|
@@ -4849,7 +4849,7 @@ async function runQuery(input) {
|
|
|
4849
4849
|
}).filter((r) => r.score > 0).sort((a, b) => b.score - a.score || a.path.localeCompare(b.path)).slice(0, limit);
|
|
4850
4850
|
let pendingSources;
|
|
4851
4851
|
if (input.includePending) {
|
|
4852
|
-
const { runSourcesPending } = await import("./sources-
|
|
4852
|
+
const { runSourcesPending } = await import("./sources-LIJAUXFU.js");
|
|
4853
4853
|
const pending = await runSourcesPending({
|
|
4854
4854
|
vault: input.vault,
|
|
4855
4855
|
match: input.text,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
atomicWriteText,
|
|
4
4
|
buildRootIndexUniverse
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-IFMHQETQ.js";
|
|
6
6
|
import {
|
|
7
7
|
authorizeRawOperation,
|
|
8
8
|
buildSourceReferenceIndex,
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
resolveExistingRegularFileInsideVault,
|
|
23
23
|
stripFencedBlocks,
|
|
24
24
|
writeLogEvent
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-E3JBAURS.js";
|
|
26
26
|
import {
|
|
27
27
|
ExitCode,
|
|
28
28
|
FleetManifestSchema,
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
scanVault,
|
|
41
41
|
splitFrontmatter,
|
|
42
42
|
vaultIoConcurrency
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-BS556WUE.js";
|
|
44
44
|
|
|
45
45
|
// src/utils/sync-lock.ts
|
|
46
46
|
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "fs";
|
package/dist/cli.js
CHANGED
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
scanConflictMarkerBlocksInText,
|
|
39
39
|
snapshotterHealthChecks,
|
|
40
40
|
upsertIndexEntry
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-WJVG3DD5.js";
|
|
42
42
|
import {
|
|
43
43
|
normalizeDistTag,
|
|
44
44
|
readCache,
|
|
@@ -51,7 +51,7 @@ import {
|
|
|
51
51
|
UNMANAGED_START,
|
|
52
52
|
renderRootIndex,
|
|
53
53
|
writeRootIndexProjection
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-QVO332CT.js";
|
|
55
55
|
import {
|
|
56
56
|
VAULT_COMMIT_PATHSPEC,
|
|
57
57
|
runManagedWritePreflight,
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
runSyncStatus,
|
|
64
64
|
runSyncUnlock,
|
|
65
65
|
stageVaultContentChanges
|
|
66
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-LACQJ6RD.js";
|
|
67
67
|
import {
|
|
68
68
|
FLEET_REL_PATH,
|
|
69
69
|
acquireOwnedSyncLock,
|
|
@@ -126,12 +126,12 @@ import {
|
|
|
126
126
|
supersedeStaleReviewRequiredJournals,
|
|
127
127
|
taxonomyCommentForPage,
|
|
128
128
|
writeDotenv
|
|
129
|
-
} from "./chunk-
|
|
129
|
+
} from "./chunk-XRBUABGE.js";
|
|
130
130
|
import {
|
|
131
131
|
assertTargetInsideVault,
|
|
132
132
|
atomicWriteText,
|
|
133
133
|
prepareTypedPage
|
|
134
|
-
} from "./chunk-
|
|
134
|
+
} from "./chunk-IFMHQETQ.js";
|
|
135
135
|
import {
|
|
136
136
|
applySourceDisposition,
|
|
137
137
|
decodeSourceActionApproval,
|
|
@@ -139,7 +139,7 @@ import {
|
|
|
139
139
|
inventorySources,
|
|
140
140
|
planSourceDisposition,
|
|
141
141
|
runSourcesPending
|
|
142
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-JUUZJJIF.js";
|
|
143
143
|
import {
|
|
144
144
|
authorizeRawOperation,
|
|
145
145
|
buildSourceReferenceIndex,
|
|
@@ -155,7 +155,7 @@ import {
|
|
|
155
155
|
resolveExistingRegularFileInsideVault,
|
|
156
156
|
validateLogEvent,
|
|
157
157
|
writeLogEvent
|
|
158
|
-
} from "./chunk-
|
|
158
|
+
} from "./chunk-E3JBAURS.js";
|
|
159
159
|
import {
|
|
160
160
|
ExitCode,
|
|
161
161
|
MetaSchema,
|
|
@@ -171,7 +171,7 @@ import {
|
|
|
171
171
|
scanSensitiveContent,
|
|
172
172
|
scanVault,
|
|
173
173
|
splitFrontmatter
|
|
174
|
-
} from "./chunk-
|
|
174
|
+
} from "./chunk-BS556WUE.js";
|
|
175
175
|
|
|
176
176
|
// src/cli.ts
|
|
177
177
|
import { join as join38 } from "path";
|
|
@@ -181,11 +181,19 @@ import { Command } from "commander";
|
|
|
181
181
|
function printJson(r) {
|
|
182
182
|
process.stdout.write(JSON.stringify(r) + "\n");
|
|
183
183
|
}
|
|
184
|
-
function printHuman(r) {
|
|
184
|
+
function printHuman(r, opts = {}) {
|
|
185
185
|
if (r.ok) {
|
|
186
186
|
if (typeof r.data === "object" && r.data !== null && "humanHint" in r.data) {
|
|
187
|
-
|
|
187
|
+
const humanHint = r.data.humanHint;
|
|
188
|
+
if (!opts.detailHints?.length) {
|
|
189
|
+
process.stdout.write(`${humanHint}
|
|
188
190
|
`);
|
|
191
|
+
} else {
|
|
192
|
+
const existingLines = new Set(humanHint.split("\n"));
|
|
193
|
+
const detailLines2 = opts.detailHints.filter((line) => !existingLines.has(line));
|
|
194
|
+
process.stdout.write(`${[humanHint, ...detailLines2].join("\n")}
|
|
195
|
+
`);
|
|
196
|
+
}
|
|
189
197
|
} else {
|
|
190
198
|
process.stdout.write(`OK
|
|
191
199
|
${formatData(r.data)}
|
|
@@ -202,6 +210,45 @@ function formatData(d) {
|
|
|
202
210
|
return JSON.stringify(d, null, 2);
|
|
203
211
|
}
|
|
204
212
|
|
|
213
|
+
// src/utils/lint-detail-hints.ts
|
|
214
|
+
function lintDetailHints(data) {
|
|
215
|
+
const record = asRecord(data);
|
|
216
|
+
if (!record) return [];
|
|
217
|
+
const bySeverity = asRecord(record.by_severity);
|
|
218
|
+
if (bySeverity && Array.isArray(bySeverity.error)) {
|
|
219
|
+
return detailLines(bySeverity.error, false);
|
|
220
|
+
}
|
|
221
|
+
return Array.isArray(record.buckets) ? detailLines(record.buckets, true) : [];
|
|
222
|
+
}
|
|
223
|
+
function healthLintDetailHints(data) {
|
|
224
|
+
const record = asRecord(data);
|
|
225
|
+
const components = asRecord(record?.components);
|
|
226
|
+
const lint = asRecord(components?.lint);
|
|
227
|
+
return Array.isArray(lint?.buckets) ? detailLines(lint.buckets, true) : [];
|
|
228
|
+
}
|
|
229
|
+
function detailLines(buckets, requireErrorSeverity) {
|
|
230
|
+
const seen = /* @__PURE__ */ new Set();
|
|
231
|
+
const lines = [];
|
|
232
|
+
for (const bucket of buckets) {
|
|
233
|
+
const record = asRecord(bucket);
|
|
234
|
+
if (!record || requireErrorSeverity && record.severity !== "error") continue;
|
|
235
|
+
const name = nonEmptyBucketName(record);
|
|
236
|
+
if (!name || seen.has(name)) continue;
|
|
237
|
+
seen.add(name);
|
|
238
|
+
lines.push(`detail: skillwiki lint --only ${name} --examples 3`);
|
|
239
|
+
}
|
|
240
|
+
return lines;
|
|
241
|
+
}
|
|
242
|
+
function nonEmptyBucketName(bucket) {
|
|
243
|
+
if (typeof bucket.kind !== "string" || !/^[a-z0-9_]+$/.test(bucket.kind)) return null;
|
|
244
|
+
if (typeof bucket.count === "number") return bucket.count > 0 ? bucket.kind : null;
|
|
245
|
+
if (Array.isArray(bucket.items)) return bucket.items.length > 0 ? bucket.kind : null;
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
function asRecord(value) {
|
|
249
|
+
return typeof value === "object" && value !== null ? value : null;
|
|
250
|
+
}
|
|
251
|
+
|
|
205
252
|
// src/utils/deprecation.ts
|
|
206
253
|
import { readFileSync } from "fs";
|
|
207
254
|
import { join } from "path";
|
|
@@ -2081,8 +2128,9 @@ import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync9, re
|
|
|
2081
2128
|
import { join as join15 } from "path";
|
|
2082
2129
|
|
|
2083
2130
|
// src/commands/work-validate.ts
|
|
2084
|
-
import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync8 } from "fs";
|
|
2131
|
+
import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync8, statSync as statSync2 } from "fs";
|
|
2085
2132
|
import { join as join14 } from "path";
|
|
2133
|
+
var GOAL_PLAN_MODE_FILES = /* @__PURE__ */ new Set(["spec.md", "plan.md", "build-report.md"]);
|
|
2086
2134
|
function normalizeWorkItemRel(workItem) {
|
|
2087
2135
|
return workItem.replace(/\\/g, "/").replace(/^\.?\//, "");
|
|
2088
2136
|
}
|
|
@@ -2092,6 +2140,22 @@ function scanFileConflicts(relPath, text) {
|
|
|
2092
2140
|
function countUnchecked(text) {
|
|
2093
2141
|
return [...text.matchAll(/^- \[ \]/gm)].length;
|
|
2094
2142
|
}
|
|
2143
|
+
function isGoalPlanMode(value) {
|
|
2144
|
+
return typeof value === "string" && ["goal-plan", "goal"].includes(value.trim().toLowerCase());
|
|
2145
|
+
}
|
|
2146
|
+
function isDirectory(path) {
|
|
2147
|
+
try {
|
|
2148
|
+
return statSync2(path).isDirectory();
|
|
2149
|
+
} catch {
|
|
2150
|
+
return false;
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
function isCompletedStatus(status) {
|
|
2154
|
+
return status === "completed" || status === "complete" || status === "done";
|
|
2155
|
+
}
|
|
2156
|
+
function planClaimsCompletion(status, goalPlanMode) {
|
|
2157
|
+
return goalPlanMode ? isCompletedStatus(status) : status === "completed" || status === "complete";
|
|
2158
|
+
}
|
|
2095
2159
|
function extractPrMetadata(fm) {
|
|
2096
2160
|
const keys = [
|
|
2097
2161
|
"pr_url",
|
|
@@ -2148,21 +2212,31 @@ async function runWorkValidate(input) {
|
|
|
2148
2212
|
}
|
|
2149
2213
|
const findings = [];
|
|
2150
2214
|
const status = {};
|
|
2151
|
-
let evidencePresent = false;
|
|
2152
2215
|
let unchecked = 0;
|
|
2153
2216
|
let conflicts = 0;
|
|
2154
2217
|
let decisionsPresent = false;
|
|
2155
2218
|
let prMetadata = null;
|
|
2156
2219
|
const files = readdirSync(workDir).filter((f) => f.endsWith(".md"));
|
|
2157
|
-
|
|
2158
|
-
findings.push({ code: "missing_spec", path: `${rel}/spec.md`, message: "spec.md is required" });
|
|
2159
|
-
}
|
|
2160
|
-
for (const file of files) {
|
|
2161
|
-
const abs = join14(workDir, file);
|
|
2162
|
-
let text;
|
|
2220
|
+
const markdownFiles = files.map((file) => {
|
|
2163
2221
|
try {
|
|
2164
|
-
text = readFileSync8(
|
|
2222
|
+
const text = readFileSync8(join14(workDir, file), "utf8");
|
|
2223
|
+
return { file, text, frontmatter: extractFrontmatter(text) };
|
|
2165
2224
|
} catch {
|
|
2225
|
+
return { file, text: null, frontmatter: null };
|
|
2226
|
+
}
|
|
2227
|
+
});
|
|
2228
|
+
const goalPlanMode = markdownFiles.some(
|
|
2229
|
+
({ file, frontmatter }) => GOAL_PLAN_MODE_FILES.has(file) && frontmatter?.ok && isGoalPlanMode(frontmatter.data.mode)
|
|
2230
|
+
);
|
|
2231
|
+
let evidencePresent = goalPlanMode && (files.includes("build-report.md") || isDirectory(join14(workDir, "evidence")));
|
|
2232
|
+
if (!files.includes("spec.md") && !goalPlanMode) {
|
|
2233
|
+
findings.push({ code: "missing_spec", path: `${rel}/spec.md`, message: "spec.md is required" });
|
|
2234
|
+
}
|
|
2235
|
+
if (goalPlanMode && !files.includes("plan.md")) {
|
|
2236
|
+
findings.push({ code: "missing_plan", path: `${rel}/plan.md`, message: "goal-plan mode requires plan.md" });
|
|
2237
|
+
}
|
|
2238
|
+
for (const { file, text, frontmatter } of markdownFiles) {
|
|
2239
|
+
if (text === null || frontmatter === null) {
|
|
2166
2240
|
findings.push({ code: "unreadable", path: `${rel}/${file}`, message: "cannot read file" });
|
|
2167
2241
|
continue;
|
|
2168
2242
|
}
|
|
@@ -2176,14 +2250,17 @@ async function runWorkValidate(input) {
|
|
|
2176
2250
|
});
|
|
2177
2251
|
}
|
|
2178
2252
|
unchecked += countUnchecked(text);
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2253
|
+
if (frontmatter.ok) {
|
|
2254
|
+
if (file === "spec.md") {
|
|
2255
|
+
status.spec = typeof frontmatter.data.status === "string" ? frontmatter.data.status : void 0;
|
|
2256
|
+
}
|
|
2257
|
+
if (file === "plan.md") {
|
|
2258
|
+
status.plan = typeof frontmatter.data.status === "string" ? frontmatter.data.status : void 0;
|
|
2259
|
+
}
|
|
2260
|
+
if (file === (goalPlanMode ? "plan.md" : "spec.md")) {
|
|
2261
|
+
prMetadata = extractPrMetadata(frontmatter.data);
|
|
2262
|
+
validatePrMetadata(prMetadata, findings);
|
|
2263
|
+
}
|
|
2187
2264
|
}
|
|
2188
2265
|
if (file === "evidence.md" || file === "retro.md") {
|
|
2189
2266
|
evidencePresent = true;
|
|
@@ -2196,25 +2273,27 @@ async function runWorkValidate(input) {
|
|
|
2196
2273
|
}
|
|
2197
2274
|
}
|
|
2198
2275
|
if (input.requireComplete) {
|
|
2199
|
-
|
|
2276
|
+
const specSource = goalPlanMode ? "plan" : "spec";
|
|
2277
|
+
const specSourceStatus = goalPlanMode ? status.plan : status.spec;
|
|
2278
|
+
if (specSourceStatus && !isCompletedStatus(specSourceStatus)) {
|
|
2200
2279
|
findings.push({
|
|
2201
2280
|
code: "spec_not_completed",
|
|
2202
|
-
path: `${rel}
|
|
2203
|
-
message:
|
|
2281
|
+
path: `${rel}/${specSource}.md`,
|
|
2282
|
+
message: `${specSource} status is ${specSourceStatus}, expected completed`
|
|
2204
2283
|
});
|
|
2205
2284
|
}
|
|
2206
|
-
if (!
|
|
2285
|
+
if (!specSourceStatus) {
|
|
2207
2286
|
findings.push({
|
|
2208
2287
|
code: "spec_status_missing",
|
|
2209
|
-
path: `${rel}
|
|
2210
|
-
message:
|
|
2288
|
+
path: `${rel}/${specSource}.md`,
|
|
2289
|
+
message: `${specSource} frontmatter status missing for completion`
|
|
2211
2290
|
});
|
|
2212
2291
|
}
|
|
2213
2292
|
if (!evidencePresent) {
|
|
2214
2293
|
findings.push({
|
|
2215
2294
|
code: "missing_evidence",
|
|
2216
2295
|
path: rel,
|
|
2217
|
-
message: "completion requires evidence.md or retro.md"
|
|
2296
|
+
message: goalPlanMode ? "completion requires build-report.md, evidence/, evidence.md, or retro.md" : "completion requires evidence.md or retro.md"
|
|
2218
2297
|
});
|
|
2219
2298
|
}
|
|
2220
2299
|
if (unchecked > 0) {
|
|
@@ -2225,12 +2304,12 @@ async function runWorkValidate(input) {
|
|
|
2225
2304
|
});
|
|
2226
2305
|
}
|
|
2227
2306
|
}
|
|
2228
|
-
if (status.plan
|
|
2229
|
-
if (!evidencePresent) {
|
|
2307
|
+
if (planClaimsCompletion(status.plan, goalPlanMode)) {
|
|
2308
|
+
if (!evidencePresent && !(goalPlanMode && input.requireComplete)) {
|
|
2230
2309
|
findings.push({
|
|
2231
2310
|
code: "missing_evidence",
|
|
2232
2311
|
path: rel,
|
|
2233
|
-
message: "plan is completed but evidence/retro is missing"
|
|
2312
|
+
message: goalPlanMode ? "plan is completed but build-report.md, evidence/, evidence.md, or retro.md is missing" : "plan is completed but evidence/retro is missing"
|
|
2234
2313
|
});
|
|
2235
2314
|
}
|
|
2236
2315
|
}
|
|
@@ -3348,7 +3427,7 @@ ${fmRewritten}
|
|
|
3348
3427
|
}
|
|
3349
3428
|
let indexUpdated = false;
|
|
3350
3429
|
if (!isRaw) {
|
|
3351
|
-
const { renderRootIndex: renderRootIndex2, writeRootIndexProjection: writeRootIndexProjection2 } = await import("./index-projection-
|
|
3430
|
+
const { renderRootIndex: renderRootIndex2, writeRootIndexProjection: writeRootIndexProjection2 } = await import("./index-projection-ZXFN5DT4.js");
|
|
3352
3431
|
const before = await readFile7(join18(input.vault, "index.md"), "utf8").catch(() => "");
|
|
3353
3432
|
const fullTarget = relPath.replace(/\.md$/, "");
|
|
3354
3433
|
const bare = fullTarget.split("/").pop() ?? fullTarget;
|
|
@@ -3468,7 +3547,7 @@ async function runRemove(input) {
|
|
|
3468
3547
|
if (relPath.endsWith(".md") && !relPath.startsWith("raw/")) {
|
|
3469
3548
|
const { readFile: readFile20 } = await import("fs/promises");
|
|
3470
3549
|
const { join: pathJoin } = await import("path");
|
|
3471
|
-
const { renderRootIndex: renderRootIndex2, writeRootIndexProjection: writeRootIndexProjection2 } = await import("./index-projection-
|
|
3550
|
+
const { renderRootIndex: renderRootIndex2, writeRootIndexProjection: writeRootIndexProjection2 } = await import("./index-projection-ZXFN5DT4.js");
|
|
3472
3551
|
const before = await readFile20(pathJoin(input.vault, "index.md"), "utf8").catch(() => "");
|
|
3473
3552
|
const fullTarget = relPath.replace(/\.md$/, "");
|
|
3474
3553
|
const bare = fullTarget.split("/").pop() ?? fullTarget;
|
|
@@ -8152,7 +8231,7 @@ function releaseSnapshotFlock(handle) {
|
|
|
8152
8231
|
}
|
|
8153
8232
|
|
|
8154
8233
|
// src/commands/backup.ts
|
|
8155
|
-
import { statSync as
|
|
8234
|
+
import { statSync as statSync3, readdirSync as readdirSync2, readFileSync as readFileSync15, mkdirSync as mkdirSync5, writeFileSync as writeFileSync6 } from "fs";
|
|
8156
8235
|
import { join as join31, relative as relative3, dirname as dirname10 } from "path";
|
|
8157
8236
|
import { PutObjectCommand, HeadObjectCommand, ListObjectsV2Command, GetObjectCommand, DeleteObjectsCommand } from "@aws-sdk/client-s3";
|
|
8158
8237
|
|
|
@@ -8201,7 +8280,7 @@ async function runBackupSync(input) {
|
|
|
8201
8280
|
const files = [...walkMarkdown(input.vault, input.vault)];
|
|
8202
8281
|
for (const relPath of files) {
|
|
8203
8282
|
const absPath = join31(input.vault, relPath);
|
|
8204
|
-
const localStat =
|
|
8283
|
+
const localStat = statSync3(absPath);
|
|
8205
8284
|
let needsUpload = true;
|
|
8206
8285
|
try {
|
|
8207
8286
|
const head = await client.send(new HeadObjectCommand({ Bucket: input.bucket, Key: relPath }));
|
|
@@ -8278,7 +8357,7 @@ async function runBackupRestore(input) {
|
|
|
8278
8357
|
if (!obj.Key) continue;
|
|
8279
8358
|
const localPath = join31(target, obj.Key);
|
|
8280
8359
|
try {
|
|
8281
|
-
const localStat =
|
|
8360
|
+
const localStat = statSync3(localPath);
|
|
8282
8361
|
if (obj.LastModified && localStat.mtime > obj.LastModified) {
|
|
8283
8362
|
conflicts++;
|
|
8284
8363
|
continue;
|
|
@@ -8322,7 +8401,7 @@ async function runBackupRestore(input) {
|
|
|
8322
8401
|
}
|
|
8323
8402
|
|
|
8324
8403
|
// src/commands/status.ts
|
|
8325
|
-
import { existsSync as existsSync10, statSync as
|
|
8404
|
+
import { existsSync as existsSync10, statSync as statSync4 } from "fs";
|
|
8326
8405
|
import { readFile as readFile16 } from "fs/promises";
|
|
8327
8406
|
import { join as join32 } from "path";
|
|
8328
8407
|
async function runStatus(input) {
|
|
@@ -8367,7 +8446,7 @@ async function runStatus(input) {
|
|
|
8367
8446
|
let maxTime = 0;
|
|
8368
8447
|
for (const page of allPages) {
|
|
8369
8448
|
try {
|
|
8370
|
-
const st =
|
|
8449
|
+
const st = statSync4(page.absPath);
|
|
8371
8450
|
if (st.mtimeMs > maxTime) {
|
|
8372
8451
|
maxTime = st.mtimeMs;
|
|
8373
8452
|
lastModified = st.mtime.toISOString();
|
|
@@ -9256,9 +9335,9 @@ async function postCommit(vault, exitCode) {
|
|
|
9256
9335
|
}
|
|
9257
9336
|
|
|
9258
9337
|
// src/commands/write-preflight.ts
|
|
9259
|
-
import { existsSync as existsSync14, readFileSync as readFileSync17, statSync as
|
|
9338
|
+
import { existsSync as existsSync14, readFileSync as readFileSync17, statSync as statSync5 } from "fs";
|
|
9260
9339
|
async function runWritePreflightCommand(input) {
|
|
9261
|
-
if (!existsSync14(input.vault) || !
|
|
9340
|
+
if (!existsSync14(input.vault) || !statSync5(input.vault).isDirectory()) {
|
|
9262
9341
|
return {
|
|
9263
9342
|
exitCode: ExitCode.VAULT_PATH_INVALID,
|
|
9264
9343
|
result: err(GateError.VAULT_PATH_INVALID, { path: input.vault })
|
|
@@ -9322,9 +9401,16 @@ var program = new Command();
|
|
|
9322
9401
|
program.name("skillwiki").description("Deterministic helpers for CodeWiki skills").version(pkg.version);
|
|
9323
9402
|
program.option("--human", "render terminal-readable output instead of JSON");
|
|
9324
9403
|
async function emit(r, vault, opts) {
|
|
9325
|
-
if (program.opts().human)
|
|
9326
|
-
|
|
9404
|
+
if (program.opts().human) {
|
|
9405
|
+
const detailHints = r.result.ok ? opts?.humanDetailHints?.(r.result.data) : void 0;
|
|
9406
|
+
printHuman(r.result, { detailHints });
|
|
9407
|
+
} else {
|
|
9408
|
+
printJson(r.result);
|
|
9409
|
+
}
|
|
9327
9410
|
if (vault && opts?.postCommit !== false) await postCommit(vault, r.exitCode);
|
|
9411
|
+
await new Promise((resolve6, reject) => {
|
|
9412
|
+
process.stdout.write("", (error) => error ? reject(error) : resolve6());
|
|
9413
|
+
});
|
|
9328
9414
|
process.exit(r.exitCode);
|
|
9329
9415
|
}
|
|
9330
9416
|
function dirtyVolumeBlock(vault, command) {
|
|
@@ -9386,7 +9472,7 @@ async function emitManagedVaultWrite(vault, command, mutate, opts) {
|
|
|
9386
9472
|
if (dirty) {
|
|
9387
9473
|
return emit(dirty, void 0, { postCommit: false });
|
|
9388
9474
|
}
|
|
9389
|
-
const { runManagedWriteTransaction: runManagedWriteTransaction2 } = await import("./managed-write-preflight-
|
|
9475
|
+
const { runManagedWriteTransaction: runManagedWriteTransaction2 } = await import("./managed-write-preflight-ANQPMOF4.js");
|
|
9390
9476
|
const run = await runManagedWriteTransaction2({
|
|
9391
9477
|
vault,
|
|
9392
9478
|
command,
|
|
@@ -9803,6 +9889,7 @@ projectionsCmd.command("repair-legacy [vault]").description("repair one supporte
|
|
|
9803
9889
|
});
|
|
9804
9890
|
program.command("lint [vault]").description("run all vault health checks").option("--days <n>", "stale threshold", (s) => parseInt(s, 10), 90).option("--lines <n>", "pagesize threshold", (s) => parseInt(s, 10), 200).option("--log-threshold <n>", "log rotation threshold", (s) => parseInt(s, 10), 500).option("--fix", "auto-fix supported lint violations").option("--only <bucket>", "run only the specified lint bucket").option("--summary", "emit bounded bucket counts instead of full item arrays", false).option("--examples <n>", "example count per bucket in summary mode", (s) => parseInt(s, 10), 3).option("--wiki <name>", "wiki profile name").action(async (vault, opts) => {
|
|
9805
9891
|
const v = await resolveVaultArg(vault, opts.wiki);
|
|
9892
|
+
const humanDetailHints = opts.only ? void 0 : lintDetailHints;
|
|
9806
9893
|
if (!v.ok) emit({ exitCode: v.exitCode, result: v.payload });
|
|
9807
9894
|
else if (opts.fix && opts.summary) return emitGuardedVaultWrite(
|
|
9808
9895
|
v.vault,
|
|
@@ -9817,7 +9904,8 @@ program.command("lint [vault]").description("run all vault health checks").optio
|
|
|
9817
9904
|
only: opts.only,
|
|
9818
9905
|
summary: true,
|
|
9819
9906
|
examplesLimit: opts.examples
|
|
9820
|
-
})
|
|
9907
|
+
}),
|
|
9908
|
+
{ humanDetailHints }
|
|
9821
9909
|
);
|
|
9822
9910
|
else if (opts.fix) return emitGuardedVaultWrite(
|
|
9823
9911
|
v.vault,
|
|
@@ -9831,7 +9919,8 @@ program.command("lint [vault]").description("run all vault health checks").optio
|
|
|
9831
9919
|
fix: true,
|
|
9832
9920
|
only: opts.only,
|
|
9833
9921
|
summary: false
|
|
9834
|
-
})
|
|
9922
|
+
}),
|
|
9923
|
+
{ humanDetailHints }
|
|
9835
9924
|
);
|
|
9836
9925
|
else if (opts.summary) emit(await runLint({
|
|
9837
9926
|
vault: v.vault,
|
|
@@ -9843,7 +9932,7 @@ program.command("lint [vault]").description("run all vault health checks").optio
|
|
|
9843
9932
|
only: opts.only,
|
|
9844
9933
|
summary: true,
|
|
9845
9934
|
examplesLimit: opts.examples
|
|
9846
|
-
}), v.vault);
|
|
9935
|
+
}), v.vault, { humanDetailHints });
|
|
9847
9936
|
else emit(await runLint({
|
|
9848
9937
|
vault: v.vault,
|
|
9849
9938
|
source: vault ? "flag" : void 0,
|
|
@@ -9852,7 +9941,7 @@ program.command("lint [vault]").description("run all vault health checks").optio
|
|
|
9852
9941
|
logThreshold: opts.logThreshold,
|
|
9853
9942
|
fix: false,
|
|
9854
9943
|
only: opts.only
|
|
9855
|
-
}), v.vault);
|
|
9944
|
+
}), v.vault, { humanDetailHints });
|
|
9856
9945
|
});
|
|
9857
9946
|
program.command("health [vault]").description("bounded whole-system wiki health report").option("--wiki <name>", "wiki profile name").option("--sync <mode>", "vault-sync policy: optional|required|off", "optional").option("--no-fail", "always exit 0 while reporting status in JSON").option("--out <path>", "write JSON result envelope to this path").option("--examples <n>", "example count per lint bucket", (s) => parseInt(s, 10), 3).action(async (vault, opts) => {
|
|
9858
9947
|
const sync = String(opts.sync ?? "optional");
|
|
@@ -9873,7 +9962,7 @@ program.command("health [vault]").description("bounded whole-system wiki health
|
|
|
9873
9962
|
noFail: opts.fail === false,
|
|
9874
9963
|
out: opts.out,
|
|
9875
9964
|
examplesLimit: opts.examples
|
|
9876
|
-
}), void 0, { postCommit: false });
|
|
9965
|
+
}), void 0, { postCommit: false, humanDetailHints: healthLintDetailHints });
|
|
9877
9966
|
});
|
|
9878
9967
|
var configCmd = program.command("config").description("manage skillwiki configuration");
|
|
9879
9968
|
configCmd.command("get <key>").description("print the value of a config key").action(async (key) => emit(await runConfigGet({ key, home: process.env.HOME ?? "" })));
|
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
UNMANAGED_START,
|
|
5
5
|
renderRootIndex,
|
|
6
6
|
writeRootIndexProjection
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-QVO332CT.js";
|
|
8
|
+
import "./chunk-IFMHQETQ.js";
|
|
9
|
+
import "./chunk-BS556WUE.js";
|
|
10
10
|
export {
|
|
11
11
|
UNMANAGED_END,
|
|
12
12
|
UNMANAGED_START,
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import {
|
|
3
3
|
runManagedWritePreflight,
|
|
4
4
|
runManagedWriteTransaction
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-LACQJ6RD.js";
|
|
6
|
+
import "./chunk-XRBUABGE.js";
|
|
7
|
+
import "./chunk-IFMHQETQ.js";
|
|
8
|
+
import "./chunk-E3JBAURS.js";
|
|
9
|
+
import "./chunk-BS556WUE.js";
|
|
10
10
|
export {
|
|
11
11
|
runManagedWritePreflight,
|
|
12
12
|
runManagedWriteTransaction
|
package/dist/skillwiki-mcp.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runSkillwikiMcpStdio
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WJVG3DD5.js";
|
|
5
5
|
import "./chunk-7I2TPIV5.js";
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-QVO332CT.js";
|
|
7
|
+
import "./chunk-XRBUABGE.js";
|
|
8
|
+
import "./chunk-IFMHQETQ.js";
|
|
9
|
+
import "./chunk-E3JBAURS.js";
|
|
10
|
+
import "./chunk-BS556WUE.js";
|
|
11
11
|
|
|
12
12
|
// src/mcp-entry.ts
|
|
13
13
|
runSkillwikiMcpStdio().catch((error) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillwiki",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.37",
|
|
4
4
|
"skills": "./",
|
|
5
5
|
"description": "Project-aware Karpathy-style knowledge base for Claude Code: 19 prompt-only skills (wiki-*, proj-*, using-skillwiki) backed by the deterministic `skillwiki` CLI.",
|
|
6
6
|
"author": {
|
|
@@ -1,16 +1,45 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# Shared SessionStart context helpers for skillwiki hook entrypoints.
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
read_workflow_config() {
|
|
5
5
|
local file="$1"
|
|
6
|
-
local key="$2"
|
|
7
|
-
local line
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
awk '
|
|
8
|
+
BEGIN {
|
|
9
|
+
count = 6
|
|
10
|
+
keys[1] = "workflow_selection"
|
|
11
|
+
keys[2] = "workflow_profile"
|
|
12
|
+
keys[3] = "workflow_capability"
|
|
13
|
+
keys[4] = "workflow_risk"
|
|
14
|
+
keys[5] = "prd_layer"
|
|
15
|
+
keys[6] = "prd_pipeline"
|
|
16
|
+
for (i = 1; i <= count; i += 1) allowed[keys[i]] = 1
|
|
17
|
+
}
|
|
18
|
+
/^[[:space:]]*```(yaml|yml)[[:space:]]*$/ { in_yaml = 1; next }
|
|
19
|
+
in_yaml && /^[[:space:]]*```[[:space:]]*$/ { in_yaml = 0; next }
|
|
20
|
+
in_yaml && /^[A-Za-z_][A-Za-z0-9_]*[[:space:]]*:/ {
|
|
21
|
+
line = $0
|
|
22
|
+
key = line
|
|
23
|
+
sub(/[[:space:]]*:.*/, "", key)
|
|
24
|
+
if (!(key in allowed)) next
|
|
25
|
+
value = line
|
|
26
|
+
sub(/^[^:]*:[[:space:]]*/, "", value)
|
|
27
|
+
sub(/[[:space:]]+#.*$/, "", value)
|
|
28
|
+
sub(/^[[:space:]]+/, "", value)
|
|
29
|
+
sub(/[[:space:]]+$/, "", value)
|
|
30
|
+
if ((substr(value, 1, 1) == "\"" && substr(value, length(value), 1) == "\"") ||
|
|
31
|
+
(substr(value, 1, 1) == "\047" && substr(value, length(value), 1) == "\047")) {
|
|
32
|
+
value = substr(value, 2, length(value) - 2)
|
|
33
|
+
}
|
|
34
|
+
values[key] = value
|
|
35
|
+
}
|
|
36
|
+
END {
|
|
37
|
+
for (i = 1; i <= count; i += 1) {
|
|
38
|
+
key = keys[i]
|
|
39
|
+
if (key in values) printf "%s\t%s\n", key, values[key]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
' "$file" 2>/dev/null
|
|
14
43
|
}
|
|
15
44
|
|
|
16
45
|
find_dev_loop_config() {
|
|
@@ -27,29 +56,199 @@ find_dev_loop_config() {
|
|
|
27
56
|
return 0
|
|
28
57
|
}
|
|
29
58
|
|
|
30
|
-
|
|
31
|
-
local config_path
|
|
59
|
+
build_project_workflow_context() {
|
|
60
|
+
local config_path=""
|
|
32
61
|
config_path=$(find_dev_loop_config)
|
|
33
|
-
|
|
62
|
+
local workflow_selection=""
|
|
63
|
+
local configured_profile=""
|
|
64
|
+
local workflow_capability=""
|
|
65
|
+
local workflow_risk=""
|
|
66
|
+
local prd_layer=""
|
|
67
|
+
local prd_pipeline=""
|
|
68
|
+
if [[ -n "$config_path" ]]; then
|
|
69
|
+
while IFS=$'\t' read -r key value; do
|
|
70
|
+
case "$key" in
|
|
71
|
+
workflow_selection) workflow_selection="$value" ;;
|
|
72
|
+
workflow_profile) configured_profile="$value" ;;
|
|
73
|
+
workflow_capability) workflow_capability="$value" ;;
|
|
74
|
+
workflow_risk) workflow_risk="$value" ;;
|
|
75
|
+
prd_layer) prd_layer="$value" ;;
|
|
76
|
+
prd_pipeline) prd_pipeline="$value" ;;
|
|
77
|
+
esac
|
|
78
|
+
done < <(read_workflow_config "$config_path")
|
|
79
|
+
fi
|
|
34
80
|
|
|
35
|
-
local
|
|
36
|
-
local
|
|
37
|
-
|
|
38
|
-
|
|
81
|
+
local authority="builtin_adaptive"
|
|
82
|
+
local resolved_profile=""
|
|
83
|
+
local resolved_pipeline=""
|
|
84
|
+
local workflow_status="resolved"
|
|
85
|
+
local reason=""
|
|
86
|
+
local has_policy="false"
|
|
87
|
+
local legacy_profile=""
|
|
88
|
+
|
|
89
|
+
prd_layer="${prd_layer:-manual}"
|
|
90
|
+
workflow_capability="${workflow_capability:-unknown}"
|
|
91
|
+
workflow_risk="${workflow_risk:-routine}"
|
|
92
|
+
|
|
93
|
+
if [[ -n "$prd_pipeline" ]]; then
|
|
94
|
+
case "$prd_pipeline" in
|
|
95
|
+
full) legacy_profile="full" ;;
|
|
96
|
+
tdd-first) legacy_profile="guided" ;;
|
|
97
|
+
single-pass|debug-only|manual) legacy_profile="native" ;;
|
|
98
|
+
*)
|
|
99
|
+
workflow_status="unresolved"
|
|
100
|
+
reason="prd_pipeline must be one of: full, tdd-first, single-pass, debug-only, manual"
|
|
101
|
+
;;
|
|
102
|
+
esac
|
|
103
|
+
fi
|
|
39
104
|
|
|
40
|
-
[[ -n "$
|
|
105
|
+
if [[ -n "$workflow_selection" || -n "$configured_profile" || \
|
|
106
|
+
"$workflow_capability" != "unknown" || "$workflow_risk" != "routine" ]]; then
|
|
107
|
+
has_policy="true"
|
|
108
|
+
authority="project"
|
|
109
|
+
if [[ -z "$workflow_selection" ]]; then
|
|
110
|
+
if [[ -n "$configured_profile" ]]; then
|
|
111
|
+
workflow_selection="fixed"
|
|
112
|
+
else
|
|
113
|
+
workflow_selection="adaptive"
|
|
114
|
+
fi
|
|
115
|
+
fi
|
|
116
|
+
elif [[ -n "$prd_pipeline" ]]; then
|
|
117
|
+
workflow_selection="fixed"
|
|
118
|
+
authority="project_legacy"
|
|
119
|
+
resolved_profile="$legacy_profile"
|
|
120
|
+
if [[ "$workflow_status" == "resolved" ]]; then
|
|
121
|
+
reason="legacy explicit prd_pipeline ${prd_pipeline} maps to the ${resolved_profile} workflow profile"
|
|
122
|
+
fi
|
|
123
|
+
elif [[ -n "${DEV_LOOP_WORKFLOW_SELECTION:-}" || -n "${DEV_LOOP_WORKFLOW_PROFILE:-}" || \
|
|
124
|
+
-n "${DEV_LOOP_WORKFLOW_CAPABILITY:-}" || -n "${DEV_LOOP_WORKFLOW_RISK:-}" ]]; then
|
|
125
|
+
has_policy="true"
|
|
126
|
+
authority="user_default"
|
|
127
|
+
workflow_selection="${DEV_LOOP_WORKFLOW_SELECTION:-}"
|
|
128
|
+
configured_profile="${DEV_LOOP_WORKFLOW_PROFILE:-}"
|
|
129
|
+
workflow_capability="${DEV_LOOP_WORKFLOW_CAPABILITY:-unknown}"
|
|
130
|
+
workflow_risk="${DEV_LOOP_WORKFLOW_RISK:-routine}"
|
|
131
|
+
if [[ -z "$workflow_selection" ]]; then
|
|
132
|
+
if [[ -n "$configured_profile" ]]; then
|
|
133
|
+
workflow_selection="fixed"
|
|
134
|
+
else
|
|
135
|
+
workflow_selection="adaptive"
|
|
136
|
+
fi
|
|
137
|
+
fi
|
|
138
|
+
else
|
|
139
|
+
workflow_selection="adaptive"
|
|
140
|
+
fi
|
|
41
141
|
|
|
42
|
-
|
|
43
|
-
|
|
142
|
+
if [[ "$has_policy" == "true" ]]; then
|
|
143
|
+
case "$workflow_selection" in
|
|
144
|
+
fixed|adaptive) ;;
|
|
145
|
+
*)
|
|
146
|
+
workflow_status="unresolved"
|
|
147
|
+
reason="workflow_selection must be one of: fixed, adaptive"
|
|
148
|
+
;;
|
|
149
|
+
esac
|
|
150
|
+
case "$configured_profile" in
|
|
151
|
+
""|native|guided|full) ;;
|
|
152
|
+
*)
|
|
153
|
+
workflow_status="unresolved"
|
|
154
|
+
reason="workflow_profile must be one of: native, guided, full"
|
|
155
|
+
;;
|
|
156
|
+
esac
|
|
157
|
+
case "$workflow_capability" in
|
|
158
|
+
self-directed|needs-guidance|unknown) ;;
|
|
159
|
+
*)
|
|
160
|
+
workflow_status="unresolved"
|
|
161
|
+
reason="workflow_capability must be one of: self-directed, needs-guidance, unknown"
|
|
162
|
+
;;
|
|
163
|
+
esac
|
|
164
|
+
case "$workflow_risk" in
|
|
165
|
+
routine|elevated) ;;
|
|
166
|
+
*)
|
|
167
|
+
workflow_status="unresolved"
|
|
168
|
+
reason="workflow_risk must be one of: routine, elevated"
|
|
169
|
+
;;
|
|
170
|
+
esac
|
|
171
|
+
|
|
172
|
+
if [[ "$workflow_status" == "resolved" && "$workflow_selection" == "fixed" && -z "$configured_profile" ]]; then
|
|
173
|
+
workflow_status="unresolved"
|
|
174
|
+
reason="fixed selection requires \`workflow_profile\`"
|
|
175
|
+
elif [[ "$workflow_status" == "resolved" && "$workflow_selection" == "adaptive" && -n "$configured_profile" ]]; then
|
|
176
|
+
workflow_status="unresolved"
|
|
177
|
+
reason="adaptive selection must not set \`workflow_profile\`; use fixed for an explicit profile"
|
|
178
|
+
elif [[ "$workflow_status" == "resolved" && "$workflow_selection" == "fixed" ]]; then
|
|
179
|
+
resolved_profile="$configured_profile"
|
|
180
|
+
reason="${authority} explicitly selected the ${resolved_profile} workflow profile"
|
|
181
|
+
elif [[ "$workflow_status" == "resolved" ]]; then
|
|
182
|
+
if [[ "$workflow_capability" == "needs-guidance" || "$workflow_risk" == "elevated" ]]; then
|
|
183
|
+
resolved_profile="guided"
|
|
184
|
+
else
|
|
185
|
+
resolved_profile="native"
|
|
186
|
+
fi
|
|
187
|
+
reason="adaptive selection chose ${resolved_profile} from capability=${workflow_capability}, risk=${workflow_risk}"
|
|
188
|
+
fi
|
|
189
|
+
elif [[ "$authority" == "builtin_adaptive" ]]; then
|
|
190
|
+
resolved_profile="native"
|
|
191
|
+
reason="built-in adaptive default chose native from capability=unknown, risk=routine"
|
|
192
|
+
fi
|
|
44
193
|
|
|
45
|
-
|
|
46
|
-
|
|
194
|
+
if [[ "$workflow_status" == "resolved" ]]; then
|
|
195
|
+
if [[ -n "$prd_pipeline" ]]; then
|
|
196
|
+
resolved_pipeline="$prd_pipeline"
|
|
197
|
+
else
|
|
198
|
+
case "$resolved_profile" in
|
|
199
|
+
native) resolved_pipeline="single-pass" ;;
|
|
200
|
+
guided) resolved_pipeline="tdd-first" ;;
|
|
201
|
+
full) resolved_pipeline="full" ;;
|
|
202
|
+
esac
|
|
203
|
+
fi
|
|
204
|
+
else
|
|
205
|
+
resolved_profile="unresolved"
|
|
206
|
+
resolved_pipeline="unresolved"
|
|
207
|
+
fi
|
|
47
208
|
|
|
48
|
-
|
|
209
|
+
local config_detection
|
|
210
|
+
if [[ -n "$config_path" ]]; then
|
|
211
|
+
config_detection="Detected \`.claude/dev-loop.config.md\` for this workspace."
|
|
212
|
+
else
|
|
213
|
+
config_detection="No \`.claude/dev-loop.config.md\` was found; using the built-in adaptive default."
|
|
214
|
+
fi
|
|
215
|
+
|
|
216
|
+
cat <<EOF
|
|
217
|
+
## Project Workflow Profile
|
|
218
|
+
|
|
219
|
+
${config_detection}
|
|
220
|
+
- workflow status: \`${workflow_status}\`
|
|
221
|
+
- \`workflow_selection\`: \`${workflow_selection}\`
|
|
222
|
+
- \`workflow_profile\`: \`${resolved_profile}\`
|
|
223
|
+
- \`workflow_capability\`: \`${workflow_capability}\`
|
|
224
|
+
- \`workflow_risk\`: \`${workflow_risk}\`
|
|
225
|
+
- authority: \`${authority}\`
|
|
226
|
+
- reason: ${reason}
|
|
49
227
|
- \`prd_layer\`: \`${prd_layer}\`
|
|
50
|
-
- \`prd_pipeline\`: \`${
|
|
228
|
+
- \`prd_pipeline\`: \`${resolved_pipeline}\`
|
|
229
|
+
|
|
230
|
+
EOF
|
|
51
231
|
|
|
52
|
-
|
|
232
|
+
if [[ "$workflow_status" == "unresolved" ]]; then
|
|
233
|
+
cat <<EOF
|
|
234
|
+
Fail closed for workflow execution until the policy is corrected. Do not infer \`full\`, do not force Superpowers, and do not enable \`EnterPlanMode\` gating from availability evidence.
|
|
235
|
+
EOF
|
|
236
|
+
elif [[ "$resolved_profile" == "full" ]]; then
|
|
237
|
+
cat <<EOF
|
|
238
|
+
Explicit full compatibility workflow is active. If the configured provider uses Superpowers or TDD planning, ensure \`EnterPlanMode\` is gated with \`wiki-gate-plan-mode\`. Run the complete configured provider/pipeline flow.
|
|
239
|
+
EOF
|
|
240
|
+
elif [[ "$resolved_profile" == "guided" ]]; then
|
|
241
|
+
cat <<EOF
|
|
242
|
+
Use only targeted guidance for enabled stages; do not run the complete Superpowers sequence or force \`EnterPlanMode\` gating. Installed providers are optional capability sources.
|
|
243
|
+
EOF
|
|
244
|
+
else
|
|
245
|
+
cat <<EOF
|
|
246
|
+
Use host-native planning, implementation, tools, and subagents. Do not force Superpowers or \`EnterPlanMode\` gating. Installation proves availability, never activation.
|
|
247
|
+
EOF
|
|
248
|
+
fi
|
|
249
|
+
|
|
250
|
+
cat <<EOF
|
|
251
|
+
Route every generated spec/plan artifact through \`proj-work\`, and never write it under \`docs/superpowers/\`. SkillWiki remains the knowledge and provenance layer; workflow selection does not change managed-write authority.
|
|
53
252
|
EOF
|
|
54
253
|
}
|
|
55
254
|
|
|
@@ -254,12 +453,12 @@ resolve_skill_path() {
|
|
|
254
453
|
|
|
255
454
|
build_skillwiki_session_context() {
|
|
256
455
|
local skill_content="$1"
|
|
257
|
-
local
|
|
456
|
+
local project_workflow_context
|
|
258
457
|
local dynamic_session_memory
|
|
259
458
|
local runtime_host_context
|
|
260
459
|
local session_context
|
|
261
460
|
|
|
262
|
-
|
|
461
|
+
project_workflow_context=$(build_project_workflow_context)
|
|
263
462
|
dynamic_session_memory=$(build_dynamic_session_memory)
|
|
264
463
|
runtime_host_context=$(build_runtime_host_context)
|
|
265
464
|
|
|
@@ -272,9 +471,9 @@ build_skillwiki_session_context() {
|
|
|
272
471
|
session_context+=$'\n\n'
|
|
273
472
|
session_context+="$dynamic_session_memory"
|
|
274
473
|
fi
|
|
275
|
-
if [[ -n "$
|
|
474
|
+
if [[ -n "$project_workflow_context" ]]; then
|
|
276
475
|
session_context+=$'\n\n'
|
|
277
|
-
session_context+="$
|
|
476
|
+
session_context+="$project_workflow_context"
|
|
278
477
|
fi
|
|
279
478
|
session_context+=$'\n\n'
|
|
280
479
|
session_context+="$skill_content"
|
package/skills/package.json
CHANGED
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: using-skillwiki
|
|
3
|
-
description: Invoke at session start or when knowledge-base tasks arise — maps skillwiki skills, dev-loop alignment,
|
|
3
|
+
description: Invoke at session start or when knowledge-base tasks arise — maps skillwiki skills, dev-loop alignment, adaptive workflow profiles, and vault routing
|
|
4
4
|
---
|
|
5
5
|
*Note: If executing as a background subagent, skip this skill section.*
|
|
6
6
|
|
|
7
7
|
# using-skillwiki
|
|
8
|
-
You have skillwiki — a project-aware Karpathy-style knowledge base for
|
|
8
|
+
You have skillwiki — a project-aware Karpathy-style knowledge base for agent harnesses.
|
|
9
9
|
|
|
10
10
|
## Last Hook Gate (SessionStart)
|
|
11
11
|
|
|
12
|
-
This skill is activated by the plugin during
|
|
12
|
+
This skill is activated by the plugin during startup and clear lifecycle
|
|
13
|
+
events, plus the harness-specific resume/compact event where supported.
|
|
13
14
|
Use this section as procedural planning guidelines:
|
|
14
15
|
|
|
15
|
-
1.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
1. Read the injected Project Workflow Profile before choosing orchestration or
|
|
17
|
+
provider skills. Installation proves availability, never activation.
|
|
18
|
+
2. For `native`, use the host agent's built-in planning and execution. For
|
|
19
|
+
`guided`, add only targeted structure. Neither profile forces Superpowers
|
|
20
|
+
or `EnterPlanMode` gating.
|
|
21
|
+
3. For explicit `full`, run the complete configured provider/pipeline. Gate
|
|
22
|
+
`EnterPlanMode` with `wiki-gate-plan-mode` only when that explicit workflow
|
|
23
|
+
uses Superpowers or TDD planning.
|
|
24
|
+
4. If workflow status is unresolved, fail closed for workflow execution; do
|
|
25
|
+
not infer `full` from installed skills or provider names.
|
|
26
|
+
5. Always apply the PRD bridge: spec/plan outputs go to vault work-item paths,
|
|
27
|
+
never `docs/superpowers/`.
|
|
19
28
|
|
|
20
29
|
## Activation File (Cross-Harness Alternative to SessionStart)
|
|
21
30
|
|
|
@@ -177,8 +186,9 @@ The vault is shared across hosts, so host-local absolute paths are not durable s
|
|
|
177
186
|
|
|
178
187
|
## dev-loop Alignment
|
|
179
188
|
|
|
180
|
-
Use these skills as the knowledge layer in dev-loop. The loop remains
|
|
181
|
-
|
|
189
|
+
Use these skills as the knowledge layer in dev-loop. The loop remains
|
|
190
|
+
capability-based: resolve `WORKFLOW_PROFILE` first, then branch on capabilities
|
|
191
|
+
(`BACKEND_CAPS`, `PRD_CAPS`), not backend names.
|
|
182
192
|
|
|
183
193
|
Typical sequence with PRD enabled:
|
|
184
194
|
`REFRESH → QUERY → WORK → SPEC → PLAN → EXECUTE → SIMPLIFY → MERGE → SAVE → RETRO`.
|
|
@@ -187,17 +197,33 @@ Typical sequence with PRD enabled:
|
|
|
187
197
|
- `SIMPLIFY` is a quality gate before merge; keep it in the loop even for small changes.
|
|
188
198
|
- For no-work cycles, run maintenance (`wiki-lint`, `wiki-audit`, `proj-distill`, `dev-loop:research`).
|
|
189
199
|
|
|
190
|
-
##
|
|
191
|
-
|
|
192
|
-
Use
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
- `
|
|
196
|
-
|
|
197
|
-
|
|
200
|
+
## Workflow Profile Compatibility
|
|
201
|
+
|
|
202
|
+
Use the resolved workflow policy from `.claude/dev-loop.config.md` and the
|
|
203
|
+
SessionStart context as the source of truth:
|
|
204
|
+
|
|
205
|
+
- `native` defaults to `single-pass` and uses host-native planning,
|
|
206
|
+
implementation, tools, and subagents. Installed providers stay inactive
|
|
207
|
+
unless explicitly selected for a stage.
|
|
208
|
+
- `guided` defaults to `tdd-first` and adds only targeted planning, TDD, or
|
|
209
|
+
provider capabilities. It does not imply the complete Superpowers sequence.
|
|
210
|
+
- `full` defaults to `full` and runs the complete compatibility workflow. It
|
|
211
|
+
is explicit-only, including the legacy compatibility signal
|
|
212
|
+
`prd_pipeline: full` when no newer workflow policy overrides it.
|
|
213
|
+
- `workflow_selection: adaptive` may choose `native` or `guided`, never
|
|
214
|
+
`full`. `workflow_selection: fixed` requires `workflow_profile`.
|
|
215
|
+
- Invalid policy is unresolved and fail-closed. Goal, headless, CI, and
|
|
216
|
+
satellite sessions do not prompt for a replacement policy.
|
|
217
|
+
|
|
218
|
+
`prd_layer` remains an independent provider-capability registry and
|
|
219
|
+
`prd_pipeline` remains an independent stage-template override. Provider or
|
|
220
|
+
cache discovery cannot select a workflow profile. Regardless of profile,
|
|
221
|
+
route generated spec and plan artifacts through `proj-work`, preserve
|
|
222
|
+
SkillWiki provenance, and keep the independent `simplify:simplify` review gate
|
|
223
|
+
for code changes.
|
|
198
224
|
|
|
199
225
|
## CLI Backbone
|
|
200
|
-
All skills are backed by the `skillwiki` CLI — a deterministic tool with no LLM calls. It handles path resolution, config management, validation, health reporting, and linting. Skills invoke it via Bash for the mechanical parts and use
|
|
226
|
+
All skills are backed by the `skillwiki` CLI — a deterministic tool with no LLM calls. It handles path resolution, config management, validation, health reporting, and linting. Skills invoke it via Bash for the mechanical parts and use the active agent for the creative parts.
|
|
201
227
|
Key CLI subcommands: `init`, `health`, `lint`, `config`, `doctor`, `path`, `lang`, `install`, `fleet context`, `fleet validate`, `graph build`, `query`, `sources pending`, `sources disposition`, `sources dispose`, `archive`, `remove`, `drift`, `dedup`, `compound`, `tag-sync`, `tag reconcile`, `page publish`, `sync status`, `seed`, `stale`, `observe`, `canvas generate`.
|
|
202
228
|
Run `skillwiki health <vault> --out /tmp/skillwiki-health.json --no-fail` for a bounded whole-system report that includes the nonblocking source-lifecycle backlog. Pending captures are informational and do not make health fail. Run `skillwiki lint <vault> --summary` for lint-only bucket counts with capped examples and details commands. Run `skillwiki doctor` to diagnose setup/runtime issues only. Run `skillwiki config list` to see current configuration.
|
|
203
229
|
|
|
@@ -39,6 +39,19 @@ Invoke a SkillWiki skill when the user: wants vault/wiki/knowledge-base operatio
|
|
|
39
39
|
|
|
40
40
|
Route PRD/spec/plan work to `wiki-adapter-prd` and `proj-work`, not `docs/superpowers/`. Spec and plan outputs must land in vault work-item paths. Never create `docs/superpowers/` in any repo.
|
|
41
41
|
|
|
42
|
+
## Workflow Profiles
|
|
43
|
+
|
|
44
|
+
Resolve workflow policy before loading provider skills. Profiles are `native`,
|
|
45
|
+
`guided`, and explicit-only `full`; selection is `adaptive` or `fixed`.
|
|
46
|
+
Adaptive chooses only native or guided. Installation and cache discovery prove
|
|
47
|
+
availability, never activation. Native and guided do not force Superpowers or
|
|
48
|
+
plan-mode gating. Explicit full may use the complete configured provider flow;
|
|
49
|
+
gate plan mode only when that flow actually uses Superpowers/TDD planning.
|
|
50
|
+
Invalid fixed policy is unresolved and fail-closed. Noninteractive sessions do
|
|
51
|
+
not prompt. Keep workflow profile, `prd_layer` provider, `prd_pipeline` stage
|
|
52
|
+
template, SkillWiki provenance, and the independent simplify review gate as
|
|
53
|
+
separate concerns.
|
|
54
|
+
|
|
42
55
|
## Fail-Closed Boundary
|
|
43
56
|
|
|
44
57
|
Never write typed pages, `index.md`, or `log.md` directly. Never bare `rm` or `git rm` as a fleet delete (snapshot resurrects from S3). Never auto `npm install -g skillwiki` in headless/goal/satellite sessions. If `skillwiki page publish --help` is unavailable, fail closed.
|
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: using-skillwiki
|
|
3
|
-
description: Invoke at session start or when knowledge-base tasks arise — maps skillwiki skills, dev-loop alignment,
|
|
3
|
+
description: Invoke at session start or when knowledge-base tasks arise — maps skillwiki skills, dev-loop alignment, adaptive workflow profiles, and vault routing
|
|
4
4
|
---
|
|
5
5
|
*Note: If executing as a background subagent, skip this skill section.*
|
|
6
6
|
|
|
7
7
|
# using-skillwiki
|
|
8
|
-
You have skillwiki — a project-aware Karpathy-style knowledge base for
|
|
8
|
+
You have skillwiki — a project-aware Karpathy-style knowledge base for agent harnesses.
|
|
9
9
|
|
|
10
10
|
## Last Hook Gate (SessionStart)
|
|
11
11
|
|
|
12
|
-
This skill is activated by the plugin during
|
|
12
|
+
This skill is activated by the plugin during startup and clear lifecycle
|
|
13
|
+
events, plus the harness-specific resume/compact event where supported.
|
|
13
14
|
Use this section as procedural planning guidelines:
|
|
14
15
|
|
|
15
|
-
1.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
1. Read the injected Project Workflow Profile before choosing orchestration or
|
|
17
|
+
provider skills. Installation proves availability, never activation.
|
|
18
|
+
2. For `native`, use the host agent's built-in planning and execution. For
|
|
19
|
+
`guided`, add only targeted structure. Neither profile forces Superpowers
|
|
20
|
+
or `EnterPlanMode` gating.
|
|
21
|
+
3. For explicit `full`, run the complete configured provider/pipeline. Gate
|
|
22
|
+
`EnterPlanMode` with `wiki-gate-plan-mode` only when that explicit workflow
|
|
23
|
+
uses Superpowers or TDD planning.
|
|
24
|
+
4. If workflow status is unresolved, fail closed for workflow execution; do
|
|
25
|
+
not infer `full` from installed skills or provider names.
|
|
26
|
+
5. Always apply the PRD bridge: spec/plan outputs go to vault work-item paths,
|
|
27
|
+
never `docs/superpowers/`.
|
|
19
28
|
|
|
20
29
|
## Activation File (Cross-Harness Alternative to SessionStart)
|
|
21
30
|
|
|
@@ -177,8 +186,9 @@ The vault is shared across hosts, so host-local absolute paths are not durable s
|
|
|
177
186
|
|
|
178
187
|
## dev-loop Alignment
|
|
179
188
|
|
|
180
|
-
Use these skills as the knowledge layer in dev-loop. The loop remains
|
|
181
|
-
|
|
189
|
+
Use these skills as the knowledge layer in dev-loop. The loop remains
|
|
190
|
+
capability-based: resolve `WORKFLOW_PROFILE` first, then branch on capabilities
|
|
191
|
+
(`BACKEND_CAPS`, `PRD_CAPS`), not backend names.
|
|
182
192
|
|
|
183
193
|
Typical sequence with PRD enabled:
|
|
184
194
|
`REFRESH → QUERY → WORK → SPEC → PLAN → EXECUTE → SIMPLIFY → MERGE → SAVE → RETRO`.
|
|
@@ -187,17 +197,33 @@ Typical sequence with PRD enabled:
|
|
|
187
197
|
- `SIMPLIFY` is a quality gate before merge; keep it in the loop even for small changes.
|
|
188
198
|
- For no-work cycles, run maintenance (`wiki-lint`, `wiki-audit`, `proj-distill`, `dev-loop:research`).
|
|
189
199
|
|
|
190
|
-
##
|
|
191
|
-
|
|
192
|
-
Use
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
- `
|
|
196
|
-
|
|
197
|
-
|
|
200
|
+
## Workflow Profile Compatibility
|
|
201
|
+
|
|
202
|
+
Use the resolved workflow policy from `.claude/dev-loop.config.md` and the
|
|
203
|
+
SessionStart context as the source of truth:
|
|
204
|
+
|
|
205
|
+
- `native` defaults to `single-pass` and uses host-native planning,
|
|
206
|
+
implementation, tools, and subagents. Installed providers stay inactive
|
|
207
|
+
unless explicitly selected for a stage.
|
|
208
|
+
- `guided` defaults to `tdd-first` and adds only targeted planning, TDD, or
|
|
209
|
+
provider capabilities. It does not imply the complete Superpowers sequence.
|
|
210
|
+
- `full` defaults to `full` and runs the complete compatibility workflow. It
|
|
211
|
+
is explicit-only, including the legacy compatibility signal
|
|
212
|
+
`prd_pipeline: full` when no newer workflow policy overrides it.
|
|
213
|
+
- `workflow_selection: adaptive` may choose `native` or `guided`, never
|
|
214
|
+
`full`. `workflow_selection: fixed` requires `workflow_profile`.
|
|
215
|
+
- Invalid policy is unresolved and fail-closed. Goal, headless, CI, and
|
|
216
|
+
satellite sessions do not prompt for a replacement policy.
|
|
217
|
+
|
|
218
|
+
`prd_layer` remains an independent provider-capability registry and
|
|
219
|
+
`prd_pipeline` remains an independent stage-template override. Provider or
|
|
220
|
+
cache discovery cannot select a workflow profile. Regardless of profile,
|
|
221
|
+
route generated spec and plan artifacts through `proj-work`, preserve
|
|
222
|
+
SkillWiki provenance, and keep the independent `simplify:simplify` review gate
|
|
223
|
+
for code changes.
|
|
198
224
|
|
|
199
225
|
## CLI Backbone
|
|
200
|
-
All skills are backed by the `skillwiki` CLI — a deterministic tool with no LLM calls. It handles path resolution, config management, validation, health reporting, and linting. Skills invoke it via Bash for the mechanical parts and use
|
|
226
|
+
All skills are backed by the `skillwiki` CLI — a deterministic tool with no LLM calls. It handles path resolution, config management, validation, health reporting, and linting. Skills invoke it via Bash for the mechanical parts and use the active agent for the creative parts.
|
|
201
227
|
Key CLI subcommands: `init`, `health`, `lint`, `config`, `doctor`, `path`, `lang`, `install`, `fleet context`, `fleet validate`, `graph build`, `query`, `sources pending`, `sources disposition`, `sources dispose`, `archive`, `remove`, `drift`, `dedup`, `compound`, `tag-sync`, `tag reconcile`, `page publish`, `sync status`, `seed`, `stale`, `observe`, `canvas generate`.
|
|
202
228
|
Run `skillwiki health <vault> --out /tmp/skillwiki-health.json --no-fail` for a bounded whole-system report that includes the nonblocking source-lifecycle backlog. Pending captures are informational and do not make health fail. Run `skillwiki lint <vault> --summary` for lint-only bucket counts with capped examples and details commands. Run `skillwiki doctor` to diagnose setup/runtime issues only. Run `skillwiki config list` to see current configuration.
|
|
203
229
|
|
|
@@ -39,6 +39,19 @@ Invoke a SkillWiki skill when the user: wants vault/wiki/knowledge-base operatio
|
|
|
39
39
|
|
|
40
40
|
Route PRD/spec/plan work to `wiki-adapter-prd` and `proj-work`, not `docs/superpowers/`. Spec and plan outputs must land in vault work-item paths. Never create `docs/superpowers/` in any repo.
|
|
41
41
|
|
|
42
|
+
## Workflow Profiles
|
|
43
|
+
|
|
44
|
+
Resolve workflow policy before loading provider skills. Profiles are `native`,
|
|
45
|
+
`guided`, and explicit-only `full`; selection is `adaptive` or `fixed`.
|
|
46
|
+
Adaptive chooses only native or guided. Installation and cache discovery prove
|
|
47
|
+
availability, never activation. Native and guided do not force Superpowers or
|
|
48
|
+
plan-mode gating. Explicit full may use the complete configured provider flow;
|
|
49
|
+
gate plan mode only when that flow actually uses Superpowers/TDD planning.
|
|
50
|
+
Invalid fixed policy is unresolved and fail-closed. Noninteractive sessions do
|
|
51
|
+
not prompt. Keep workflow profile, `prd_layer` provider, `prd_pipeline` stage
|
|
52
|
+
template, SkillWiki provenance, and the independent simplify review gate as
|
|
53
|
+
separate concerns.
|
|
54
|
+
|
|
42
55
|
## Fail-Closed Boundary
|
|
43
56
|
|
|
44
57
|
Never write typed pages, `index.md`, or `log.md` directly. Never bare `rm` or `git rm` as a fleet delete (snapshot resurrects from S3). Never auto `npm install -g skillwiki` in headless/goal/satellite sessions. If `skillwiki page publish --help` is unavailable, fail closed.
|
package/templates/SCHEMA.md
CHANGED
|
@@ -26,6 +26,13 @@ Four shapes: typed-knowledge, raw, work-item, compound. See spec for full Zod sc
|
|
|
26
26
|
Work-item statuses are `planned`, `in-progress`, `completed`, and `abandoned`.
|
|
27
27
|
`status: proposed` is not supported by the current SkillWiki schema. Non-executing queued findings use raw `task` or `bug` captures under `raw/transcripts/` with a `project` wikilink; humans promote them into `planned` work items.
|
|
28
28
|
|
|
29
|
+
### Work Item Validation Shapes
|
|
30
|
+
|
|
31
|
+
- **Standard:** `spec.md` is the specification source. A completed item provides `evidence.md` or `retro.md`.
|
|
32
|
+
- **Goal-plan:** frontmatter `mode: goal-plan` (or the compatibility alias `mode: goal`) makes `plan.md` the specification source. Completion evidence may be `build-report.md`, an `evidence/` directory, `evidence.md`, or `retro.md`; `spec.md` is optional for this shape.
|
|
33
|
+
|
|
34
|
+
`skillwiki work-validate --require-complete` accepts `completed`, `complete`, or `done` on the active specification source. Goal-plan handling does not relax the standard shape: without a goal mode, `spec.md` and the standard completion evidence remain required.
|
|
35
|
+
|
|
29
36
|
## Tag Taxonomy
|
|
30
37
|
|
|
31
38
|
```yaml
|