skillwiki 0.9.21 → 0.9.23
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/cli.js +256 -59
- package/package.json +1 -1
- package/skills/.claude-plugin/plugin.json +1 -1
- package/skills/.codex-plugin/plugin.json +1 -1
- package/skills/package.json +1 -1
- package/dist/chunk-TPS5XD2J.js +0 -19
- package/dist/git-M4WGJ5G3.js +0 -9
package/dist/cli.js
CHANGED
|
@@ -8,10 +8,6 @@ import {
|
|
|
8
8
|
normalizeDistTag,
|
|
9
9
|
semverGt
|
|
10
10
|
} from "./chunk-E6UWZ3S3.js";
|
|
11
|
-
import {
|
|
12
|
-
git,
|
|
13
|
-
gitStrict
|
|
14
|
-
} from "./chunk-TPS5XD2J.js";
|
|
15
11
|
|
|
16
12
|
// src/cli.ts
|
|
17
13
|
import { join as join49 } from "path";
|
|
@@ -3529,6 +3525,7 @@ function buildCliSurface() {
|
|
|
3529
3525
|
memoryCmd2.command("topics").option("--project <slug>").option("--limit <n>").option("--wiki <name>");
|
|
3530
3526
|
memoryCmd2.command("index").requiredOption("--project <slug>").option("--check").option("--if-stale").option("--wiki <name>");
|
|
3531
3527
|
memoryCmd2.command("recall").requiredOption("--project <slug>").requiredOption("--topic <slug>").option("--scope <scope>").option("--limit <n>").option("--wiki <name>");
|
|
3528
|
+
memoryCmd2.command("review").requiredOption("--project <slug>").option("--dry-run").option("--wiki <name>");
|
|
3532
3529
|
memoryCmd2.command("import").requiredOption("--from <path>").requiredOption("--project <slug>").option("--dry-run").option("--apply").option("--max-bytes <n>").option("--wiki <name>");
|
|
3533
3530
|
const fleetCmd2 = program2.commands.find((c) => c.name() === "fleet");
|
|
3534
3531
|
fleetCmd2.command("validate");
|
|
@@ -9142,6 +9139,41 @@ async function runMemoryRecall(input) {
|
|
|
9142
9139
|
})
|
|
9143
9140
|
};
|
|
9144
9141
|
}
|
|
9142
|
+
async function runMemoryReview(input) {
|
|
9143
|
+
const scan = await scanVault(input.vault);
|
|
9144
|
+
if (!scan.ok) return { exitCode: ExitCode.VAULT_PATH_INVALID, result: scan };
|
|
9145
|
+
const state = await buildMemoryIndexState(scan.data.allMarkdown, input.project);
|
|
9146
|
+
const checked = await checkMemoryIndex(input.vault, input.project, state);
|
|
9147
|
+
if (!checked.ok) {
|
|
9148
|
+
return {
|
|
9149
|
+
exitCode: checked.error.exitCode,
|
|
9150
|
+
result: checked.error.result
|
|
9151
|
+
};
|
|
9152
|
+
}
|
|
9153
|
+
const findings = buildMemoryReviewFindings({
|
|
9154
|
+
project: input.project,
|
|
9155
|
+
status: checked.data,
|
|
9156
|
+
indexState: state,
|
|
9157
|
+
reviewPages: state.reviewPages
|
|
9158
|
+
});
|
|
9159
|
+
const generatedAt = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
9160
|
+
return {
|
|
9161
|
+
exitCode: ExitCode.OK,
|
|
9162
|
+
result: ok({
|
|
9163
|
+
project: input.project,
|
|
9164
|
+
generated_at: generatedAt,
|
|
9165
|
+
cache: {
|
|
9166
|
+
present: checked.data.cache_present,
|
|
9167
|
+
...checked.data.generated_at ? { generated_at: checked.data.generated_at } : {},
|
|
9168
|
+
stale: checked.data.stale,
|
|
9169
|
+
source_hash_mismatches: checked.data.drift.changed_sources
|
|
9170
|
+
},
|
|
9171
|
+
findings,
|
|
9172
|
+
files_written: [],
|
|
9173
|
+
humanHint: renderMemoryReviewHint(input.project, checked.data, findings)
|
|
9174
|
+
})
|
|
9175
|
+
};
|
|
9176
|
+
}
|
|
9145
9177
|
async function runMemoryImport(input) {
|
|
9146
9178
|
const scan = await scanVault(input.vault);
|
|
9147
9179
|
if (!scan.ok) return { exitCode: ExitCode.VAULT_PATH_INVALID, result: scan };
|
|
@@ -9201,14 +9233,18 @@ async function buildMemoryIndexState(pages, project) {
|
|
|
9201
9233
|
const warnings = [];
|
|
9202
9234
|
const sourcePages = dedupePages(pages);
|
|
9203
9235
|
const sources = [];
|
|
9236
|
+
const reviewPages = [];
|
|
9204
9237
|
for (const page of sourcePages) {
|
|
9205
|
-
const
|
|
9206
|
-
if (
|
|
9238
|
+
const memoryPage = await readMemoryPage(page, project, warnings);
|
|
9239
|
+
if (!memoryPage) continue;
|
|
9240
|
+
sources.push(memoryPage.source);
|
|
9241
|
+
if (memoryPage.reviewPage) reviewPages.push(memoryPage.reviewPage);
|
|
9207
9242
|
}
|
|
9208
9243
|
return {
|
|
9209
9244
|
sources,
|
|
9210
9245
|
topics: buildTopics(project, sources),
|
|
9211
|
-
warnings
|
|
9246
|
+
warnings,
|
|
9247
|
+
reviewPages
|
|
9212
9248
|
};
|
|
9213
9249
|
}
|
|
9214
9250
|
async function checkMemoryIndex(vault, project, current) {
|
|
@@ -9294,6 +9330,175 @@ function emptyMemoryIndexDrift() {
|
|
|
9294
9330
|
changed_sources: []
|
|
9295
9331
|
};
|
|
9296
9332
|
}
|
|
9333
|
+
async function readMemoryPage(page, project, warnings) {
|
|
9334
|
+
const text = await readPage(page);
|
|
9335
|
+
const fm = extractFrontmatter(text);
|
|
9336
|
+
if (!fm.ok) return null;
|
|
9337
|
+
const rawTopics = typeof fm.data.memory_topics === "string" ? [fm.data.memory_topics] : stringArray(fm.data.memory_topics);
|
|
9338
|
+
if (rawTopics.length === 0) return null;
|
|
9339
|
+
const topics = normalizeMemoryTopics(fm.data.memory_topics, page.relPath, warnings);
|
|
9340
|
+
if (topics.length === 0) return null;
|
|
9341
|
+
const scope = stringField2(fm.data.memory_scope);
|
|
9342
|
+
const projects = memoryProjects(page.relPath, fm.data);
|
|
9343
|
+
if (!projects.includes(project) && scope !== "global" && scope !== "cross-agent") return null;
|
|
9344
|
+
const privacy = stringField2(fm.data.memory_privacy) || "local";
|
|
9345
|
+
if (privacy === "secret-blocked") {
|
|
9346
|
+
warnings.push(`${page.relPath}: skipped secret-blocked memory`);
|
|
9347
|
+
return null;
|
|
9348
|
+
}
|
|
9349
|
+
const status = stringField2(fm.data.memory_status) || "active";
|
|
9350
|
+
if (status === "archived" || status === "rejected") return null;
|
|
9351
|
+
const metadataGaps = [];
|
|
9352
|
+
if (!scope) metadataGaps.push("memory_scope");
|
|
9353
|
+
if (!stringField2(fm.data.memory_policy)) metadataGaps.push("memory_policy");
|
|
9354
|
+
if (!stringField2(fm.data.memory_privacy)) metadataGaps.push("memory_privacy");
|
|
9355
|
+
if (!stringField2(fm.data.memory_status)) metadataGaps.push("memory_status");
|
|
9356
|
+
if (!stringField2(fm.data.last_seen) && !stringField2(fm.data.updated) && !stringField2(fm.data.ingested)) {
|
|
9357
|
+
metadataGaps.push("freshness");
|
|
9358
|
+
}
|
|
9359
|
+
const split = splitFrontmatter(text);
|
|
9360
|
+
const body = split.ok ? split.data.body : text;
|
|
9361
|
+
const updated = stringField2(fm.data.last_seen) || stringField2(fm.data.updated) || stringField2(fm.data.ingested) || dateFromPath2(page.relPath);
|
|
9362
|
+
const title = stringField2(fm.data.title) || page.relPath.split("/").pop()?.replace(/\.md$/, "") || page.relPath;
|
|
9363
|
+
return {
|
|
9364
|
+
source: {
|
|
9365
|
+
path: page.relPath,
|
|
9366
|
+
title,
|
|
9367
|
+
summary: summarize2(body),
|
|
9368
|
+
updated,
|
|
9369
|
+
hash: createHash8("sha256").update(Buffer.from(body, "utf8")).digest("hex"),
|
|
9370
|
+
topics,
|
|
9371
|
+
project,
|
|
9372
|
+
...stringField2(fm.data.memory_kind) ? { memory_kind: stringField2(fm.data.memory_kind) } : {},
|
|
9373
|
+
...scope ? { memory_scope: scope } : {},
|
|
9374
|
+
...stringField2(fm.data.memory_policy) ? { memory_policy: stringField2(fm.data.memory_policy) } : {},
|
|
9375
|
+
memory_privacy: privacy,
|
|
9376
|
+
memory_status: status
|
|
9377
|
+
},
|
|
9378
|
+
...metadataGaps.length > 0 ? {
|
|
9379
|
+
reviewPage: {
|
|
9380
|
+
path: page.relPath,
|
|
9381
|
+
metadataGaps
|
|
9382
|
+
}
|
|
9383
|
+
} : {}
|
|
9384
|
+
};
|
|
9385
|
+
}
|
|
9386
|
+
function buildMemoryReviewFindings(input) {
|
|
9387
|
+
const findings = [];
|
|
9388
|
+
if (!input.status.cache_present) {
|
|
9389
|
+
findings.push({
|
|
9390
|
+
id: `cache_missing:${input.project}`,
|
|
9391
|
+
severity: "warn",
|
|
9392
|
+
kind: "cache_missing",
|
|
9393
|
+
message: `memory cache for ${input.project} is missing`,
|
|
9394
|
+
suggested_action: `Run skillwiki memory index --project ${input.project} to build the local cache.`
|
|
9395
|
+
});
|
|
9396
|
+
} else if (input.status.stale) {
|
|
9397
|
+
findings.push({
|
|
9398
|
+
id: `cache_stale:${input.project}`,
|
|
9399
|
+
severity: "warn",
|
|
9400
|
+
kind: "cache_stale",
|
|
9401
|
+
message: `memory cache for ${input.project} is stale: ${input.status.drift.missing_sources.length} missing, ${input.status.drift.removed_sources.length} removed, ${input.status.drift.changed_sources.length} changed source(s)`,
|
|
9402
|
+
suggested_action: `Run skillwiki memory index --project ${input.project} or --if-stale to refresh the local cache.`
|
|
9403
|
+
});
|
|
9404
|
+
}
|
|
9405
|
+
for (const path of input.status.drift.changed_sources) {
|
|
9406
|
+
findings.push({
|
|
9407
|
+
id: `source_hash_drift:${path}`,
|
|
9408
|
+
severity: "warn",
|
|
9409
|
+
kind: "source_hash_drift",
|
|
9410
|
+
path,
|
|
9411
|
+
message: `${path} changed since the last cache build`,
|
|
9412
|
+
suggested_action: `Refresh the cache for ${input.project} and review whether the source summary still matches.`
|
|
9413
|
+
});
|
|
9414
|
+
}
|
|
9415
|
+
for (const warning of input.indexState.warnings) {
|
|
9416
|
+
const parsed = parseInvalidTopicWarning(warning);
|
|
9417
|
+
if (!parsed) continue;
|
|
9418
|
+
findings.push({
|
|
9419
|
+
id: `invalid_topic_slug:${parsed.path}:${parsed.topic}`,
|
|
9420
|
+
severity: "warn",
|
|
9421
|
+
kind: "invalid_topic_slug",
|
|
9422
|
+
path: parsed.path,
|
|
9423
|
+
topic: parsed.topic,
|
|
9424
|
+
message: `${parsed.path} declares invalid memory topic slug ${parsed.topic}`,
|
|
9425
|
+
suggested_action: "Normalize the topic slug to lowercase kebab-case so memory index and review can include it."
|
|
9426
|
+
});
|
|
9427
|
+
}
|
|
9428
|
+
for (const page of input.reviewPages) {
|
|
9429
|
+
if (page.metadataGaps.length === 0) continue;
|
|
9430
|
+
findings.push({
|
|
9431
|
+
id: `metadata_gap:${page.path}`,
|
|
9432
|
+
severity: "warn",
|
|
9433
|
+
kind: "metadata_gap",
|
|
9434
|
+
path: page.path,
|
|
9435
|
+
message: `${page.path} is missing explicit memory metadata: ${page.metadataGaps.join(", ")}`,
|
|
9436
|
+
suggested_action: "Add the missing frontmatter fields before relying on this source for cross-device memory review."
|
|
9437
|
+
});
|
|
9438
|
+
}
|
|
9439
|
+
const byTopic = groupSourcesByTopic(input.indexState.sources);
|
|
9440
|
+
for (const [topic, sources] of byTopic.entries()) {
|
|
9441
|
+
if (sources.length === 1) {
|
|
9442
|
+
findings.push({
|
|
9443
|
+
id: `sparse_topic:${topic}`,
|
|
9444
|
+
severity: "info",
|
|
9445
|
+
kind: "sparse_topic",
|
|
9446
|
+
topic,
|
|
9447
|
+
...sources[0]?.path ? { path: sources[0].path } : {},
|
|
9448
|
+
message: `topic ${topic} has only one active memory source`,
|
|
9449
|
+
suggested_action: "Decide whether the topic needs more coverage or should stay intentionally narrow."
|
|
9450
|
+
});
|
|
9451
|
+
}
|
|
9452
|
+
const hasProjectSource = sources.some((source) => isProjectMemorySource(source, input.project));
|
|
9453
|
+
const hasNonProjectScope = sources.some((source) => source.memory_scope === "global" || source.memory_scope === "cross-agent");
|
|
9454
|
+
if (hasProjectSource && hasNonProjectScope) {
|
|
9455
|
+
findings.push({
|
|
9456
|
+
id: `scope_gap:${topic}`,
|
|
9457
|
+
severity: "info",
|
|
9458
|
+
kind: "scope_gap",
|
|
9459
|
+
topic,
|
|
9460
|
+
message: `topic ${topic} mixes project and non-project memory scopes`,
|
|
9461
|
+
suggested_action: `Use skillwiki memory recall --project ${input.project} --topic ${topic} --scope <project|global|cross-agent|all> when reviewing this topic.`
|
|
9462
|
+
});
|
|
9463
|
+
}
|
|
9464
|
+
if (sources.length >= 3) {
|
|
9465
|
+
findings.push({
|
|
9466
|
+
id: `consolidation_candidate:${topic}`,
|
|
9467
|
+
severity: "info",
|
|
9468
|
+
kind: "consolidation_candidate",
|
|
9469
|
+
topic,
|
|
9470
|
+
message: `topic ${topic} has ${sources.length} active memory sources and may be ready for consolidation`,
|
|
9471
|
+
suggested_action: "Review this topic in office-hours or proj-distill before promoting or merging related memory pages."
|
|
9472
|
+
});
|
|
9473
|
+
}
|
|
9474
|
+
}
|
|
9475
|
+
return findings.sort(compareMemoryReviewFindings);
|
|
9476
|
+
}
|
|
9477
|
+
function parseInvalidTopicWarning(warning) {
|
|
9478
|
+
const match = warning.match(/^(.*): invalid memory topic slug (.+)$/);
|
|
9479
|
+
if (!match) return null;
|
|
9480
|
+
return {
|
|
9481
|
+
path: match[1] ?? "",
|
|
9482
|
+
topic: match[2] ?? ""
|
|
9483
|
+
};
|
|
9484
|
+
}
|
|
9485
|
+
function groupSourcesByTopic(sources) {
|
|
9486
|
+
const byTopic = /* @__PURE__ */ new Map();
|
|
9487
|
+
for (const source of sources) {
|
|
9488
|
+
for (const topic of source.topics) {
|
|
9489
|
+
const list = byTopic.get(topic) ?? [];
|
|
9490
|
+
list.push(source);
|
|
9491
|
+
byTopic.set(topic, list);
|
|
9492
|
+
}
|
|
9493
|
+
}
|
|
9494
|
+
return byTopic;
|
|
9495
|
+
}
|
|
9496
|
+
function compareMemoryReviewFindings(a, b) {
|
|
9497
|
+
return severityRank(b.severity) - severityRank(a.severity) || a.kind.localeCompare(b.kind) || (a.topic ?? "").localeCompare(b.topic ?? "") || (a.path ?? "").localeCompare(b.path ?? "") || a.id.localeCompare(b.id);
|
|
9498
|
+
}
|
|
9499
|
+
function severityRank(severity) {
|
|
9500
|
+
return severity === "warn" ? 2 : 1;
|
|
9501
|
+
}
|
|
9297
9502
|
function renderMemoryIndexStatusHint(status) {
|
|
9298
9503
|
if (!status.cache_present) {
|
|
9299
9504
|
return `memory index cache missing for ${status.project}; rebuild with memory index --project ${status.project}`;
|
|
@@ -9539,6 +9744,9 @@ function normalizeRecallScope(value) {
|
|
|
9539
9744
|
if (!value) return void 0;
|
|
9540
9745
|
return isRecallScope(value) ? value : void 0;
|
|
9541
9746
|
}
|
|
9747
|
+
function isValidMemoryTopicSlug(value) {
|
|
9748
|
+
return /^[a-z0-9][a-z0-9-]*$/.test(value);
|
|
9749
|
+
}
|
|
9542
9750
|
function isRecallScope(value) {
|
|
9543
9751
|
return value === "project" || value === "global" || value === "cross-agent" || value === "all";
|
|
9544
9752
|
}
|
|
@@ -9566,6 +9774,12 @@ function renderRecallHint(topic, sources) {
|
|
|
9566
9774
|
if (sources.length === 0) return `no memory sources found for topic ${topic}`;
|
|
9567
9775
|
return sources.map((source) => `${source.updated} ${source.title} (${source.path}) \u2014 ${source.summary}`).join("\n");
|
|
9568
9776
|
}
|
|
9777
|
+
function renderMemoryReviewHint(project, status, findings) {
|
|
9778
|
+
const warns = findings.filter((finding) => finding.severity === "warn").length;
|
|
9779
|
+
const infos = findings.length - warns;
|
|
9780
|
+
const cacheStatus = !status.cache_present ? "cache missing" : status.stale ? "cache stale" : "cache current";
|
|
9781
|
+
return `memory review for ${project}: ${findings.length} finding(s) (${warns} warn, ${infos} info); ${cacheStatus}`;
|
|
9782
|
+
}
|
|
9569
9783
|
function memoryCacheRelPath(project) {
|
|
9570
9784
|
return `.skillwiki/memory/${project}/topics.json`;
|
|
9571
9785
|
}
|
|
@@ -9586,46 +9800,11 @@ function dedupePages(pages) {
|
|
|
9586
9800
|
}
|
|
9587
9801
|
return out;
|
|
9588
9802
|
}
|
|
9589
|
-
async function readMemorySource(page, project, warnings) {
|
|
9590
|
-
const text = await readPage(page);
|
|
9591
|
-
const fm = extractFrontmatter(text);
|
|
9592
|
-
if (!fm.ok) return null;
|
|
9593
|
-
const topics = normalizeMemoryTopics(fm.data.memory_topics, page.relPath, warnings);
|
|
9594
|
-
if (topics.length === 0) return null;
|
|
9595
|
-
const projects = memoryProjects(page.relPath, fm.data);
|
|
9596
|
-
const scope = stringField2(fm.data.memory_scope);
|
|
9597
|
-
if (!projects.includes(project) && scope !== "global" && scope !== "cross-agent") return null;
|
|
9598
|
-
const privacy = stringField2(fm.data.memory_privacy) || "local";
|
|
9599
|
-
if (privacy === "secret-blocked") {
|
|
9600
|
-
warnings.push(`${page.relPath}: skipped secret-blocked memory`);
|
|
9601
|
-
return null;
|
|
9602
|
-
}
|
|
9603
|
-
const status = stringField2(fm.data.memory_status) || "active";
|
|
9604
|
-
if (status === "archived" || status === "rejected") return null;
|
|
9605
|
-
const split = splitFrontmatter(text);
|
|
9606
|
-
const body = split.ok ? split.data.body : text;
|
|
9607
|
-
const updated = stringField2(fm.data.last_seen) || stringField2(fm.data.updated) || stringField2(fm.data.ingested) || dateFromPath2(page.relPath);
|
|
9608
|
-
const title = stringField2(fm.data.title) || page.relPath.split("/").pop()?.replace(/\.md$/, "") || page.relPath;
|
|
9609
|
-
return {
|
|
9610
|
-
path: page.relPath,
|
|
9611
|
-
title,
|
|
9612
|
-
summary: summarize2(body),
|
|
9613
|
-
updated,
|
|
9614
|
-
hash: createHash8("sha256").update(Buffer.from(body, "utf8")).digest("hex"),
|
|
9615
|
-
topics,
|
|
9616
|
-
project,
|
|
9617
|
-
...stringField2(fm.data.memory_kind) ? { memory_kind: stringField2(fm.data.memory_kind) } : {},
|
|
9618
|
-
...scope ? { memory_scope: scope } : {},
|
|
9619
|
-
...stringField2(fm.data.memory_policy) ? { memory_policy: stringField2(fm.data.memory_policy) } : {},
|
|
9620
|
-
memory_privacy: privacy,
|
|
9621
|
-
memory_status: status
|
|
9622
|
-
};
|
|
9623
|
-
}
|
|
9624
9803
|
function normalizeMemoryTopics(value, path, warnings) {
|
|
9625
9804
|
const rawTopics = typeof value === "string" ? [value] : stringArray(value);
|
|
9626
9805
|
const topics = [];
|
|
9627
9806
|
for (const topic of rawTopics) {
|
|
9628
|
-
if (
|
|
9807
|
+
if (!isValidMemoryTopicSlug(topic)) {
|
|
9629
9808
|
warnings.push(`${path}: invalid memory topic slug ${topic}`);
|
|
9630
9809
|
continue;
|
|
9631
9810
|
}
|
|
@@ -10154,6 +10333,19 @@ ${body}`;
|
|
|
10154
10333
|
import { existsSync as existsSync17 } from "fs";
|
|
10155
10334
|
import { join as join42 } from "path";
|
|
10156
10335
|
|
|
10336
|
+
// src/utils/git.ts
|
|
10337
|
+
import { execFileSync } from "child_process";
|
|
10338
|
+
function git(cwd, args) {
|
|
10339
|
+
try {
|
|
10340
|
+
return execFileSync("git", args, { cwd, encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
10341
|
+
} catch {
|
|
10342
|
+
return "";
|
|
10343
|
+
}
|
|
10344
|
+
}
|
|
10345
|
+
function gitStrict(cwd, args) {
|
|
10346
|
+
return execFileSync("git", args, { cwd, encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
10347
|
+
}
|
|
10348
|
+
|
|
10157
10349
|
// src/utils/sync-lock.ts
|
|
10158
10350
|
import { existsSync as existsSync16, mkdirSync as mkdirSync6, readFileSync as readFileSync11, renameSync as renameSync2, unlinkSync as unlinkSync5, writeFileSync as writeFileSync7 } from "fs";
|
|
10159
10351
|
import { join as join41 } from "path";
|
|
@@ -10264,6 +10456,15 @@ var VAULT_GENERATED_COMMIT_EXCLUDES = [
|
|
|
10264
10456
|
...VAULT_GENERATED_COMMIT_PATHS.map((path) => `:!${path}`)
|
|
10265
10457
|
];
|
|
10266
10458
|
var VAULT_COMMIT_PATHSPEC = [".", ...VAULT_GENERATED_COMMIT_EXCLUDES];
|
|
10459
|
+
function stageVaultContentChanges(vault) {
|
|
10460
|
+
gitStrict(vault, ["add", "-A", "--", "."]);
|
|
10461
|
+
for (const generatedPath of VAULT_GENERATED_COMMIT_PATHS) {
|
|
10462
|
+
try {
|
|
10463
|
+
gitStrict(vault, ["reset", "HEAD", "--", generatedPath]);
|
|
10464
|
+
} catch (_e) {
|
|
10465
|
+
}
|
|
10466
|
+
}
|
|
10467
|
+
}
|
|
10267
10468
|
|
|
10268
10469
|
// src/commands/sync.ts
|
|
10269
10470
|
function runSyncStatus(input) {
|
|
@@ -10390,13 +10591,7 @@ async function runSyncPush(input) {
|
|
|
10390
10591
|
};
|
|
10391
10592
|
}
|
|
10392
10593
|
try {
|
|
10393
|
-
|
|
10394
|
-
for (const generatedPath of VAULT_GENERATED_COMMIT_PATHS) {
|
|
10395
|
-
try {
|
|
10396
|
-
gitStrict(vault, ["reset", "HEAD", "--", generatedPath]);
|
|
10397
|
-
} catch (_e) {
|
|
10398
|
-
}
|
|
10399
|
-
}
|
|
10594
|
+
stageVaultContentChanges(vault);
|
|
10400
10595
|
} catch (e) {
|
|
10401
10596
|
return {
|
|
10402
10597
|
exitCode: ExitCode.SYNC_PUSH_FAILED,
|
|
@@ -11383,15 +11578,8 @@ async function postCommit(vault, exitCode) {
|
|
|
11383
11578
|
if (lastOps.length === 0) return;
|
|
11384
11579
|
const porcelain = git(vault, ["status", "--porcelain", "--", ...VAULT_COMMIT_PATHSPEC]);
|
|
11385
11580
|
if (!porcelain || porcelain.trim().length === 0) return;
|
|
11386
|
-
const { gitStrict: gitStrict2 } = await import("./git-M4WGJ5G3.js");
|
|
11387
11581
|
try {
|
|
11388
|
-
|
|
11389
|
-
for (const generatedPath of VAULT_GENERATED_COMMIT_PATHS) {
|
|
11390
|
-
try {
|
|
11391
|
-
gitStrict2(vault, ["reset", "HEAD", "--", generatedPath]);
|
|
11392
|
-
} catch (_e) {
|
|
11393
|
-
}
|
|
11394
|
-
}
|
|
11582
|
+
stageVaultContentChanges(vault);
|
|
11395
11583
|
} catch (e) {
|
|
11396
11584
|
process.stderr.write(`auto-commit: git add failed: ${String(e)}
|
|
11397
11585
|
`);
|
|
@@ -11399,7 +11587,7 @@ async function postCommit(vault, exitCode) {
|
|
|
11399
11587
|
}
|
|
11400
11588
|
const commitMessage = lastOps.map((op) => `${op.operation}: ${op.summary} (${op.files.length} files)`).join("; ");
|
|
11401
11589
|
try {
|
|
11402
|
-
|
|
11590
|
+
gitStrict(vault, ["commit", "-m", commitMessage]);
|
|
11403
11591
|
} catch (e) {
|
|
11404
11592
|
process.stderr.write(`auto-commit: git commit failed: ${String(e)}
|
|
11405
11593
|
`);
|
|
@@ -11831,6 +12019,15 @@ memoryCmd.command("recall [vault]").description("recall bounded source summaries
|
|
|
11831
12019
|
limit: opts.limit
|
|
11832
12020
|
}), v.vault, { postCommit: false });
|
|
11833
12021
|
});
|
|
12022
|
+
memoryCmd.command("review [vault]").description("review deterministic memory gaps and cache drift without writing").requiredOption("--project <slug>", "project slug").option("--dry-run", "preview only; writes are not supported on this surface", false).option("--wiki <name>", "wiki profile name").action(async (vault, opts) => {
|
|
12023
|
+
const v = await resolveVaultArg(vault, opts.wiki);
|
|
12024
|
+
if (!v.ok) emit({ exitCode: v.exitCode, result: v.payload });
|
|
12025
|
+
else emit(await runMemoryReview({
|
|
12026
|
+
vault: v.vault,
|
|
12027
|
+
project: opts.project,
|
|
12028
|
+
dryRun: !!opts.dryRun
|
|
12029
|
+
}), v.vault, { postCommit: false });
|
|
12030
|
+
});
|
|
11834
12031
|
memoryCmd.command("import [vault]").description("preview or apply local memory imports into raw captures").requiredOption("--from <path>", "source file or directory to scan").requiredOption("--project <slug>", "project slug").option("--dry-run", "preview only; do not write captures", false).option("--apply", "write validated raw captures for ready entries", false).option("--max-bytes <n>", "reject source files above this size", (s) => parseInt(s, 10), 2e5).option("--wiki <name>", "wiki profile name").action(async (vault, opts) => {
|
|
11835
12032
|
const v = await resolveVaultArg(vault, opts.wiki);
|
|
11836
12033
|
if (!v.ok) emit({ exitCode: v.exitCode, result: v.payload });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillwiki",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.23",
|
|
4
4
|
"skills": "./",
|
|
5
5
|
"description": "Project-aware Karpathy-style knowledge base for Claude Code: 18 prompt-only skills (wiki-*, proj-*, using-skillwiki) backed by the deterministic `skillwiki` CLI.",
|
|
6
6
|
"author": {
|
package/skills/package.json
CHANGED
package/dist/chunk-TPS5XD2J.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/utils/git.ts
|
|
4
|
-
import { execFileSync } from "child_process";
|
|
5
|
-
function git(cwd, args) {
|
|
6
|
-
try {
|
|
7
|
-
return execFileSync("git", args, { cwd, encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
8
|
-
} catch {
|
|
9
|
-
return "";
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
function gitStrict(cwd, args) {
|
|
13
|
-
return execFileSync("git", args, { cwd, encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export {
|
|
17
|
-
git,
|
|
18
|
-
gitStrict
|
|
19
|
-
};
|