@kaddo/mcp 3.124.3 → 3.124.5
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 +171 -83
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10406,16 +10406,25 @@ function buildGuardHistory(dir) {
|
|
|
10406
10406
|
// ../cli/src/core/reporting-evidence.ts
|
|
10407
10407
|
function graphHintFinding(hint) {
|
|
10408
10408
|
const affected = [hint.artifact_id, ...hint.path ? [hint.path] : []];
|
|
10409
|
+
const semantics = {
|
|
10410
|
+
"work-item": { classification: "coverage_gap", priority: "medium", action: "Review whether the active Work Item needs the missing declared relationship." },
|
|
10411
|
+
decision: { classification: "coverage_gap", priority: "low", action: "Review whether this decision should declare governed code paths." },
|
|
10412
|
+
capability: { classification: "coverage_gap", priority: "low", action: "Review whether this capability should connect to existing Work Items; the relationship is optional." },
|
|
10413
|
+
"knowledge-capsule": { classification: "review_hint", priority: "low", action: "Confirm whether this capsule is intended for direct contextual use or Work Item relationships." }
|
|
10414
|
+
};
|
|
10415
|
+
const semantic = semantics[hint.artifact_type];
|
|
10409
10416
|
return {
|
|
10410
10417
|
id: `graph-hint:${hint.artifact_id}:${hint.missing.join(",")}`,
|
|
10411
10418
|
category: "topology",
|
|
10419
|
+
classification: semantic.classification,
|
|
10420
|
+
resolution_status: "open",
|
|
10412
10421
|
source: "graph-hints",
|
|
10413
10422
|
affected_artifacts: affected,
|
|
10414
|
-
// Graph Hints are intentionally
|
|
10415
|
-
priority:
|
|
10423
|
+
// Graph Hints are intentionally non-blocking; their type determines priority and meaning.
|
|
10424
|
+
priority: semantic.priority,
|
|
10416
10425
|
evidence: hint.reason,
|
|
10417
10426
|
explanation: hint.message,
|
|
10418
|
-
suggested_action:
|
|
10427
|
+
suggested_action: semantic.action
|
|
10419
10428
|
};
|
|
10420
10429
|
}
|
|
10421
10430
|
function reportingProjectContext(dir) {
|
|
@@ -10635,9 +10644,11 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10635
10644
|
findings.push({
|
|
10636
10645
|
id: `knowledge-health:${layer2.toLowerCase()}`,
|
|
10637
10646
|
category: "knowledge",
|
|
10647
|
+
classification: "coverage_gap",
|
|
10648
|
+
resolution_status: "open",
|
|
10638
10649
|
source: "knowledge-health",
|
|
10639
10650
|
affected_artifacts: [layer2],
|
|
10640
|
-
priority: status === "Missing" ? "
|
|
10651
|
+
priority: status === "Missing" ? "medium" : "low",
|
|
10641
10652
|
evidence: `${layer2} knowledge maturity is ${status}.`,
|
|
10642
10653
|
explanation: `This assesses documented ${layer2} knowledge, not the quality of the product or implementation.`,
|
|
10643
10654
|
suggested_action: `Review ${layer2} knowledge coverage and the artifacts or relationships available for it.`
|
|
@@ -10647,12 +10658,29 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10647
10658
|
findings.push({
|
|
10648
10659
|
id: `ownership:${gap.id}`,
|
|
10649
10660
|
category: "delivery",
|
|
10661
|
+
classification: "coverage_gap",
|
|
10662
|
+
resolution_status: "open",
|
|
10650
10663
|
source: "work-item-ownership",
|
|
10651
10664
|
affected_artifacts: [gap.id, gap.path],
|
|
10652
10665
|
priority: "medium",
|
|
10653
10666
|
evidence: "A corrective Work Item has no declared code ownership.",
|
|
10654
10667
|
explanation: gap.title,
|
|
10655
|
-
suggested_action:
|
|
10668
|
+
suggested_action: "Review and add relevant code ownership declarations."
|
|
10669
|
+
});
|
|
10670
|
+
}
|
|
10671
|
+
for (const wi of completedWis) {
|
|
10672
|
+
if (!wi.validationStatus || !["not-started", "in-progress", "partial", "failed", "blocked"].includes(wi.validationStatus)) continue;
|
|
10673
|
+
findings.push({
|
|
10674
|
+
id: `completion-validation:${wi.id || wi.title}`,
|
|
10675
|
+
category: "delivery",
|
|
10676
|
+
classification: "review_hint",
|
|
10677
|
+
resolution_status: "open",
|
|
10678
|
+
source: "work-item-lifecycle",
|
|
10679
|
+
affected_artifacts: [wi.id || wi.title, wi.relPath],
|
|
10680
|
+
priority: "medium",
|
|
10681
|
+
evidence: `Lifecycle is completed while persisted validation is ${wi.validationStatus}.`,
|
|
10682
|
+
explanation: "This requires review against the Work Item completion contract; it is not automatically a failed or invalid completion.",
|
|
10683
|
+
suggested_action: "Review the validation evidence and confirm whether the completed lifecycle state is consistent with the Work Item completion contract."
|
|
10656
10684
|
});
|
|
10657
10685
|
}
|
|
10658
10686
|
findings.push(...graphHintEntries.map(graphHintFinding));
|
|
@@ -10695,7 +10723,6 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10695
10723
|
else if (g.scope === "active" && g.quality === "empty") actions.push("Run `kaddo impact --scope all` to measure accumulated knowledge impact.");
|
|
10696
10724
|
if (exp.roadmap.remaining > 0) actions.push(`Materialize the ${exp.roadmap.remaining} remaining roadmap candidate(s) with \`kaddo create --from roadmap\`.`);
|
|
10697
10725
|
for (const a2 of [
|
|
10698
|
-
groupedAction(gaps.missing_code_ownership, "Add `code:` ownership to"),
|
|
10699
10726
|
groupedAction(gaps.missing_source, "Add `source`/`source_id` to")
|
|
10700
10727
|
]) if (a2) actions.push(a2);
|
|
10701
10728
|
if (gaps.broad_ownership_globs.length > 0) actions.push(`Narrow ${gaps.broad_ownership_globs.length} broad ownership glob(s) into specific paths.`);
|
|
@@ -10783,7 +10810,7 @@ function buildImpactReport(dir, opts = {}, now = /* @__PURE__ */ new Date()) {
|
|
|
10783
10810
|
function ratio(have, total) {
|
|
10784
10811
|
return `${have}/${total}`;
|
|
10785
10812
|
}
|
|
10786
|
-
function renderImpactMarkdown(r2) {
|
|
10813
|
+
function renderImpactMarkdown(r2, opts = {}) {
|
|
10787
10814
|
const L = [];
|
|
10788
10815
|
L.push("# Kaddo Knowledge Impact Report", "");
|
|
10789
10816
|
L.push(`Generated at: ${r2.generated_at}`);
|
|
@@ -10805,10 +10832,10 @@ function renderImpactMarkdown(r2) {
|
|
|
10805
10832
|
if (r2.findings.length === 0) L.push("No current findings detected by the executed deterministic checks.");
|
|
10806
10833
|
if (r2.findings.length > 0) {
|
|
10807
10834
|
const cell = (value) => value.replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
|
|
10808
|
-
L.push("| Priority | Source | Affected | Finding | Suggested action |");
|
|
10809
|
-
L.push("
|
|
10835
|
+
L.push("| Classification | Priority | Status | Source | Affected | Finding | Suggested action |");
|
|
10836
|
+
L.push("|---|---|---|---|---|---|---|");
|
|
10810
10837
|
for (const finding of r2.findings) {
|
|
10811
|
-
L.push(`| ${finding.priority} | ${cell(finding.source)} | ${cell(finding.affected_artifacts.join(", ") || "not available")} | ${cell(finding.explanation)} Evidence: ${cell(finding.evidence)} | ${cell(finding.suggested_action)} |`);
|
|
10838
|
+
L.push(`| ${finding.classification} | ${finding.priority} | ${finding.resolution_status} | ${cell(finding.source)} | ${cell(finding.affected_artifacts.join(", ") || "not available")} | ${cell(finding.explanation)} Evidence: ${cell(finding.evidence)} | ${cell(finding.suggested_action)} |`);
|
|
10812
10839
|
}
|
|
10813
10840
|
}
|
|
10814
10841
|
L.push("");
|
|
@@ -10920,9 +10947,9 @@ function renderImpactMarkdown(r2) {
|
|
|
10920
10947
|
}
|
|
10921
10948
|
L.push("");
|
|
10922
10949
|
};
|
|
10923
|
-
gapSection("Work Items missing source", gp.missing_source);
|
|
10924
|
-
gapSection("Work Items missing code ownership", gp.missing_code_ownership);
|
|
10925
|
-
if (gp.broad_ownership_globs.length > 0) {
|
|
10950
|
+
if (opts.details) gapSection("Work Items missing source", gp.missing_source);
|
|
10951
|
+
if (opts.details) gapSection("Work Items missing code ownership", gp.missing_code_ownership);
|
|
10952
|
+
if (opts.details && gp.broad_ownership_globs.length > 0) {
|
|
10926
10953
|
L.push("### Broad ownership globs", "");
|
|
10927
10954
|
for (const b2 of gp.broad_ownership_globs) {
|
|
10928
10955
|
L.push(`- ${b2.id} \u2014 ${b2.title}`);
|
|
@@ -10933,16 +10960,26 @@ function renderImpactMarkdown(r2) {
|
|
|
10933
10960
|
}
|
|
10934
10961
|
if (gp.ownership_overlaps.length > 0) {
|
|
10935
10962
|
L.push("### Shared code-path history (review only)", "");
|
|
10936
|
-
|
|
10937
|
-
|
|
10938
|
-
|
|
10939
|
-
|
|
10963
|
+
if (opts.details) {
|
|
10964
|
+
for (const o2 of gp.ownership_overlaps) {
|
|
10965
|
+
L.push(`- \`${o2.code_path}\``);
|
|
10966
|
+
L.push(` - Owned by: ${o2.work_items.join(", ")}`);
|
|
10967
|
+
L.push(` - Suggested action: ${o2.suggested_action}`);
|
|
10968
|
+
}
|
|
10969
|
+
} else {
|
|
10970
|
+
L.push(`- ${gp.ownership_overlaps.length} shared path declaration(s) detected. These are historical relationships, not necessarily ownership conflicts.`);
|
|
10971
|
+
const areas = gp.ownership_overlaps.slice(0, 3).map((o2) => `\`${o2.code_path}\``);
|
|
10972
|
+
if (areas.length > 0) L.push(`- Most involved paths: ${areas.join(", ")}.`);
|
|
10973
|
+
L.push("- Run `kaddo impact --details` for the complete shared-path inventory.");
|
|
10940
10974
|
}
|
|
10941
10975
|
L.push("");
|
|
10942
10976
|
}
|
|
10943
10977
|
const anyGaps = gp.missing_source.length + gp.missing_code_ownership.length + gp.broad_ownership_globs.length;
|
|
10944
10978
|
if (anyGaps === 0) {
|
|
10945
10979
|
L.push("No actionable knowledge gaps detected. \u{1F389}", "");
|
|
10980
|
+
} else if (!opts.details) {
|
|
10981
|
+
L.push("- Current actionable items are listed in Key Findings. Run `kaddo impact --details` for the full artifact inventory.");
|
|
10982
|
+
L.push("");
|
|
10946
10983
|
}
|
|
10947
10984
|
const historical = [
|
|
10948
10985
|
["knowledge level", gp.missing_knowledge_level],
|
|
@@ -11205,7 +11242,7 @@ function renderSavingsMarkdown(r2) {
|
|
|
11205
11242
|
L.push("");
|
|
11206
11243
|
L.push("## Evidence Used", "");
|
|
11207
11244
|
const e = r2.evidence;
|
|
11208
|
-
L.push(`- Knowledge Impact Score: ${e.knowledge_impact_score ?? "not available"}${e.knowledge_impact_score !== null ? "/100" : ""}`);
|
|
11245
|
+
L.push(`- Legacy Knowledge Impact Score: ${e.knowledge_impact_score ?? "not available"}${e.knowledge_impact_score !== null ? "/100" : ""} (deprecated; informational only and not used for confidence)`);
|
|
11209
11246
|
L.push(`- Completed Work Items: ${e.completed_work_items}`);
|
|
11210
11247
|
L.push(`- Ownership coverage: ${e.ownership_coverage_percent}%`);
|
|
11211
11248
|
L.push(`- Work Items with Acceptance Criteria: ${e.work_items_with_acceptance_criteria}`);
|
|
@@ -11280,7 +11317,15 @@ function buildDriftReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
11280
11317
|
const workItems = discoverWorkItems(dir);
|
|
11281
11318
|
const verificationEvidence = workItems.filter((wi) => wi.validationStatus && wi.validationStatus !== "not-started");
|
|
11282
11319
|
const plans = getDeprecationPlans(dir);
|
|
11283
|
-
const
|
|
11320
|
+
const planDetails = plans.map((plan) => getDeprecationPlan(dir, plan.id)).filter((plan) => plan !== null);
|
|
11321
|
+
const plansWithoutTargets = planDetails.filter((plan) => plan.targets.length === 0);
|
|
11322
|
+
const plansWithTargets = planDetails.filter((plan) => plan.targets.length > 0);
|
|
11323
|
+
const targetFindingsByPlan = new Map(plansWithTargets.map((plan) => [
|
|
11324
|
+
plan.id,
|
|
11325
|
+
plan.targets.flatMap(validateTarget)
|
|
11326
|
+
]));
|
|
11327
|
+
const deprecationFindings = [...targetFindingsByPlan.values()].flat();
|
|
11328
|
+
const plansWithoutStructuralFindings = plansWithTargets.filter((plan) => (targetFindingsByPlan.get(plan.id) ?? []).length === 0);
|
|
11284
11329
|
const config = loadConfig(dir);
|
|
11285
11330
|
const topology = config ? buildGraph(dir, config, { scope: "all" }, now) : null;
|
|
11286
11331
|
const graphHints = topology ? buildGraphHints(dir, topology, now) : null;
|
|
@@ -11290,13 +11335,27 @@ function buildDriftReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
11290
11335
|
...deprecationFindings.map((finding, index) => ({
|
|
11291
11336
|
id: `deprecation-target:${index + 1}`,
|
|
11292
11337
|
category: "consistency",
|
|
11338
|
+
classification: "consistency_violation",
|
|
11339
|
+
resolution_status: "open",
|
|
11293
11340
|
source: "deprecation-target-validation",
|
|
11294
|
-
affected_artifacts: [],
|
|
11295
|
-
priority: "medium",
|
|
11296
|
-
evidence:
|
|
11341
|
+
affected_artifacts: finding.target ? [finding.target] : [],
|
|
11342
|
+
priority: finding.severity === "error" ? "high" : "medium",
|
|
11343
|
+
evidence: finding.message,
|
|
11297
11344
|
explanation: "A deterministic deprecation target consistency check reported a finding.",
|
|
11298
11345
|
suggested_action: "Review the affected deprecation target and its declared lifecycle evidence."
|
|
11299
|
-
}))
|
|
11346
|
+
})),
|
|
11347
|
+
...h2.available && h2.total_runs >= 2 ? h2.threads.filter((thread) => thread.status === "open").map((thread) => ({
|
|
11348
|
+
id: `guard-history:${thread.code_path}`,
|
|
11349
|
+
category: "consistency",
|
|
11350
|
+
classification: "historical_drift",
|
|
11351
|
+
resolution_status: "open",
|
|
11352
|
+
source: "guard-history",
|
|
11353
|
+
affected_artifacts: [thread.code_path, ...thread.related_artifacts],
|
|
11354
|
+
priority: "medium",
|
|
11355
|
+
evidence: `Recorded Guard observations from ${thread.first_detected} through ${thread.last_seen} remain unresolved.`,
|
|
11356
|
+
explanation: "Comparable Guard runs observed a possible code/knowledge drift thread over time.",
|
|
11357
|
+
suggested_action: "Review the recorded drift thread and update the relevant knowledge or ownership evidence."
|
|
11358
|
+
})) : []
|
|
11300
11359
|
];
|
|
11301
11360
|
const actions = [];
|
|
11302
11361
|
if (!h2.available) {
|
|
@@ -11313,12 +11372,17 @@ function buildDriftReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
11313
11372
|
consistency_evidence: [
|
|
11314
11373
|
{ id: "guard-current-consistency", label: "Current Guard consistency", classification: h2.available ? "observed" : "unknown", reason: h2.available ? `${h2.total_runs} recorded Guard run(s) provide deterministic consistency evidence.` : "No recorded Guard history is available." },
|
|
11315
11374
|
{ id: "lifecycle-consistency", label: "Lifecycle evidence consistency", classification: verificationEvidence.length > 0 ? "observed" : "unknown", reason: verificationEvidence.length > 0 ? `${verificationEvidence.length} Work Item(s) persist an implementation validation status.` : "No persisted Work Item validation status is available." },
|
|
11316
|
-
{ id: "deprecation-consistency", label: "Deprecation consistency", classification: plans.length === 0 ? "not_applicable" : deprecationFindings.length === 0 ? "derived" : "observed", reason: plans.length === 0 ? "No deprecation plans exist in this project." : deprecationFindings.length === 0 ? `${
|
|
11375
|
+
{ id: "deprecation-consistency", label: "Deprecation consistency", classification: plans.length === 0 ? "not_applicable" : plansWithTargets.length === 0 ? "unknown" : deprecationFindings.length === 0 ? "derived" : "observed", reason: plans.length === 0 ? "No deprecation plans exist in this project." : plansWithTargets.length === 0 ? `${plansWithoutTargets.length} plan(s) have no targets, so target consistency was not evaluated.` : deprecationFindings.length === 0 ? `${plansWithTargets.length} plan(s) with targets passed deterministic target consistency checks; ${plansWithoutTargets.length} plan(s) remain unevaluated because they have no targets.` : `${deprecationFindings.length} deterministic deprecation consistency finding(s) were detected.` },
|
|
11317
11376
|
{ id: "topology-consistency", label: "Knowledge topology consistency", classification: topology === null ? "unknown" : topologyHints === 0 ? "derived" : "observed", reason: topology === null ? "No project configuration is available to construct the topology." : topologyHints === 0 ? `The in-memory topology has ${topology.nodes.length} node(s) and no open deterministic hints.` : `The in-memory topology has ${topologyHints} open deterministic hint(s).` }
|
|
11318
11377
|
],
|
|
11319
11378
|
current_consistency_findings: currentConsistencyFindings,
|
|
11320
11379
|
structural_consistency: {
|
|
11321
|
-
deprecation_target_checks: plans.length === 0 ? "not_applicable" : deprecationFindings.length === 0 ? "passed" : "findings_detected",
|
|
11380
|
+
deprecation_target_checks: plans.length === 0 ? "not_applicable" : plansWithTargets.length === 0 ? "not_evaluated" : deprecationFindings.length === 0 ? "passed" : "findings_detected",
|
|
11381
|
+
plans_discovered: plans.length,
|
|
11382
|
+
plans_without_targets: plansWithoutTargets.length,
|
|
11383
|
+
plans_with_targets_evaluated: plansWithTargets.length,
|
|
11384
|
+
structural_findings: deprecationFindings.length,
|
|
11385
|
+
plans_without_structural_findings: plansWithoutStructuralFindings.length,
|
|
11322
11386
|
note: plans.length === 0 ? "No deprecation plans exist in this project." : "Target consistency checks validate declared structural state only; they do not verify operational removal from infrastructure, production or external consumers."
|
|
11323
11387
|
},
|
|
11324
11388
|
guard_history: {
|
|
@@ -11346,22 +11410,41 @@ function renderDriftMarkdown(r2) {
|
|
|
11346
11410
|
L.push("## Consistency Evidence", "");
|
|
11347
11411
|
for (const item of r2.consistency_evidence) L.push(`- ${item.label}: ${item.classification} \u2014 ${item.reason}`);
|
|
11348
11412
|
L.push("");
|
|
11349
|
-
|
|
11350
|
-
|
|
11351
|
-
|
|
11352
|
-
|
|
11413
|
+
const findingGroups = [
|
|
11414
|
+
{ classification: "consistency_violation", title: "Consistency Violations" },
|
|
11415
|
+
{ classification: "coverage_gap", title: "Coverage Gaps" },
|
|
11416
|
+
{ classification: "review_hint", title: "Review Hints" },
|
|
11417
|
+
{ classification: "historical_drift", title: "Historical Drift" }
|
|
11418
|
+
];
|
|
11419
|
+
L.push("## Current Findings Summary", "");
|
|
11420
|
+
for (const group of findingGroups) {
|
|
11421
|
+
const count = r2.current_consistency_findings.filter((finding) => finding.classification === group.classification).length;
|
|
11422
|
+
const unavailable = group.classification === "historical_drift" && !r2.guard_history.available;
|
|
11423
|
+
L.push(`- ${group.title}: ${unavailable ? "not available \u2014 no recorded Guard runs" : count}`);
|
|
11353
11424
|
}
|
|
11354
|
-
|
|
11355
|
-
|
|
11356
|
-
|
|
11357
|
-
|
|
11358
|
-
|
|
11359
|
-
|
|
11425
|
+
L.push("");
|
|
11426
|
+
L.push("## Current Consistency Findings", "");
|
|
11427
|
+
if (r2.current_consistency_findings.length === 0) L.push("No findings detected by the executed consistency checks.", "");
|
|
11428
|
+
const cell = (value) => value.replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
|
|
11429
|
+
for (const group of findingGroups) {
|
|
11430
|
+
const findings = r2.current_consistency_findings.filter((finding) => finding.classification === group.classification);
|
|
11431
|
+
if (findings.length === 0) continue;
|
|
11432
|
+
L.push(`### ${group.title}`, "");
|
|
11433
|
+
L.push("| Classification | Priority | Status | Source | Affected | Finding | Suggested action |");
|
|
11434
|
+
L.push("|---|---|---|---|---|---|---|");
|
|
11435
|
+
for (const finding of findings) {
|
|
11436
|
+
L.push(`| ${finding.classification} | ${finding.priority} | ${finding.resolution_status} | ${cell(finding.source)} | ${cell(finding.affected_artifacts.join(", ") || "not available")} | ${cell(finding.explanation)} Evidence: ${cell(finding.evidence)} | ${cell(finding.suggested_action)} |`);
|
|
11360
11437
|
}
|
|
11361
11438
|
L.push("");
|
|
11362
11439
|
}
|
|
11363
11440
|
L.push("## Structural Consistency Boundaries", "");
|
|
11364
11441
|
L.push(`- Deprecation target checks: ${r2.structural_consistency.deprecation_target_checks}`);
|
|
11442
|
+
L.push(`- Plans discovered: ${r2.structural_consistency.plans_discovered}`);
|
|
11443
|
+
L.push(`- Plans without targets: ${r2.structural_consistency.plans_without_targets}`);
|
|
11444
|
+
L.push(`- Plans with targets evaluated: ${r2.structural_consistency.plans_with_targets_evaluated}`);
|
|
11445
|
+
L.push(`- Structural findings: ${r2.structural_consistency.structural_findings}`);
|
|
11446
|
+
L.push(`- Plans without structural findings: ${r2.structural_consistency.plans_without_structural_findings}`);
|
|
11447
|
+
if (r2.structural_consistency.plans_without_targets > 0) L.push("- Target consistency for plans without targets: not evaluated \u2014 no targets defined.");
|
|
11365
11448
|
L.push(`- Note: ${r2.structural_consistency.note}`);
|
|
11366
11449
|
L.push("");
|
|
11367
11450
|
if (!r2.guard_history.available) {
|
|
@@ -12038,7 +12121,7 @@ function getPrompt(root, name) {
|
|
|
12038
12121
|
}
|
|
12039
12122
|
|
|
12040
12123
|
// src/tools.ts
|
|
12041
|
-
import
|
|
12124
|
+
import matter21 from "gray-matter";
|
|
12042
12125
|
|
|
12043
12126
|
// ../cli/dist/core.js
|
|
12044
12127
|
import fs3 from "fs";
|
|
@@ -12065,21 +12148,23 @@ import { dirname as dirname2, join as join22, parse as parse2 } from "path";
|
|
|
12065
12148
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
12066
12149
|
import matter92 from "gray-matter";
|
|
12067
12150
|
import matter102 from "gray-matter";
|
|
12151
|
+
import { parse as parseYaml82 } from "yaml";
|
|
12068
12152
|
import matter112 from "gray-matter";
|
|
12069
|
-
import
|
|
12153
|
+
import matter122 from "gray-matter";
|
|
12154
|
+
import { parse as parseYaml92, stringify as stringifyYaml52 } from "yaml";
|
|
12070
12155
|
import fs4 from "fs";
|
|
12071
12156
|
import path4 from "path";
|
|
12072
12157
|
import crypto2 from "crypto";
|
|
12073
|
-
import
|
|
12158
|
+
import matter132 from "gray-matter";
|
|
12074
12159
|
import crypto3 from "crypto";
|
|
12075
12160
|
import fs5 from "fs";
|
|
12076
|
-
import matter132 from "gray-matter";
|
|
12077
12161
|
import matter142 from "gray-matter";
|
|
12078
|
-
import { parse as parseYaml92, stringify as stringifyYaml6 } from "yaml";
|
|
12079
|
-
import { parse as parseYaml102, stringify as stringifyYaml7 } from "yaml";
|
|
12080
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";
|
|
12081
12165
|
import matter16 from "gray-matter";
|
|
12082
12166
|
import matter17 from "gray-matter";
|
|
12167
|
+
import matter18 from "gray-matter";
|
|
12083
12168
|
function exists2(p) {
|
|
12084
12169
|
return fs3.existsSync(p);
|
|
12085
12170
|
}
|
|
@@ -18396,6 +18481,9 @@ var LEGACY_STEPS2 = [
|
|
|
18396
18481
|
runGuard2,
|
|
18397
18482
|
captureLearning2
|
|
18398
18483
|
];
|
|
18484
|
+
var HISTORY_DIR2 = ".kaddo/history";
|
|
18485
|
+
var RUNS_PATH2 = `${HISTORY_DIR2}/guard-runs.jsonl`;
|
|
18486
|
+
var SUMMARY_PATH2 = `${HISTORY_DIR2}/guard-summary.json`;
|
|
18399
18487
|
var USER_FACING_KEYWORDS_EN = [
|
|
18400
18488
|
"user",
|
|
18401
18489
|
"visitor",
|
|
@@ -18582,7 +18670,7 @@ function loadSystemTopology(dir) {
|
|
|
18582
18670
|
function parseTopologyContent(raw, dir) {
|
|
18583
18671
|
let parsed;
|
|
18584
18672
|
try {
|
|
18585
|
-
parsed =
|
|
18673
|
+
parsed = parseYaml92(raw) ?? {};
|
|
18586
18674
|
} catch {
|
|
18587
18675
|
return { entities: [], relationships: [], findings: [{ level: "blocking", message: "The topology could not be parsed." }] };
|
|
18588
18676
|
}
|
|
@@ -18801,7 +18889,7 @@ function parseOriginalSnapshot(fm) {
|
|
|
18801
18889
|
function readBody(filePath) {
|
|
18802
18890
|
try {
|
|
18803
18891
|
const raw = readFile2(filePath);
|
|
18804
|
-
return
|
|
18892
|
+
return matter122(raw).content;
|
|
18805
18893
|
} catch {
|
|
18806
18894
|
return "";
|
|
18807
18895
|
}
|
|
@@ -19086,7 +19174,7 @@ function ensureH1(body, title) {
|
|
|
19086
19174
|
${trimmed}`;
|
|
19087
19175
|
}
|
|
19088
19176
|
function serialize2(data, body) {
|
|
19089
|
-
return
|
|
19177
|
+
return matter132.stringify(`
|
|
19090
19178
|
${body.trim()}
|
|
19091
19179
|
`, data);
|
|
19092
19180
|
}
|
|
@@ -20000,7 +20088,7 @@ function detectFormat(raw) {
|
|
|
20000
20088
|
if (!trimmed) throw new ImportError("EMPTY_INPUT", "Import content is empty.");
|
|
20001
20089
|
if (trimmed.startsWith("---")) {
|
|
20002
20090
|
try {
|
|
20003
|
-
const { data } =
|
|
20091
|
+
const { data } = matter142(trimmed);
|
|
20004
20092
|
if (data && typeof data === "object" && Object.keys(data).length > 0) {
|
|
20005
20093
|
const d3 = data;
|
|
20006
20094
|
if (d3.type === "work-item" || d3.id && typeof d3.id === "string" && /^WI-\d+/.test(d3.id)) {
|
|
@@ -20022,7 +20110,7 @@ function parseContent(raw) {
|
|
|
20022
20110
|
let bodyText = trimmed;
|
|
20023
20111
|
if (format === "kaddo-frontmatter" || format === "markdown-frontmatter") {
|
|
20024
20112
|
try {
|
|
20025
|
-
const parsed =
|
|
20113
|
+
const parsed = matter142(trimmed);
|
|
20026
20114
|
frontmatterFields = parsed.data ?? {};
|
|
20027
20115
|
bodyText = parsed.content.trim();
|
|
20028
20116
|
} catch {
|
|
@@ -20119,7 +20207,7 @@ function findDuplicateByHash(dir, hash) {
|
|
|
20119
20207
|
const raw = readFile2(item.filePath);
|
|
20120
20208
|
if (!raw) continue;
|
|
20121
20209
|
try {
|
|
20122
|
-
const { data } =
|
|
20210
|
+
const { data } = matter142(raw);
|
|
20123
20211
|
const source22 = data?.source;
|
|
20124
20212
|
if (source22 && typeof source22 === "object" && !Array.isArray(source22)) {
|
|
20125
20213
|
const s = source22;
|
|
@@ -20835,7 +20923,7 @@ function persistConsent(dir, consent) {
|
|
|
20835
20923
|
const configPath = join3(dir, ".kaddo", "config.yml");
|
|
20836
20924
|
if (!exists2(configPath)) return;
|
|
20837
20925
|
const raw = readFile2(configPath);
|
|
20838
|
-
const doc =
|
|
20926
|
+
const doc = parseYaml11(raw) ?? {};
|
|
20839
20927
|
const prev = doc.telemetry ?? {};
|
|
20840
20928
|
delete prev.enabled;
|
|
20841
20929
|
doc.telemetry = { ...prev, consent, consentVersion: CURRENT_CONSENT_VERSION };
|
|
@@ -21014,7 +21102,7 @@ function buildInitiativeContent(id, input) {
|
|
|
21014
21102
|
if (input.priority) data.priority = input.priority;
|
|
21015
21103
|
if (input.source) data.source = input.source;
|
|
21016
21104
|
if (input.sourceId) data.source_id = input.sourceId;
|
|
21017
|
-
return
|
|
21105
|
+
return matter16.stringify("\n" + (input.body ?? defaultBody(input.title.trim())), data);
|
|
21018
21106
|
}
|
|
21019
21107
|
function createInitiative(dir, input) {
|
|
21020
21108
|
if (!input.title?.trim()) throw new InitiativeWriteError("Initiative title is required.");
|
|
@@ -21038,10 +21126,10 @@ function transitionInitiative(dir, id, to) {
|
|
|
21038
21126
|
throw new InitiativeWriteError(`Invalid transition ${ini.status} \u2192 ${to}.`);
|
|
21039
21127
|
}
|
|
21040
21128
|
const raw = readFile2(ini.filePath);
|
|
21041
|
-
const { data, content } =
|
|
21129
|
+
const { data, content } = matter16(raw, {});
|
|
21042
21130
|
data.status = to;
|
|
21043
21131
|
if (to === "completed") data.completed_at = today2();
|
|
21044
|
-
const newContent =
|
|
21132
|
+
const newContent = matter16.stringify(content, data);
|
|
21045
21133
|
writeFile2(ini.filePath, newContent);
|
|
21046
21134
|
const updated = parseInitiative2(dir, ini.filePath, newContent);
|
|
21047
21135
|
if (!updated) throw new InitiativeWriteError("Failed to parse the Initiative after transition.");
|
|
@@ -21051,7 +21139,7 @@ function addCandidate(dir, id, candidate) {
|
|
|
21051
21139
|
const ini = getInitiative(dir, id);
|
|
21052
21140
|
if (!ini) throw new InitiativeWriteError(`Initiative ${id} not found.`);
|
|
21053
21141
|
const raw = readFile2(ini.filePath);
|
|
21054
|
-
const { data, content } =
|
|
21142
|
+
const { data, content } = matter16(raw, {});
|
|
21055
21143
|
const existing = Array.isArray(data.candidates) ? data.candidates : [];
|
|
21056
21144
|
const fallbackId = `WI-CANDIDATE-${String(existing.length + 1).padStart(3, "0")}`;
|
|
21057
21145
|
const normalized = normalizeCandidate(candidate, fallbackId);
|
|
@@ -21059,7 +21147,7 @@ function addCandidate(dir, id, candidate) {
|
|
|
21059
21147
|
throw new InitiativeWriteError(`Candidate ${normalized.id} already exists in ${id}.`);
|
|
21060
21148
|
}
|
|
21061
21149
|
data.candidates = [...existing, candidateToData(normalized)];
|
|
21062
|
-
const newContent =
|
|
21150
|
+
const newContent = matter16.stringify(content, data);
|
|
21063
21151
|
writeFile2(ini.filePath, newContent);
|
|
21064
21152
|
const updated = parseInitiative2(dir, ini.filePath, newContent);
|
|
21065
21153
|
if (!updated) throw new InitiativeWriteError("Failed to parse the Initiative after adding a candidate.");
|
|
@@ -21069,7 +21157,7 @@ function updateInitiative(dir, id, patch) {
|
|
|
21069
21157
|
const ini = getInitiative(dir, id);
|
|
21070
21158
|
if (!ini) throw new InitiativeWriteError(`Initiative ${id} not found.`);
|
|
21071
21159
|
const raw = readFile2(ini.filePath);
|
|
21072
|
-
const { data, content } =
|
|
21160
|
+
const { data, content } = matter16(raw, {});
|
|
21073
21161
|
if (patch.title !== void 0) {
|
|
21074
21162
|
if (!patch.title.trim()) throw new InitiativeWriteError("Initiative title cannot be empty.");
|
|
21075
21163
|
data.title = patch.title.trim();
|
|
@@ -21079,7 +21167,7 @@ function updateInitiative(dir, id, patch) {
|
|
|
21079
21167
|
if (patch.knowledgeLevel !== void 0) data.knowledge_level = patch.knowledgeLevel;
|
|
21080
21168
|
if (patch.domains !== void 0) data.domains = patch.domains;
|
|
21081
21169
|
if (patch.relatedCapabilities !== void 0) data.related_capabilities = patch.relatedCapabilities;
|
|
21082
|
-
const newContent =
|
|
21170
|
+
const newContent = matter16.stringify(content, data);
|
|
21083
21171
|
writeFile2(ini.filePath, newContent);
|
|
21084
21172
|
const updated = parseInitiative2(dir, ini.filePath, newContent);
|
|
21085
21173
|
if (!updated) throw new InitiativeWriteError("Failed to parse the Initiative after update.");
|
|
@@ -21097,10 +21185,10 @@ function addExternalLink(dir, id, link) {
|
|
|
21097
21185
|
throw new InitiativeWriteError(`External link ${link.integration}:${link.externalId} already exists on ${id}.`);
|
|
21098
21186
|
}
|
|
21099
21187
|
const raw = readFile2(ini.filePath);
|
|
21100
|
-
const { data, content } =
|
|
21188
|
+
const { data, content } = matter16(raw, {});
|
|
21101
21189
|
const existing = Array.isArray(data.external_links) ? data.external_links : [];
|
|
21102
21190
|
data.external_links = [...existing, externalLinkToData(link)];
|
|
21103
|
-
const newContent =
|
|
21191
|
+
const newContent = matter16.stringify(content, data);
|
|
21104
21192
|
writeFile2(ini.filePath, newContent);
|
|
21105
21193
|
const updated = parseInitiative2(dir, ini.filePath, newContent);
|
|
21106
21194
|
if (!updated) throw new InitiativeWriteError("Failed to parse the Initiative after adding an external link.");
|
|
@@ -21169,7 +21257,7 @@ function buildWorkItemContent(wiId, iniId, candidate) {
|
|
|
21169
21257
|
"_What did we learn? Update after completion._",
|
|
21170
21258
|
""
|
|
21171
21259
|
].join("\n");
|
|
21172
|
-
return
|
|
21260
|
+
return matter16.stringify("\n" + body, data);
|
|
21173
21261
|
}
|
|
21174
21262
|
function materializeCandidate(dir, id, candidateId) {
|
|
21175
21263
|
const ini = getInitiative(dir, id);
|
|
@@ -21186,13 +21274,13 @@ function materializeCandidate(dir, id, candidateId) {
|
|
|
21186
21274
|
ensureDir2(join3(dir, DRAFT_DIR));
|
|
21187
21275
|
writeFile2(join3(dir, DRAFT_DIR, fileName), buildWorkItemContent(wiId, ini.id, candidate));
|
|
21188
21276
|
const raw = readFile2(ini.filePath);
|
|
21189
|
-
const { data, content } =
|
|
21277
|
+
const { data, content } = matter16(raw, {});
|
|
21190
21278
|
const cands = Array.isArray(data.candidates) ? data.candidates : [];
|
|
21191
21279
|
for (const c of cands) {
|
|
21192
21280
|
if (c && typeof c === "object" && String(c.id) === candidateId) c.materialized_as = wiId;
|
|
21193
21281
|
}
|
|
21194
21282
|
data.candidates = cands;
|
|
21195
|
-
const newContent =
|
|
21283
|
+
const newContent = matter16.stringify(content, data);
|
|
21196
21284
|
writeFile2(ini.filePath, newContent);
|
|
21197
21285
|
const updated = parseInitiative2(dir, ini.filePath, newContent);
|
|
21198
21286
|
if (!updated) throw new InitiativeWriteError("Failed to parse the Initiative after materialization.");
|
|
@@ -21306,7 +21394,7 @@ function evaluateInitiativeCompletion(dir, ini) {
|
|
|
21306
21394
|
// ../cli/src/core/resource-write.ts
|
|
21307
21395
|
import fs6 from "fs";
|
|
21308
21396
|
import path5 from "path";
|
|
21309
|
-
import
|
|
21397
|
+
import matter19 from "gray-matter";
|
|
21310
21398
|
var RESOURCES_DIR = "knowledge/tech/resources";
|
|
21311
21399
|
var ResourceWriteError = class extends Error {
|
|
21312
21400
|
constructor(code, message) {
|
|
@@ -21386,7 +21474,7 @@ function buildFrontmatter(id, input, base = {}) {
|
|
|
21386
21474
|
return data;
|
|
21387
21475
|
}
|
|
21388
21476
|
function serialize(data, body) {
|
|
21389
|
-
return
|
|
21477
|
+
return matter19.stringify(`
|
|
21390
21478
|
${body.trim()}
|
|
21391
21479
|
`, data);
|
|
21392
21480
|
}
|
|
@@ -21426,7 +21514,7 @@ function updateResource(dir, id, input) {
|
|
|
21426
21514
|
throw new ResourceWriteError("VALIDATION_FAILED", findings.filter((f3) => f3.level === "error").map((f3) => f3.message).join("; "));
|
|
21427
21515
|
}
|
|
21428
21516
|
const raw = readFile(match.filePath);
|
|
21429
|
-
const parsed =
|
|
21517
|
+
const parsed = matter19(raw);
|
|
21430
21518
|
const base = parsed.data ?? {};
|
|
21431
21519
|
const data = buildFrontmatter(match.id || id, input, base);
|
|
21432
21520
|
let body = parsed.content.trim();
|
|
@@ -21659,7 +21747,7 @@ var CANDIDATE_DISCOVERY_GUIDANCE2 = [
|
|
|
21659
21747
|
// ../cli/src/core/deprecation-write.ts
|
|
21660
21748
|
import fs7 from "fs";
|
|
21661
21749
|
import path6 from "path";
|
|
21662
|
-
import
|
|
21750
|
+
import matter20 from "gray-matter";
|
|
21663
21751
|
var DeprecationWriteError = class extends Error {
|
|
21664
21752
|
constructor(code, message) {
|
|
21665
21753
|
super(message);
|
|
@@ -21677,7 +21765,7 @@ function atomicWrite2(filePath, content) {
|
|
|
21677
21765
|
fs7.renameSync(tmp, filePath);
|
|
21678
21766
|
}
|
|
21679
21767
|
function serialize3(data, body) {
|
|
21680
|
-
return
|
|
21768
|
+
return matter20.stringify(`
|
|
21681
21769
|
${body.trim()}
|
|
21682
21770
|
`, data);
|
|
21683
21771
|
}
|
|
@@ -21743,7 +21831,7 @@ function validateTargetInput(dir, raw) {
|
|
|
21743
21831
|
function loadPlanRaw(dir, planId) {
|
|
21744
21832
|
const match = allPlanArtifacts(dir).find((a2) => a2.id === planId || a2.title === planId);
|
|
21745
21833
|
if (!match) throw new DeprecationWriteError("NOT_FOUND", `Deprecation Plan "${planId}" not found.`);
|
|
21746
|
-
const parsed =
|
|
21834
|
+
const parsed = matter20(readFile(match.filePath));
|
|
21747
21835
|
const data = { ...parsed.data ?? {} };
|
|
21748
21836
|
return { filePath: match.filePath, data, body: parsed.content.trim() };
|
|
21749
21837
|
}
|
|
@@ -21931,12 +22019,12 @@ function markWorkItemReady(root, id, confirm2) {
|
|
|
21931
22019
|
}
|
|
21932
22020
|
const raw = readText(root, item.path);
|
|
21933
22021
|
if (!raw) return fail(`Could not read Work Item file: ${item.path}`);
|
|
21934
|
-
const parsed =
|
|
22022
|
+
const parsed = matter21(raw);
|
|
21935
22023
|
const data = { ...parsed.data };
|
|
21936
22024
|
const today3 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
21937
22025
|
data.status = "ready";
|
|
21938
22026
|
data.ready_at = today3;
|
|
21939
|
-
const newContent =
|
|
22027
|
+
const newContent = matter21.stringify(parsed.content, data);
|
|
21940
22028
|
const posixPath = item.path.replace(/\\/g, "/");
|
|
21941
22029
|
let newRelPath = item.path;
|
|
21942
22030
|
if (posixPath.includes("/work-items/draft/")) {
|
|
@@ -22231,8 +22319,8 @@ function removeDeprecationTargetTool(root, planId, targetId, confirm2) {
|
|
|
22231
22319
|
// src/multirepo.ts
|
|
22232
22320
|
import fs8 from "fs";
|
|
22233
22321
|
import path7 from "path";
|
|
22234
|
-
import
|
|
22235
|
-
import { parse as
|
|
22322
|
+
import matter23 from "gray-matter";
|
|
22323
|
+
import { parse as parseYaml12, stringify as stringifyYaml8 } from "yaml";
|
|
22236
22324
|
var ok2 = (data) => ({ ok: true, data });
|
|
22237
22325
|
var fail2 = (message) => ({ ok: false, message });
|
|
22238
22326
|
function moduleRepoPath(m2) {
|
|
@@ -22268,7 +22356,7 @@ function detectModuleStatus2(root, repoPath) {
|
|
|
22268
22356
|
}
|
|
22269
22357
|
let parsed = null;
|
|
22270
22358
|
try {
|
|
22271
|
-
parsed =
|
|
22359
|
+
parsed = parseYaml12(fs8.readFileSync(configPath, "utf-8"));
|
|
22272
22360
|
} catch {
|
|
22273
22361
|
}
|
|
22274
22362
|
const role = parsed?.project?.role ?? parsed?.multirepo?.role;
|
|
@@ -22383,7 +22471,7 @@ function validateWorkItemModulesTool(root, args) {
|
|
|
22383
22471
|
if (!wi) return fail2(`Work Item "${args.workItemId}" not found.`);
|
|
22384
22472
|
const raw = readText(root, wi.path);
|
|
22385
22473
|
if (!raw) return fail2(`Could not read Work Item file.`);
|
|
22386
|
-
const parsed =
|
|
22474
|
+
const parsed = matter23(raw);
|
|
22387
22475
|
const data = parsed.data;
|
|
22388
22476
|
const affectedModules = Array.isArray(data.affected_modules) ? data.affected_modules.map(String) : [];
|
|
22389
22477
|
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) : [] })) : [];
|
|
@@ -22436,7 +22524,7 @@ function getWorkItemContextTool(root, args) {
|
|
|
22436
22524
|
if (!wi) return fail2(`Work Item "${args.workItemId}" not found.`);
|
|
22437
22525
|
const raw = readText(root, wi.path);
|
|
22438
22526
|
if (!raw) return fail2(`Could not read Work Item file.`);
|
|
22439
|
-
const parsed =
|
|
22527
|
+
const parsed = matter23(raw);
|
|
22440
22528
|
const data = parsed.data;
|
|
22441
22529
|
const affectedModules = Array.isArray(data.affected_modules) ? data.affected_modules.map(String) : [];
|
|
22442
22530
|
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) : [] })) : [];
|
|
@@ -22522,7 +22610,7 @@ function suggestBranchStrategyTool(root, args) {
|
|
|
22522
22610
|
if (!wi) return fail2(`Work Item "${args.workItemId}" not found.`);
|
|
22523
22611
|
const raw = readText(root, wi.path);
|
|
22524
22612
|
if (!raw) return fail2(`Could not read Work Item file.`);
|
|
22525
|
-
const parsed =
|
|
22613
|
+
const parsed = matter23(raw);
|
|
22526
22614
|
const data = parsed.data;
|
|
22527
22615
|
const affectedModules = Array.isArray(data.affected_modules) ? data.affected_modules.map(String) : [];
|
|
22528
22616
|
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) : [] })) : [];
|
|
@@ -22695,7 +22783,7 @@ function modulesDiscoverTool(root, args) {
|
|
|
22695
22783
|
}
|
|
22696
22784
|
let parsed = null;
|
|
22697
22785
|
try {
|
|
22698
|
-
parsed =
|
|
22786
|
+
parsed = parseYaml12(fs8.readFileSync(cfgPath, "utf-8"));
|
|
22699
22787
|
} catch {
|
|
22700
22788
|
}
|
|
22701
22789
|
const role = parsed?.project?.role ?? parsed?.multirepo?.role;
|
|
@@ -22768,7 +22856,7 @@ ${list3(data.owners)}
|
|
|
22768
22856
|
}
|
|
22769
22857
|
|
|
22770
22858
|
// ../cli/src/core/system-topology.ts
|
|
22771
|
-
import { parse as
|
|
22859
|
+
import { parse as parseYaml13, stringify as stringifyYaml9 } from "yaml";
|
|
22772
22860
|
import fs9 from "fs";
|
|
22773
22861
|
import path8 from "path";
|
|
22774
22862
|
import crypto from "crypto";
|
|
@@ -22815,7 +22903,7 @@ function loadSystemTopology2(dir) {
|
|
|
22815
22903
|
function parseTopologyContent2(raw, dir) {
|
|
22816
22904
|
let parsed;
|
|
22817
22905
|
try {
|
|
22818
|
-
parsed =
|
|
22906
|
+
parsed = parseYaml13(raw) ?? {};
|
|
22819
22907
|
} catch {
|
|
22820
22908
|
return { entities: [], relationships: [], findings: [{ level: "blocking", message: "The topology could not be parsed." }] };
|
|
22821
22909
|
}
|
|
@@ -23282,14 +23370,14 @@ function systemImpactCandidatesTool(root, args) {
|
|
|
23282
23370
|
}
|
|
23283
23371
|
|
|
23284
23372
|
// ../cli/src/services/integrations.ts
|
|
23285
|
-
import
|
|
23286
|
-
import { parse as
|
|
23373
|
+
import matter25 from "gray-matter";
|
|
23374
|
+
import { parse as parseYaml14, stringify as stringifyYaml10 } from "yaml";
|
|
23287
23375
|
|
|
23288
23376
|
// ../cli/src/core/work-item-write.ts
|
|
23289
23377
|
import fs10 from "fs";
|
|
23290
23378
|
import path9 from "path";
|
|
23291
23379
|
import crypto4 from "crypto";
|
|
23292
|
-
import
|
|
23380
|
+
import matter24 from "gray-matter";
|
|
23293
23381
|
var SECTION_ORDER2 = [
|
|
23294
23382
|
"Actor",
|
|
23295
23383
|
"Outcome",
|
|
@@ -24164,7 +24252,7 @@ function loadRaw(dir) {
|
|
|
24164
24252
|
const abs = join(dir, INTEGRATIONS_FILE);
|
|
24165
24253
|
if (!exists(abs)) return { integrations: [] };
|
|
24166
24254
|
try {
|
|
24167
|
-
return
|
|
24255
|
+
return parseYaml14(readFile(abs)) ?? { integrations: [] };
|
|
24168
24256
|
} catch {
|
|
24169
24257
|
return { integrations: [] };
|
|
24170
24258
|
}
|
|
@@ -24337,7 +24425,7 @@ async function integrationsWorkItemTool(root, args) {
|
|
|
24337
24425
|
}
|
|
24338
24426
|
|
|
24339
24427
|
// ../cli/src/core/context-pack.ts
|
|
24340
|
-
import
|
|
24428
|
+
import matter26 from "gray-matter";
|
|
24341
24429
|
var CONTEXT_PACK_VERSION = "1";
|
|
24342
24430
|
var ARCH_DIR4 = "knowledge";
|
|
24343
24431
|
function readScanJson(dir) {
|
|
@@ -24350,7 +24438,7 @@ function readScanJson(dir) {
|
|
|
24350
24438
|
}
|
|
24351
24439
|
}
|
|
24352
24440
|
function firstParagraph4(markdown) {
|
|
24353
|
-
const body =
|
|
24441
|
+
const body = matter26(markdown).content.trim();
|
|
24354
24442
|
const para = body.split("\n\n").map((p) => p.trim()).find((p) => p && !p.startsWith("#"));
|
|
24355
24443
|
return para ?? "";
|
|
24356
24444
|
}
|
package/package.json
CHANGED