@kaddo/cli 3.48.0 → 3.50.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 +254 -77
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5396,6 +5396,7 @@ function buildFrontMatter(id, type, level, title, answers) {
|
|
|
5396
5396
|
`domains: []`,
|
|
5397
5397
|
`code: []`,
|
|
5398
5398
|
`created_at: ${today2}`,
|
|
5399
|
+
`source: manual`,
|
|
5399
5400
|
`summary: "${answers.problem?.split(".")[0] ?? title}"`,
|
|
5400
5401
|
"---"
|
|
5401
5402
|
];
|
|
@@ -5482,6 +5483,7 @@ function buildModuleFrontMatter(id, modType, title, answers) {
|
|
|
5482
5483
|
`domains: []`,
|
|
5483
5484
|
`code: []`,
|
|
5484
5485
|
`created_at: ${today2}`,
|
|
5486
|
+
`source: manual`,
|
|
5485
5487
|
`summary: "${title}"`,
|
|
5486
5488
|
...extraLines,
|
|
5487
5489
|
"---"
|
|
@@ -5661,6 +5663,8 @@ function buildRoadmapFrontMatter(id, type, level, title, candidate, answers) {
|
|
|
5661
5663
|
// from the specific Work Item candidate it was materialized from.
|
|
5662
5664
|
`source_roadmap_initiative: ${candidate.initiative?.id ?? "unknown"}`,
|
|
5663
5665
|
`source_work_item_candidate: ${candidate.id}`,
|
|
5666
|
+
`source_title: "${q(candidate.title)}"`,
|
|
5667
|
+
`source_context: "Materialized from roadmap candidate ${candidate.id}${candidate.initiative?.id ? ` under initiative ${candidate.initiative.id}` : ""}."`,
|
|
5664
5668
|
...candidate.initiative?.title ? [`source_initiative_title: "${q(candidate.initiative.title)}"`] : [],
|
|
5665
5669
|
...candidate.domain ? [`related_domain: "${q(candidate.domain)}"`] : [],
|
|
5666
5670
|
...yamlList2("related_capabilities", relatedCapabilities),
|
|
@@ -5930,6 +5934,7 @@ function parseArtifact(filePath, raw) {
|
|
|
5930
5934
|
initiative: String(data.initiative ?? data.source_initiative ?? ""),
|
|
5931
5935
|
source: data.source ? String(data.source) : "",
|
|
5932
5936
|
sourceId: String(data.source_id ?? ""),
|
|
5937
|
+
rawFrontmatter: data,
|
|
5933
5938
|
decisions: Array.isArray(data.decisions) ? data.decisions.map(String).filter(Boolean) : [],
|
|
5934
5939
|
capsules: Array.isArray(data.capsules) ? data.capsules.map(String).filter(Boolean) : []
|
|
5935
5940
|
};
|
|
@@ -9047,7 +9052,7 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
9047
9052
|
const ctx = buildCodexAdapterContext(dir);
|
|
9048
9053
|
const agents = ctx.hasAgents ? "present" : "missing";
|
|
9049
9054
|
const skills = ctx.hasSkills ? "present" : "missing";
|
|
9050
|
-
const
|
|
9055
|
+
const bootstrapBaseline2 = presence.business !== "missing" && presence.product !== "missing" ? "complete" : "incomplete";
|
|
9051
9056
|
const roadmap = roadmapSignal(dir);
|
|
9052
9057
|
const work_items = workItemsSignal(dir);
|
|
9053
9058
|
const adapters = installedAdapters(dir);
|
|
@@ -9055,7 +9060,7 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
9055
9060
|
const signals = {
|
|
9056
9061
|
scan: scan2,
|
|
9057
9062
|
understand,
|
|
9058
|
-
bootstrap_baseline:
|
|
9063
|
+
bootstrap_baseline: bootstrapBaseline2,
|
|
9059
9064
|
agents,
|
|
9060
9065
|
skills,
|
|
9061
9066
|
current_state: presence.current_state,
|
|
@@ -9074,7 +9079,7 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
9074
9079
|
const firstWeak = KNOWLEDGE_FILES.find((f) => presence[f.key] !== "useful");
|
|
9075
9080
|
let overall;
|
|
9076
9081
|
if (scan2 === "missing") overall = "initialized";
|
|
9077
|
-
else if (
|
|
9082
|
+
else if (bootstrapBaseline2 === "incomplete") overall = "bootstrap-incomplete";
|
|
9078
9083
|
else if (agents === "missing") overall = "agents-missing";
|
|
9079
9084
|
else if (skills === "missing") overall = "skills-missing";
|
|
9080
9085
|
else if (understand === "missing") overall = "scanned";
|
|
@@ -9241,6 +9246,84 @@ function buildRoadmapQuality(dir) {
|
|
|
9241
9246
|
return { initiatives, work_item_candidates };
|
|
9242
9247
|
}
|
|
9243
9248
|
|
|
9249
|
+
// src/core/work-item-source.ts
|
|
9250
|
+
var VALID_SOURCES = [
|
|
9251
|
+
"manual",
|
|
9252
|
+
"roadmap",
|
|
9253
|
+
"jira",
|
|
9254
|
+
"github",
|
|
9255
|
+
"notion",
|
|
9256
|
+
"xlsx",
|
|
9257
|
+
"csv",
|
|
9258
|
+
"api",
|
|
9259
|
+
"external",
|
|
9260
|
+
"unknown"
|
|
9261
|
+
];
|
|
9262
|
+
function isValidSource(s) {
|
|
9263
|
+
return VALID_SOURCES.includes(s);
|
|
9264
|
+
}
|
|
9265
|
+
function parseWorkItemSource(frontmatter) {
|
|
9266
|
+
const raw = frontmatter.source ? String(frontmatter.source) : "";
|
|
9267
|
+
if (raw && isValidSource(raw)) {
|
|
9268
|
+
return {
|
|
9269
|
+
type: raw,
|
|
9270
|
+
id: optStr(frontmatter.source_id),
|
|
9271
|
+
title: optStr(frontmatter.source_title),
|
|
9272
|
+
context: optStr(frontmatter.source_context),
|
|
9273
|
+
provider: optStr(frontmatter.source_provider),
|
|
9274
|
+
url: optStr(frontmatter.source_url),
|
|
9275
|
+
imported_at: optStr(frontmatter.source_imported_at),
|
|
9276
|
+
synced_at: optStr(frontmatter.source_synced_at),
|
|
9277
|
+
inferred: false
|
|
9278
|
+
};
|
|
9279
|
+
}
|
|
9280
|
+
if (raw && !isValidSource(raw)) {
|
|
9281
|
+
return {
|
|
9282
|
+
type: "unknown",
|
|
9283
|
+
id: optStr(frontmatter.source_id),
|
|
9284
|
+
title: optStr(frontmatter.source_title),
|
|
9285
|
+
context: optStr(frontmatter.source_context),
|
|
9286
|
+
provider: optStr(frontmatter.source_provider),
|
|
9287
|
+
url: optStr(frontmatter.source_url),
|
|
9288
|
+
imported_at: optStr(frontmatter.source_imported_at),
|
|
9289
|
+
synced_at: optStr(frontmatter.source_synced_at),
|
|
9290
|
+
inferred: true,
|
|
9291
|
+
reason: `Invalid source value: "${raw}".`
|
|
9292
|
+
};
|
|
9293
|
+
}
|
|
9294
|
+
if (frontmatter.source_work_item_candidate || frontmatter.source_roadmap_initiative) {
|
|
9295
|
+
return {
|
|
9296
|
+
type: "roadmap",
|
|
9297
|
+
id: optStr(frontmatter.source_id) ?? optStr(frontmatter.source_work_item_candidate),
|
|
9298
|
+
title: optStr(frontmatter.source_initiative_title),
|
|
9299
|
+
inferred: true,
|
|
9300
|
+
reason: "Inferred from legacy roadmap fields."
|
|
9301
|
+
};
|
|
9302
|
+
}
|
|
9303
|
+
if (frontmatter.source_id) {
|
|
9304
|
+
return {
|
|
9305
|
+
type: "unknown",
|
|
9306
|
+
id: optStr(frontmatter.source_id),
|
|
9307
|
+
inferred: true,
|
|
9308
|
+
reason: "Has source_id but no source type."
|
|
9309
|
+
};
|
|
9310
|
+
}
|
|
9311
|
+
return {
|
|
9312
|
+
type: "unknown",
|
|
9313
|
+
inferred: true,
|
|
9314
|
+
reason: "No source metadata found."
|
|
9315
|
+
};
|
|
9316
|
+
}
|
|
9317
|
+
function renderSourceCompact(source) {
|
|
9318
|
+
const parts = [source.type];
|
|
9319
|
+
if (source.id) parts.push(source.id);
|
|
9320
|
+
return parts.join(" \xB7 ");
|
|
9321
|
+
}
|
|
9322
|
+
function optStr(v) {
|
|
9323
|
+
if (typeof v === "string" && v.trim()) return v.trim();
|
|
9324
|
+
return void 0;
|
|
9325
|
+
}
|
|
9326
|
+
|
|
9244
9327
|
// src/core/project-route.ts
|
|
9245
9328
|
function isUseful(q) {
|
|
9246
9329
|
return q === "useful";
|
|
@@ -9263,6 +9346,14 @@ var scanRepository = {
|
|
|
9263
9346
|
return { status: "done", evidence: [".kaddo/scan.json"] };
|
|
9264
9347
|
}
|
|
9265
9348
|
};
|
|
9349
|
+
var bootstrapBaseline = {
|
|
9350
|
+
id: "bootstrap",
|
|
9351
|
+
label: "Bootstrap knowledge baseline",
|
|
9352
|
+
evaluate: (ctx) => {
|
|
9353
|
+
if (ctx.qBusiness !== "missing" && ctx.qProduct !== "missing") return { status: "done", evidence: ["knowledge/business/business.md", "knowledge/product/product.md"] };
|
|
9354
|
+
return { status: "pending", command: "kaddo bootstrap", reason: "The knowledge baseline is incomplete." };
|
|
9355
|
+
}
|
|
9356
|
+
};
|
|
9266
9357
|
var defineBusiness = {
|
|
9267
9358
|
id: "define-business",
|
|
9268
9359
|
label: "Define business context",
|
|
@@ -9327,12 +9418,12 @@ var captureTechDecisions = {
|
|
|
9327
9418
|
var createWorkSource = {
|
|
9328
9419
|
id: "create-work-source",
|
|
9329
9420
|
label: "Create or connect work source",
|
|
9330
|
-
evaluate: (ctx) =>
|
|
9331
|
-
|
|
9332
|
-
|
|
9333
|
-
|
|
9334
|
-
|
|
9335
|
-
}
|
|
9421
|
+
evaluate: (ctx) => {
|
|
9422
|
+
if (!ctx.hasRoadmap && ctx.totalWorkItems === 0) return { status: "pending", command: "kaddo roadmap", agent: "roadmap-agent" };
|
|
9423
|
+
if (ctx.hasUnknownSources) return { status: "warning", evidence: ["Work Items with unknown source"], reason: "Some Work Items have no source metadata." };
|
|
9424
|
+
const evidence = ctx.hasRoadmap ? ["knowledge/delivery/roadmap.md"] : void 0;
|
|
9425
|
+
return { status: "done", evidence };
|
|
9426
|
+
}
|
|
9336
9427
|
};
|
|
9337
9428
|
var materializeWorkItem = {
|
|
9338
9429
|
id: "materialize-work-item",
|
|
@@ -9459,6 +9550,7 @@ var NEW_STEPS = [
|
|
|
9459
9550
|
var PRE_AI_STEPS = [
|
|
9460
9551
|
enableKaddo,
|
|
9461
9552
|
scanRepository,
|
|
9553
|
+
bootstrapBaseline,
|
|
9462
9554
|
defineBusiness,
|
|
9463
9555
|
defineProduct,
|
|
9464
9556
|
discoverCapabilities,
|
|
@@ -9476,6 +9568,7 @@ var PRE_AI_STEPS = [
|
|
|
9476
9568
|
var LEGACY_STEPS = [
|
|
9477
9569
|
enableKaddo,
|
|
9478
9570
|
scanRepository,
|
|
9571
|
+
bootstrapBaseline,
|
|
9479
9572
|
identifyLegacyModules,
|
|
9480
9573
|
{ ...discoverCapabilities, label: "Discover critical capabilities" },
|
|
9481
9574
|
describeArchitecture,
|
|
@@ -9549,6 +9642,10 @@ function buildRouteContext(dir) {
|
|
|
9549
9642
|
adaptersInstalled: adapters.length,
|
|
9550
9643
|
hasGuardHistory: exists(join(dir, ".kaddo", "history", "guard-runs.jsonl")),
|
|
9551
9644
|
hasScanWarnings: hasScan ? loadScanWarnings(dir) : false,
|
|
9645
|
+
hasUnknownSources: wis.some((w) => {
|
|
9646
|
+
const src = parseWorkItemSource(w.rawFrontmatter);
|
|
9647
|
+
return src.type === "unknown" && src.inferred;
|
|
9648
|
+
}),
|
|
9552
9649
|
nextStepId: mapNextStepId(nextStep.id)
|
|
9553
9650
|
};
|
|
9554
9651
|
}
|
|
@@ -9563,7 +9660,7 @@ function loadScanWarnings(dir) {
|
|
|
9563
9660
|
function mapNextStepId(id) {
|
|
9564
9661
|
const MAP = {
|
|
9565
9662
|
init: "enable-kaddo",
|
|
9566
|
-
bootstrap: "
|
|
9663
|
+
bootstrap: "bootstrap",
|
|
9567
9664
|
"add-agents": "enable-kaddo",
|
|
9568
9665
|
"add-skills": "enable-kaddo",
|
|
9569
9666
|
scan: "scan-repository",
|
|
@@ -9732,6 +9829,15 @@ function hasAgents(dir) {
|
|
|
9732
9829
|
}
|
|
9733
9830
|
return hasAgentMd(agentsDir);
|
|
9734
9831
|
}
|
|
9832
|
+
function hasSkills(dir) {
|
|
9833
|
+
const skillsDir = join(dir, ARCH_DIR4, "skills");
|
|
9834
|
+
if (!exists(skillsDir)) return false;
|
|
9835
|
+
try {
|
|
9836
|
+
return readDir(skillsDir).some((e) => e.endsWith(".md") && isFile(join(skillsDir, e)));
|
|
9837
|
+
} catch {
|
|
9838
|
+
return false;
|
|
9839
|
+
}
|
|
9840
|
+
}
|
|
9735
9841
|
function buildProjectExplanation(dir) {
|
|
9736
9842
|
const config = loadConfig(dir);
|
|
9737
9843
|
const project = {
|
|
@@ -9758,23 +9864,30 @@ function buildProjectExplanation(dir) {
|
|
|
9758
9864
|
hasInventory: exists(join(dir, ARCH_DIR4, "inventory.md")),
|
|
9759
9865
|
hasContextPack: exists(join(dir, ".kaddo", "context-pack.md")),
|
|
9760
9866
|
hasUnderstand: exists(join(dir, ".kaddo", "understand.md")),
|
|
9867
|
+
hasBusiness: exists(join(dir, "knowledge/business/business.md")),
|
|
9868
|
+
hasProduct: exists(join(dir, "knowledge/product/product.md")),
|
|
9761
9869
|
hasCapabilities: layerStatus("Product") !== "Missing",
|
|
9762
9870
|
hasArchitecture: layerStatus("Tech") !== "Missing",
|
|
9763
9871
|
hasRoadmap: layerStatus("Delivery") !== "Missing",
|
|
9764
|
-
hasAgents: hasAgents(dir)
|
|
9872
|
+
hasAgents: hasAgents(dir),
|
|
9873
|
+
hasSkills: hasSkills(dir)
|
|
9765
9874
|
};
|
|
9766
9875
|
const workItemArtifacts = discoverWorkItems(dir);
|
|
9767
|
-
const items = workItemArtifacts.map((a) =>
|
|
9768
|
-
|
|
9769
|
-
|
|
9770
|
-
|
|
9771
|
-
|
|
9772
|
-
|
|
9773
|
-
|
|
9774
|
-
|
|
9775
|
-
|
|
9776
|
-
|
|
9777
|
-
|
|
9876
|
+
const items = workItemArtifacts.map((a) => {
|
|
9877
|
+
const src = parseWorkItemSource(a.rawFrontmatter);
|
|
9878
|
+
return {
|
|
9879
|
+
id: a.id || a.title,
|
|
9880
|
+
title: a.title,
|
|
9881
|
+
type: a.type,
|
|
9882
|
+
status: a.status,
|
|
9883
|
+
lifecycle: lifecycleStateOf({ status: a.status, filePath: a.filePath }),
|
|
9884
|
+
initiative: a.initiative,
|
|
9885
|
+
knowledgeLevel: a.knowledgeLevel,
|
|
9886
|
+
hasOwnership: a.codeGlobs.length > 0,
|
|
9887
|
+
domains: a.domains,
|
|
9888
|
+
source: { type: src.type, ...src.id ? { id: src.id } : {}, inferred: src.inferred }
|
|
9889
|
+
};
|
|
9890
|
+
});
|
|
9778
9891
|
const byState = lifecycleCounts(items.map((i) => i.lifecycle));
|
|
9779
9892
|
const byType = {};
|
|
9780
9893
|
for (const i of items) {
|
|
@@ -9822,33 +9935,42 @@ function buildProjectExplanation(dir) {
|
|
|
9822
9935
|
if (!knowledge.hasAgents) missingKnowledge.push("Agents (knowledge/agents/)");
|
|
9823
9936
|
if (items.length === 0) missingKnowledge.push("Work items (knowledge/delivery/work-items/)");
|
|
9824
9937
|
const suggestedNextSteps = [];
|
|
9825
|
-
|
|
9826
|
-
|
|
9827
|
-
|
|
9828
|
-
suggestedNextSteps.push("
|
|
9829
|
-
|
|
9830
|
-
|
|
9831
|
-
suggestedNextSteps.push("
|
|
9832
|
-
}
|
|
9833
|
-
|
|
9834
|
-
|
|
9835
|
-
|
|
9836
|
-
|
|
9837
|
-
|
|
9838
|
-
|
|
9839
|
-
|
|
9840
|
-
|
|
9841
|
-
|
|
9842
|
-
|
|
9843
|
-
|
|
9844
|
-
)
|
|
9845
|
-
|
|
9846
|
-
|
|
9847
|
-
|
|
9848
|
-
|
|
9849
|
-
|
|
9850
|
-
|
|
9851
|
-
|
|
9938
|
+
const baselineIncomplete = !knowledge.hasBusiness || !knowledge.hasProduct;
|
|
9939
|
+
if (baselineIncomplete) {
|
|
9940
|
+
suggestedNextSteps.push("Run `kaddo bootstrap` to create the project knowledge baseline.");
|
|
9941
|
+
if (!knowledge.hasAgents) suggestedNextSteps.push("Then run `kaddo add agents`.");
|
|
9942
|
+
if (!knowledge.hasSkills) suggestedNextSteps.push("Then run `kaddo add skills`.");
|
|
9943
|
+
suggestedNextSteps.push("Then run `kaddo context`.");
|
|
9944
|
+
suggestedNextSteps.push("Then run `kaddo understand`.");
|
|
9945
|
+
} else {
|
|
9946
|
+
if (!knowledge.hasScan) {
|
|
9947
|
+
suggestedNextSteps.push("Run `kaddo scan` to detect the technical stack.");
|
|
9948
|
+
} else if (!knowledge.hasContextPack) {
|
|
9949
|
+
suggestedNextSteps.push("Run `kaddo context` to prepare an LLM context pack.");
|
|
9950
|
+
}
|
|
9951
|
+
if (!knowledge.hasAgents) {
|
|
9952
|
+
suggestedNextSteps.push("Run `kaddo add agents` to install knowledge agents.");
|
|
9953
|
+
}
|
|
9954
|
+
if (!knowledge.hasCapabilities) {
|
|
9955
|
+
suggestedNextSteps.push("Use capability-agent to generate knowledge/product/capabilities.md.");
|
|
9956
|
+
}
|
|
9957
|
+
if (!knowledge.hasArchitecture) {
|
|
9958
|
+
suggestedNextSteps.push("Use architecture-agent to generate knowledge/tech/current-state.md.");
|
|
9959
|
+
}
|
|
9960
|
+
if (!knowledge.hasRoadmap) {
|
|
9961
|
+
suggestedNextSteps.push("Use roadmap-agent to generate knowledge/delivery/roadmap.md.");
|
|
9962
|
+
} else if (roadmap.remaining > 0) {
|
|
9963
|
+
suggestedNextSteps.push(
|
|
9964
|
+
`Materialize ${roadmap.remaining} roadmap candidate(s) with \`kaddo create --from roadmap\`.`
|
|
9965
|
+
);
|
|
9966
|
+
}
|
|
9967
|
+
if (items.length === 0 && !roadmap.present) {
|
|
9968
|
+
suggestedNextSteps.push("Create your first Work Item with `kaddo create`.");
|
|
9969
|
+
} else if (ownership.workItemsMissingOwnership > 0) {
|
|
9970
|
+
suggestedNextSteps.push(
|
|
9971
|
+
"Run `kaddo owners suggest` for Work Items without code ownership."
|
|
9972
|
+
);
|
|
9973
|
+
}
|
|
9852
9974
|
}
|
|
9853
9975
|
const readiness = buildReadinessReport(dir);
|
|
9854
9976
|
return {
|
|
@@ -9971,6 +10093,17 @@ function renderExplanationHuman(exp) {
|
|
|
9971
10093
|
for (const [t, n] of typeEntries) lines.push(`- ${typeLabel(t)}: ${n}`);
|
|
9972
10094
|
lines.push("");
|
|
9973
10095
|
}
|
|
10096
|
+
const sourceCounts = {};
|
|
10097
|
+
for (const i of exp.workItems.items) {
|
|
10098
|
+
const t = i.source?.type ?? "unknown";
|
|
10099
|
+
sourceCounts[t] = (sourceCounts[t] ?? 0) + 1;
|
|
10100
|
+
}
|
|
10101
|
+
const sourceEntries = Object.entries(sourceCounts).filter(([, n]) => n > 0);
|
|
10102
|
+
if (sourceEntries.length > 0) {
|
|
10103
|
+
lines.push("## Work Item Sources");
|
|
10104
|
+
for (const [t, n] of sourceEntries) lines.push(`- ${t.charAt(0).toUpperCase() + t.slice(1)}: ${n}`);
|
|
10105
|
+
lines.push("");
|
|
10106
|
+
}
|
|
9974
10107
|
const grouped = exp.workItems.initiatives.filter(
|
|
9975
10108
|
(g) => LIFECYCLE_STATES.some((s2) => g.states[s2] > 0)
|
|
9976
10109
|
);
|
|
@@ -10439,7 +10572,8 @@ function toContextWorkItem(a) {
|
|
|
10439
10572
|
status: a.status,
|
|
10440
10573
|
lifecycle: lifecycleStateOf({ status: a.status, filePath: a.filePath }),
|
|
10441
10574
|
knowledgeLevel: a.knowledgeLevel,
|
|
10442
|
-
domains: a.domains
|
|
10575
|
+
domains: a.domains,
|
|
10576
|
+
source: parseWorkItemSource(a.rawFrontmatter)
|
|
10443
10577
|
};
|
|
10444
10578
|
}
|
|
10445
10579
|
function toContextArtifact(a) {
|
|
@@ -10780,7 +10914,10 @@ function renderContextPack(pack) {
|
|
|
10780
10914
|
const level = wi.knowledgeLevel ? ` [${wi.knowledgeLevel}]` : "";
|
|
10781
10915
|
const status = wi.lifecycle ? ` (${wi.lifecycle})` : wi.status ? ` (${wi.status})` : "";
|
|
10782
10916
|
const domains = wi.domains.length > 0 ? ` \xB7 domains: ${wi.domains.join(", ")}` : "";
|
|
10783
|
-
|
|
10917
|
+
const line = `- ${wi.id || wi.title} [${wi.type}]${level}${status} \u2014 ${wi.title}${domains}`;
|
|
10918
|
+
const src = wi.source && wi.source.type !== "unknown" ? `
|
|
10919
|
+
- Source: ${renderSourceCompact(wi.source)}` : "";
|
|
10920
|
+
return `${line}${src}`;
|
|
10784
10921
|
});
|
|
10785
10922
|
parts.push(lines.join("\n") + "\n");
|
|
10786
10923
|
} else {
|
|
@@ -10872,19 +11009,35 @@ function renderContextPack(pack) {
|
|
|
10872
11009
|
parts.push(pack.skills.map((s) => `- ${s}`).join("\n") + "\n");
|
|
10873
11010
|
parts.push("Read full skill definitions in `knowledge/skills/` or via the Kaddo MCP server (`kaddo://skills`).\n");
|
|
10874
11011
|
}
|
|
11012
|
+
const isBootstrapIncomplete = rec.id === "bootstrap";
|
|
10875
11013
|
parts.push("## Missing Context\n");
|
|
10876
|
-
if (
|
|
11014
|
+
if (isBootstrapIncomplete) {
|
|
11015
|
+
const baselineMissing = [
|
|
11016
|
+
"- Bootstrap baseline is incomplete.",
|
|
11017
|
+
...!pack.knowledgeQuality.business || pack.knowledgeQuality.business.status === "Missing" ? ["- Missing business knowledge."] : [],
|
|
11018
|
+
...!pack.knowledgeQuality.product || pack.knowledgeQuality.product.status === "Missing" ? ["- Missing product knowledge."] : []
|
|
11019
|
+
];
|
|
11020
|
+
if (missing.length > 0) {
|
|
11021
|
+
baselineMissing.push(...missing.filter((m) => !baselineMissing.some((b) => b.includes(m))));
|
|
11022
|
+
}
|
|
11023
|
+
parts.push(baselineMissing.join("\n") + "\n");
|
|
11024
|
+
} else if (missing.length > 0) {
|
|
10877
11025
|
parts.push(missing.map((m) => `- ${m}`).join("\n") + "\n");
|
|
10878
11026
|
} else {
|
|
10879
11027
|
parts.push("_None \u2014 all expected context is present._\n");
|
|
10880
11028
|
}
|
|
10881
11029
|
parts.push("## Recommended Agent Handoff\n");
|
|
10882
|
-
|
|
11030
|
+
if (isBootstrapIncomplete) {
|
|
11031
|
+
parts.push("No agent handoff yet.\n");
|
|
11032
|
+
parts.push("Run `kaddo bootstrap` first to create the baseline files.\n");
|
|
11033
|
+
} else {
|
|
11034
|
+
parts.push(`Recommended next for the **${pack.phase.phase}** phase:
|
|
10883
11035
|
`);
|
|
10884
|
-
|
|
10885
|
-
|
|
10886
|
-
|
|
10887
|
-
|
|
11036
|
+
parts.push(handoff.recommendedAgents.map((a, i) => `${i + 1}. ${a}`).join("\n") + "\n");
|
|
11037
|
+
if (handoff.nextSteps.length > 0) {
|
|
11038
|
+
parts.push("Next step:\n");
|
|
11039
|
+
parts.push(handoff.nextSteps.map((s) => `- ${s}`).join("\n") + "\n");
|
|
11040
|
+
}
|
|
10888
11041
|
}
|
|
10889
11042
|
parts.push("## Instructions for the LLM\n");
|
|
10890
11043
|
parts.push(handoff.instructions.map((i) => `- ${i}`).join("\n") + "\n");
|
|
@@ -11049,7 +11202,12 @@ function renderUnderstand(plan) {
|
|
|
11049
11202
|
parts.push("## Project Route\n");
|
|
11050
11203
|
parts.push(renderRouteCompact(plan.projectRoute));
|
|
11051
11204
|
}
|
|
11052
|
-
|
|
11205
|
+
const isBootstrap = rec && rec.id === "bootstrap";
|
|
11206
|
+
if (isBootstrap) {
|
|
11207
|
+
parts.push("## Agent Handoff\n");
|
|
11208
|
+
parts.push("Agent handoff is not ready yet.\n");
|
|
11209
|
+
parts.push("Run `kaddo bootstrap` first.\n");
|
|
11210
|
+
} else if (steps.length > 0) {
|
|
11053
11211
|
parts.push("## Recommended Agent Flow\n");
|
|
11054
11212
|
parts.push(`Recommended order for a ${stateLabel2(project.state)} project:
|
|
11055
11213
|
`);
|
|
@@ -11090,7 +11248,11 @@ function renderUnderstand(plan) {
|
|
|
11090
11248
|
if (plan.activeWorkItems && plan.activeWorkItems.length > 0) {
|
|
11091
11249
|
parts.push("## Active Work Items\n");
|
|
11092
11250
|
parts.push(
|
|
11093
|
-
plan.activeWorkItems.map((w) =>
|
|
11251
|
+
plan.activeWorkItems.map((w) => {
|
|
11252
|
+
const src = w.source && w.source.type !== "unknown" ? `
|
|
11253
|
+
- Source: ${w.source.type}${w.source.id ? ` \xB7 ${w.source.id}` : ""}` : "";
|
|
11254
|
+
return `- ${w.id} [${w.type}] ${w.lifecycle} \u2014 ${w.title}${src}`;
|
|
11255
|
+
}).join("\n") + "\n"
|
|
11094
11256
|
);
|
|
11095
11257
|
}
|
|
11096
11258
|
parts.push("## Context Pack\n");
|
|
@@ -11198,25 +11360,36 @@ function renderUnderstandTerminal(plan) {
|
|
|
11198
11360
|
lines.push(`Team: ${project.teamSize}`);
|
|
11199
11361
|
lines.push(`Structure: ${project.structure}`);
|
|
11200
11362
|
lines.push("");
|
|
11201
|
-
const
|
|
11202
|
-
|
|
11203
|
-
|
|
11204
|
-
|
|
11205
|
-
|
|
11206
|
-
|
|
11207
|
-
});
|
|
11208
|
-
lines.push("");
|
|
11209
|
-
lines.push(`First step: use ${agentName(first2.agent)}.`);
|
|
11210
|
-
lines.push("");
|
|
11211
|
-
lines.push(` Context: ${plan.contextPackPath}`);
|
|
11212
|
-
lines.push(` Agent prompt: ${agentInstallPath(first2.agent)}`);
|
|
11213
|
-
lines.push(` Expected output: ${first2.output}`);
|
|
11363
|
+
const rec = plan.nextStepRecommendation;
|
|
11364
|
+
const isBootstrapIncomplete = rec && rec.id === "bootstrap";
|
|
11365
|
+
if (isBootstrapIncomplete) {
|
|
11366
|
+
lines.push("Current phase: Setup");
|
|
11367
|
+
lines.push("Next step: Run `kaddo bootstrap` to create the project knowledge baseline.");
|
|
11368
|
+
lines.push("Reason: The knowledge baseline is incomplete.");
|
|
11214
11369
|
lines.push("");
|
|
11215
|
-
lines.push("
|
|
11216
|
-
lines.push("
|
|
11217
|
-
lines.push(" prompt. Ask the LLM to generate the expected output and save it in the target file.");
|
|
11370
|
+
lines.push("Agent handoff is not ready yet.");
|
|
11371
|
+
lines.push("Run `kaddo bootstrap` first.");
|
|
11218
11372
|
} else {
|
|
11219
|
-
|
|
11373
|
+
const first2 = steps[0];
|
|
11374
|
+
if (first2) {
|
|
11375
|
+
lines.push("Foundational knowledge still needed:");
|
|
11376
|
+
steps.forEach((s, i) => {
|
|
11377
|
+
const flag = s.installed ? "" : " (not installed)";
|
|
11378
|
+
lines.push(` ${i + 1}. ${agentName(s.agent)} \u2192 ${s.output}${flag}`);
|
|
11379
|
+
});
|
|
11380
|
+
lines.push("");
|
|
11381
|
+
lines.push(`First step: use ${agentName(first2.agent)}.`);
|
|
11382
|
+
lines.push("");
|
|
11383
|
+
lines.push(` Context: ${plan.contextPackPath}`);
|
|
11384
|
+
lines.push(` Agent prompt: ${agentInstallPath(first2.agent)}`);
|
|
11385
|
+
lines.push(` Expected output: ${first2.output}`);
|
|
11386
|
+
lines.push("");
|
|
11387
|
+
lines.push("Instructions:");
|
|
11388
|
+
lines.push(" Open your preferred LLM chat, paste the context pack, then paste the agent");
|
|
11389
|
+
lines.push(" prompt. Ask the LLM to generate the expected output and save it in the target file.");
|
|
11390
|
+
} else {
|
|
11391
|
+
lines.push("Foundational knowledge looks complete \u2014 see the phase recommendation below.");
|
|
11392
|
+
}
|
|
11220
11393
|
}
|
|
11221
11394
|
lines.push("");
|
|
11222
11395
|
lines.push("Kaddo does not call an LLM. You stay in control of the interpretation.");
|
|
@@ -11411,7 +11584,11 @@ function runUnderstand() {
|
|
|
11411
11584
|
type: w.type,
|
|
11412
11585
|
lifecycle: w.lifecycle ?? "draft",
|
|
11413
11586
|
knowledgeLevel: w.knowledgeLevel,
|
|
11414
|
-
hasOwnership: w.codeGlobs.length > 0
|
|
11587
|
+
hasOwnership: w.codeGlobs.length > 0,
|
|
11588
|
+
source: (() => {
|
|
11589
|
+
const s = parseWorkItemSource(w.rawFrontmatter);
|
|
11590
|
+
return { type: s.type, ...s.id ? { id: s.id } : {} };
|
|
11591
|
+
})()
|
|
11415
11592
|
}));
|
|
11416
11593
|
const recommendedPaths = [];
|
|
11417
11594
|
if (rec.agent) {
|