@kaddo/mcp 3.103.0 → 3.105.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.
- package/dist/index.js +223 -56
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10783,7 +10783,7 @@ function getPrompt(root, name) {
|
|
|
10783
10783
|
}
|
|
10784
10784
|
|
|
10785
10785
|
// src/tools.ts
|
|
10786
|
-
import
|
|
10786
|
+
import matter12 from "gray-matter";
|
|
10787
10787
|
|
|
10788
10788
|
// ../cli/dist/core.js
|
|
10789
10789
|
import fs3 from "fs";
|
|
@@ -10815,18 +10815,25 @@ import fs4 from "fs";
|
|
|
10815
10815
|
import matter82 from "gray-matter";
|
|
10816
10816
|
import matter92 from "gray-matter";
|
|
10817
10817
|
import { parse as parseYaml92, stringify as stringifyYaml5 } from "yaml";
|
|
10818
|
-
|
|
10819
|
-
|
|
10818
|
+
import { parse as parseYaml102, stringify as stringifyYaml6 } from "yaml";
|
|
10819
|
+
import matter102 from "gray-matter";
|
|
10820
|
+
import matter11 from "gray-matter";
|
|
10821
|
+
function exists2(p) {
|
|
10822
|
+
return fs3.existsSync(p);
|
|
10820
10823
|
}
|
|
10821
|
-
function readFile2(
|
|
10822
|
-
return fs3.readFileSync(
|
|
10824
|
+
function readFile2(p) {
|
|
10825
|
+
return fs3.readFileSync(p, "utf-8");
|
|
10826
|
+
}
|
|
10827
|
+
function writeFile2(filePath, content) {
|
|
10828
|
+
fs3.mkdirSync(path3.dirname(filePath), { recursive: true });
|
|
10829
|
+
fs3.writeFileSync(filePath, content, "utf-8");
|
|
10823
10830
|
}
|
|
10824
10831
|
function readDir2(dirPath) {
|
|
10825
10832
|
if (!exists2(dirPath)) return [];
|
|
10826
10833
|
return fs3.readdirSync(dirPath);
|
|
10827
10834
|
}
|
|
10828
|
-
function isFile2(
|
|
10829
|
-
return exists2(
|
|
10835
|
+
function isFile2(p) {
|
|
10836
|
+
return exists2(p) && fs3.statSync(p).isFile();
|
|
10830
10837
|
}
|
|
10831
10838
|
function join3(...parts) {
|
|
10832
10839
|
return path3.join(...parts);
|
|
@@ -11051,8 +11058,8 @@ function isActiveState2(s) {
|
|
|
11051
11058
|
return ACTIVE_STATES3.includes(s);
|
|
11052
11059
|
}
|
|
11053
11060
|
function lifecycleFolderOf2(filePath) {
|
|
11054
|
-
const
|
|
11055
|
-
const m2 =
|
|
11061
|
+
const p = filePath.replace(/\\/g, "/");
|
|
11062
|
+
const m2 = p.match(/\/delivery\/work-items\/([^/]+)\//);
|
|
11056
11063
|
if (m2 && isLifecycleState2(m2[1])) return m2[1];
|
|
11057
11064
|
return null;
|
|
11058
11065
|
}
|
|
@@ -11065,8 +11072,8 @@ function lifecycleStateOf2(item) {
|
|
|
11065
11072
|
return "ready";
|
|
11066
11073
|
}
|
|
11067
11074
|
var ARCH_DIR3 = "knowledge";
|
|
11068
|
-
function toPosix6(
|
|
11069
|
-
return
|
|
11075
|
+
function toPosix6(p) {
|
|
11076
|
+
return p.replace(/\\/g, "/");
|
|
11070
11077
|
}
|
|
11071
11078
|
function relativeTo2(dir, filePath) {
|
|
11072
11079
|
const base = toPosix6(dir).replace(/\/+$/, "");
|
|
@@ -12311,10 +12318,10 @@ ${QUALITY2}
|
|
|
12311
12318
|
`;
|
|
12312
12319
|
var EXTERNAL_PATH2 = ".kaddo/external.yml";
|
|
12313
12320
|
function loadExternalRegistry2(dir) {
|
|
12314
|
-
const
|
|
12315
|
-
if (!exists2(
|
|
12321
|
+
const p = join3(dir, EXTERNAL_PATH2);
|
|
12322
|
+
if (!exists2(p)) return [];
|
|
12316
12323
|
try {
|
|
12317
|
-
const parsed = parseYaml62(readFile2(
|
|
12324
|
+
const parsed = parseYaml62(readFile2(p));
|
|
12318
12325
|
return Array.isArray(parsed?.external) ? parsed.external : [];
|
|
12319
12326
|
} catch {
|
|
12320
12327
|
return [];
|
|
@@ -12326,8 +12333,8 @@ var ALL_STATUSES2 = ["draft", "ready", "in-progress", "blocked", "completed"];
|
|
|
12326
12333
|
function scopeStatuses2(scope) {
|
|
12327
12334
|
return scope === "all" ? { included: ALL_STATUSES2, excluded: ["archived"] } : { included: ACTIVE_STATUSES2, excluded: ["completed", "archived"] };
|
|
12328
12335
|
}
|
|
12329
|
-
function toPosix22(
|
|
12330
|
-
return
|
|
12336
|
+
function toPosix22(p) {
|
|
12337
|
+
return p.replace(/\\/g, "/");
|
|
12331
12338
|
}
|
|
12332
12339
|
function slug3(s) {
|
|
12333
12340
|
return s.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -12465,8 +12472,8 @@ function buildGraph2(dir, config, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
12465
12472
|
};
|
|
12466
12473
|
}
|
|
12467
12474
|
var KNOWLEDGE32 = "knowledge";
|
|
12468
|
-
function toPosix32(
|
|
12469
|
-
return
|
|
12475
|
+
function toPosix32(p) {
|
|
12476
|
+
return p.replace(/\\/g, "/");
|
|
12470
12477
|
}
|
|
12471
12478
|
function slug22(s) {
|
|
12472
12479
|
return s.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -12475,9 +12482,9 @@ function isAdr22(a2) {
|
|
|
12475
12482
|
return toPosix32(a2.filePath).includes("/tech/decisions/") && Boolean(a2.type);
|
|
12476
12483
|
}
|
|
12477
12484
|
function capabilityHeadings2(dir) {
|
|
12478
|
-
const
|
|
12479
|
-
if (!exists2(
|
|
12480
|
-
return readFile2(
|
|
12485
|
+
const p = join3(dir, KNOWLEDGE32, "product", "capabilities.md");
|
|
12486
|
+
if (!exists2(p)) return [];
|
|
12487
|
+
return readFile2(p).split(/\r?\n/).map((l2) => l2.match(/^#{2,3}\s+(.+?)\s*$/)).filter((m2) => Boolean(m2)).map((m2) => m2[1].trim()).filter((h2) => !/^(summary|resumen|overview|capabilities|capacidades)$/i.test(h2));
|
|
12481
12488
|
}
|
|
12482
12489
|
function humanMissing2(field) {
|
|
12483
12490
|
switch (field) {
|
|
@@ -15783,7 +15790,7 @@ var AGENT_PROMPTS2 = [
|
|
|
15783
15790
|
// Graph relationship quality (metadata hints → precise front matter — VS-056)
|
|
15784
15791
|
{ fileName: "graph-agent.md", content: GRAPH_AGENT2 }
|
|
15785
15792
|
// Every official prompt ends with its responsibility boundaries + Agent Trace footer.
|
|
15786
|
-
].map((
|
|
15793
|
+
].map((p) => ({ fileName: p.fileName, content: withResponsibilityTrace2(p.fileName, p.content) }));
|
|
15787
15794
|
function withAgentFrontMatter2(fileName, content) {
|
|
15788
15795
|
const name = fileName.replace(/\.md$/, "");
|
|
15789
15796
|
const fm = [
|
|
@@ -16422,8 +16429,8 @@ var TECHNICAL_RELATIONSHIP_TYPES = /* @__PURE__ */ new Set([
|
|
|
16422
16429
|
"implemented-by"
|
|
16423
16430
|
]);
|
|
16424
16431
|
var PROVENANCE = /* @__PURE__ */ new Set(["declared", "derived", "agent-reviewed"]);
|
|
16425
|
-
function isRelative(
|
|
16426
|
-
return typeof
|
|
16432
|
+
function isRelative(p) {
|
|
16433
|
+
return typeof p === "string" && p.trim() !== "" && !/^([a-zA-Z]:[\\/]|\/)/.test(p) && !p.includes("..");
|
|
16427
16434
|
}
|
|
16428
16435
|
function strList(v) {
|
|
16429
16436
|
return Array.isArray(v) ? v.map((x2) => typeof x2 === "string" ? x2.trim() : "").filter(Boolean) : [];
|
|
@@ -16466,9 +16473,9 @@ function parseTopologyContent(raw, dir) {
|
|
|
16466
16473
|
const moduleRaw = typeof e.module === "string" ? e.module.trim() : void 0;
|
|
16467
16474
|
if (moduleRaw && !validModules.has(moduleRaw)) findings.push({ level: "warning", message: `Entity "${id}" references unregistered module "${moduleRaw}".` });
|
|
16468
16475
|
const rawImpl = e.implementation ?? e.implementation_refs;
|
|
16469
|
-
const implementation = strList(rawImpl).filter((
|
|
16470
|
-
if (isRelative(
|
|
16471
|
-
findings.push({ level: "warning", message: `Entity "${id}" implementation ref "${
|
|
16476
|
+
const implementation = strList(rawImpl).filter((p) => {
|
|
16477
|
+
if (isRelative(p)) return true;
|
|
16478
|
+
findings.push({ level: "warning", message: `Entity "${id}" implementation ref "${p}" is not a safe relative path and was dropped.` });
|
|
16472
16479
|
return false;
|
|
16473
16480
|
});
|
|
16474
16481
|
const prov = e.provenance;
|
|
@@ -16676,8 +16683,8 @@ function splitSections(body) {
|
|
|
16676
16683
|
flush();
|
|
16677
16684
|
return sections;
|
|
16678
16685
|
}
|
|
16679
|
-
function isPlaceholder(
|
|
16680
|
-
const t =
|
|
16686
|
+
function isPlaceholder(text22) {
|
|
16687
|
+
const t = text22.trim();
|
|
16681
16688
|
if (!t) return true;
|
|
16682
16689
|
if (/^tbd$/i.test(t)) return true;
|
|
16683
16690
|
if (/^_[^_]*_$/.test(t) && !t.includes("\n")) return true;
|
|
@@ -16704,15 +16711,15 @@ function extractBullets(body) {
|
|
|
16704
16711
|
for (const line of body.split(/\r?\n/)) {
|
|
16705
16712
|
const m2 = line.match(/^\s*[-*+]\s+(.*)$/);
|
|
16706
16713
|
if (!m2) continue;
|
|
16707
|
-
let
|
|
16714
|
+
let text22 = m2[1].trim();
|
|
16708
16715
|
let checked = null;
|
|
16709
|
-
const cb =
|
|
16716
|
+
const cb = text22.match(/^\[([ xX])\]\s*(.*)$/);
|
|
16710
16717
|
if (cb) {
|
|
16711
16718
|
checked = cb[1].toLowerCase() === "x";
|
|
16712
|
-
|
|
16719
|
+
text22 = cb[2].trim();
|
|
16713
16720
|
}
|
|
16714
|
-
if (!
|
|
16715
|
-
out.push({ text:
|
|
16721
|
+
if (!text22 || isPlaceholder(text22)) continue;
|
|
16722
|
+
out.push({ text: text22, checked });
|
|
16716
16723
|
}
|
|
16717
16724
|
return out;
|
|
16718
16725
|
}
|
|
@@ -17457,7 +17464,7 @@ var SECRET_PATTERNS = [
|
|
|
17457
17464
|
/\.pfx$/i
|
|
17458
17465
|
];
|
|
17459
17466
|
function filterSecretPaths(paths) {
|
|
17460
|
-
return paths.filter((
|
|
17467
|
+
return paths.filter((p) => !SECRET_PATTERNS.some((re) => re.test(p)));
|
|
17461
17468
|
}
|
|
17462
17469
|
function collectImplementationEvidence(dir, workItemId, input) {
|
|
17463
17470
|
const artifacts = discoverWorkItems2(dir);
|
|
@@ -18488,6 +18495,103 @@ function createDefaultRegistry() {
|
|
|
18488
18495
|
return registry22;
|
|
18489
18496
|
}
|
|
18490
18497
|
var registry = createDefaultRegistry();
|
|
18498
|
+
var CURRENT_CONSENT_VERSION = 1;
|
|
18499
|
+
var DEFERRAL_DURATION_MS = 24 * 60 * 60 * 1e3;
|
|
18500
|
+
function getConsentState(config) {
|
|
18501
|
+
if (!config) return "unset";
|
|
18502
|
+
const t = config.telemetry;
|
|
18503
|
+
if (!t) return "unset";
|
|
18504
|
+
if (t.consent === "enabled") return "enabled";
|
|
18505
|
+
if (t.consent === "disabled") return "disabled";
|
|
18506
|
+
if (t.consent === void 0) {
|
|
18507
|
+
if (t.enabled === true) return "enabled";
|
|
18508
|
+
if (t.enabled === false) return "disabled";
|
|
18509
|
+
}
|
|
18510
|
+
return "unset";
|
|
18511
|
+
}
|
|
18512
|
+
function persistConsent(dir, consent) {
|
|
18513
|
+
const configPath = join3(dir, ".kaddo", "config.yml");
|
|
18514
|
+
if (!exists2(configPath)) return;
|
|
18515
|
+
const raw = readFile2(configPath);
|
|
18516
|
+
const doc = parseYaml102(raw) ?? {};
|
|
18517
|
+
const prev = doc.telemetry ?? {};
|
|
18518
|
+
delete prev.enabled;
|
|
18519
|
+
doc.telemetry = { ...prev, consent, consentVersion: CURRENT_CONSENT_VERSION };
|
|
18520
|
+
writeFile2(configPath, stringifyYaml6(doc));
|
|
18521
|
+
}
|
|
18522
|
+
function isDeferralActive(dir) {
|
|
18523
|
+
const p = join3(dir, ".kaddo", "telemetry-deferred.json");
|
|
18524
|
+
if (!exists2(p)) return false;
|
|
18525
|
+
try {
|
|
18526
|
+
const data = JSON.parse(readFile2(p));
|
|
18527
|
+
return data.deferredUntil > Date.now();
|
|
18528
|
+
} catch {
|
|
18529
|
+
return false;
|
|
18530
|
+
}
|
|
18531
|
+
}
|
|
18532
|
+
function deferConsent(dir) {
|
|
18533
|
+
const p = join3(dir, ".kaddo", "telemetry-deferred.json");
|
|
18534
|
+
writeFile2(p, JSON.stringify({ deferredUntil: Date.now() + DEFERRAL_DURATION_MS }));
|
|
18535
|
+
}
|
|
18536
|
+
function consentNotice() {
|
|
18537
|
+
return '[Telemetry consent] Anonymous usage telemetry has not been configured.\n Collects: command usage, version, lifecycle events.\n Never collects: source code, knowledge, prompts or PII.\n Use kaddo_set_telemetry_consent to enable, disable, or defer ("not-now").';
|
|
18538
|
+
}
|
|
18539
|
+
var TELEMETRY_DIR = ".kaddo/telemetry";
|
|
18540
|
+
var IDENTITY_FILE = "identity.json";
|
|
18541
|
+
function identityPath(dir) {
|
|
18542
|
+
return join3(dir, TELEMETRY_DIR, IDENTITY_FILE);
|
|
18543
|
+
}
|
|
18544
|
+
function loadIdentity(dir) {
|
|
18545
|
+
const p = identityPath(dir);
|
|
18546
|
+
if (!exists2(p)) return null;
|
|
18547
|
+
try {
|
|
18548
|
+
return JSON.parse(readFile2(p));
|
|
18549
|
+
} catch {
|
|
18550
|
+
return null;
|
|
18551
|
+
}
|
|
18552
|
+
}
|
|
18553
|
+
var TELEMETRY_DIR2 = ".kaddo/telemetry";
|
|
18554
|
+
var BUFFER_FILE = "buffer.json";
|
|
18555
|
+
function bufferPath(dir) {
|
|
18556
|
+
return join3(dir, TELEMETRY_DIR2, BUFFER_FILE);
|
|
18557
|
+
}
|
|
18558
|
+
function readBuffer(dir) {
|
|
18559
|
+
const p = bufferPath(dir);
|
|
18560
|
+
if (!exists2(p)) return [];
|
|
18561
|
+
try {
|
|
18562
|
+
const data = JSON.parse(readFile2(p));
|
|
18563
|
+
return Array.isArray(data) ? data : [];
|
|
18564
|
+
} catch {
|
|
18565
|
+
return [];
|
|
18566
|
+
}
|
|
18567
|
+
}
|
|
18568
|
+
function bufferSize(dir) {
|
|
18569
|
+
return readBuffer(dir).length;
|
|
18570
|
+
}
|
|
18571
|
+
function getStatus(dir) {
|
|
18572
|
+
const config = loadConfig2(dir);
|
|
18573
|
+
const consent = getConsentState(config);
|
|
18574
|
+
const enabled = consent === "enabled";
|
|
18575
|
+
const identity = loadIdentity(dir);
|
|
18576
|
+
return {
|
|
18577
|
+
consent,
|
|
18578
|
+
enabled,
|
|
18579
|
+
registered: identity?.registered ?? false,
|
|
18580
|
+
pendingEvents: enabled ? bufferSize(dir) : 0,
|
|
18581
|
+
lastError: null
|
|
18582
|
+
};
|
|
18583
|
+
}
|
|
18584
|
+
var INITIATIVE_STATES = [
|
|
18585
|
+
"candidate",
|
|
18586
|
+
"planned",
|
|
18587
|
+
"in-progress",
|
|
18588
|
+
"completed",
|
|
18589
|
+
"deferred",
|
|
18590
|
+
"cancelled"
|
|
18591
|
+
];
|
|
18592
|
+
var STATUS_SET = new Set(INITIATIVE_STATES);
|
|
18593
|
+
var WORK_ITEMS_DIR2 = "knowledge/delivery/work-items";
|
|
18594
|
+
var DRAFT_DIR = `${WORK_ITEMS_DIR2}/draft`;
|
|
18491
18595
|
|
|
18492
18596
|
// src/tools.ts
|
|
18493
18597
|
var ok = (data) => ({ ok: true, data });
|
|
@@ -18584,12 +18688,12 @@ function markWorkItemReady(root, id, confirm2) {
|
|
|
18584
18688
|
}
|
|
18585
18689
|
const raw = readText(root, item.path);
|
|
18586
18690
|
if (!raw) return fail(`Could not read Work Item file: ${item.path}`);
|
|
18587
|
-
const parsed =
|
|
18691
|
+
const parsed = matter12(raw);
|
|
18588
18692
|
const data = { ...parsed.data };
|
|
18589
18693
|
const today2 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
18590
18694
|
data.status = "ready";
|
|
18591
18695
|
data.ready_at = today2;
|
|
18592
|
-
const newContent =
|
|
18696
|
+
const newContent = matter12.stringify(parsed.content, data);
|
|
18593
18697
|
const posixPath = item.path.replace(/\\/g, "/");
|
|
18594
18698
|
let newRelPath = item.path;
|
|
18595
18699
|
if (posixPath.includes("/work-items/draft/")) {
|
|
@@ -18719,12 +18823,45 @@ function verifyWorkItemTool(root, args) {
|
|
|
18719
18823
|
return fail("Work Item verification failed.");
|
|
18720
18824
|
}
|
|
18721
18825
|
}
|
|
18826
|
+
function telemetryStatusTool(root) {
|
|
18827
|
+
const status = getStatus(root);
|
|
18828
|
+
const result = {
|
|
18829
|
+
consent: status.consent,
|
|
18830
|
+
registered: status.registered,
|
|
18831
|
+
pendingEvents: status.pendingEvents
|
|
18832
|
+
};
|
|
18833
|
+
if (status.consent === "unset" && !isDeferralActive(root)) {
|
|
18834
|
+
result.notice = consentNotice();
|
|
18835
|
+
}
|
|
18836
|
+
return ok(result);
|
|
18837
|
+
}
|
|
18838
|
+
function setTelemetryConsentTool(root, args) {
|
|
18839
|
+
const valid = ["enabled", "disabled", "not-now"];
|
|
18840
|
+
if (!valid.includes(args.consent)) {
|
|
18841
|
+
return fail(`consent must be one of: ${valid.join(", ")}`);
|
|
18842
|
+
}
|
|
18843
|
+
if (!args.confirm) {
|
|
18844
|
+
const preview = {
|
|
18845
|
+
action: args.consent,
|
|
18846
|
+
effect: args.consent === "enabled" ? "Anonymous usage telemetry will be activated. Kaddo will send command usage, version, and lifecycle events to telemetry.kaddo.org. No source code, knowledge, prompts or PII is ever transmitted." : args.consent === "disabled" ? "Telemetry will be permanently disabled. No data will be sent. Kaddo will not ask again." : "Consent decision deferred for 24 hours. Telemetry remains inactive. Kaddo will remind again after the deferral expires.",
|
|
18847
|
+
instruction: "Call again with confirm=true to apply."
|
|
18848
|
+
};
|
|
18849
|
+
return ok(preview);
|
|
18850
|
+
}
|
|
18851
|
+
if (args.consent === "not-now") {
|
|
18852
|
+
deferConsent(root);
|
|
18853
|
+
return ok({ applied: true, consent: "unset", deferred: true, message: "Consent deferred for 24 hours." });
|
|
18854
|
+
}
|
|
18855
|
+
const consent = args.consent;
|
|
18856
|
+
persistConsent(root, consent);
|
|
18857
|
+
return ok({ applied: true, consent, message: `Telemetry ${consent}.` });
|
|
18858
|
+
}
|
|
18722
18859
|
|
|
18723
18860
|
// src/multirepo.ts
|
|
18724
18861
|
import fs5 from "fs";
|
|
18725
18862
|
import path4 from "path";
|
|
18726
|
-
import
|
|
18727
|
-
import { parse as parseYaml11, stringify as
|
|
18863
|
+
import matter13 from "gray-matter";
|
|
18864
|
+
import { parse as parseYaml11, stringify as stringifyYaml7 } from "yaml";
|
|
18728
18865
|
var ok2 = (data) => ({ ok: true, data });
|
|
18729
18866
|
var fail2 = (message) => ({ ok: false, message });
|
|
18730
18867
|
function moduleRepoPath(m2) {
|
|
@@ -18733,7 +18870,7 @@ function moduleRepoPath(m2) {
|
|
|
18733
18870
|
function loadModulesDescriptor(root) {
|
|
18734
18871
|
return readYaml(root, ".kaddo/modules.yml") ?? { modules: [] };
|
|
18735
18872
|
}
|
|
18736
|
-
function
|
|
18873
|
+
function loadConfig4(root) {
|
|
18737
18874
|
return readYaml(root, ".kaddo/config.yml");
|
|
18738
18875
|
}
|
|
18739
18876
|
function projectRole2(config) {
|
|
@@ -18799,7 +18936,7 @@ function slugify3(s) {
|
|
|
18799
18936
|
return s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40);
|
|
18800
18937
|
}
|
|
18801
18938
|
function modulesListTool(root, args) {
|
|
18802
|
-
const config =
|
|
18939
|
+
const config = loadConfig4(root);
|
|
18803
18940
|
if (!config) return fail2("No Kaddo config found. Run `kaddo init` first.");
|
|
18804
18941
|
if (!isCore2(config)) return fail2("kaddo_modules_list can only be called from a core repository (project.role: core).");
|
|
18805
18942
|
const descriptor = loadModulesDescriptor(root);
|
|
@@ -18827,7 +18964,7 @@ function modulesListTool(root, args) {
|
|
|
18827
18964
|
});
|
|
18828
18965
|
}
|
|
18829
18966
|
function getModuleContextTool(root, args) {
|
|
18830
|
-
const config =
|
|
18967
|
+
const config = loadConfig4(root);
|
|
18831
18968
|
if (!config) return fail2("No Kaddo config found.");
|
|
18832
18969
|
const descriptor = loadModulesDescriptor(root);
|
|
18833
18970
|
const mod = (descriptor.modules ?? []).find((m2) => m2.id === args.module);
|
|
@@ -18875,7 +19012,7 @@ function validateWorkItemModulesTool(root, args) {
|
|
|
18875
19012
|
if (!wi) return fail2(`Work Item "${args.workItemId}" not found.`);
|
|
18876
19013
|
const raw = readText(root, wi.path);
|
|
18877
19014
|
if (!raw) return fail2(`Could not read Work Item file.`);
|
|
18878
|
-
const parsed =
|
|
19015
|
+
const parsed = matter13(raw);
|
|
18879
19016
|
const data = parsed.data;
|
|
18880
19017
|
const affectedModules = Array.isArray(data.affected_modules) ? data.affected_modules.map(String) : [];
|
|
18881
19018
|
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) : [] })) : [];
|
|
@@ -18921,14 +19058,14 @@ function validateWorkItemModulesTool(root, args) {
|
|
|
18921
19058
|
});
|
|
18922
19059
|
}
|
|
18923
19060
|
function getWorkItemContextTool(root, args) {
|
|
18924
|
-
const config =
|
|
19061
|
+
const config = loadConfig4(root);
|
|
18925
19062
|
if (!config) return fail2("No Kaddo config found.");
|
|
18926
19063
|
const items = listWorkItems(root);
|
|
18927
19064
|
const wi = items.find((w3) => w3.id === args.workItemId);
|
|
18928
19065
|
if (!wi) return fail2(`Work Item "${args.workItemId}" not found.`);
|
|
18929
19066
|
const raw = readText(root, wi.path);
|
|
18930
19067
|
if (!raw) return fail2(`Could not read Work Item file.`);
|
|
18931
|
-
const parsed =
|
|
19068
|
+
const parsed = matter13(raw);
|
|
18932
19069
|
const data = parsed.data;
|
|
18933
19070
|
const affectedModules = Array.isArray(data.affected_modules) ? data.affected_modules.map(String) : [];
|
|
18934
19071
|
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) : [] })) : [];
|
|
@@ -19014,7 +19151,7 @@ function suggestBranchStrategyTool(root, args) {
|
|
|
19014
19151
|
if (!wi) return fail2(`Work Item "${args.workItemId}" not found.`);
|
|
19015
19152
|
const raw = readText(root, wi.path);
|
|
19016
19153
|
if (!raw) return fail2(`Could not read Work Item file.`);
|
|
19017
|
-
const parsed =
|
|
19154
|
+
const parsed = matter13(raw);
|
|
19018
19155
|
const data = parsed.data;
|
|
19019
19156
|
const affectedModules = Array.isArray(data.affected_modules) ? data.affected_modules.map(String) : [];
|
|
19020
19157
|
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) : [] })) : [];
|
|
@@ -19027,7 +19164,7 @@ function suggestBranchStrategyTool(root, args) {
|
|
|
19027
19164
|
});
|
|
19028
19165
|
}
|
|
19029
19166
|
function exportCapsuleTool(root, args) {
|
|
19030
|
-
const config =
|
|
19167
|
+
const config = loadConfig4(root);
|
|
19031
19168
|
if (!config) return fail2("No Kaddo config found.");
|
|
19032
19169
|
const role = projectRole2(config);
|
|
19033
19170
|
const warnings = [];
|
|
@@ -19157,7 +19294,7 @@ function exportCapsuleTool(root, args) {
|
|
|
19157
19294
|
return ok2({ exported: true, type: capsuleType, module: args.module ?? void 0, paths: { json: jsonPath, md: mdPath }, warnings });
|
|
19158
19295
|
}
|
|
19159
19296
|
function modulesDiscoverTool(root, args) {
|
|
19160
|
-
const config =
|
|
19297
|
+
const config = loadConfig4(root);
|
|
19161
19298
|
if (!config) return fail2("No Kaddo config found.");
|
|
19162
19299
|
if (!isCore2(config)) return fail2("Module discovery is only available from a core repository.");
|
|
19163
19300
|
const sysName = config.system?.name ?? config.project?.name ?? "";
|
|
@@ -19214,7 +19351,7 @@ function modulesDiscoverTool(root, args) {
|
|
|
19214
19351
|
descriptor.modules.push({ id: d3.id, name: d3.id, path: d3.path, parent_system: sysName, status: "configured" });
|
|
19215
19352
|
}
|
|
19216
19353
|
}
|
|
19217
|
-
const ymlContent =
|
|
19354
|
+
const ymlContent = stringifyYaml7({ version: descriptor.version ?? 1, system: sysName, workspace_roots: workspaceRoots2, modules: descriptor.modules ?? [] });
|
|
19218
19355
|
writeDerived(root, ".kaddo/modules.yml", ymlContent);
|
|
19219
19356
|
return ok2({ discovered, applied: true });
|
|
19220
19357
|
}
|
|
@@ -19260,7 +19397,7 @@ ${list3(data.owners)}
|
|
|
19260
19397
|
}
|
|
19261
19398
|
|
|
19262
19399
|
// ../cli/src/core/system-topology.ts
|
|
19263
|
-
import { parse as parseYaml12, stringify as
|
|
19400
|
+
import { parse as parseYaml12, stringify as stringifyYaml8 } from "yaml";
|
|
19264
19401
|
import fs6 from "fs";
|
|
19265
19402
|
import path5 from "path";
|
|
19266
19403
|
import crypto from "crypto";
|
|
@@ -19774,14 +19911,14 @@ function systemImpactCandidatesTool(root, args) {
|
|
|
19774
19911
|
}
|
|
19775
19912
|
|
|
19776
19913
|
// ../cli/src/services/integrations.ts
|
|
19777
|
-
import
|
|
19778
|
-
import { parse as parseYaml13, stringify as
|
|
19914
|
+
import matter15 from "gray-matter";
|
|
19915
|
+
import { parse as parseYaml13, stringify as stringifyYaml9 } from "yaml";
|
|
19779
19916
|
|
|
19780
19917
|
// ../cli/src/core/work-item-write.ts
|
|
19781
19918
|
import fs7 from "fs";
|
|
19782
19919
|
import path6 from "path";
|
|
19783
19920
|
import crypto4 from "crypto";
|
|
19784
|
-
import
|
|
19921
|
+
import matter14 from "gray-matter";
|
|
19785
19922
|
var SECTION_ORDER2 = [
|
|
19786
19923
|
"Actor",
|
|
19787
19924
|
"Outcome",
|
|
@@ -20829,7 +20966,7 @@ async function integrationsWorkItemTool(root, args) {
|
|
|
20829
20966
|
}
|
|
20830
20967
|
|
|
20831
20968
|
// ../cli/src/core/context-pack.ts
|
|
20832
|
-
import
|
|
20969
|
+
import matter16 from "gray-matter";
|
|
20833
20970
|
var CONTEXT_PACK_VERSION = "1";
|
|
20834
20971
|
var ARCH_DIR4 = "knowledge";
|
|
20835
20972
|
function readScanJson(dir) {
|
|
@@ -20842,7 +20979,7 @@ function readScanJson(dir) {
|
|
|
20842
20979
|
}
|
|
20843
20980
|
}
|
|
20844
20981
|
function firstParagraph4(markdown) {
|
|
20845
|
-
const body =
|
|
20982
|
+
const body = matter16(markdown).content.trim();
|
|
20846
20983
|
const para = body.split("\n\n").map((p) => p.trim()).find((p) => p && !p.startsWith("#"));
|
|
20847
20984
|
return para ?? "";
|
|
20848
20985
|
}
|
|
@@ -22019,7 +22156,16 @@ function createServer(root) {
|
|
|
22019
22156
|
server.registerTool(
|
|
22020
22157
|
"kaddo_project_status",
|
|
22021
22158
|
{ title: "Kaddo project status", description: "Compact project status (state, phase, work items, ownership, graph quality, capsules).", inputSchema: {} },
|
|
22022
|
-
async () =>
|
|
22159
|
+
async () => {
|
|
22160
|
+
const result = guarded(root, () => projectStatus(root));
|
|
22161
|
+
if (result.ok) {
|
|
22162
|
+
const config = loadConfig2(root);
|
|
22163
|
+
if (getConsentState(config) === "unset" && !isDeferralActive(root)) {
|
|
22164
|
+
result.data.telemetryNotice = consentNotice();
|
|
22165
|
+
}
|
|
22166
|
+
}
|
|
22167
|
+
return toolText(result);
|
|
22168
|
+
}
|
|
22023
22169
|
);
|
|
22024
22170
|
server.registerTool(
|
|
22025
22171
|
"kaddo_list_work_items",
|
|
@@ -22344,6 +22490,27 @@ function createServer(root) {
|
|
|
22344
22490
|
},
|
|
22345
22491
|
async (args) => toolText(guarded(root, () => verifyWorkItemTool(root, args)))
|
|
22346
22492
|
);
|
|
22493
|
+
server.registerTool(
|
|
22494
|
+
"kaddo_telemetry_status",
|
|
22495
|
+
{
|
|
22496
|
+
title: "Telemetry status",
|
|
22497
|
+
description: "Read-only telemetry consent state, registration status, and pending events. Includes a consent notice when telemetry has not been configured.",
|
|
22498
|
+
inputSchema: {}
|
|
22499
|
+
},
|
|
22500
|
+
async () => toolText(guarded(root, () => telemetryStatusTool(root)))
|
|
22501
|
+
);
|
|
22502
|
+
server.registerTool(
|
|
22503
|
+
"kaddo_set_telemetry_consent",
|
|
22504
|
+
{
|
|
22505
|
+
title: "Set telemetry consent",
|
|
22506
|
+
description: "Set telemetry consent to enabled, disabled, or not-now (defer 24h). Without confirm=true returns a preview of the action. With confirm=true applies the change. Writes only .kaddo/config.yml (consent field).",
|
|
22507
|
+
inputSchema: {
|
|
22508
|
+
consent: z4.enum(["enabled", "disabled", "not-now"]).describe("Consent decision: enable telemetry, disable it, or defer for 24 hours"),
|
|
22509
|
+
confirm: z4.boolean().optional().describe("Must be true to apply the change")
|
|
22510
|
+
}
|
|
22511
|
+
},
|
|
22512
|
+
async (args) => toolText(guarded(root, () => setTelemetryConsentTool(root, args)))
|
|
22513
|
+
);
|
|
22347
22514
|
let installedSkills = [];
|
|
22348
22515
|
try {
|
|
22349
22516
|
assertKaddoProject(root);
|
package/package.json
CHANGED