skillwiki 0.10.75 → 0.10.77
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-4XCBKPKD.js → chunk-5XT6MBWA.js} +3 -0
- package/dist/{chunk-WAUWBPIQ.js → chunk-CLF6DZ6C.js} +1 -1
- package/dist/cli.js +125 -5
- package/dist/{managed-write-preflight-KCFPPZNF.js → managed-write-preflight-LSG2Y24X.js} +1 -1
- package/dist/skillwiki-mcp.js +2 -2
- package/package.json +1 -1
- package/skills/.claude-plugin/plugin.json +1 -1
- package/skills/.codex-plugin/plugin.json +1 -1
- package/skills/.cursor-plugin/plugin.json +1 -1
- package/skills/agents/proj-init.md +2 -0
- package/skills/package.json +1 -1
- package/skills/proj-init/SKILL.md +7 -0
- package/skills/skills/proj-init/SKILL.md +7 -0
- package/skills/skills/skillwiki-mcp/SKILL.md +4 -1
- package/skills/skills/using-skillwiki/SKILL.md +3 -2
- package/skills/skills/using-skillwiki/activation.md +1 -1
- package/skills/skillwiki-mcp/SKILL.md +4 -1
- package/skills/using-skillwiki/SKILL.md +3 -2
- package/skills/using-skillwiki/activation.md +1 -1
|
@@ -3360,6 +3360,7 @@ function buildCliSurface() {
|
|
|
3360
3360
|
program.command("project-page");
|
|
3361
3361
|
program.command("write-preflight").option("--command <name>").option("--dirty-threshold <n>").option("--skip-dirty").option("--prior-artifact-file <path>").option("--prior-artifact-text <text>").option("--consecutive-no-decision <n>").option("--no-decision-threshold <n>").option("--human-allow").option("--mission-kind <kind>").option("--skip-mission").option("--project <slug>").option("--capture-day <date>").option("--capture-budget <n>").option("--severity <level>").option("--skip-budget").option("--checks <list>").option("--wiki <name>");
|
|
3362
3362
|
program.command("mcp");
|
|
3363
|
+
program.command("mcp-auth");
|
|
3363
3364
|
const graphCmd = program.commands.find((c) => c.name() === "graph");
|
|
3364
3365
|
graphCmd.command("build").option("--out <path>").option("--wiki <name>");
|
|
3365
3366
|
const vectorsCmd = program.commands.find((c) => c.name() === "vectors");
|
|
@@ -3436,6 +3437,8 @@ function buildCliSurface() {
|
|
|
3436
3437
|
fleetCmd.command("validate");
|
|
3437
3438
|
fleetCmd.command("context").option("--file <path>").option("--host-id <id>");
|
|
3438
3439
|
fleetCmd.command("health").option("--file <path>").option("--host-id <id>").option("--json");
|
|
3440
|
+
const mcpAuth = program.commands.find((c) => c.name() === "mcp-auth");
|
|
3441
|
+
mcpAuth.command("issue-host").requiredOption("--host-id <id>").option("--map <path>").option("--write");
|
|
3439
3442
|
const surface = /* @__PURE__ */ new Map();
|
|
3440
3443
|
const rootFlags = new Set(program.options.map((o) => o.long ?? o.short).filter((f) => f != null));
|
|
3441
3444
|
function walk(cmd, prefix, parentFlags) {
|
package/dist/cli.js
CHANGED
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
snapshotterHealthChecks,
|
|
51
51
|
upsertIndexEntry,
|
|
52
52
|
vectorIndexStatus
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-CLF6DZ6C.js";
|
|
54
54
|
import {
|
|
55
55
|
normalizeDistTag,
|
|
56
56
|
readCache,
|
|
@@ -151,7 +151,7 @@ import {
|
|
|
151
151
|
supersedeStaleReviewRequiredJournals,
|
|
152
152
|
taxonomyCommentForPage,
|
|
153
153
|
writeDotenv
|
|
154
|
-
} from "./chunk-
|
|
154
|
+
} from "./chunk-5XT6MBWA.js";
|
|
155
155
|
import {
|
|
156
156
|
assertTargetInsideVault,
|
|
157
157
|
atomicWriteText,
|
|
@@ -10293,8 +10293,119 @@ async function postCommit(vault, exitCode) {
|
|
|
10293
10293
|
clearLastOp(vault);
|
|
10294
10294
|
}
|
|
10295
10295
|
|
|
10296
|
+
// src/commands/mcp-auth.ts
|
|
10297
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync8 } from "fs";
|
|
10298
|
+
|
|
10299
|
+
// src/utils/mcp-token-map.ts
|
|
10300
|
+
import { createHash as createHash7, randomBytes } from "crypto";
|
|
10301
|
+
import yaml from "js-yaml";
|
|
10302
|
+
var HOST_ID_RE = /^[a-z][a-z0-9-]{1,62}$/;
|
|
10303
|
+
function parseMcpTokenMap(yamlText) {
|
|
10304
|
+
const parsed = yaml.load(yamlText);
|
|
10305
|
+
const map = /* @__PURE__ */ new Map();
|
|
10306
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
10307
|
+
return map;
|
|
10308
|
+
}
|
|
10309
|
+
const records = parsed;
|
|
10310
|
+
const nested = records.tokens;
|
|
10311
|
+
const source = nested && typeof nested === "object" && !Array.isArray(nested) ? nested : records;
|
|
10312
|
+
for (const [hash, hostId] of Object.entries(source)) {
|
|
10313
|
+
if (hash === "tokens") continue;
|
|
10314
|
+
if (typeof hostId !== "string" || hostId.length === 0) continue;
|
|
10315
|
+
const normalized = hash.trim().toLowerCase();
|
|
10316
|
+
if (!/^[0-9a-f]{64}$/.test(normalized)) continue;
|
|
10317
|
+
map.set(normalized, hostId);
|
|
10318
|
+
}
|
|
10319
|
+
return map;
|
|
10320
|
+
}
|
|
10321
|
+
function generateHostBearer(rng) {
|
|
10322
|
+
const bytes = (rng ?? (() => randomBytes(32)))();
|
|
10323
|
+
const raw = bytes.toString("base64url");
|
|
10324
|
+
const hashHex = createHash7("sha256").update(raw, "utf8").digest("hex");
|
|
10325
|
+
return { raw, hashHex };
|
|
10326
|
+
}
|
|
10327
|
+
function appendHostHash(yamlText, hashHex, hostId) {
|
|
10328
|
+
if (!HOST_ID_RE.test(hostId)) {
|
|
10329
|
+
return { error: "INVALID_HOST_ID" };
|
|
10330
|
+
}
|
|
10331
|
+
const map = parseMcpTokenMap(yamlText);
|
|
10332
|
+
const normalizedHash = hashHex.trim().toLowerCase();
|
|
10333
|
+
if ([...map.values()].includes(hostId)) {
|
|
10334
|
+
return { error: "DUPLICATE_HOST_ID" };
|
|
10335
|
+
}
|
|
10336
|
+
if (map.has(normalizedHash)) {
|
|
10337
|
+
return { error: "DUPLICATE_HASH" };
|
|
10338
|
+
}
|
|
10339
|
+
return { yaml: yamlText.replace(/\s*$/, "") + `
|
|
10340
|
+
${normalizedHash}: ${hostId}
|
|
10341
|
+
` };
|
|
10342
|
+
}
|
|
10343
|
+
|
|
10344
|
+
// src/commands/mcp-auth.ts
|
|
10345
|
+
function isEnoent(error) {
|
|
10346
|
+
return error.code === "ENOENT";
|
|
10347
|
+
}
|
|
10348
|
+
function preflight(error) {
|
|
10349
|
+
return { exitCode: ExitCode.PREFLIGHT_FAILED, result: err(error) };
|
|
10350
|
+
}
|
|
10351
|
+
async function runMcpAuthIssueHost(input) {
|
|
10352
|
+
const isTty = input.isTty ?? Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
10353
|
+
const readFile22 = input.readFile ?? readFileSync17;
|
|
10354
|
+
const writeFile10 = input.writeFile ?? writeFileSync8;
|
|
10355
|
+
const stderrWrite = input.stderrWrite ?? ((s) => {
|
|
10356
|
+
process.stderr.write(s);
|
|
10357
|
+
});
|
|
10358
|
+
const write = Boolean(input.write);
|
|
10359
|
+
const mapPath = input.mapPath;
|
|
10360
|
+
const hostId = input.hostId;
|
|
10361
|
+
if (!mapPath) return preflight("MAP_PATH_REQUIRED");
|
|
10362
|
+
if (!HOST_ID_RE.test(hostId)) return preflight("INVALID_HOST_ID");
|
|
10363
|
+
if (write && !isTty) return preflight("NO_TTY");
|
|
10364
|
+
let yamlText = "";
|
|
10365
|
+
try {
|
|
10366
|
+
yamlText = readFile22(mapPath, "utf8");
|
|
10367
|
+
} catch (error) {
|
|
10368
|
+
if (!isEnoent(error)) throw error;
|
|
10369
|
+
}
|
|
10370
|
+
const map = parseMcpTokenMap(yamlText);
|
|
10371
|
+
if ([...map.values()].includes(hostId)) return preflight("DUPLICATE_HOST_ID");
|
|
10372
|
+
if (!write) {
|
|
10373
|
+
return {
|
|
10374
|
+
exitCode: ExitCode.OK,
|
|
10375
|
+
result: ok({
|
|
10376
|
+
host_id: hostId,
|
|
10377
|
+
hash_prefix: "",
|
|
10378
|
+
map_path: mapPath,
|
|
10379
|
+
wrote: false
|
|
10380
|
+
})
|
|
10381
|
+
};
|
|
10382
|
+
}
|
|
10383
|
+
const { raw, hashHex } = generateHostBearer(input.rng);
|
|
10384
|
+
const appended = appendHostHash(yamlText, hashHex, hostId);
|
|
10385
|
+
if ("error" in appended) return preflight(appended.error);
|
|
10386
|
+
try {
|
|
10387
|
+
writeFile10(mapPath, appended.yaml, { encoding: "utf8", mode: 416 });
|
|
10388
|
+
} catch (error) {
|
|
10389
|
+
if (isEnoent(error)) {
|
|
10390
|
+
return { exitCode: ExitCode.FILE_NOT_FOUND, result: err("FILE_NOT_FOUND") };
|
|
10391
|
+
}
|
|
10392
|
+
throw error;
|
|
10393
|
+
}
|
|
10394
|
+
stderrWrite(`issued host_id=${hostId} copy once: ${raw}
|
|
10395
|
+
`);
|
|
10396
|
+
return {
|
|
10397
|
+
exitCode: ExitCode.OK,
|
|
10398
|
+
result: ok({
|
|
10399
|
+
host_id: hostId,
|
|
10400
|
+
hash_prefix: hashHex.slice(0, 8),
|
|
10401
|
+
map_path: mapPath,
|
|
10402
|
+
wrote: true
|
|
10403
|
+
})
|
|
10404
|
+
};
|
|
10405
|
+
}
|
|
10406
|
+
|
|
10296
10407
|
// src/commands/write-preflight.ts
|
|
10297
|
-
import { existsSync as existsSync15, readFileSync as
|
|
10408
|
+
import { existsSync as existsSync15, readFileSync as readFileSync18, statSync as statSync5 } from "fs";
|
|
10298
10409
|
async function runWritePreflightCommand(input) {
|
|
10299
10410
|
if (!existsSync15(input.vault) || !statSync5(input.vault).isDirectory()) {
|
|
10300
10411
|
return {
|
|
@@ -10310,7 +10421,7 @@ async function runWritePreflightCommand(input) {
|
|
|
10310
10421
|
result: err("FILE_NOT_FOUND", { path: input.priorArtifactFile })
|
|
10311
10422
|
};
|
|
10312
10423
|
}
|
|
10313
|
-
priorText =
|
|
10424
|
+
priorText = readFileSync18(input.priorArtifactFile, "utf8");
|
|
10314
10425
|
}
|
|
10315
10426
|
const checkList = input.checks ? input.checks.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
|
|
10316
10427
|
const result = runWritePreflight({
|
|
@@ -10431,7 +10542,7 @@ async function emitManagedVaultWrite(vault, command, mutate, opts) {
|
|
|
10431
10542
|
if (dirty) {
|
|
10432
10543
|
return emit(dirty, void 0, { postCommit: false });
|
|
10433
10544
|
}
|
|
10434
|
-
const { runManagedWriteTransaction: runManagedWriteTransaction2 } = await import("./managed-write-preflight-
|
|
10545
|
+
const { runManagedWriteTransaction: runManagedWriteTransaction2 } = await import("./managed-write-preflight-LSG2Y24X.js");
|
|
10435
10546
|
const run = await runManagedWriteTransaction2({
|
|
10436
10547
|
vault,
|
|
10437
10548
|
command,
|
|
@@ -11656,6 +11767,15 @@ vectorsCmd.command("prune-page [vault]").description("prune deleted pages from t
|
|
|
11656
11767
|
program.command("mcp").description("start stdio Model Context Protocol server (read-only vault tools)").action(async () => {
|
|
11657
11768
|
await runSkillwikiMcpStdio();
|
|
11658
11769
|
});
|
|
11770
|
+
var mcpAuthCmd = program.command("mcp-auth").description("attended HTTP MCP host-id bearer issuance (metal)");
|
|
11771
|
+
mcpAuthCmd.command("issue-host").description("append a host-id hash to the metal map; print raw once on a TTY").requiredOption("--host-id <id>", "host identity to bind").option("--map <path>", "hash map file (defaults to SKILLWIKI_MCP_TOKEN_MAP)").option("--write", "append the hash (default is dry-run)", false).action(async (opts) => {
|
|
11772
|
+
const mapPath = opts.map || process.env.SKILLWIKI_MCP_TOKEN_MAP || "";
|
|
11773
|
+
emit(await runMcpAuthIssueHost({
|
|
11774
|
+
hostId: String(opts.hostId),
|
|
11775
|
+
mapPath,
|
|
11776
|
+
write: !!opts.write
|
|
11777
|
+
}));
|
|
11778
|
+
});
|
|
11659
11779
|
for (const w of getDeprecatedWarnings(process.env.HOME ?? "")) {
|
|
11660
11780
|
process.stderr.write(w + "\n");
|
|
11661
11781
|
}
|
package/dist/skillwiki-mcp.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runSkillwikiMcpStdio
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CLF6DZ6C.js";
|
|
5
5
|
import "./chunk-7I2TPIV5.js";
|
|
6
6
|
import "./chunk-KFEOMMWK.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-5XT6MBWA.js";
|
|
8
8
|
import "./chunk-BPJ5KWIT.js";
|
|
9
9
|
import "./chunk-NPTIYO2S.js";
|
|
10
10
|
import "./chunk-OMO45AHI.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillwiki",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.77",
|
|
4
4
|
"skills": "./",
|
|
5
5
|
"description": "Project-aware Karpathy-style knowledge base for Claude Code: 21 prompt-only skills (wiki-*, proj-*, using-skillwiki, skillwiki-mcp) backed by the deterministic `skillwiki` CLI.",
|
|
6
6
|
"author": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillwiki",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.77",
|
|
4
4
|
"description": "Project-aware Karpathy-style knowledge base: 21 prompt-only skills (wiki-*, proj-*, using-skillwiki, skillwiki-mcp) backed by HTTP MCP wiki_capture.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "karlorz"
|
|
@@ -20,6 +20,8 @@ You are a project workspace bootstrapper specializing in creating the `projects/
|
|
|
20
20
|
3. Render README.md from template
|
|
21
21
|
4. Update vault index.md and log.md
|
|
22
22
|
|
|
23
|
+
**Leaf-host rule (HTTP MCP):** If `$VAULT/.WIKI_GIT_FROZEN` exists, do not local-write. Bootstrap via MCP `wiki_workitem_write` (workspace families: `projects/{slug}/README.md`, `architecture/**`, `requirements/**`, `compound/**` — `.md` only; omit `base_sha256` on create). Use at most `wiki_log_append` for the log entry; never edit `index.md` locally on a leaf. If `wiki_workitem_write` is absent or the deployed server predates the workspace-family allowlist (`PATH_DENIED`), STOP — never rclone/wiki-push.
|
|
24
|
+
|
|
23
25
|
**Execution Process:**
|
|
24
26
|
|
|
25
27
|
1. **Resolve vault.** Run `skillwiki path`. If NO_VAULT_CONFIGURED, report failure and STOP.
|
package/skills/package.json
CHANGED
|
@@ -22,8 +22,15 @@ Standard four reads (vault SCHEMA, index, log) — no project context yet.
|
|
|
22
22
|
4. Update vault `index.md` "Projects" section: add `- [[projects/{slug}]]`.
|
|
23
23
|
5. Append vault `log.md` entry: "Project {slug} initialized."
|
|
24
24
|
|
|
25
|
+
## Leaf hosts (HTTP MCP)
|
|
26
|
+
On a leaf host (vault has `.WIKI_GIT_FROZEN` or the HTTP MCP server is the writer), bootstrap goes through MCP instead of local file creation:
|
|
27
|
+
- Write `projects/{slug}/README.md` and any initial `requirements/` or `architecture/` markdown via `wiki_workitem_write` (CAS: omit `base_sha256` on create). Directories materialize implicitly with the first file.
|
|
28
|
+
- The `index.md` "Projects" line and the structural log stay projection/snapshotter-owned: use at most `wiki_log_append` for the init entry. Never edit `index.md` locally on a leaf.
|
|
29
|
+
- If `wiki_workitem_write` is absent from the live tool list or the deployed server predates the workspace-family allowlist (`PATH_DENIED`), STOP — do not local-write, rclone, or wiki-push.
|
|
30
|
+
|
|
25
31
|
## Stop conditions
|
|
26
32
|
- `projects/{slug}/` already exists.
|
|
33
|
+
- Leaf host without a usable `wiki_workitem_write` (fail closed; capture the intent via `wiki_capture` instead).
|
|
27
34
|
|
|
28
35
|
## Forbidden
|
|
29
36
|
- Modifying any other project's files.
|
|
@@ -22,8 +22,15 @@ Standard four reads (vault SCHEMA, index, log) — no project context yet.
|
|
|
22
22
|
4. Update vault `index.md` "Projects" section: add `- [[projects/{slug}]]`.
|
|
23
23
|
5. Append vault `log.md` entry: "Project {slug} initialized."
|
|
24
24
|
|
|
25
|
+
## Leaf hosts (HTTP MCP)
|
|
26
|
+
On a leaf host (vault has `.WIKI_GIT_FROZEN` or the HTTP MCP server is the writer), bootstrap goes through MCP instead of local file creation:
|
|
27
|
+
- Write `projects/{slug}/README.md` and any initial `requirements/` or `architecture/` markdown via `wiki_workitem_write` (CAS: omit `base_sha256` on create). Directories materialize implicitly with the first file.
|
|
28
|
+
- The `index.md` "Projects" line and the structural log stay projection/snapshotter-owned: use at most `wiki_log_append` for the init entry. Never edit `index.md` locally on a leaf.
|
|
29
|
+
- If `wiki_workitem_write` is absent from the live tool list or the deployed server predates the workspace-family allowlist (`PATH_DENIED`), STOP — do not local-write, rclone, or wiki-push.
|
|
30
|
+
|
|
25
31
|
## Stop conditions
|
|
26
32
|
- `projects/{slug}/` already exists.
|
|
33
|
+
- Leaf host without a usable `wiki_workitem_write` (fail closed; capture the intent via `wiki_capture` instead).
|
|
27
34
|
|
|
28
35
|
## Forbidden
|
|
29
36
|
- Modifying any other project's files.
|
|
@@ -16,6 +16,8 @@ SkillWiki captures are HTTP MCP only (`type: http`). Claude/Grok use `SKILLWIKI_
|
|
|
16
16
|
- Resolve the installed plugin root from `GROK_PLUGIN_ROOT`, falling back to `CLAUDE_PLUGIN_ROOT`, and run `python3 "$PLUGIN_ROOT/scripts/check_readiness.py" --apply --json` before the first SkillWiki MCP call.
|
|
17
17
|
- **Cursor / Grok Bot:** the Cursor-native plugin requires `SKILLWIKI_MCP_TOKEN` under **Plugins → Configure**. It pins `https://wiki.karldigi.dev/mcp`. Grok Bot does not inherit Mac process env or `~/.cursor/mcp.json`. `failed_to_load` with no token box means this package is missing; after this package is installed, Configure is the token field (same pattern as grok-search).
|
|
18
18
|
- `missing_prereq` means `SKILLWIKI_MCP_TOKEN` is absent from process environment; stop and ask for a bearer. Do not invent a stdio MCP.
|
|
19
|
+
- A new host (a machine that should write the wiki for the first time) needs an issued host-id bearer before handshake can pass. The operator runs `skillwiki mcp-auth issue-host --host-id <id> --write` on metal (TTY required). The client pastes the printed value into process env or host Configure. Do not auto-write `mcp.env`, `mcp.json`, or Grok `config.toml`. Do not invent a second admin skill. A local vault/FUSE mirror is optional.
|
|
20
|
+
- First-run order: install plugin/CLI → operator issues on metal → paste into process env or Configure → **new session** → `skillwiki doctor --check-mcp` → one write (`wiki_capture`, work-item write, or page publish).
|
|
19
21
|
- `in_sync` means the probe has a usable URL/token decision.
|
|
20
22
|
- A 401 is an MCP handshake failure, not a readiness-probe status. Report that the token is missing or rejected and stop.
|
|
21
23
|
- Grok SessionStart cannot inject the parent MCP environment. A restart cannot supply a missing token.
|
|
@@ -33,9 +35,10 @@ On leaf hosts, wiki captures go through MCP. Do **not** write `raw/transcripts/`
|
|
|
33
35
|
1. Call MCP `wiki_capture` with `kind` (`task` | `idea` | `bug` | `note`), `project`, `title`, and `content`. Optional `agent_note`.
|
|
34
36
|
2. Call MCP `wiki_log_append` when a structural `log.md` line is needed. Pass append-only `content`. Do not rewrite log history.
|
|
35
37
|
3. **Feature-detect work-item and page-publish tools**:
|
|
36
|
-
- When the server advertises `wiki_workitem_write`: use it to create, mutate, or close work items under `projects/<slug>/work/**` or update `projects/<slug>/knowledge.md`. Pass `path`, `content`, and `base_sha256` of existing bytes (from `wiki_read_page` or local mirror). On `FILE_CHANGED`, re-read and retry once.
|
|
38
|
+
- When the server advertises `wiki_workitem_write`: use it to create, mutate, or close work items under `projects/<slug>/work/**` or update `projects/<slug>/knowledge.md`, and to save Layer-3 workspace markdown: `projects/<slug>/README.md`, `projects/<slug>/architecture/**/*.md`, `projects/<slug>/requirements/**/*.md`, `projects/<slug>/compound/**/*.md`. Pass `path`, `content`, and `base_sha256` of existing bytes (from `wiki_read_page` or local mirror). On `FILE_CHANGED`, re-read and retry once. Deployed servers that predate the workspace-family allowlist deny those paths — treat that `PATH_DENIED` as "server predates this release"; STOP, do not fall back.
|
|
37
39
|
- When the server advertises `wiki_page_publish`: use it to publish typed Layer-2 pages (`entities/`, `concepts/`, `comparisons/`, `queries/`, `meta/`) using the same CAS protocol.
|
|
38
40
|
- When those tools are **absent** from the live tool list (e.g. server is captures-only): do not call them or claim they exist. If `$VAULT/.WIKI_GIT_FROZEN` exists, fall back to capturing a close note via `wiki_capture` or STOP. Work-item close remains unavailable on the frozen leaf without `wiki_workitem_write`. Do not `git commit` / `wiki-push` against `~/wiki`.
|
|
41
|
+
4. **`PATH_DENIED` means STOP.** Paths outside the allowlist (`projects/<slug>/history/**`, non-`.md` files such as `fleet.yaml` or `.canvas`, `AGENTS.md`/`CLAUDE.md`, raw edits, index/projection rebuilds) have no agent write path over MCP. wiki-push / `rclone copy` is **not** an agent writer: it bypasses the daemon working copy, so `wiki_read_page` cannot see those bytes until the sg01 snapshot. Never report an S3-only copy as "saved to wiki". Capture the blocked intent via `wiki_capture` and report the denial instead.
|
|
39
42
|
|
|
40
43
|
## Reads
|
|
41
44
|
|
|
@@ -171,6 +171,7 @@ If the vault has `.WIKI_GIT_FROZEN`:
|
|
|
171
171
|
|---|---|---|
|
|
172
172
|
| Capture note/idea/bug/task | Yes | HTTP MCP `wiki_capture` / `wiki_log_append` |
|
|
173
173
|
| Close or mutate a work item (`projects/*/work/**`, `knowledge.md`) | Conditional | If live MCP tools include `wiki_workitem_write`, mutate/close via MCP CAS; if absent, capture a close note via MCP `wiki_capture` or STOP. Never local-write. |
|
|
174
|
+
| Save project workspace file (`architecture/`, `README.md`, `requirements/`, `compound/` — `.md` only) | Conditional | Via `wiki_workitem_write` CAS. Feature-detect: if the tool is absent or the deployed server predates the workspace-family allowlist (`PATH_DENIED`), STOP. Never rclone/wiki-push as a fallback writer. |
|
|
174
175
|
| Publish typed Layer-2 page (`concepts/`, `queries/`, etc.) | Conditional | If live MCP tools include `wiki_page_publish`, publish via MCP CAS; if absent, STOP. Do not run local `skillwiki page publish`. |
|
|
175
176
|
| `wiki-sync` push/commit | **No** | Git fail-closed. GitHub is sg01 `wiki-snapshot`. |
|
|
176
177
|
| Read local `~/wiki` | Yes | Mirror reads only |
|
|
@@ -242,11 +243,11 @@ for code changes.
|
|
|
242
243
|
|
|
243
244
|
## CLI Backbone
|
|
244
245
|
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.
|
|
245
|
-
Key CLI subcommands: `init`, `health`, `lint`, `config`, `doctor`, `path`, `lang`, `install`, `fleet context`, `fleet validate`, `graph build`, `query`, `vectors rebuild`, `vectors status`, `sources pending`, `sources compile`, `sources review`, `sources reviews`, `sources disposition`, `sources dispose`, `archive`, `remove`, `drift`, `dedup`, `compound`, `tag-sync`, `tag reconcile`, `page publish`, `sync status`, `seed`, `stale`, `claim`, `claims audit`, `observe`, `canvas generate`, `mcp`.
|
|
246
|
+
Key CLI subcommands: `init`, `health`, `lint`, `config`, `doctor`, `path`, `lang`, `install`, `fleet context`, `fleet validate`, `graph build`, `query`, `vectors rebuild`, `vectors status`, `sources pending`, `sources compile`, `sources review`, `sources reviews`, `sources disposition`, `sources dispose`, `archive`, `remove`, `drift`, `dedup`, `compound`, `tag-sync`, `tag reconcile`, `page publish`, `sync status`, `seed`, `stale`, `claim`, `claims audit`, `observe`, `canvas generate`, `mcp`, `mcp-auth`.
|
|
246
247
|
Optional read-only MCP (`skillwiki mcp`) exposes pending/compile/review list tools. Do not use MCP for compile claim, publish, or review writes.
|
|
247
248
|
`skillwiki claim` binds a transcript to a work item only through an exact `raw/transcripts/...` path in `source:` / `sources:` / `closes:`. A `--project` that contradicts the capture's explicit project is rejected. `skillwiki stale --project` uses exact normalized slugs, not substring matching. `skillwiki claims audit` is the read-only integrity report for duplicate, malformed, dangling, cross-project, and unbacked claims; it never rewrites captures or work items.
|
|
248
249
|
|
|
249
|
-
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, including HTTP MCP URL/auth presence and the frozen-leaf write path. Pass `--check-mcp` for a live initialize handshake and pin/tool-list lag; the default doctor path does not contact HTTP MCP. There is no second MCP admin skill. Run `skillwiki config list` to see current configuration.
|
|
250
|
+
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, including HTTP MCP URL/auth presence and the frozen-leaf write path. Pass `--check-mcp` for a live initialize handshake and pin/tool-list lag; the default doctor path does not contact HTTP MCP. New hosts need an issued host-id bearer from metal `skillwiki mcp-auth issue-host` before handshake can pass. There is no second MCP admin skill. Run `skillwiki config list` to see current configuration.
|
|
250
251
|
|
|
251
252
|
## Runtime Host Context and Fleet Freshness
|
|
252
253
|
Resolve the active project vault with `skillwiki path` first. Then pass that exact path to `skillwiki --human fleet context <vault>` for host identity and safety guidance. `fleet context` is authoritative for host identity. It overrides stale injected SessionStart context, remembered workspace context, and prior conversation summaries. `fleet context` is local and network-free; it reports `identity_status`, resolver trace, warnings, and the fact that remote freshness was not checked.
|
|
@@ -55,7 +55,7 @@ separate concerns.
|
|
|
55
55
|
|
|
56
56
|
## Fail-Closed Boundary
|
|
57
57
|
|
|
58
|
-
Never write typed pages, `index.md`, or `log.md` directly. On leaf hosts, captures use HTTP MCP (`wiki_capture`), never local `raw/transcripts` or `log.md` writes. 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.
|
|
58
|
+
Never write typed pages, `index.md`, or `log.md` directly. On leaf hosts, captures use HTTP MCP (`wiki_capture`), never local `raw/transcripts` or `log.md` writes. Project workspace saves (`projects/<slug>/README.md`, `architecture/`, `requirements/`, `compound/` — `.md` only) go through MCP `wiki_workitem_write` CAS; feature-detect and STOP if the tool is absent or the deployed server predates the workspace-family allowlist (`PATH_DENIED`). wiki-push / rclone is never an agent writer — an S3-only copy is invisible to `wiki_read_page` until the sg01 snapshot; never report it as "saved to wiki". 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.
|
|
59
59
|
|
|
60
60
|
## Sensitive Content
|
|
61
61
|
|
|
@@ -16,6 +16,8 @@ SkillWiki captures are HTTP MCP only (`type: http`). Claude/Grok use `SKILLWIKI_
|
|
|
16
16
|
- Resolve the installed plugin root from `GROK_PLUGIN_ROOT`, falling back to `CLAUDE_PLUGIN_ROOT`, and run `python3 "$PLUGIN_ROOT/scripts/check_readiness.py" --apply --json` before the first SkillWiki MCP call.
|
|
17
17
|
- **Cursor / Grok Bot:** the Cursor-native plugin requires `SKILLWIKI_MCP_TOKEN` under **Plugins → Configure**. It pins `https://wiki.karldigi.dev/mcp`. Grok Bot does not inherit Mac process env or `~/.cursor/mcp.json`. `failed_to_load` with no token box means this package is missing; after this package is installed, Configure is the token field (same pattern as grok-search).
|
|
18
18
|
- `missing_prereq` means `SKILLWIKI_MCP_TOKEN` is absent from process environment; stop and ask for a bearer. Do not invent a stdio MCP.
|
|
19
|
+
- A new host (a machine that should write the wiki for the first time) needs an issued host-id bearer before handshake can pass. The operator runs `skillwiki mcp-auth issue-host --host-id <id> --write` on metal (TTY required). The client pastes the printed value into process env or host Configure. Do not auto-write `mcp.env`, `mcp.json`, or Grok `config.toml`. Do not invent a second admin skill. A local vault/FUSE mirror is optional.
|
|
20
|
+
- First-run order: install plugin/CLI → operator issues on metal → paste into process env or Configure → **new session** → `skillwiki doctor --check-mcp` → one write (`wiki_capture`, work-item write, or page publish).
|
|
19
21
|
- `in_sync` means the probe has a usable URL/token decision.
|
|
20
22
|
- A 401 is an MCP handshake failure, not a readiness-probe status. Report that the token is missing or rejected and stop.
|
|
21
23
|
- Grok SessionStart cannot inject the parent MCP environment. A restart cannot supply a missing token.
|
|
@@ -33,9 +35,10 @@ On leaf hosts, wiki captures go through MCP. Do **not** write `raw/transcripts/`
|
|
|
33
35
|
1. Call MCP `wiki_capture` with `kind` (`task` | `idea` | `bug` | `note`), `project`, `title`, and `content`. Optional `agent_note`.
|
|
34
36
|
2. Call MCP `wiki_log_append` when a structural `log.md` line is needed. Pass append-only `content`. Do not rewrite log history.
|
|
35
37
|
3. **Feature-detect work-item and page-publish tools**:
|
|
36
|
-
- When the server advertises `wiki_workitem_write`: use it to create, mutate, or close work items under `projects/<slug>/work/**` or update `projects/<slug>/knowledge.md`. Pass `path`, `content`, and `base_sha256` of existing bytes (from `wiki_read_page` or local mirror). On `FILE_CHANGED`, re-read and retry once.
|
|
38
|
+
- When the server advertises `wiki_workitem_write`: use it to create, mutate, or close work items under `projects/<slug>/work/**` or update `projects/<slug>/knowledge.md`, and to save Layer-3 workspace markdown: `projects/<slug>/README.md`, `projects/<slug>/architecture/**/*.md`, `projects/<slug>/requirements/**/*.md`, `projects/<slug>/compound/**/*.md`. Pass `path`, `content`, and `base_sha256` of existing bytes (from `wiki_read_page` or local mirror). On `FILE_CHANGED`, re-read and retry once. Deployed servers that predate the workspace-family allowlist deny those paths — treat that `PATH_DENIED` as "server predates this release"; STOP, do not fall back.
|
|
37
39
|
- When the server advertises `wiki_page_publish`: use it to publish typed Layer-2 pages (`entities/`, `concepts/`, `comparisons/`, `queries/`, `meta/`) using the same CAS protocol.
|
|
38
40
|
- When those tools are **absent** from the live tool list (e.g. server is captures-only): do not call them or claim they exist. If `$VAULT/.WIKI_GIT_FROZEN` exists, fall back to capturing a close note via `wiki_capture` or STOP. Work-item close remains unavailable on the frozen leaf without `wiki_workitem_write`. Do not `git commit` / `wiki-push` against `~/wiki`.
|
|
41
|
+
4. **`PATH_DENIED` means STOP.** Paths outside the allowlist (`projects/<slug>/history/**`, non-`.md` files such as `fleet.yaml` or `.canvas`, `AGENTS.md`/`CLAUDE.md`, raw edits, index/projection rebuilds) have no agent write path over MCP. wiki-push / `rclone copy` is **not** an agent writer: it bypasses the daemon working copy, so `wiki_read_page` cannot see those bytes until the sg01 snapshot. Never report an S3-only copy as "saved to wiki". Capture the blocked intent via `wiki_capture` and report the denial instead.
|
|
39
42
|
|
|
40
43
|
## Reads
|
|
41
44
|
|
|
@@ -171,6 +171,7 @@ If the vault has `.WIKI_GIT_FROZEN`:
|
|
|
171
171
|
|---|---|---|
|
|
172
172
|
| Capture note/idea/bug/task | Yes | HTTP MCP `wiki_capture` / `wiki_log_append` |
|
|
173
173
|
| Close or mutate a work item (`projects/*/work/**`, `knowledge.md`) | Conditional | If live MCP tools include `wiki_workitem_write`, mutate/close via MCP CAS; if absent, capture a close note via MCP `wiki_capture` or STOP. Never local-write. |
|
|
174
|
+
| Save project workspace file (`architecture/`, `README.md`, `requirements/`, `compound/` — `.md` only) | Conditional | Via `wiki_workitem_write` CAS. Feature-detect: if the tool is absent or the deployed server predates the workspace-family allowlist (`PATH_DENIED`), STOP. Never rclone/wiki-push as a fallback writer. |
|
|
174
175
|
| Publish typed Layer-2 page (`concepts/`, `queries/`, etc.) | Conditional | If live MCP tools include `wiki_page_publish`, publish via MCP CAS; if absent, STOP. Do not run local `skillwiki page publish`. |
|
|
175
176
|
| `wiki-sync` push/commit | **No** | Git fail-closed. GitHub is sg01 `wiki-snapshot`. |
|
|
176
177
|
| Read local `~/wiki` | Yes | Mirror reads only |
|
|
@@ -242,11 +243,11 @@ for code changes.
|
|
|
242
243
|
|
|
243
244
|
## CLI Backbone
|
|
244
245
|
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.
|
|
245
|
-
Key CLI subcommands: `init`, `health`, `lint`, `config`, `doctor`, `path`, `lang`, `install`, `fleet context`, `fleet validate`, `graph build`, `query`, `vectors rebuild`, `vectors status`, `sources pending`, `sources compile`, `sources review`, `sources reviews`, `sources disposition`, `sources dispose`, `archive`, `remove`, `drift`, `dedup`, `compound`, `tag-sync`, `tag reconcile`, `page publish`, `sync status`, `seed`, `stale`, `claim`, `claims audit`, `observe`, `canvas generate`, `mcp`.
|
|
246
|
+
Key CLI subcommands: `init`, `health`, `lint`, `config`, `doctor`, `path`, `lang`, `install`, `fleet context`, `fleet validate`, `graph build`, `query`, `vectors rebuild`, `vectors status`, `sources pending`, `sources compile`, `sources review`, `sources reviews`, `sources disposition`, `sources dispose`, `archive`, `remove`, `drift`, `dedup`, `compound`, `tag-sync`, `tag reconcile`, `page publish`, `sync status`, `seed`, `stale`, `claim`, `claims audit`, `observe`, `canvas generate`, `mcp`, `mcp-auth`.
|
|
246
247
|
Optional read-only MCP (`skillwiki mcp`) exposes pending/compile/review list tools. Do not use MCP for compile claim, publish, or review writes.
|
|
247
248
|
`skillwiki claim` binds a transcript to a work item only through an exact `raw/transcripts/...` path in `source:` / `sources:` / `closes:`. A `--project` that contradicts the capture's explicit project is rejected. `skillwiki stale --project` uses exact normalized slugs, not substring matching. `skillwiki claims audit` is the read-only integrity report for duplicate, malformed, dangling, cross-project, and unbacked claims; it never rewrites captures or work items.
|
|
248
249
|
|
|
249
|
-
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, including HTTP MCP URL/auth presence and the frozen-leaf write path. Pass `--check-mcp` for a live initialize handshake and pin/tool-list lag; the default doctor path does not contact HTTP MCP. There is no second MCP admin skill. Run `skillwiki config list` to see current configuration.
|
|
250
|
+
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, including HTTP MCP URL/auth presence and the frozen-leaf write path. Pass `--check-mcp` for a live initialize handshake and pin/tool-list lag; the default doctor path does not contact HTTP MCP. New hosts need an issued host-id bearer from metal `skillwiki mcp-auth issue-host` before handshake can pass. There is no second MCP admin skill. Run `skillwiki config list` to see current configuration.
|
|
250
251
|
|
|
251
252
|
## Runtime Host Context and Fleet Freshness
|
|
252
253
|
Resolve the active project vault with `skillwiki path` first. Then pass that exact path to `skillwiki --human fleet context <vault>` for host identity and safety guidance. `fleet context` is authoritative for host identity. It overrides stale injected SessionStart context, remembered workspace context, and prior conversation summaries. `fleet context` is local and network-free; it reports `identity_status`, resolver trace, warnings, and the fact that remote freshness was not checked.
|
|
@@ -55,7 +55,7 @@ separate concerns.
|
|
|
55
55
|
|
|
56
56
|
## Fail-Closed Boundary
|
|
57
57
|
|
|
58
|
-
Never write typed pages, `index.md`, or `log.md` directly. On leaf hosts, captures use HTTP MCP (`wiki_capture`), never local `raw/transcripts` or `log.md` writes. 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.
|
|
58
|
+
Never write typed pages, `index.md`, or `log.md` directly. On leaf hosts, captures use HTTP MCP (`wiki_capture`), never local `raw/transcripts` or `log.md` writes. Project workspace saves (`projects/<slug>/README.md`, `architecture/`, `requirements/`, `compound/` — `.md` only) go through MCP `wiki_workitem_write` CAS; feature-detect and STOP if the tool is absent or the deployed server predates the workspace-family allowlist (`PATH_DENIED`). wiki-push / rclone is never an agent writer — an S3-only copy is invisible to `wiki_read_page` until the sg01 snapshot; never report it as "saved to wiki". 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.
|
|
59
59
|
|
|
60
60
|
## Sensitive Content
|
|
61
61
|
|