skillwiki 0.10.79 → 0.10.81

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.
@@ -40,7 +40,7 @@ import {
40
40
  snapshotterAliasForLocalHost,
41
41
  toUndirectedWeighted,
42
42
  writeDotenv
43
- } from "./chunk-5XT6MBWA.js";
43
+ } from "./chunk-GPUK2IAW.js";
44
44
  import {
45
45
  atomicWriteText,
46
46
  prepareTypedPage
@@ -1125,8 +1125,46 @@ function findPluginInstallations(home, key = PLUGIN_KEY) {
1125
1125
  }
1126
1126
  const codexPlugin = findCodexPlugin(home, key, parsed.pluginName, parsed.marketplace);
1127
1127
  if (codexPlugin) installs.push(codexPlugin);
1128
+ const grokPlugin = findGrokPlugin(home, key, parsed.pluginName, parsed.marketplace);
1129
+ if (grokPlugin) installs.push(grokPlugin);
1128
1130
  return installs;
1129
1131
  }
1132
+ function findGrokPlugin(home, key, pluginName, marketplace) {
1133
+ const pluginsRoot = join6(home, ".grok", "installed-plugins");
1134
+ if (!existsSync3(pluginsRoot)) return null;
1135
+ let entries;
1136
+ try {
1137
+ entries = readdirSync(pluginsRoot, { withFileTypes: true });
1138
+ } catch {
1139
+ return null;
1140
+ }
1141
+ let best = null;
1142
+ for (const entry of entries) {
1143
+ if (!entry.isDirectory()) continue;
1144
+ const installPath = join6(pluginsRoot, entry.name);
1145
+ let manifest;
1146
+ try {
1147
+ manifest = JSON.parse(readFileSync2(join6(installPath, ".claude-plugin", "plugin.json"), "utf8"));
1148
+ } catch {
1149
+ continue;
1150
+ }
1151
+ if (manifest.name !== pluginName) continue;
1152
+ if (typeof manifest.version !== "string" || manifest.version.length === 0) continue;
1153
+ const candidate = {
1154
+ channel: "grok",
1155
+ label: "Grok",
1156
+ key,
1157
+ pluginName,
1158
+ marketplace,
1159
+ installPath,
1160
+ version: manifest.version
1161
+ };
1162
+ if (!best || semverGt(candidate.version, best.version)) {
1163
+ best = candidate;
1164
+ }
1165
+ }
1166
+ return best;
1167
+ }
1130
1168
  function findCodexPlugin(home, key, pluginName, marketplace) {
1131
1169
  const config = readCodexPluginConfig(home, key, marketplace);
1132
1170
  if (!config?.enabled) return null;
@@ -2676,6 +2714,9 @@ function pluginUpdateCommand(plugin, currentVersion) {
2676
2714
  if (plugin.channel === "claude") {
2677
2715
  return "claude plugin update skillwiki@llm-wiki";
2678
2716
  }
2717
+ if (plugin.channel === "grok") {
2718
+ return "grok plugin update skillwiki";
2719
+ }
2679
2720
  if (plugin.sourceType === "git") {
2680
2721
  return "codex plugin marketplace upgrade llm-wiki && codex plugin remove skillwiki@llm-wiki && codex plugin add skillwiki@llm-wiki";
2681
2722
  }
@@ -6208,11 +6249,24 @@ var CONCEPT_INDICATORS = /* @__PURE__ */ new Set([
6208
6249
  "model",
6209
6250
  "definition"
6210
6251
  ]);
6252
+ function resolveQueryScope(value) {
6253
+ const scope = value ?? "typed";
6254
+ if (scope === "typed" || scope === "work" || scope === "all") return scope;
6255
+ return null;
6256
+ }
6211
6257
  async function runQuery(input) {
6212
6258
  const scan = await scanVault(input.vault);
6213
6259
  if (!scan.ok) return { exitCode: ExitCode.VAULT_PATH_INVALID, result: scan };
6260
+ const scope = resolveQueryScope(input.scope);
6261
+ if (!scope) {
6262
+ return {
6263
+ exitCode: ExitCode.USAGE,
6264
+ result: err("USAGE", { message: "scope must be typed, work, or all" })
6265
+ };
6266
+ }
6214
6267
  const limit = input.limit ?? 10;
6215
6268
  const queryTerms = tokenize2(input.text);
6269
+ const candidates = queryCandidates(scan.data.typedKnowledge, scan.data.workItems, scope);
6216
6270
  if (queryTerms.length === 0) {
6217
6271
  return {
6218
6272
  exitCode: ExitCode.OK,
@@ -6221,17 +6275,17 @@ async function runQuery(input) {
6221
6275
  }
6222
6276
  const graph = await loadOrBuildGraph(input.vault);
6223
6277
  const pages = [];
6224
- for (const p of scan.data.typedKnowledge) {
6278
+ for (const p of candidates) {
6225
6279
  const text = await readPage(p);
6226
6280
  const fm = extractFrontmatter(text);
6227
6281
  if (!fm.ok) continue;
6228
6282
  const title = String(fm.data.title ?? "");
6229
- const type = String(fm.data.type ?? "");
6283
+ const type = String(fm.data.type ?? (p.relPath.includes("/work/") ? "work" : ""));
6230
6284
  const tags = Array.isArray(fm.data.tags) ? fm.data.tags.map(String) : [];
6231
6285
  const sources = Array.isArray(fm.data.sources) ? fm.data.sources.map(String) : [];
6232
6286
  const split = splitFrontmatter(text);
6233
6287
  const body = split.ok ? split.data.body : text;
6234
- const keywordScore = computeKeywordScore(queryTerms, title, tags, body);
6288
+ const keywordScore = computeKeywordScore(queryTerms, title, tags, body, p.relPath);
6235
6289
  pages.push({
6236
6290
  relPath: p.relPath,
6237
6291
  title,
@@ -6242,38 +6296,21 @@ async function runQuery(input) {
6242
6296
  historicalCycle: isHistoricalCyclePage(p.relPath, title)
6243
6297
  });
6244
6298
  }
6245
- const seedPaths = /* @__PURE__ */ new Set();
6246
- const operationalSeedPaths = /* @__PURE__ */ new Set();
6247
- let historicalCyclePageCount = 0;
6248
- let hasDirectOperationalSeed = false;
6249
- for (const page of pages) {
6250
- if (page.historicalCycle) historicalCyclePageCount += 1;
6251
- if (page.keywordScore <= 0) continue;
6252
- seedPaths.add(page.relPath);
6253
- if (!page.historicalCycle) {
6254
- operationalSeedPaths.add(page.relPath);
6255
- hasDirectOperationalSeed = true;
6256
- }
6299
+ let structural;
6300
+ let results;
6301
+ let rankingGuardrails;
6302
+ if (scope === "all") {
6303
+ const rankedWork = rankPages(pages.filter((page) => isWorkPath(page.relPath)), graph, queryTerms);
6304
+ const rankedTyped = rankPages(pages.filter((page) => !isWorkPath(page.relPath)), graph, queryTerms);
6305
+ structural = [...rankedWork.results, ...rankedTyped.results];
6306
+ results = zipMergeScopeResults(rankedWork.results, rankedTyped.results, limit);
6307
+ rankingGuardrails = rankedTyped.rankingGuardrails;
6308
+ } else {
6309
+ const ranked = rankPages(pages, graph, queryTerms);
6310
+ structural = ranked.results;
6311
+ results = structural.slice(0, limit);
6312
+ rankingGuardrails = ranked.rankingGuardrails;
6257
6313
  }
6258
- const suppressRepetitiveHistoricalCycles = historicalCyclePageCount >= 3 && hasDirectOperationalSeed;
6259
- const structuralSeedPaths = suppressRepetitiveHistoricalCycles ? operationalSeedPaths : seedPaths;
6260
- const structural = pages.map((page) => {
6261
- const sourceOverlap = scoreSourceOverlap(page, pages, structuralSeedPaths);
6262
- const wikilink = scoreWikilink(page.relPath, structuralSeedPaths, graph);
6263
- const aa = scoreAdamicAdar(page.relPath, structuralSeedPaths, graph);
6264
- const typeAffinity = scoreTypeAffinity(page.type, queryTerms);
6265
- const isSeed = page.keywordScore > 0;
6266
- const structuralBoost = sourceOverlap * W_SOURCE_OVERLAP + wikilink * W_WIKILINK + aa * W_ADAMIC_ADAR;
6267
- const composite = isSeed ? page.keywordScore * W_KEYWORD + structuralBoost + typeAffinity * W_TYPE_AFFINITY : structuralBoost * NON_SEED_FACTOR + typeAffinity * W_TYPE_AFFINITY;
6268
- const guardedComposite = suppressRepetitiveHistoricalCycles && page.historicalCycle ? composite * HISTORICAL_CYCLE_FACTOR : composite;
6269
- return {
6270
- path: page.relPath,
6271
- score: Math.round(guardedComposite * 1e3) / 1e3,
6272
- title: page.title,
6273
- type: page.type
6274
- };
6275
- }).filter((r) => r.score > 0).sort((a, b) => b.score - a.score || a.path.localeCompare(b.path));
6276
- let results = structural.slice(0, limit);
6277
6314
  let hybridMeta;
6278
6315
  if (input.hybrid) {
6279
6316
  const index = await loadVectorIndex(input.vault);
@@ -6305,10 +6342,6 @@ async function runQuery(input) {
6305
6342
  }
6306
6343
  const humanHint = results.length === 0 ? pendingSources && pendingSources.length > 0 ? `no matching typed pages found
6307
6344
  ${pendingSources.length} matching pending source(s)` : "no matching pages found" : results.map((r) => `${r.path} (score: ${r.score})`).join("\n");
6308
- const rankingGuardrails = suppressRepetitiveHistoricalCycles ? {
6309
- repetitive_historical_cycles_suppressed: true,
6310
- historical_cycle_page_count: historicalCyclePageCount
6311
- } : void 0;
6312
6345
  return {
6313
6346
  exitCode: ExitCode.OK,
6314
6347
  result: ok({
@@ -6320,6 +6353,97 @@ ${pendingSources.length} matching pending source(s)` : "no matching pages found"
6320
6353
  })
6321
6354
  };
6322
6355
  }
6356
+ function queryCandidates(typedKnowledge, workItems, scope) {
6357
+ if (scope === "work") return workItems;
6358
+ if (scope === "all") return [...typedKnowledge, ...workItems];
6359
+ return typedKnowledge;
6360
+ }
6361
+ function isWorkPath(relPath) {
6362
+ return relPath.includes("/work/");
6363
+ }
6364
+ var GENERIC_PATH_TERMS = /* @__PURE__ */ new Set([
6365
+ "work",
6366
+ "open",
6367
+ "projects",
6368
+ "spec",
6369
+ "plan",
6370
+ "log",
6371
+ "md",
6372
+ "http",
6373
+ "mcp",
6374
+ "and",
6375
+ "the",
6376
+ "for",
6377
+ "with",
6378
+ "from",
6379
+ "item",
6380
+ "items"
6381
+ ]);
6382
+ function pathSegmentBonus(terms, relPath) {
6383
+ if (!isWorkPath(relPath)) return 0;
6384
+ const segments = new Set(
6385
+ relPath.toLowerCase().split("/").flatMap((part) => {
6386
+ const noExt = part.replace(/\.(md|markdown)$/i, "");
6387
+ return noExt === part ? [part] : [part, noExt];
6388
+ })
6389
+ );
6390
+ let bonus = 0;
6391
+ for (const term of terms) {
6392
+ if (GENERIC_PATH_TERMS.has(term)) continue;
6393
+ if (segments.has(term)) bonus += 100;
6394
+ }
6395
+ return bonus;
6396
+ }
6397
+ function zipMergeScopeResults(work, typed, limit) {
6398
+ const merged = [];
6399
+ const n = Math.max(work.length, typed.length);
6400
+ for (let i = 0; i < n && merged.length < limit; i++) {
6401
+ if (i < work.length) merged.push(work[i]);
6402
+ if (merged.length >= limit) break;
6403
+ if (i < typed.length) merged.push(typed[i]);
6404
+ }
6405
+ return merged;
6406
+ }
6407
+ function rankPages(pages, graph, queryTerms) {
6408
+ const seedPaths = /* @__PURE__ */ new Set();
6409
+ const operationalSeedPaths = /* @__PURE__ */ new Set();
6410
+ let historicalCyclePageCount = 0;
6411
+ let hasDirectOperationalSeed = false;
6412
+ for (const page of pages) {
6413
+ if (page.historicalCycle) historicalCyclePageCount += 1;
6414
+ if (page.keywordScore <= 0) continue;
6415
+ seedPaths.add(page.relPath);
6416
+ if (!page.historicalCycle) {
6417
+ operationalSeedPaths.add(page.relPath);
6418
+ hasDirectOperationalSeed = true;
6419
+ }
6420
+ }
6421
+ const suppressRepetitiveHistoricalCycles = historicalCyclePageCount >= 3 && hasDirectOperationalSeed;
6422
+ const structuralSeedPaths = suppressRepetitiveHistoricalCycles ? operationalSeedPaths : seedPaths;
6423
+ const results = pages.map((page) => {
6424
+ const sourceOverlap = scoreSourceOverlap(page, pages, structuralSeedPaths);
6425
+ const wikilink = scoreWikilink(page.relPath, structuralSeedPaths, graph);
6426
+ const aa = scoreAdamicAdar(page.relPath, structuralSeedPaths, graph);
6427
+ const typeAffinity = scoreTypeAffinity(page.type, queryTerms);
6428
+ const isSeed = page.keywordScore > 0;
6429
+ const structuralBoost = sourceOverlap * W_SOURCE_OVERLAP + wikilink * W_WIKILINK + aa * W_ADAMIC_ADAR;
6430
+ const composite = isSeed ? page.keywordScore * W_KEYWORD + structuralBoost + typeAffinity * W_TYPE_AFFINITY : structuralBoost * NON_SEED_FACTOR + typeAffinity * W_TYPE_AFFINITY;
6431
+ const guardedComposite = suppressRepetitiveHistoricalCycles && page.historicalCycle ? composite * HISTORICAL_CYCLE_FACTOR : composite;
6432
+ return {
6433
+ path: page.relPath,
6434
+ score: Math.round(guardedComposite * 1e3) / 1e3,
6435
+ title: page.title,
6436
+ type: page.type
6437
+ };
6438
+ }).filter((r) => r.score > 0).sort((a, b) => b.score - a.score || a.path.localeCompare(b.path));
6439
+ return {
6440
+ results,
6441
+ rankingGuardrails: suppressRepetitiveHistoricalCycles ? {
6442
+ repetitive_historical_cycles_suppressed: true,
6443
+ historical_cycle_page_count: historicalCyclePageCount
6444
+ } : void 0
6445
+ };
6446
+ }
6323
6447
  function scoreSourceOverlap(page, allPages, seedPaths) {
6324
6448
  if (page.sources.length === 0) return 0;
6325
6449
  let total = 0;
@@ -6362,7 +6486,7 @@ function isHistoricalCyclePage(relPath, title) {
6362
6486
  function tokenize2(text) {
6363
6487
  return text.toLowerCase().split(/\s+/).filter((t) => t.length > 0);
6364
6488
  }
6365
- function computeKeywordScore(terms, title, tags, body) {
6489
+ function computeKeywordScore(terms, title, tags, body, relPath) {
6366
6490
  const lowerTitle = title.toLowerCase();
6367
6491
  const lowerTags = tags.map((t) => t.toLowerCase());
6368
6492
  const lowerBody = body.toLowerCase();
@@ -6372,6 +6496,7 @@ function computeKeywordScore(terms, title, tags, body) {
6372
6496
  if (lowerTags.some((t) => t.includes(term))) score += 2;
6373
6497
  if (lowerBody.includes(term)) score += 1;
6374
6498
  }
6499
+ if (relPath) score += pathSegmentBonus(terms, relPath);
6375
6500
  return score;
6376
6501
  }
6377
6502
  async function loadOrBuildGraph(vault) {
@@ -6601,17 +6726,18 @@ function registerMcpTools(server) {
6601
6726
  server.registerTool(
6602
6727
  "skillwiki.query",
6603
6728
  {
6604
- description: "Ranked vault query over typed knowledge (read-only). Returns Result envelope JSON.",
6729
+ description: "Ranked vault query. Default scope is typed knowledge. Use scope=work or all for Layer-3 work items. Returns Result envelope JSON.",
6605
6730
  inputSchema: z.object({
6606
6731
  ...vaultFields,
6607
6732
  text: z.string().min(1).describe("Query text"),
6608
- limit: z.number().int().positive().optional().describe("Max results (default 10)")
6733
+ limit: z.number().int().positive().optional().describe("Max results (default 10)"),
6734
+ scope: z.enum(["typed", "work", "all"]).optional().describe("typed (default), work, or all")
6609
6735
  })
6610
6736
  },
6611
- async ({ vault, wiki, text, limit }) => runMcpToolHandler("skillwiki.query", { vault, wiki }, async () => {
6737
+ async ({ vault, wiki, text, limit, scope }) => runMcpToolHandler("skillwiki.query", { vault, wiki }, async () => {
6612
6738
  const v = await resolveMcpVault({ vault, wiki });
6613
6739
  if (!v.ok) return formatToolResult({ exitCode: 25, result: v });
6614
- const r = await runQuery({ vault: v.data.vault, text, limit });
6740
+ const r = await runQuery({ vault: v.data.vault, text, limit, scope });
6615
6741
  return formatToolResult(r);
6616
6742
  })
6617
6743
  );
@@ -3304,7 +3304,7 @@ function buildCliSurface() {
3304
3304
  program.command("canvas");
3305
3305
  program.command("eval").option("--base <git-ref>").option("--top <n>").option("--wiki <name>");
3306
3306
  program.command("overlap").option("--wiki <name>");
3307
- program.command("query").option("--limit <n>").option("--include-pending").option("--hybrid").option("--wiki <name>");
3307
+ program.command("query").option("--limit <n>").option("--include-pending").option("--scope <scope>").option("--hybrid").option("--wiki <name>");
3308
3308
  program.command("vectors");
3309
3309
  program.command("sources");
3310
3310
  program.command("orphans").option("--wiki <name>");
package/dist/cli.js CHANGED
@@ -50,7 +50,7 @@ import {
50
50
  snapshotterHealthChecks,
51
51
  upsertIndexEntry,
52
52
  vectorIndexStatus
53
- } from "./chunk-CLF6DZ6C.js";
53
+ } from "./chunk-G7I34RQW.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-5XT6MBWA.js";
154
+ } from "./chunk-GPUK2IAW.js";
155
155
  import {
156
156
  assertTargetInsideVault,
157
157
  atomicWriteText,
@@ -10559,7 +10559,7 @@ async function emitManagedVaultWrite(vault, command, mutate, opts) {
10559
10559
  if (dirty) {
10560
10560
  return emit(dirty, void 0, { postCommit: false });
10561
10561
  }
10562
- const { runManagedWriteTransaction: runManagedWriteTransaction2 } = await import("./managed-write-preflight-LSG2Y24X.js");
10562
+ const { runManagedWriteTransaction: runManagedWriteTransaction2 } = await import("./managed-write-preflight-DEPLZAA6.js");
10563
10563
  const run = await runManagedWriteTransaction2({
10564
10564
  vault,
10565
10565
  command,
@@ -10608,7 +10608,7 @@ program.command("overlap [vault]").description("detect typed-knowledge pages tha
10608
10608
  if (!v.ok) emit({ exitCode: v.exitCode, result: v.payload });
10609
10609
  else emit(await runOverlap({ vault: v.vault }), v.vault);
10610
10610
  });
10611
- program.command("query <text> [vault]").description("score and rank vault pages by relevance to a query").option("--limit <n>", "max results to return", (s) => parseInt(s, 10), 10).option("--include-pending", "include a separate pending-evidence channel").option("--hybrid", "RRF-fuse 4-signal ranks with the local TF-IDF cache").option("--wiki <name>", "wiki profile name").action(async (text, vault, opts) => {
10611
+ program.command("query <text> [vault]").description("score and rank vault pages by relevance to a query").option("--limit <n>", "max results to return", (s) => parseInt(s, 10), 10).option("--include-pending", "include a separate pending-evidence channel").option("--scope <scope>", "typed, work, or all (default typed)").option("--hybrid", "RRF-fuse 4-signal ranks with the local TF-IDF cache").option("--wiki <name>", "wiki profile name").action(async (text, vault, opts) => {
10612
10612
  const v = await resolveVaultArg(vault, opts.wiki);
10613
10613
  if (!v.ok) emit({ exitCode: v.exitCode, result: v.payload });
10614
10614
  else emit(await runQuery({
@@ -10616,7 +10616,8 @@ program.command("query <text> [vault]").description("score and rank vault pages
10616
10616
  vault: v.vault,
10617
10617
  limit: opts.limit,
10618
10618
  includePending: opts.includePending,
10619
- hybrid: opts.hybrid
10619
+ hybrid: opts.hybrid,
10620
+ scope: opts.scope
10620
10621
  }), v.vault, { postCommit: false });
10621
10622
  });
10622
10623
  var sourcesCmd = program.command("sources").description("inspect raw-source lifecycle state");
@@ -6,7 +6,7 @@ import {
6
6
  runManagedWritePeerGate,
7
7
  runManagedWritePreflight,
8
8
  runManagedWriteTransaction
9
- } from "./chunk-5XT6MBWA.js";
9
+ } from "./chunk-GPUK2IAW.js";
10
10
  import "./chunk-BPJ5KWIT.js";
11
11
  import "./chunk-OMO45AHI.js";
12
12
  import "./chunk-HJ4ALQG6.js";
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runSkillwikiMcpStdio
4
- } from "./chunk-CLF6DZ6C.js";
4
+ } from "./chunk-G7I34RQW.js";
5
5
  import "./chunk-7I2TPIV5.js";
6
6
  import "./chunk-KFEOMMWK.js";
7
- import "./chunk-5XT6MBWA.js";
7
+ import "./chunk-GPUK2IAW.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.79",
3
+ "version": "0.10.81",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "skillwiki": "dist/cli.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.10.79",
3
+ "version": "0.10.81",
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.79",
3
+ "version": "0.10.81",
4
4
  "description": "Project-aware Karpathy-style knowledge base for Codex with 21 prompt-only skills backed by the deterministic skillwiki CLI.",
5
5
  "author": {
6
6
  "name": "karlorz",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.10.79",
3
+ "version": "0.10.81",
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"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skillwiki/skills",
3
- "version": "0.10.79",
3
+ "version": "0.10.81",
4
4
  "private": true,
5
5
  "files": [
6
6
  "wiki-*",
@@ -44,6 +44,8 @@ On leaf hosts, wiki captures go through MCP. Do **not** write `raw/transcripts/`
44
44
 
45
45
  Local `~/wiki` (or `skillwiki path`) is fine for reads. MCP read tools are optional. Prefer ordinary file reads of the local mirror.
46
46
 
47
+ `wiki_query` is typed knowledge only unless `scope` is `work` or `all`. For queued work, doctor, plugin-drift, or MCP diagnose questions, call `wiki_context` first (active_work) or pass `scope: "work"` / `"all"`. Do not treat a top typed packet hit as the live work queue.
48
+
47
49
  ## Errors
48
50
 
49
51
  Report handshake, capture, and append failures literally. If tools are missing after a 401 or `missing_prereq`, stop and tell the operator to export `SKILLWIKI_MCP_TOKEN`, run `grok plugin update skillwiki`, and start a new session. Do not fall back to local `raw/transcripts/` writes.
@@ -184,7 +184,7 @@ If the vault has `.WIKI_GIT_FROZEN`:
184
184
  |-------|----------------|
185
185
  | `wiki-init` | Bootstrap a vault and install `_Templates/web-clipper/llm-wiki-clippings.json` plus import guidance |
186
186
  | `wiki-ingest` | Convert URLs, files, or pasted text into typed-knowledge pages |
187
- | `wiki-query` | Search typed knowledge by default; explicitly requested fresh/raw evidence uses the separate pending channel |
187
+ | `wiki-query` | Search typed knowledge by default; work-queue / doctor / MCP diagnose questions use `wiki_context` or `--scope work` / `--scope all`; explicitly requested fresh/raw evidence uses the separate pending channel |
188
188
  | `wiki-lint` | Vault health and lint checks; use `health` for whole-system reports and `lint --summary` for bounded lint buckets |
189
189
  | `wiki-crystallize` | Distill the current working session into a typed-knowledge page |
190
190
  | `wiki-audit` | Verify raw provenance references and source frontmatter integrity |
@@ -286,7 +286,7 @@ Before asking questions or running scheduled maintenance, resolve the session ki
286
286
  ## Typical Workflow
287
287
  1. **Init** (`wiki-init`) — create vault, set domain and taxonomy
288
288
  2. **Ingest** (`wiki-ingest`) — add sources, build pages
289
- 3. **Query** (`wiki-query`) — search typed knowledge; explicitly include pending captures for fresh/raw intent
289
+ 3. **Query** (`wiki-query`) — search typed knowledge; work-queue / doctor / MCP questions use `wiki_context` or `--scope work` / `--scope all`; explicitly include pending captures for fresh/raw intent
290
290
  4. **Lint** (`wiki-lint`) — periodic health checks
291
291
  5. **Crystallize** (`wiki-crystallize`) — save session insights as pages
292
292
  6. **Audit** (`wiki-audit`) — verify source integrity
@@ -14,6 +14,7 @@ Standard four reads (SCHEMA, index, log, project context if applicable).
14
14
  0. **Resolve vault and language.** Run `skillwiki path` (fail if NO_VAULT_CONFIGURED) and `skillwiki lang`.
15
15
  1. **Determine scope.** Ask the user once if ambiguous: vault | current project | project+concepts.
16
16
  - Ordinary questions are typed-knowledge-first. Run `skillwiki query "<text>" [vault]` without widening into raw captures. Default ranking is 4-signal only. Optional `skillwiki query "<text>" --hybrid` RRF-fuses that ranking with a rebuildable TF-IDF cache (`skillwiki vectors rebuild`); if the cache is missing, stop and rebuild instead of silently falling back.
17
+ - Setup, MCP, doctor, plugin-drift, or "open work" questions are not typed-knowledge searches. Call `wiki_context` (active_work) or `skillwiki query "<text>" --scope work` / `--scope all`. Default typed query never ranks `projects/*/work`.
17
18
  - Explicit freshness language — `new`, `recent`, `fresh`, `clipped`, `raw`, `pending`, `undigested`, `unprocessed`, `not yet ingested`, or `not yet integrated` — requests the pending evidence channel. Run `skillwiki sources pending [vault]` for inventory and `skillwiki query "<text>" [vault] --include-pending` for synthesis support.
18
19
  2. **Refresh graph.** If `.skillwiki/graph.json` is missing or older than 24h: `skillwiki graph build <vault>`.
19
20
  3. **Compute overlap.** `skillwiki overlap <vault>`.
@@ -44,6 +44,8 @@ On leaf hosts, wiki captures go through MCP. Do **not** write `raw/transcripts/`
44
44
 
45
45
  Local `~/wiki` (or `skillwiki path`) is fine for reads. MCP read tools are optional. Prefer ordinary file reads of the local mirror.
46
46
 
47
+ `wiki_query` is typed knowledge only unless `scope` is `work` or `all`. For queued work, doctor, plugin-drift, or MCP diagnose questions, call `wiki_context` first (active_work) or pass `scope: "work"` / `"all"`. Do not treat a top typed packet hit as the live work queue.
48
+
47
49
  ## Errors
48
50
 
49
51
  Report handshake, capture, and append failures literally. If tools are missing after a 401 or `missing_prereq`, stop and tell the operator to export `SKILLWIKI_MCP_TOKEN`, run `grok plugin update skillwiki`, and start a new session. Do not fall back to local `raw/transcripts/` writes.
@@ -184,7 +184,7 @@ If the vault has `.WIKI_GIT_FROZEN`:
184
184
  |-------|----------------|
185
185
  | `wiki-init` | Bootstrap a vault and install `_Templates/web-clipper/llm-wiki-clippings.json` plus import guidance |
186
186
  | `wiki-ingest` | Convert URLs, files, or pasted text into typed-knowledge pages |
187
- | `wiki-query` | Search typed knowledge by default; explicitly requested fresh/raw evidence uses the separate pending channel |
187
+ | `wiki-query` | Search typed knowledge by default; work-queue / doctor / MCP diagnose questions use `wiki_context` or `--scope work` / `--scope all`; explicitly requested fresh/raw evidence uses the separate pending channel |
188
188
  | `wiki-lint` | Vault health and lint checks; use `health` for whole-system reports and `lint --summary` for bounded lint buckets |
189
189
  | `wiki-crystallize` | Distill the current working session into a typed-knowledge page |
190
190
  | `wiki-audit` | Verify raw provenance references and source frontmatter integrity |
@@ -286,7 +286,7 @@ Before asking questions or running scheduled maintenance, resolve the session ki
286
286
  ## Typical Workflow
287
287
  1. **Init** (`wiki-init`) — create vault, set domain and taxonomy
288
288
  2. **Ingest** (`wiki-ingest`) — add sources, build pages
289
- 3. **Query** (`wiki-query`) — search typed knowledge; explicitly include pending captures for fresh/raw intent
289
+ 3. **Query** (`wiki-query`) — search typed knowledge; work-queue / doctor / MCP questions use `wiki_context` or `--scope work` / `--scope all`; explicitly include pending captures for fresh/raw intent
290
290
  4. **Lint** (`wiki-lint`) — periodic health checks
291
291
  5. **Crystallize** (`wiki-crystallize`) — save session insights as pages
292
292
  6. **Audit** (`wiki-audit`) — verify source integrity
@@ -14,6 +14,7 @@ Standard four reads (SCHEMA, index, log, project context if applicable).
14
14
  0. **Resolve vault and language.** Run `skillwiki path` (fail if NO_VAULT_CONFIGURED) and `skillwiki lang`.
15
15
  1. **Determine scope.** Ask the user once if ambiguous: vault | current project | project+concepts.
16
16
  - Ordinary questions are typed-knowledge-first. Run `skillwiki query "<text>" [vault]` without widening into raw captures. Default ranking is 4-signal only. Optional `skillwiki query "<text>" --hybrid` RRF-fuses that ranking with a rebuildable TF-IDF cache (`skillwiki vectors rebuild`); if the cache is missing, stop and rebuild instead of silently falling back.
17
+ - Setup, MCP, doctor, plugin-drift, or "open work" questions are not typed-knowledge searches. Call `wiki_context` (active_work) or `skillwiki query "<text>" --scope work` / `--scope all`. Default typed query never ranks `projects/*/work`.
17
18
  - Explicit freshness language — `new`, `recent`, `fresh`, `clipped`, `raw`, `pending`, `undigested`, `unprocessed`, `not yet ingested`, or `not yet integrated` — requests the pending evidence channel. Run `skillwiki sources pending [vault]` for inventory and `skillwiki query "<text>" [vault] --include-pending` for synthesis support.
18
19
  2. **Refresh graph.** If `.skillwiki/graph.json` is missing or older than 24h: `skillwiki graph build <vault>`.
19
20
  3. **Compute overlap.** `skillwiki overlap <vault>`.