@kaddo/cli 3.66.0 → 3.67.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 +117 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6939,17 +6939,27 @@ function analyzeCrossRepoEvidence(input) {
|
|
|
6939
6939
|
}
|
|
6940
6940
|
}
|
|
6941
6941
|
}
|
|
6942
|
+
if (validationStatus === "accepted-with-exceptions") {
|
|
6943
|
+
const hasExceptions = exceptions.length > 0;
|
|
6944
|
+
const hasValidationGate = releaseGates.some(
|
|
6945
|
+
(g) => (g.status === "pending" || g.status === "blocked") && (g.id.includes("validation") || g.id.includes("test"))
|
|
6946
|
+
);
|
|
6947
|
+
if (!hasExceptions && !hasValidationGate) {
|
|
6948
|
+
findings.push({ id, severity: "warning", message: "Validation status is accepted-with-exceptions, but no exception evidence was found." });
|
|
6949
|
+
}
|
|
6950
|
+
}
|
|
6942
6951
|
if (raw.status === "done") {
|
|
6943
6952
|
findings.push({ id, severity: "warning", message: "Legacy status `done` detected. Canonical status is `completed`." });
|
|
6944
6953
|
}
|
|
6945
6954
|
if (raw.refined_by && raw.implemented_by && raw.refined_by === raw.implemented_by) {
|
|
6946
6955
|
findings.push({ id, severity: "fyi", message: "refined_by and implemented_by point to the same agent." });
|
|
6947
6956
|
}
|
|
6957
|
+
const historicalDefault = lifecycle === "completed" || lifecycle === "archived" ? "not-assessed" : "not-started";
|
|
6948
6958
|
return {
|
|
6949
6959
|
id,
|
|
6950
6960
|
lifecycle,
|
|
6951
|
-
implementationStatus: implementationStatus ||
|
|
6952
|
-
validationStatus: validationStatus ||
|
|
6961
|
+
implementationStatus: implementationStatus || historicalDefault,
|
|
6962
|
+
validationStatus: validationStatus || historicalDefault,
|
|
6953
6963
|
releaseStatus: releaseStatus || "not-assessed",
|
|
6954
6964
|
affectedModules,
|
|
6955
6965
|
findings,
|
|
@@ -11741,6 +11751,8 @@ function workItemsSignal(dir) {
|
|
|
11741
11751
|
if (wis.length === 0) return "none";
|
|
11742
11752
|
if (wis.some((w) => w.lifecycle === "in-progress")) return "in-progress";
|
|
11743
11753
|
if (wis.some((w) => w.lifecycle === "ready")) return "ready";
|
|
11754
|
+
const hasActive = wis.some((w) => w.lifecycle === "draft" || w.lifecycle === "blocked");
|
|
11755
|
+
if (!hasActive && wis.some((w) => w.lifecycle === "completed" || w.lifecycle === "archived")) return "completed-only";
|
|
11744
11756
|
return "none-ready";
|
|
11745
11757
|
}
|
|
11746
11758
|
function installedAdapters(dir) {
|
|
@@ -12169,6 +12181,8 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
12169
12181
|
else if (understand === "missing") overall = "scanned";
|
|
12170
12182
|
else if (firstWeak) overall = "knowledge-incomplete";
|
|
12171
12183
|
else if (oq.summary.blocking_open > 0) overall = "needs-decisions";
|
|
12184
|
+
else if (work_items === "in-progress") overall = "active-implementation";
|
|
12185
|
+
else if (work_items === "completed-only") overall = deriveDeliveryCompletedStatus(dir);
|
|
12172
12186
|
else if (roadmap !== "has-candidates") overall = "ready-for-roadmap";
|
|
12173
12187
|
else if (work_items === "none" || work_items === "none-ready") overall = "ready-for-work-item";
|
|
12174
12188
|
else overall = "ready-for-implementation";
|
|
@@ -12181,6 +12195,16 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
12181
12195
|
nextStepRecommendation: rec
|
|
12182
12196
|
};
|
|
12183
12197
|
}
|
|
12198
|
+
function deriveDeliveryCompletedStatus(dir) {
|
|
12199
|
+
const wis = discoverWorkItems(dir);
|
|
12200
|
+
const completed = wis.filter((w) => lifecycleStateOf({ status: w.status, filePath: w.filePath }) === "completed");
|
|
12201
|
+
if (completed.length === 0) return "delivery-completed";
|
|
12202
|
+
const hasReleaseBlocked = completed.some((w) => w.releaseStatus === "blocked");
|
|
12203
|
+
const hasReleaseReady = completed.some((w) => w.releaseStatus === "ready" || w.releaseStatus === "released");
|
|
12204
|
+
if (hasReleaseBlocked) return "delivery-completed-release-blocked";
|
|
12205
|
+
if (hasReleaseReady) return "delivery-completed-release-ready";
|
|
12206
|
+
return "delivery-completed";
|
|
12207
|
+
}
|
|
12184
12208
|
|
|
12185
12209
|
// src/core/assets.ts
|
|
12186
12210
|
import matter5 from "gray-matter";
|
|
@@ -12544,7 +12568,7 @@ var refineWorkItem = {
|
|
|
12544
12568
|
id: "refine-work-item",
|
|
12545
12569
|
label: "Refine Work Item",
|
|
12546
12570
|
evaluate: (ctx) => {
|
|
12547
|
-
if (ctx.readyWorkItems > 0 || ctx.inProgressWorkItems > 0) return { status: "done" };
|
|
12571
|
+
if (ctx.readyWorkItems > 0 || ctx.inProgressWorkItems > 0 || ctx.blockedWorkItems > 0 || ctx.completedWorkItems > 0 || ctx.archivedWorkItems > 0) return { status: "done" };
|
|
12548
12572
|
if (ctx.draftWorkItems > 0) {
|
|
12549
12573
|
return {
|
|
12550
12574
|
status: "current",
|
|
@@ -12795,7 +12819,9 @@ function buildRouteContext(dir) {
|
|
|
12795
12819
|
draftWorkItems: byState("draft"),
|
|
12796
12820
|
readyWorkItems: byState("ready"),
|
|
12797
12821
|
inProgressWorkItems: byState("in-progress"),
|
|
12822
|
+
blockedWorkItems: byState("blocked"),
|
|
12798
12823
|
completedWorkItems: byState("completed"),
|
|
12824
|
+
archivedWorkItems: byState("archived"),
|
|
12799
12825
|
ownershipCoverage: `${withOwnership}/${total}`,
|
|
12800
12826
|
ownershipComplete: total > 0 && withOwnership >= total,
|
|
12801
12827
|
decisionCandidates: td.candidates,
|
|
@@ -13210,6 +13236,20 @@ function buildProjectExplanation(dir) {
|
|
|
13210
13236
|
scanSignals: loadScanSignals(dir),
|
|
13211
13237
|
metadataHealth: analyzeMetadataHealth(dir),
|
|
13212
13238
|
isModuleRepo: config != null && isModule(config),
|
|
13239
|
+
deliverySummary: (() => {
|
|
13240
|
+
const completed = workItemArtifacts.filter((a) => lifecycleStateOf({ status: a.status, filePath: a.filePath }) === "completed");
|
|
13241
|
+
const archived = workItemArtifacts.filter((a) => lifecycleStateOf({ status: a.status, filePath: a.filePath }) === "archived");
|
|
13242
|
+
const active = workItemArtifacts.filter((a) => isActiveState(lifecycleStateOf({ status: a.status, filePath: a.filePath })));
|
|
13243
|
+
if (completed.length === 0 && archived.length === 0) return null;
|
|
13244
|
+
return {
|
|
13245
|
+
completedWorkItems: completed.length,
|
|
13246
|
+
archivedWorkItems: archived.length,
|
|
13247
|
+
activeWorkItems: active.length,
|
|
13248
|
+
implementationCompleted: completed.filter((a) => a.implementationStatus === "completed").length,
|
|
13249
|
+
releaseBlocked: completed.filter((a) => a.releaseStatus === "blocked").length,
|
|
13250
|
+
releaseReady: completed.filter((a) => a.releaseStatus === "ready" || a.releaseStatus === "released").length
|
|
13251
|
+
};
|
|
13252
|
+
})(),
|
|
13213
13253
|
implementationEvidence: workItemArtifacts.filter((a) => a.affectedModules.length > 0).map((a) => {
|
|
13214
13254
|
const fm2 = a.rawFrontmatter;
|
|
13215
13255
|
const evidence = fm2.implementation_evidence;
|
|
@@ -13221,11 +13261,13 @@ function buildProjectExplanation(dir) {
|
|
|
13221
13261
|
status: String(data.status ?? "unknown")
|
|
13222
13262
|
};
|
|
13223
13263
|
}
|
|
13264
|
+
const lc = lifecycleStateOf({ status: a.status, filePath: a.filePath });
|
|
13265
|
+
const historicalDefault = lc === "completed" || lc === "archived" ? "not-assessed" : "not-started";
|
|
13224
13266
|
return {
|
|
13225
13267
|
id: a.id || a.title,
|
|
13226
|
-
lifecycle:
|
|
13227
|
-
implementationStatus: a.implementationStatus ||
|
|
13228
|
-
validationStatus: a.validationStatus ||
|
|
13268
|
+
lifecycle: lc,
|
|
13269
|
+
implementationStatus: a.implementationStatus || historicalDefault,
|
|
13270
|
+
validationStatus: a.validationStatus || historicalDefault,
|
|
13229
13271
|
releaseStatus: a.releaseStatus || "not-assessed",
|
|
13230
13272
|
affectedModules: a.affectedModules,
|
|
13231
13273
|
releaseGates: Array.isArray(fm2.release_gates) ? fm2.release_gates : [],
|
|
@@ -13470,6 +13512,17 @@ function renderExplanationHuman(exp) {
|
|
|
13470
13512
|
}
|
|
13471
13513
|
lines.push(`- Next step: ${exp.readiness.recommended_next_step.label}`);
|
|
13472
13514
|
lines.push("");
|
|
13515
|
+
if (exp.deliverySummary) {
|
|
13516
|
+
const ds = exp.deliverySummary;
|
|
13517
|
+
lines.push("## Delivery Summary");
|
|
13518
|
+
lines.push(`- Completed Work Items: ${ds.completedWorkItems}`);
|
|
13519
|
+
if (ds.archivedWorkItems > 0) lines.push(`- Archived Work Items: ${ds.archivedWorkItems}`);
|
|
13520
|
+
lines.push(`- Active Work Items: ${ds.activeWorkItems}`);
|
|
13521
|
+
if (ds.implementationCompleted > 0) lines.push(`- Implementation completed: ${ds.implementationCompleted}`);
|
|
13522
|
+
if (ds.releaseBlocked > 0) lines.push(`- Release blocked: ${ds.releaseBlocked}`);
|
|
13523
|
+
if (ds.releaseReady > 0) lines.push(`- Release ready: ${ds.releaseReady}`);
|
|
13524
|
+
lines.push("");
|
|
13525
|
+
}
|
|
13473
13526
|
const rec = exp.nextStepRecommendation;
|
|
13474
13527
|
const secondary = rec.secondary ?? [];
|
|
13475
13528
|
const steps = secondary.length > 0 || /Delivery|Active|Maintenance/.test(rec.phase) ? [rec.label, ...secondary.map((s2) => s2.label)] : exp.suggestedNextSteps;
|
|
@@ -13504,6 +13557,10 @@ function renderExplanationHuman(exp) {
|
|
|
13504
13557
|
if (!exp.isModuleRepo) {
|
|
13505
13558
|
lines.push(`- roadmap: ${s.roadmap}`);
|
|
13506
13559
|
lines.push(`- work-items: ${s.work_items}`);
|
|
13560
|
+
if (exp.deliverySummary) {
|
|
13561
|
+
lines.push(`- work-items completed: ${exp.deliverySummary.completedWorkItems}`);
|
|
13562
|
+
lines.push(`- work-items active: ${exp.deliverySummary.activeWorkItems}`);
|
|
13563
|
+
}
|
|
13507
13564
|
lines.push(`- adapters: ${s.adapters.length > 0 ? s.adapters.join(", ") + " installed" : "none installed"}`);
|
|
13508
13565
|
} else {
|
|
13509
13566
|
lines.push("- roadmap: managed-by-core");
|
|
@@ -13845,19 +13902,21 @@ var OPERATING_RULES = [
|
|
|
13845
13902
|
"Kaddo itself never calls an LLM and never runs git \u2014 every git action is the human\u2019s."
|
|
13846
13903
|
];
|
|
13847
13904
|
function toContextWorkItem(a) {
|
|
13905
|
+
const lifecycle = lifecycleStateOf({ status: a.status, filePath: a.filePath });
|
|
13906
|
+
const isHistorical = lifecycle === "completed" || lifecycle === "archived";
|
|
13848
13907
|
const wi = {
|
|
13849
13908
|
id: a.id,
|
|
13850
13909
|
type: a.type,
|
|
13851
13910
|
title: a.title,
|
|
13852
13911
|
status: a.status,
|
|
13853
|
-
lifecycle
|
|
13912
|
+
lifecycle,
|
|
13854
13913
|
knowledgeLevel: a.knowledgeLevel,
|
|
13855
13914
|
domains: a.domains,
|
|
13856
13915
|
source: parseWorkItemSource(a.rawFrontmatter)
|
|
13857
13916
|
};
|
|
13858
|
-
|
|
13859
|
-
|
|
13860
|
-
|
|
13917
|
+
wi.implementationStatus = a.implementationStatus || (isHistorical ? "not-assessed" : void 0);
|
|
13918
|
+
wi.validationStatus = a.validationStatus || (isHistorical ? "not-assessed" : void 0);
|
|
13919
|
+
wi.releaseStatus = a.releaseStatus || (isHistorical ? "not-assessed" : void 0);
|
|
13861
13920
|
if (a.affectedModules.length > 0) wi.affectedModules = a.affectedModules;
|
|
13862
13921
|
return wi;
|
|
13863
13922
|
}
|
|
@@ -13888,10 +13947,17 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
13888
13947
|
missing.push("No roadmap baseline found.");
|
|
13889
13948
|
}
|
|
13890
13949
|
const allArtifacts = discoverKnowledge(dir);
|
|
13891
|
-
const
|
|
13892
|
-
|
|
13950
|
+
const allWorkItemArtifacts = allArtifacts.filter((a) => isDeliveryWorkItem(a));
|
|
13951
|
+
const workItems = allWorkItemArtifacts.filter(
|
|
13952
|
+
(a) => isActiveState(lifecycleStateOf({ status: a.status, filePath: a.filePath }))
|
|
13953
|
+
);
|
|
13954
|
+
const completedWorkItems = allWorkItemArtifacts.filter(
|
|
13955
|
+
(a) => lifecycleStateOf({ status: a.status, filePath: a.filePath }) === "completed"
|
|
13893
13956
|
);
|
|
13894
|
-
|
|
13957
|
+
const archivedWorkItems = allWorkItemArtifacts.filter(
|
|
13958
|
+
(a) => lifecycleStateOf({ status: a.status, filePath: a.filePath }) === "archived"
|
|
13959
|
+
);
|
|
13960
|
+
if (allWorkItemArtifacts.length === 0 && !moduleRepo) {
|
|
13895
13961
|
missing.push("No work items found.");
|
|
13896
13962
|
}
|
|
13897
13963
|
const state = config.project.state;
|
|
@@ -14006,6 +14072,10 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
14006
14072
|
roadmapSummary,
|
|
14007
14073
|
inventoryAvailable,
|
|
14008
14074
|
workItems: workItems.map(toContextWorkItem),
|
|
14075
|
+
activeWorkItems: workItems.map(toContextWorkItem),
|
|
14076
|
+
completedWorkItems: completedWorkItems.map(toContextWorkItem),
|
|
14077
|
+
archivedWorkItems: archivedWorkItems.map(toContextWorkItem),
|
|
14078
|
+
allWorkItems: allWorkItemArtifacts.map(toContextWorkItem),
|
|
14009
14079
|
artifacts: allArtifacts.filter((a) => a.codeGlobs.length > 0).map(toContextArtifact)
|
|
14010
14080
|
},
|
|
14011
14081
|
layers,
|
|
@@ -14022,6 +14092,30 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
14022
14092
|
const compact = (a) => ({ total: a.total, installed: a.total - a.missing, outdated: a.outdated, unknown_version: a.unknown_version, modified: a.modified });
|
|
14023
14093
|
return { version: s.version, agents: compact(s.agents), skills: compact(s.skills) };
|
|
14024
14094
|
})(),
|
|
14095
|
+
workItemSummary: (() => {
|
|
14096
|
+
const lc = (s) => allWorkItemArtifacts.filter(
|
|
14097
|
+
(a) => lifecycleStateOf({ status: a.status, filePath: a.filePath }) === s
|
|
14098
|
+
).length;
|
|
14099
|
+
const draft = lc("draft");
|
|
14100
|
+
const ready = lc("ready");
|
|
14101
|
+
const inProgress = lc("in-progress");
|
|
14102
|
+
const blocked = lc("blocked");
|
|
14103
|
+
const completed = lc("completed");
|
|
14104
|
+
const archived = lc("archived");
|
|
14105
|
+
const active = draft + ready + inProgress + blocked;
|
|
14106
|
+
const total = allWorkItemArtifacts.length;
|
|
14107
|
+
let summary = "none";
|
|
14108
|
+
if (total === 0) summary = "none";
|
|
14109
|
+
else if (active === 0 && completed > 0 && archived === 0) summary = "completed-only";
|
|
14110
|
+
else if (active === 0 && archived > 0 && completed === 0) summary = "archived-only";
|
|
14111
|
+
else if (active === 0 && completed + archived > 0) summary = "historical-only";
|
|
14112
|
+
else if (inProgress > 0) summary = "active";
|
|
14113
|
+
else if (blocked > 0 && ready === 0 && inProgress === 0) summary = "blocked";
|
|
14114
|
+
else if (ready > 0) summary = "ready";
|
|
14115
|
+
else if (draft > 0 && ready === 0) summary = "draft-only";
|
|
14116
|
+
else summary = "mixed-active";
|
|
14117
|
+
return { total, active, draft, ready, in_progress: inProgress, blocked, completed, archived, summary };
|
|
14118
|
+
})(),
|
|
14025
14119
|
deliveryMix,
|
|
14026
14120
|
external: loadExternalCapsules(dir),
|
|
14027
14121
|
graph: loadGraphSummary(dir),
|
|
@@ -14950,6 +15044,16 @@ function runUnderstand() {
|
|
|
14950
15044
|
} else if (rec.agentPath) {
|
|
14951
15045
|
console.log(` Agent prompt: ${rec.agentPath}`);
|
|
14952
15046
|
}
|
|
15047
|
+
if (exp.deliverySummary) {
|
|
15048
|
+
const ds2 = exp.deliverySummary;
|
|
15049
|
+
console.log("");
|
|
15050
|
+
console.log("Previous delivery:");
|
|
15051
|
+
console.log(` - Completed Work Items: ${ds2.completedWorkItems}`);
|
|
15052
|
+
if (ds2.implementationCompleted > 0) console.log(` - Implementation completed: ${ds2.implementationCompleted}`);
|
|
15053
|
+
if (ds2.releaseBlocked > 0) console.log(` - Release blocked: ${ds2.releaseBlocked}`);
|
|
15054
|
+
if (ds2.releaseReady > 0) console.log(` - Release ready: ${ds2.releaseReady}`);
|
|
15055
|
+
console.log(` - Current active work: ${ds2.activeWorkItems > 0 ? ds2.activeWorkItems : "none"}`);
|
|
15056
|
+
}
|
|
14953
15057
|
if (rec.skill) console.log(`Recommended skill: ${rec.skill}`);
|
|
14954
15058
|
console.log(`Next step: ${rec.label}`);
|
|
14955
15059
|
if (rec.reason) console.log(`Why: ${rec.reason}`);
|