@kaddo/mcp 3.124.4 → 3.125.0

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.
Files changed (2) hide show
  1. package/dist/index.js +118 -112
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -12121,7 +12121,7 @@ function getPrompt(root, name) {
12121
12121
  }
12122
12122
 
12123
12123
  // src/tools.ts
12124
- import matter20 from "gray-matter";
12124
+ import matter23 from "gray-matter";
12125
12125
 
12126
12126
  // ../cli/dist/core.js
12127
12127
  import fs3 from "fs";
@@ -12148,21 +12148,24 @@ import { dirname as dirname2, join as join22, parse as parse2 } from "path";
12148
12148
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
12149
12149
  import matter92 from "gray-matter";
12150
12150
  import matter102 from "gray-matter";
12151
+ import { parse as parseYaml82 } from "yaml";
12151
12152
  import matter112 from "gray-matter";
12152
- import { parse as parseYaml82, stringify as stringifyYaml52 } from "yaml";
12153
+ import matter122 from "gray-matter";
12154
+ import { parse as parseYaml92, stringify as stringifyYaml52 } from "yaml";
12153
12155
  import fs4 from "fs";
12154
12156
  import path4 from "path";
12155
12157
  import crypto2 from "crypto";
12156
- import matter122 from "gray-matter";
12158
+ import matter132 from "gray-matter";
12157
12159
  import crypto3 from "crypto";
12158
12160
  import fs5 from "fs";
12159
- import matter132 from "gray-matter";
12160
12161
  import matter142 from "gray-matter";
12161
- import { parse as parseYaml92, stringify as stringifyYaml6 } from "yaml";
12162
- import { parse as parseYaml102, stringify as stringifyYaml7 } from "yaml";
12163
12162
  import matter15 from "gray-matter";
12163
+ import { parse as parseYaml102, stringify as stringifyYaml6 } from "yaml";
12164
+ import { parse as parseYaml11, stringify as stringifyYaml7 } from "yaml";
12164
12165
  import matter16 from "gray-matter";
12165
12166
  import matter17 from "gray-matter";
12167
+ import matter18 from "gray-matter";
12168
+ import matter19 from "gray-matter";
12166
12169
  function exists2(p) {
12167
12170
  return fs3.existsSync(p);
12168
12171
  }
@@ -12281,8 +12284,8 @@ function loadConfig2(dir) {
12281
12284
  const parsed = configSchema2.safeParse(raw ?? {});
12282
12285
  if (!parsed.success) {
12283
12286
  const issues = parsed.error.issues.map((i) => {
12284
- const path62 = i.path.join(".");
12285
- return path62 ? ` - ${path62}: ${i.message}` : ` - ${i.message}`;
12287
+ const path82 = i.path.join(".");
12288
+ return path82 ? ` - ${path82}: ${i.message}` : ` - ${i.message}`;
12286
12289
  }).join("\n");
12287
12290
  throw new ConfigError2(`Invalid .kaddo/config.yml:
12288
12291
  ${issues}`);
@@ -12486,11 +12489,11 @@ function moduleArtifactCoverage2(dir, id) {
12486
12489
  };
12487
12490
  }
12488
12491
  function loadMappedModules2(dir) {
12489
- const path62 = join3(dir, DESCRIPTOR_PATH2);
12490
- if (!exists2(path62)) return [];
12492
+ const path82 = join3(dir, DESCRIPTOR_PATH2);
12493
+ if (!exists2(path82)) return [];
12491
12494
  let parsed;
12492
12495
  try {
12493
- parsed = parseYaml32(readFile2(path62));
12496
+ parsed = parseYaml32(readFile2(path82));
12494
12497
  } catch {
12495
12498
  return [];
12496
12499
  }
@@ -14223,9 +14226,9 @@ function buildGraph2(dir, config, opts = {}, now = /* @__PURE__ */ new Date()) {
14223
14226
  ];
14224
14227
  const presentLayers = [];
14225
14228
  for (const layer2 of layerDocs) {
14226
- const path62 = layer2.files.map((f3) => `${KNOWLEDGE22}/${f3}`).find((rel) => exists2(join3(dir, rel)));
14227
- if (path62) {
14228
- addNode({ id: layer2.id, type: layer2.type, label: layer2.label, path: path62 });
14229
+ const path82 = layer2.files.map((f3) => `${KNOWLEDGE22}/${f3}`).find((rel) => exists2(join3(dir, rel)));
14230
+ if (path82) {
14231
+ addNode({ id: layer2.id, type: layer2.type, label: layer2.label, path: path82 });
14229
14232
  presentLayers.push(layer2.id);
14230
14233
  }
14231
14234
  }
@@ -14704,13 +14707,13 @@ function meaningful2(text22) {
14704
14707
  });
14705
14708
  }
14706
14709
  function readPocSummary2(dir) {
14707
- const path62 = join3(dir, POC_ARTIFACT_PATH2);
14708
- if (!exists2(path62)) {
14710
+ const path82 = join3(dir, POC_ARTIFACT_PATH2);
14711
+ if (!exists2(path82)) {
14709
14712
  return { exists: false, hypothesisDefined: false, successCriteriaCount: 0, constraintsDefined: false, nonGoalsDefined: false, conclusion: "pending" };
14710
14713
  }
14711
14714
  let markdown = "";
14712
14715
  try {
14713
- markdown = readFile2(path62);
14716
+ markdown = readFile2(path82);
14714
14717
  } catch {
14715
14718
  return { exists: false, hypothesisDefined: false, successCriteriaCount: 0, constraintsDefined: false, nonGoalsDefined: false, conclusion: "pending" };
14716
14719
  }
@@ -14741,11 +14744,11 @@ function redactSecrets2(value) {
14741
14744
  return line.replace(/([:=]\s*)\S+.*/, "$1[redacted]");
14742
14745
  }).join("\n");
14743
14746
  }
14744
- function source2(dir, path62, kind) {
14745
- const absolute = join3(dir, path62);
14747
+ function source2(dir, path82, kind) {
14748
+ const absolute = join3(dir, path82);
14746
14749
  if (!exists2(absolute)) return null;
14747
14750
  const raw = readFile2(absolute);
14748
- return { path: posix2(path62), kind, digest: sha2(raw), content: redactSecrets2(raw) };
14751
+ return { path: posix2(path82), kind, digest: sha2(raw), content: redactSecrets2(raw) };
14749
14752
  }
14750
14753
  function reportFiles2(dir) {
14751
14754
  const delivery = join3(dir, "knowledge", "delivery");
@@ -14785,9 +14788,9 @@ function buildPocReportContext2(dir) {
14785
14788
  };
14786
14789
  }
14787
14790
  const sources = [];
14788
- const add = (path62, kind) => {
14789
- if (sources.some((item2) => item2.path === posix2(path62))) return;
14790
- const item = source2(dir, path62, kind);
14791
+ const add = (path82, kind) => {
14792
+ if (sources.some((item2) => item2.path === posix2(path82))) return;
14793
+ const item = source2(dir, path82, kind);
14791
14794
  if (item) sources.push(item);
14792
14795
  };
14793
14796
  add(POC_ARTIFACT_PATH2, "poc");
@@ -14815,7 +14818,7 @@ function buildPocReportContext2(dir) {
14815
14818
  const sourceFingerprint = sha2(sources.map((item) => `${item.path}\0${item.digest}`).join("\n"));
14816
14819
  const status = !latestReport ? "missing" : latestReport.sourceFingerprint === sourceFingerprint ? "current" : "stale";
14817
14820
  const currentManifest = Object.fromEntries(sources.map((item) => [item.path, item.digest]));
14818
- const changesSinceLatest = status === "stale" ? [.../* @__PURE__ */ new Set([...Object.keys(currentManifest), ...Object.keys(latestReport?.sourceManifest ?? {})])].filter((path62) => currentManifest[path62] !== latestReport?.sourceManifest[path62]).sort() : [];
14821
+ const changesSinceLatest = status === "stale" ? [.../* @__PURE__ */ new Set([...Object.keys(currentManifest), ...Object.keys(latestReport?.sourceManifest ?? {})])].filter((path82) => currentManifest[path82] !== latestReport?.sourceManifest[path82]).sort() : [];
14819
14822
  const sourceList = sources.map((item) => `- ${item.path} (${item.kind})`).join("\n") || "- No sources selected.";
14820
14823
  return {
14821
14824
  eligible: true,
@@ -15968,8 +15971,8 @@ function withResponsibilityTrace2(fileName, content) {
15968
15971
  const skills = renderSkillsSection2(agent);
15969
15972
  const skillsBlock = skills ? `${skills}
15970
15973
  ` : "";
15971
- const frontmatter = renderFrontmatterRules2(agent);
15972
- const frontmatterBlock = frontmatter ? `${frontmatter}
15974
+ const frontmatter2 = renderFrontmatterRules2(agent);
15975
+ const frontmatterBlock = frontmatter2 ? `${frontmatter2}
15973
15976
  ` : "";
15974
15977
  return `${content.trimEnd()}
15975
15978
 
@@ -18161,23 +18164,23 @@ var VALID_SOURCES3 = [
18161
18164
  function isValidSource2(s) {
18162
18165
  return VALID_SOURCES3.includes(s);
18163
18166
  }
18164
- function parseWorkItemSource2(frontmatter) {
18165
- const rawSource = frontmatter.source;
18167
+ function parseWorkItemSource2(frontmatter2) {
18168
+ const rawSource = frontmatter2.source;
18166
18169
  if (rawSource != null && typeof rawSource === "object" && !Array.isArray(rawSource)) {
18167
18170
  const obj = rawSource;
18168
18171
  const t = optStr22(obj.type);
18169
18172
  const type = t && isValidSource2(t) ? t : "unknown";
18170
18173
  return {
18171
18174
  type,
18172
- id: optStr22(obj.id) ?? optStr22(frontmatter.source_id),
18173
- title: optStr22(obj.title) ?? optStr22(frontmatter.source_title),
18174
- context: optStr22(obj.context) ?? optStr22(frontmatter.source_context),
18175
- provider: optStr22(obj.provider) ?? optStr22(frontmatter.source_provider),
18176
- integration: optStr22(obj.integration) ?? optStr22(frontmatter.source_integration),
18177
- url: optStr22(obj.url) ?? optStr22(frontmatter.source_url),
18178
- imported_at: optStr22(obj.imported_at) ?? optStr22(frontmatter.source_imported_at),
18179
- external_updated_at: optStr22(obj.external_updated_at) ?? optStr22(frontmatter.source_external_updated_at),
18180
- synced_at: optStr22(obj.synced_at) ?? optStr22(frontmatter.source_synced_at),
18175
+ id: optStr22(obj.id) ?? optStr22(frontmatter2.source_id),
18176
+ title: optStr22(obj.title) ?? optStr22(frontmatter2.source_title),
18177
+ context: optStr22(obj.context) ?? optStr22(frontmatter2.source_context),
18178
+ provider: optStr22(obj.provider) ?? optStr22(frontmatter2.source_provider),
18179
+ integration: optStr22(obj.integration) ?? optStr22(frontmatter2.source_integration),
18180
+ url: optStr22(obj.url) ?? optStr22(frontmatter2.source_url),
18181
+ imported_at: optStr22(obj.imported_at) ?? optStr22(frontmatter2.source_imported_at),
18182
+ external_updated_at: optStr22(obj.external_updated_at) ?? optStr22(frontmatter2.source_external_updated_at),
18183
+ synced_at: optStr22(obj.synced_at) ?? optStr22(frontmatter2.source_synced_at),
18181
18184
  inferred: obj.inferred === true || obj.inferred === "true",
18182
18185
  reason: t && !isValidSource2(t) ? `Invalid source type in object: "${t}".` : void 0
18183
18186
  };
@@ -18186,45 +18189,45 @@ function parseWorkItemSource2(frontmatter) {
18186
18189
  if (raw && isValidSource2(raw)) {
18187
18190
  return {
18188
18191
  type: raw,
18189
- id: optStr22(frontmatter.source_id),
18190
- title: optStr22(frontmatter.source_title),
18191
- context: optStr22(frontmatter.source_context),
18192
- provider: optStr22(frontmatter.source_provider),
18193
- url: optStr22(frontmatter.source_url),
18194
- imported_at: optStr22(frontmatter.source_imported_at),
18195
- external_updated_at: optStr22(frontmatter.source_external_updated_at),
18196
- synced_at: optStr22(frontmatter.source_synced_at),
18192
+ id: optStr22(frontmatter2.source_id),
18193
+ title: optStr22(frontmatter2.source_title),
18194
+ context: optStr22(frontmatter2.source_context),
18195
+ provider: optStr22(frontmatter2.source_provider),
18196
+ url: optStr22(frontmatter2.source_url),
18197
+ imported_at: optStr22(frontmatter2.source_imported_at),
18198
+ external_updated_at: optStr22(frontmatter2.source_external_updated_at),
18199
+ synced_at: optStr22(frontmatter2.source_synced_at),
18197
18200
  inferred: false
18198
18201
  };
18199
18202
  }
18200
18203
  if (raw && !isValidSource2(raw)) {
18201
18204
  return {
18202
18205
  type: "unknown",
18203
- id: optStr22(frontmatter.source_id),
18204
- title: optStr22(frontmatter.source_title),
18205
- context: optStr22(frontmatter.source_context),
18206
- provider: optStr22(frontmatter.source_provider),
18207
- url: optStr22(frontmatter.source_url),
18208
- imported_at: optStr22(frontmatter.source_imported_at),
18209
- external_updated_at: optStr22(frontmatter.source_external_updated_at),
18210
- synced_at: optStr22(frontmatter.source_synced_at),
18206
+ id: optStr22(frontmatter2.source_id),
18207
+ title: optStr22(frontmatter2.source_title),
18208
+ context: optStr22(frontmatter2.source_context),
18209
+ provider: optStr22(frontmatter2.source_provider),
18210
+ url: optStr22(frontmatter2.source_url),
18211
+ imported_at: optStr22(frontmatter2.source_imported_at),
18212
+ external_updated_at: optStr22(frontmatter2.source_external_updated_at),
18213
+ synced_at: optStr22(frontmatter2.source_synced_at),
18211
18214
  inferred: true,
18212
18215
  reason: `Invalid source value: "${raw}".`
18213
18216
  };
18214
18217
  }
18215
- if (frontmatter.source_work_item_candidate || frontmatter.source_roadmap_initiative) {
18218
+ if (frontmatter2.source_work_item_candidate || frontmatter2.source_roadmap_initiative) {
18216
18219
  return {
18217
18220
  type: "roadmap",
18218
- id: optStr22(frontmatter.source_id) ?? optStr22(frontmatter.source_work_item_candidate),
18219
- title: optStr22(frontmatter.source_initiative_title),
18221
+ id: optStr22(frontmatter2.source_id) ?? optStr22(frontmatter2.source_work_item_candidate),
18222
+ title: optStr22(frontmatter2.source_initiative_title),
18220
18223
  inferred: true,
18221
18224
  reason: "Inferred from legacy roadmap fields."
18222
18225
  };
18223
18226
  }
18224
- if (frontmatter.source_id) {
18227
+ if (frontmatter2.source_id) {
18225
18228
  return {
18226
18229
  type: "unknown",
18227
- id: optStr22(frontmatter.source_id),
18230
+ id: optStr22(frontmatter2.source_id),
18228
18231
  inferred: true,
18229
18232
  reason: "Has source_id but no source type."
18230
18233
  };
@@ -18479,6 +18482,9 @@ var LEGACY_STEPS2 = [
18479
18482
  runGuard2,
18480
18483
  captureLearning2
18481
18484
  ];
18485
+ var HISTORY_DIR2 = ".kaddo/history";
18486
+ var RUNS_PATH2 = `${HISTORY_DIR2}/guard-runs.jsonl`;
18487
+ var SUMMARY_PATH2 = `${HISTORY_DIR2}/guard-summary.json`;
18482
18488
  var USER_FACING_KEYWORDS_EN = [
18483
18489
  "user",
18484
18490
  "visitor",
@@ -18665,7 +18671,7 @@ function loadSystemTopology(dir) {
18665
18671
  function parseTopologyContent(raw, dir) {
18666
18672
  let parsed;
18667
18673
  try {
18668
- parsed = parseYaml82(raw) ?? {};
18674
+ parsed = parseYaml92(raw) ?? {};
18669
18675
  } catch {
18670
18676
  return { entities: [], relationships: [], findings: [{ level: "blocking", message: "The topology could not be parsed." }] };
18671
18677
  }
@@ -18828,8 +18834,8 @@ function parseGraphReason(v) {
18828
18834
  if (!v || typeof v !== "object") return null;
18829
18835
  const o2 = v;
18830
18836
  const relationship = typeof o2.relationship === "string" && o2.relationship.trim() ? o2.relationship.trim() : null;
18831
- const path62 = Array.isArray(o2.path) ? o2.path.map(String).filter(Boolean) : [];
18832
- return relationship || path62.length ? { relationship, path: path62 } : null;
18837
+ const path82 = Array.isArray(o2.path) ? o2.path.map(String).filter(Boolean) : [];
18838
+ return relationship || path82.length ? { relationship, path: path82 } : null;
18833
18839
  }
18834
18840
  function parseExplain(o2) {
18835
18841
  const refs = Array.isArray(o2.evidence) ? o2.evidence : Array.isArray(o2.evidence_refs) ? o2.evidence_refs : [];
@@ -18884,7 +18890,7 @@ function parseOriginalSnapshot(fm) {
18884
18890
  function readBody(filePath) {
18885
18891
  try {
18886
18892
  const raw = readFile2(filePath);
18887
- return matter112(raw).content;
18893
+ return matter122(raw).content;
18888
18894
  } catch {
18889
18895
  return "";
18890
18896
  }
@@ -19084,7 +19090,7 @@ function slugify22(s) {
19084
19090
  function nextWorkItemId(dir) {
19085
19091
  const wiDir = join3(dir, WORK_ITEMS_DIR);
19086
19092
  let max = 0;
19087
- const walk = (d3) => {
19093
+ const walk2 = (d3) => {
19088
19094
  if (!exists2(d3)) return;
19089
19095
  for (const entry of fs4.readdirSync(d3)) {
19090
19096
  const full = join3(d3, entry);
@@ -19092,11 +19098,11 @@ function nextWorkItemId(dir) {
19092
19098
  const m2 = entry.match(/WI-(\d+)/);
19093
19099
  if (m2) max = Math.max(max, parseInt(m2[1], 10));
19094
19100
  } else if (!entry.startsWith(".")) {
19095
- walk(full);
19101
+ walk2(full);
19096
19102
  }
19097
19103
  }
19098
19104
  };
19099
- walk(wiDir);
19105
+ walk2(wiDir);
19100
19106
  return `WI-${String(max + 1).padStart(3, "0")}`;
19101
19107
  }
19102
19108
  function atomicWrite3(filePath, content) {
@@ -19169,7 +19175,7 @@ function ensureH1(body, title) {
19169
19175
  ${trimmed}`;
19170
19176
  }
19171
19177
  function serialize2(data, body) {
19172
- return matter122.stringify(`
19178
+ return matter132.stringify(`
19173
19179
  ${body.trim()}
19174
19180
  `, data);
19175
19181
  }
@@ -20083,7 +20089,7 @@ function detectFormat(raw) {
20083
20089
  if (!trimmed) throw new ImportError("EMPTY_INPUT", "Import content is empty.");
20084
20090
  if (trimmed.startsWith("---")) {
20085
20091
  try {
20086
- const { data } = matter132(trimmed);
20092
+ const { data } = matter142(trimmed);
20087
20093
  if (data && typeof data === "object" && Object.keys(data).length > 0) {
20088
20094
  const d3 = data;
20089
20095
  if (d3.type === "work-item" || d3.id && typeof d3.id === "string" && /^WI-\d+/.test(d3.id)) {
@@ -20105,7 +20111,7 @@ function parseContent(raw) {
20105
20111
  let bodyText = trimmed;
20106
20112
  if (format === "kaddo-frontmatter" || format === "markdown-frontmatter") {
20107
20113
  try {
20108
- const parsed = matter132(trimmed);
20114
+ const parsed = matter142(trimmed);
20109
20115
  frontmatterFields = parsed.data ?? {};
20110
20116
  bodyText = parsed.content.trim();
20111
20117
  } catch {
@@ -20202,7 +20208,7 @@ function findDuplicateByHash(dir, hash) {
20202
20208
  const raw = readFile2(item.filePath);
20203
20209
  if (!raw) continue;
20204
20210
  try {
20205
- const { data } = matter132(raw);
20211
+ const { data } = matter142(raw);
20206
20212
  const source22 = data?.source;
20207
20213
  if (source22 && typeof source22 === "object" && !Array.isArray(source22)) {
20208
20214
  const s = source22;
@@ -20711,8 +20717,8 @@ async function handleJiraResponse(res) {
20711
20717
  }
20712
20718
  return await res.json();
20713
20719
  }
20714
- async function jiraFetch(baseUrl, path62, auth, timeoutMs, params) {
20715
- const url = new URL(path62, baseUrl + "/");
20720
+ async function jiraFetch(baseUrl, path82, auth, timeoutMs, params) {
20721
+ const url = new URL(path82, baseUrl + "/");
20716
20722
  if (params) for (const [k2, v] of Object.entries(params)) url.searchParams.set(k2, v);
20717
20723
  const controller = new AbortController();
20718
20724
  const timer = setTimeout(() => controller.abort(), timeoutMs);
@@ -20730,8 +20736,8 @@ async function jiraFetch(baseUrl, path62, auth, timeoutMs, params) {
20730
20736
  clearTimeout(timer);
20731
20737
  }
20732
20738
  }
20733
- async function jiraPost(baseUrl, path62, auth, timeoutMs, body) {
20734
- const url = new URL(path62, baseUrl + "/");
20739
+ async function jiraPost(baseUrl, path82, auth, timeoutMs, body) {
20740
+ const url = new URL(path82, baseUrl + "/");
20735
20741
  const controller = new AbortController();
20736
20742
  const timer = setTimeout(() => controller.abort(), timeoutMs);
20737
20743
  try {
@@ -20918,7 +20924,7 @@ function persistConsent(dir, consent) {
20918
20924
  const configPath = join3(dir, ".kaddo", "config.yml");
20919
20925
  if (!exists2(configPath)) return;
20920
20926
  const raw = readFile2(configPath);
20921
- const doc = parseYaml102(raw) ?? {};
20927
+ const doc = parseYaml11(raw) ?? {};
20922
20928
  const prev = doc.telemetry ?? {};
20923
20929
  delete prev.enabled;
20924
20930
  doc.telemetry = { ...prev, consent, consentVersion: CURRENT_CONSENT_VERSION };
@@ -21097,7 +21103,7 @@ function buildInitiativeContent(id, input) {
21097
21103
  if (input.priority) data.priority = input.priority;
21098
21104
  if (input.source) data.source = input.source;
21099
21105
  if (input.sourceId) data.source_id = input.sourceId;
21100
- return matter15.stringify("\n" + (input.body ?? defaultBody(input.title.trim())), data);
21106
+ return matter16.stringify("\n" + (input.body ?? defaultBody(input.title.trim())), data);
21101
21107
  }
21102
21108
  function createInitiative(dir, input) {
21103
21109
  if (!input.title?.trim()) throw new InitiativeWriteError("Initiative title is required.");
@@ -21121,10 +21127,10 @@ function transitionInitiative(dir, id, to) {
21121
21127
  throw new InitiativeWriteError(`Invalid transition ${ini.status} \u2192 ${to}.`);
21122
21128
  }
21123
21129
  const raw = readFile2(ini.filePath);
21124
- const { data, content } = matter15(raw, {});
21130
+ const { data, content } = matter16(raw, {});
21125
21131
  data.status = to;
21126
21132
  if (to === "completed") data.completed_at = today2();
21127
- const newContent = matter15.stringify(content, data);
21133
+ const newContent = matter16.stringify(content, data);
21128
21134
  writeFile2(ini.filePath, newContent);
21129
21135
  const updated = parseInitiative2(dir, ini.filePath, newContent);
21130
21136
  if (!updated) throw new InitiativeWriteError("Failed to parse the Initiative after transition.");
@@ -21134,7 +21140,7 @@ function addCandidate(dir, id, candidate) {
21134
21140
  const ini = getInitiative(dir, id);
21135
21141
  if (!ini) throw new InitiativeWriteError(`Initiative ${id} not found.`);
21136
21142
  const raw = readFile2(ini.filePath);
21137
- const { data, content } = matter15(raw, {});
21143
+ const { data, content } = matter16(raw, {});
21138
21144
  const existing = Array.isArray(data.candidates) ? data.candidates : [];
21139
21145
  const fallbackId = `WI-CANDIDATE-${String(existing.length + 1).padStart(3, "0")}`;
21140
21146
  const normalized = normalizeCandidate(candidate, fallbackId);
@@ -21142,7 +21148,7 @@ function addCandidate(dir, id, candidate) {
21142
21148
  throw new InitiativeWriteError(`Candidate ${normalized.id} already exists in ${id}.`);
21143
21149
  }
21144
21150
  data.candidates = [...existing, candidateToData(normalized)];
21145
- const newContent = matter15.stringify(content, data);
21151
+ const newContent = matter16.stringify(content, data);
21146
21152
  writeFile2(ini.filePath, newContent);
21147
21153
  const updated = parseInitiative2(dir, ini.filePath, newContent);
21148
21154
  if (!updated) throw new InitiativeWriteError("Failed to parse the Initiative after adding a candidate.");
@@ -21152,7 +21158,7 @@ function updateInitiative(dir, id, patch) {
21152
21158
  const ini = getInitiative(dir, id);
21153
21159
  if (!ini) throw new InitiativeWriteError(`Initiative ${id} not found.`);
21154
21160
  const raw = readFile2(ini.filePath);
21155
- const { data, content } = matter15(raw, {});
21161
+ const { data, content } = matter16(raw, {});
21156
21162
  if (patch.title !== void 0) {
21157
21163
  if (!patch.title.trim()) throw new InitiativeWriteError("Initiative title cannot be empty.");
21158
21164
  data.title = patch.title.trim();
@@ -21162,7 +21168,7 @@ function updateInitiative(dir, id, patch) {
21162
21168
  if (patch.knowledgeLevel !== void 0) data.knowledge_level = patch.knowledgeLevel;
21163
21169
  if (patch.domains !== void 0) data.domains = patch.domains;
21164
21170
  if (patch.relatedCapabilities !== void 0) data.related_capabilities = patch.relatedCapabilities;
21165
- const newContent = matter15.stringify(content, data);
21171
+ const newContent = matter16.stringify(content, data);
21166
21172
  writeFile2(ini.filePath, newContent);
21167
21173
  const updated = parseInitiative2(dir, ini.filePath, newContent);
21168
21174
  if (!updated) throw new InitiativeWriteError("Failed to parse the Initiative after update.");
@@ -21180,10 +21186,10 @@ function addExternalLink(dir, id, link) {
21180
21186
  throw new InitiativeWriteError(`External link ${link.integration}:${link.externalId} already exists on ${id}.`);
21181
21187
  }
21182
21188
  const raw = readFile2(ini.filePath);
21183
- const { data, content } = matter15(raw, {});
21189
+ const { data, content } = matter16(raw, {});
21184
21190
  const existing = Array.isArray(data.external_links) ? data.external_links : [];
21185
21191
  data.external_links = [...existing, externalLinkToData(link)];
21186
- const newContent = matter15.stringify(content, data);
21192
+ const newContent = matter16.stringify(content, data);
21187
21193
  writeFile2(ini.filePath, newContent);
21188
21194
  const updated = parseInitiative2(dir, ini.filePath, newContent);
21189
21195
  if (!updated) throw new InitiativeWriteError("Failed to parse the Initiative after adding an external link.");
@@ -21192,7 +21198,7 @@ function addExternalLink(dir, id, link) {
21192
21198
  function nextWorkItemId2(dir) {
21193
21199
  const wiDir = join3(dir, WORK_ITEMS_DIR2);
21194
21200
  let max = 0;
21195
- const walk = (d3) => {
21201
+ const walk2 = (d3) => {
21196
21202
  if (!exists2(d3)) return;
21197
21203
  for (const entry of readDir2(d3)) {
21198
21204
  const full = join3(d3, entry);
@@ -21200,11 +21206,11 @@ function nextWorkItemId2(dir) {
21200
21206
  const m2 = entry.match(/WI-(\d+)/);
21201
21207
  if (m2) max = Math.max(max, parseInt(m2[1], 10));
21202
21208
  } else if (!entry.startsWith(".")) {
21203
- walk(full);
21209
+ walk2(full);
21204
21210
  }
21205
21211
  }
21206
21212
  };
21207
- walk(wiDir);
21213
+ walk2(wiDir);
21208
21214
  return `WI-${String(max + 1).padStart(3, "0")}`;
21209
21215
  }
21210
21216
  function buildWorkItemContent(wiId, iniId, candidate) {
@@ -21252,7 +21258,7 @@ function buildWorkItemContent(wiId, iniId, candidate) {
21252
21258
  "_What did we learn? Update after completion._",
21253
21259
  ""
21254
21260
  ].join("\n");
21255
- return matter15.stringify("\n" + body, data);
21261
+ return matter16.stringify("\n" + body, data);
21256
21262
  }
21257
21263
  function materializeCandidate(dir, id, candidateId) {
21258
21264
  const ini = getInitiative(dir, id);
@@ -21269,13 +21275,13 @@ function materializeCandidate(dir, id, candidateId) {
21269
21275
  ensureDir2(join3(dir, DRAFT_DIR));
21270
21276
  writeFile2(join3(dir, DRAFT_DIR, fileName), buildWorkItemContent(wiId, ini.id, candidate));
21271
21277
  const raw = readFile2(ini.filePath);
21272
- const { data, content } = matter15(raw, {});
21278
+ const { data, content } = matter16(raw, {});
21273
21279
  const cands = Array.isArray(data.candidates) ? data.candidates : [];
21274
21280
  for (const c of cands) {
21275
21281
  if (c && typeof c === "object" && String(c.id) === candidateId) c.materialized_as = wiId;
21276
21282
  }
21277
21283
  data.candidates = cands;
21278
- const newContent = matter15.stringify(content, data);
21284
+ const newContent = matter16.stringify(content, data);
21279
21285
  writeFile2(ini.filePath, newContent);
21280
21286
  const updated = parseInitiative2(dir, ini.filePath, newContent);
21281
21287
  if (!updated) throw new InitiativeWriteError("Failed to parse the Initiative after materialization.");
@@ -21389,7 +21395,7 @@ function evaluateInitiativeCompletion(dir, ini) {
21389
21395
  // ../cli/src/core/resource-write.ts
21390
21396
  import fs6 from "fs";
21391
21397
  import path5 from "path";
21392
- import matter18 from "gray-matter";
21398
+ import matter20 from "gray-matter";
21393
21399
  var RESOURCES_DIR = "knowledge/tech/resources";
21394
21400
  var ResourceWriteError = class extends Error {
21395
21401
  constructor(code, message) {
@@ -21469,7 +21475,7 @@ function buildFrontmatter(id, input, base = {}) {
21469
21475
  return data;
21470
21476
  }
21471
21477
  function serialize(data, body) {
21472
- return matter18.stringify(`
21478
+ return matter20.stringify(`
21473
21479
  ${body.trim()}
21474
21480
  `, data);
21475
21481
  }
@@ -21509,7 +21515,7 @@ function updateResource(dir, id, input) {
21509
21515
  throw new ResourceWriteError("VALIDATION_FAILED", findings.filter((f3) => f3.level === "error").map((f3) => f3.message).join("; "));
21510
21516
  }
21511
21517
  const raw = readFile(match.filePath);
21512
- const parsed = matter18(raw);
21518
+ const parsed = matter20(raw);
21513
21519
  const base = parsed.data ?? {};
21514
21520
  const data = buildFrontmatter(match.id || id, input, base);
21515
21521
  let body = parsed.content.trim();
@@ -21742,7 +21748,7 @@ var CANDIDATE_DISCOVERY_GUIDANCE2 = [
21742
21748
  // ../cli/src/core/deprecation-write.ts
21743
21749
  import fs7 from "fs";
21744
21750
  import path6 from "path";
21745
- import matter19 from "gray-matter";
21751
+ import matter21 from "gray-matter";
21746
21752
  var DeprecationWriteError = class extends Error {
21747
21753
  constructor(code, message) {
21748
21754
  super(message);
@@ -21760,7 +21766,7 @@ function atomicWrite2(filePath, content) {
21760
21766
  fs7.renameSync(tmp, filePath);
21761
21767
  }
21762
21768
  function serialize3(data, body) {
21763
- return matter19.stringify(`
21769
+ return matter21.stringify(`
21764
21770
  ${body.trim()}
21765
21771
  `, data);
21766
21772
  }
@@ -21826,7 +21832,7 @@ function validateTargetInput(dir, raw) {
21826
21832
  function loadPlanRaw(dir, planId) {
21827
21833
  const match = allPlanArtifacts(dir).find((a2) => a2.id === planId || a2.title === planId);
21828
21834
  if (!match) throw new DeprecationWriteError("NOT_FOUND", `Deprecation Plan "${planId}" not found.`);
21829
- const parsed = matter19(readFile(match.filePath));
21835
+ const parsed = matter21(readFile(match.filePath));
21830
21836
  const data = { ...parsed.data ?? {} };
21831
21837
  return { filePath: match.filePath, data, body: parsed.content.trim() };
21832
21838
  }
@@ -22014,12 +22020,12 @@ function markWorkItemReady(root, id, confirm2) {
22014
22020
  }
22015
22021
  const raw = readText(root, item.path);
22016
22022
  if (!raw) return fail(`Could not read Work Item file: ${item.path}`);
22017
- const parsed = matter20(raw);
22023
+ const parsed = matter23(raw);
22018
22024
  const data = { ...parsed.data };
22019
22025
  const today3 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
22020
22026
  data.status = "ready";
22021
22027
  data.ready_at = today3;
22022
- const newContent = matter20.stringify(parsed.content, data);
22028
+ const newContent = matter23.stringify(parsed.content, data);
22023
22029
  const posixPath = item.path.replace(/\\/g, "/");
22024
22030
  let newRelPath = item.path;
22025
22031
  if (posixPath.includes("/work-items/draft/")) {
@@ -22314,8 +22320,8 @@ function removeDeprecationTargetTool(root, planId, targetId, confirm2) {
22314
22320
  // src/multirepo.ts
22315
22321
  import fs8 from "fs";
22316
22322
  import path7 from "path";
22317
- import matter21 from "gray-matter";
22318
- import { parse as parseYaml11, stringify as stringifyYaml8 } from "yaml";
22323
+ import matter24 from "gray-matter";
22324
+ import { parse as parseYaml12, stringify as stringifyYaml8 } from "yaml";
22319
22325
  var ok2 = (data) => ({ ok: true, data });
22320
22326
  var fail2 = (message) => ({ ok: false, message });
22321
22327
  function moduleRepoPath(m2) {
@@ -22351,7 +22357,7 @@ function detectModuleStatus2(root, repoPath) {
22351
22357
  }
22352
22358
  let parsed = null;
22353
22359
  try {
22354
- parsed = parseYaml11(fs8.readFileSync(configPath, "utf-8"));
22360
+ parsed = parseYaml12(fs8.readFileSync(configPath, "utf-8"));
22355
22361
  } catch {
22356
22362
  }
22357
22363
  const role = parsed?.project?.role ?? parsed?.multirepo?.role;
@@ -22466,7 +22472,7 @@ function validateWorkItemModulesTool(root, args) {
22466
22472
  if (!wi) return fail2(`Work Item "${args.workItemId}" not found.`);
22467
22473
  const raw = readText(root, wi.path);
22468
22474
  if (!raw) return fail2(`Could not read Work Item file.`);
22469
- const parsed = matter21(raw);
22475
+ const parsed = matter24(raw);
22470
22476
  const data = parsed.data;
22471
22477
  const affectedModules = Array.isArray(data.affected_modules) ? data.affected_modules.map(String) : [];
22472
22478
  const codeEntries = Array.isArray(data.code) ? data.code.filter((c) => typeof c === "object" && c !== null).map((c) => ({ repo: typeof c.repo === "string" ? c.repo : void 0, paths: Array.isArray(c.paths) ? c.paths.map(String) : [] })) : [];
@@ -22519,7 +22525,7 @@ function getWorkItemContextTool(root, args) {
22519
22525
  if (!wi) return fail2(`Work Item "${args.workItemId}" not found.`);
22520
22526
  const raw = readText(root, wi.path);
22521
22527
  if (!raw) return fail2(`Could not read Work Item file.`);
22522
- const parsed = matter21(raw);
22528
+ const parsed = matter24(raw);
22523
22529
  const data = parsed.data;
22524
22530
  const affectedModules = Array.isArray(data.affected_modules) ? data.affected_modules.map(String) : [];
22525
22531
  const codeEntries = Array.isArray(data.code) ? data.code.filter((c) => typeof c === "object" && c !== null).map((c) => ({ repo: typeof c.repo === "string" ? c.repo : void 0, paths: Array.isArray(c.paths) ? c.paths.map(String) : [] })) : [];
@@ -22605,7 +22611,7 @@ function suggestBranchStrategyTool(root, args) {
22605
22611
  if (!wi) return fail2(`Work Item "${args.workItemId}" not found.`);
22606
22612
  const raw = readText(root, wi.path);
22607
22613
  if (!raw) return fail2(`Could not read Work Item file.`);
22608
- const parsed = matter21(raw);
22614
+ const parsed = matter24(raw);
22609
22615
  const data = parsed.data;
22610
22616
  const affectedModules = Array.isArray(data.affected_modules) ? data.affected_modules.map(String) : [];
22611
22617
  const codeEntries = Array.isArray(data.code) ? data.code.filter((c) => typeof c === "object" && c !== null).map((c) => ({ repo: typeof c.repo === "string" ? c.repo : void 0, paths: Array.isArray(c.paths) ? c.paths.map(String) : [] })) : [];
@@ -22778,7 +22784,7 @@ function modulesDiscoverTool(root, args) {
22778
22784
  }
22779
22785
  let parsed = null;
22780
22786
  try {
22781
- parsed = parseYaml11(fs8.readFileSync(cfgPath, "utf-8"));
22787
+ parsed = parseYaml12(fs8.readFileSync(cfgPath, "utf-8"));
22782
22788
  } catch {
22783
22789
  }
22784
22790
  const role = parsed?.project?.role ?? parsed?.multirepo?.role;
@@ -22851,7 +22857,7 @@ ${list3(data.owners)}
22851
22857
  }
22852
22858
 
22853
22859
  // ../cli/src/core/system-topology.ts
22854
- import { parse as parseYaml12, stringify as stringifyYaml9 } from "yaml";
22860
+ import { parse as parseYaml13, stringify as stringifyYaml9 } from "yaml";
22855
22861
  import fs9 from "fs";
22856
22862
  import path8 from "path";
22857
22863
  import crypto from "crypto";
@@ -22898,7 +22904,7 @@ function loadSystemTopology2(dir) {
22898
22904
  function parseTopologyContent2(raw, dir) {
22899
22905
  let parsed;
22900
22906
  try {
22901
- parsed = parseYaml12(raw) ?? {};
22907
+ parsed = parseYaml13(raw) ?? {};
22902
22908
  } catch {
22903
22909
  return { entities: [], relationships: [], findings: [{ level: "blocking", message: "The topology could not be parsed." }] };
22904
22910
  }
@@ -23365,14 +23371,14 @@ function systemImpactCandidatesTool(root, args) {
23365
23371
  }
23366
23372
 
23367
23373
  // ../cli/src/services/integrations.ts
23368
- import matter24 from "gray-matter";
23369
- import { parse as parseYaml13, stringify as stringifyYaml10 } from "yaml";
23374
+ import matter26 from "gray-matter";
23375
+ import { parse as parseYaml14, stringify as stringifyYaml10 } from "yaml";
23370
23376
 
23371
23377
  // ../cli/src/core/work-item-write.ts
23372
23378
  import fs10 from "fs";
23373
23379
  import path9 from "path";
23374
23380
  import crypto4 from "crypto";
23375
- import matter23 from "gray-matter";
23381
+ import matter25 from "gray-matter";
23376
23382
  var SECTION_ORDER2 = [
23377
23383
  "Actor",
23378
23384
  "Outcome",
@@ -24247,7 +24253,7 @@ function loadRaw(dir) {
24247
24253
  const abs = join(dir, INTEGRATIONS_FILE);
24248
24254
  if (!exists(abs)) return { integrations: [] };
24249
24255
  try {
24250
- return parseYaml13(readFile(abs)) ?? { integrations: [] };
24256
+ return parseYaml14(readFile(abs)) ?? { integrations: [] };
24251
24257
  } catch {
24252
24258
  return { integrations: [] };
24253
24259
  }
@@ -24420,7 +24426,7 @@ async function integrationsWorkItemTool(root, args) {
24420
24426
  }
24421
24427
 
24422
24428
  // ../cli/src/core/context-pack.ts
24423
- import matter25 from "gray-matter";
24429
+ import matter27 from "gray-matter";
24424
24430
  var CONTEXT_PACK_VERSION = "1";
24425
24431
  var ARCH_DIR4 = "knowledge";
24426
24432
  function readScanJson(dir) {
@@ -24433,7 +24439,7 @@ function readScanJson(dir) {
24433
24439
  }
24434
24440
  }
24435
24441
  function firstParagraph4(markdown) {
24436
- const body = matter25(markdown).content.trim();
24442
+ const body = matter27(markdown).content.trim();
24437
24443
  const para = body.split("\n\n").map((p) => p.trim()).find((p) => p && !p.startsWith("#"));
24438
24444
  return para ?? "";
24439
24445
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/mcp",
3
- "version": "3.124.4",
3
+ "version": "3.125.0",
4
4
  "description": "MCP server for Kaddo project knowledge: read-only resources/tools/prompts plus safe derived generation under .kaddo/.",
5
5
  "license": "MIT",
6
6
  "repository": {