@kaddo/mcp 3.66.0 → 3.68.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 +389 -29
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -500,6 +500,53 @@ function isCore(config) {
|
|
|
500
500
|
|
|
501
501
|
// ../cli/src/services/artifact-reader.ts
|
|
502
502
|
import matter3 from "gray-matter";
|
|
503
|
+
var VALID_SCOPE_CONFIDENCE_LEVELS = /* @__PURE__ */ new Set(["high", "medium", "low"]);
|
|
504
|
+
var VALID_COVERAGE_STATUSES = /* @__PURE__ */ new Set(["affected", "reviewed-not-affected", "unknown", "not-applicable"]);
|
|
505
|
+
function parseScopeConfidence(data) {
|
|
506
|
+
const sc = data.scope_confidence;
|
|
507
|
+
if (!sc || typeof sc !== "object" || Array.isArray(sc)) return null;
|
|
508
|
+
const obj = sc;
|
|
509
|
+
const level = String(obj.level ?? "");
|
|
510
|
+
if (!VALID_SCOPE_CONFIDENCE_LEVELS.has(level)) return null;
|
|
511
|
+
const reasons = Array.isArray(obj.reasons) ? obj.reasons.map(String).filter(Boolean) : [];
|
|
512
|
+
return { level, reasons };
|
|
513
|
+
}
|
|
514
|
+
function parseModuleCoverage(data) {
|
|
515
|
+
const mc = data.module_coverage;
|
|
516
|
+
if (!mc || typeof mc !== "object" || Array.isArray(mc)) return null;
|
|
517
|
+
const result = {};
|
|
518
|
+
for (const [id, val] of Object.entries(mc)) {
|
|
519
|
+
if (!val || typeof val !== "object" || Array.isArray(val)) continue;
|
|
520
|
+
const v = val;
|
|
521
|
+
const status = String(v.status ?? "");
|
|
522
|
+
if (!VALID_COVERAGE_STATUSES.has(status)) continue;
|
|
523
|
+
result[id] = {
|
|
524
|
+
status,
|
|
525
|
+
...v.reason ? { reason: String(v.reason) } : {},
|
|
526
|
+
...Array.isArray(v.evidence) ? { evidence: v.evidence.map(String).filter(Boolean) } : {}
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
return Object.keys(result).length > 0 ? result : null;
|
|
530
|
+
}
|
|
531
|
+
function parseImpactAnalysis(data) {
|
|
532
|
+
const ia = data.impact_analysis;
|
|
533
|
+
if (!ia || typeof ia !== "object" || Array.isArray(ia)) return null;
|
|
534
|
+
const surfaces = ia.surfaces;
|
|
535
|
+
if (!surfaces || typeof surfaces !== "object" || Array.isArray(surfaces)) return null;
|
|
536
|
+
const result = {};
|
|
537
|
+
for (const [id, val] of Object.entries(surfaces)) {
|
|
538
|
+
if (!val || typeof val !== "object" || Array.isArray(val)) continue;
|
|
539
|
+
const v = val;
|
|
540
|
+
const status = String(v.status ?? "");
|
|
541
|
+
if (!VALID_COVERAGE_STATUSES.has(status)) continue;
|
|
542
|
+
result[id] = {
|
|
543
|
+
status,
|
|
544
|
+
...v.reason ? { reason: String(v.reason) } : {},
|
|
545
|
+
...v.question ? { question: String(v.question) } : {}
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
return Object.keys(result).length > 0 ? result : null;
|
|
549
|
+
}
|
|
503
550
|
function parseArtifact(filePath, raw) {
|
|
504
551
|
try {
|
|
505
552
|
const { data } = matter3(raw);
|
|
@@ -528,7 +575,10 @@ function parseArtifact(filePath, raw) {
|
|
|
528
575
|
affectedModules: Array.isArray(data.affected_modules) ? data.affected_modules.map(String).filter(Boolean) : [],
|
|
529
576
|
refinedBy: String(data.refined_by ?? ""),
|
|
530
577
|
implementedBy: String(data.implemented_by ?? ""),
|
|
531
|
-
closedBy: String(data.closed_by ?? "")
|
|
578
|
+
closedBy: String(data.closed_by ?? ""),
|
|
579
|
+
scopeConfidence: parseScopeConfidence(data),
|
|
580
|
+
moduleCoverage: parseModuleCoverage(data),
|
|
581
|
+
impactAnalysis: parseImpactAnalysis(data)
|
|
532
582
|
};
|
|
533
583
|
} catch {
|
|
534
584
|
return null;
|
|
@@ -1105,12 +1155,44 @@ domains: []
|
|
|
1105
1155
|
capabilities: []
|
|
1106
1156
|
code: []
|
|
1107
1157
|
created_at: YYYY-MM-DD
|
|
1158
|
+
# scope_confidence:
|
|
1159
|
+
# level: medium
|
|
1160
|
+
# reasons: []
|
|
1161
|
+
# module_coverage:
|
|
1162
|
+
# core:
|
|
1163
|
+
# status: affected
|
|
1164
|
+
# reason: ""
|
|
1165
|
+
# impact_analysis:
|
|
1166
|
+
# surfaces:
|
|
1167
|
+
# frontend:
|
|
1168
|
+
# status: affected
|
|
1169
|
+
# reason: ""
|
|
1108
1170
|
---
|
|
1109
1171
|
|
|
1110
1172
|
# <Title>
|
|
1111
1173
|
|
|
1112
1174
|
> Type: feature \xB7 Level: K2
|
|
1113
1175
|
|
|
1176
|
+
## Actor and outcome
|
|
1177
|
+
|
|
1178
|
+
_Who experiences the change and what is the observable result?_
|
|
1179
|
+
|
|
1180
|
+
## Current behavior
|
|
1181
|
+
|
|
1182
|
+
_What happens today?_
|
|
1183
|
+
|
|
1184
|
+
## Target behavior
|
|
1185
|
+
|
|
1186
|
+
_What should happen after this change?_
|
|
1187
|
+
|
|
1188
|
+
## Entry points
|
|
1189
|
+
|
|
1190
|
+
_Where does the flow start for the actor?_
|
|
1191
|
+
|
|
1192
|
+
## End-to-end flow
|
|
1193
|
+
|
|
1194
|
+
_Describe the complete flow from entry point to final result._
|
|
1195
|
+
|
|
1114
1196
|
## Problem
|
|
1115
1197
|
|
|
1116
1198
|
_What problem or opportunity does this address?_
|
|
@@ -1119,9 +1201,26 @@ _What problem or opportunity does this address?_
|
|
|
1119
1201
|
|
|
1120
1202
|
_What should be true once this is done?_
|
|
1121
1203
|
|
|
1204
|
+
## Impact analysis
|
|
1205
|
+
|
|
1206
|
+
_Which surfaces are affected, reviewed-not-affected, unknown, or not-applicable?_
|
|
1207
|
+
|
|
1208
|
+
## Module coverage
|
|
1209
|
+
|
|
1210
|
+
_For multirepo: which modules were evaluated and their status._
|
|
1211
|
+
|
|
1212
|
+
## Scope unknowns
|
|
1213
|
+
|
|
1214
|
+
_What remains unknown? Include focused questions._
|
|
1215
|
+
|
|
1216
|
+
## Scope confidence
|
|
1217
|
+
|
|
1218
|
+
_high / medium / low \u2014 with reasons._
|
|
1219
|
+
|
|
1122
1220
|
## Acceptance criteria
|
|
1123
1221
|
|
|
1124
1222
|
- [ ] ...
|
|
1223
|
+
- [ ] _Include at least one end-to-end criterion for user-facing changes._
|
|
1125
1224
|
|
|
1126
1225
|
## Design
|
|
1127
1226
|
|
|
@@ -1153,6 +1252,9 @@ ${QUALITY}
|
|
|
1153
1252
|
- [ ] Title is specific and action-oriented.
|
|
1154
1253
|
- [ ] \`code:\` globs declared so Guard can relate changes.
|
|
1155
1254
|
- [ ] Knowledge level matches the real uncertainty.
|
|
1255
|
+
- [ ] Actor and outcome are identified.
|
|
1256
|
+
- [ ] Current and target behavior are documented.
|
|
1257
|
+
- [ ] Scope confidence is declared.
|
|
1156
1258
|
`;
|
|
1157
1259
|
var ROADMAP = `---
|
|
1158
1260
|
type: roadmap
|
|
@@ -3963,6 +4065,8 @@ function workItemsSignal(dir) {
|
|
|
3963
4065
|
if (wis.length === 0) return "none";
|
|
3964
4066
|
if (wis.some((w3) => w3.lifecycle === "in-progress")) return "in-progress";
|
|
3965
4067
|
if (wis.some((w3) => w3.lifecycle === "ready")) return "ready";
|
|
4068
|
+
const hasActive = wis.some((w3) => w3.lifecycle === "draft" || w3.lifecycle === "blocked");
|
|
4069
|
+
if (!hasActive && wis.some((w3) => w3.lifecycle === "completed" || w3.lifecycle === "archived")) return "completed-only";
|
|
3966
4070
|
return "none-ready";
|
|
3967
4071
|
}
|
|
3968
4072
|
function installedAdapters(dir) {
|
|
@@ -4391,6 +4495,8 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
4391
4495
|
else if (understand === "missing") overall = "scanned";
|
|
4392
4496
|
else if (firstWeak) overall = "knowledge-incomplete";
|
|
4393
4497
|
else if (oq.summary.blocking_open > 0) overall = "needs-decisions";
|
|
4498
|
+
else if (work_items === "in-progress") overall = "active-implementation";
|
|
4499
|
+
else if (work_items === "completed-only") overall = deriveDeliveryCompletedStatus(dir);
|
|
4394
4500
|
else if (roadmap !== "has-candidates") overall = "ready-for-roadmap";
|
|
4395
4501
|
else if (work_items === "none" || work_items === "none-ready") overall = "ready-for-work-item";
|
|
4396
4502
|
else overall = "ready-for-implementation";
|
|
@@ -4403,6 +4509,16 @@ function buildReadinessReport(dir, now = /* @__PURE__ */ new Date()) {
|
|
|
4403
4509
|
nextStepRecommendation: rec
|
|
4404
4510
|
};
|
|
4405
4511
|
}
|
|
4512
|
+
function deriveDeliveryCompletedStatus(dir) {
|
|
4513
|
+
const wis = discoverWorkItems(dir);
|
|
4514
|
+
const completed = wis.filter((w3) => lifecycleStateOf({ status: w3.status, filePath: w3.filePath }) === "completed");
|
|
4515
|
+
if (completed.length === 0) return "delivery-completed";
|
|
4516
|
+
const hasReleaseBlocked = completed.some((w3) => w3.releaseStatus === "blocked");
|
|
4517
|
+
const hasReleaseReady = completed.some((w3) => w3.releaseStatus === "ready" || w3.releaseStatus === "released");
|
|
4518
|
+
if (hasReleaseBlocked) return "delivery-completed-release-blocked";
|
|
4519
|
+
if (hasReleaseReady) return "delivery-completed-release-ready";
|
|
4520
|
+
return "delivery-completed";
|
|
4521
|
+
}
|
|
4406
4522
|
|
|
4407
4523
|
// ../cli/src/core/assets.ts
|
|
4408
4524
|
import matter6 from "gray-matter";
|
|
@@ -4545,8 +4661,23 @@ The context pack and the Work Item (draft or candidate).
|
|
|
4545
4661
|
|
|
4546
4662
|
## Output
|
|
4547
4663
|
|
|
4548
|
-
An improved Work Item with:
|
|
4549
|
-
|
|
4664
|
+
An improved Work Item with: actor and outcome, current behavior, target behavior, entry points,
|
|
4665
|
+
end-to-end flow, impact analysis, module coverage, scope unknowns, scope confidence, problem,
|
|
4666
|
+
expected result, scope, out of scope, acceptance criteria (including end-to-end criteria for
|
|
4667
|
+
user-facing changes), validation (how to test it), definition of done, open questions and
|
|
4668
|
+
dependencies.
|
|
4669
|
+
|
|
4670
|
+
## Steps
|
|
4671
|
+
|
|
4672
|
+
1. **Outcome framing** \u2014 identify actor, current behavior, target behavior, observable completion.
|
|
4673
|
+
2. **Journey reconstruction** \u2014 map entry point, interaction, service/API, state change, response,
|
|
4674
|
+
final outcome.
|
|
4675
|
+
3. **Surface review** \u2014 evaluate: product/UI, frontend, backend, database, configuration, feature
|
|
4676
|
+
flags, content/copy, authentication/authorization, notifications, analytics, documentation,
|
|
4677
|
+
operations/release \u2014 as affected, reviewed-not-affected, unknown, or not-applicable.
|
|
4678
|
+
4. **Module review** \u2014 for multirepo, evaluate each mapped module with the same statuses.
|
|
4679
|
+
5. **Completeness review** \u2014 confirm: outcome covered, journey covered, modules assessed, unknowns
|
|
4680
|
+
visible, acceptance criteria end-to-end, scope and out-of-scope coherent.
|
|
4550
4681
|
|
|
4551
4682
|
## Rules
|
|
4552
4683
|
|
|
@@ -4554,14 +4685,23 @@ validation (how to test it), definition of done, open questions and dependencies
|
|
|
4554
4685
|
- Do not expand scope without explicit confirmation.
|
|
4555
4686
|
- Do not create mega Work Items \u2014 split when it covers multiple outcomes.
|
|
4556
4687
|
- Keep acceptance criteria testable.
|
|
4688
|
+
- Include at least one end-to-end acceptance criterion for user-facing changes.
|
|
4689
|
+
- Do not reduce a product intent to the first technical implementation found.
|
|
4690
|
+
- Evaluate surfaces and modules before proposing files.
|
|
4557
4691
|
- This skill refines scope and acceptance criteria but does not approve implementation readiness.
|
|
4558
4692
|
Readiness requires human confirmation through \`kaddo ready\` or the MCP \`mark_work_item_ready\` action.
|
|
4559
4693
|
|
|
4560
4694
|
## Quality checklist
|
|
4561
4695
|
|
|
4696
|
+
- Actor and outcome are identified.
|
|
4697
|
+
- Current and target behavior are documented.
|
|
4698
|
+
- Journey is reconstructed for user-facing changes.
|
|
4699
|
+
- Surfaces and modules are evaluated with explicit statuses.
|
|
4562
4700
|
- Problem and expected result are unambiguous.
|
|
4563
4701
|
- Scope and out-of-scope are explicit.
|
|
4564
|
-
- Acceptance criteria
|
|
4702
|
+
- Acceptance criteria include end-to-end validation when applicable.
|
|
4703
|
+
- Scope unknowns are visible, not hidden.
|
|
4704
|
+
- Scope confidence is declared with reasons.
|
|
4565
4705
|
- Open questions and dependencies are surfaced, not hidden.
|
|
4566
4706
|
|
|
4567
4707
|
## Example output
|
|
@@ -4782,14 +4922,19 @@ steps, and stop criteria (when to pause and ask).
|
|
|
4782
4922
|
## Rules
|
|
4783
4923
|
|
|
4784
4924
|
- Do not start coding without confirmation.
|
|
4785
|
-
- Do not expand scope.
|
|
4925
|
+
- Do not expand scope without updating the Work Item.
|
|
4786
4926
|
- Never make commits or push \u2014 suggest only.
|
|
4927
|
+
- Review scope coverage before planning: check that expected result, current/target behavior,
|
|
4928
|
+
module coverage, and acceptance criteria are consistent. Flag contradictions (e.g., user-facing
|
|
4929
|
+
change with unassessed frontend module).
|
|
4787
4930
|
|
|
4788
4931
|
## Quality checklist
|
|
4789
4932
|
|
|
4933
|
+
- Pre-implementation scope review is documented.
|
|
4790
4934
|
- Scope and expected files are explicit.
|
|
4791
4935
|
- Risks and validations are listed.
|
|
4792
4936
|
- Stop criteria are defined.
|
|
4937
|
+
- Module coverage aligns with planned changes.
|
|
4793
4938
|
|
|
4794
4939
|
## Example output
|
|
4795
4940
|
|
|
@@ -5937,18 +6082,31 @@ A refined Work Item intended to be saved under the lifecycle workspace:
|
|
|
5937
6082
|
|
|
5938
6083
|
## Instructions
|
|
5939
6084
|
|
|
5940
|
-
1.
|
|
5941
|
-
2.
|
|
5942
|
-
3.
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
6.
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
6085
|
+
1. **Interpret the outcome** \u2014 what must change for the actor or consumer of this change.
|
|
6086
|
+
2. **Identify the actor** \u2014 who experiences or triggers the change.
|
|
6087
|
+
3. **Describe current behavior** \u2014 what happens today.
|
|
6088
|
+
4. **Describe target behavior** \u2014 what should happen after the change.
|
|
6089
|
+
5. **Reconstruct the journey** \u2014 for user-facing changes, map the end-to-end flow from entry
|
|
6090
|
+
point to final observable result before proposing files.
|
|
6091
|
+
6. **Evaluate surfaces** \u2014 assess each potentially affected surface (frontend, backend, database,
|
|
6092
|
+
configuration, content, feature flags, authentication, notifications, analytics, documentation,
|
|
6093
|
+
operations) as \`affected\`, \`reviewed-not-affected\`, \`unknown\`, or \`not-applicable\`.
|
|
6094
|
+
7. **Evaluate modules** \u2014 for multirepo projects, assess each plausibly related mapped module with
|
|
6095
|
+
the same statuses. A module must be \`affected\`, \`reviewed-not-affected\`, \`unknown\`, or
|
|
6096
|
+
\`not-applicable\`. Do not leave related modules unmentioned.
|
|
6097
|
+
8. Restate the problem in one clear sentence.
|
|
6098
|
+
9. Split the candidate if it is too large for a single Work Item.
|
|
6099
|
+
10. Preserve the candidate's type (\`feature\`, \`bugfix\`, \`hotfix\`, \`spike\`, \`chore\`).
|
|
6100
|
+
Keep \`chore\` for maintenance/tooling/config/infra work \u2014 never upgrade a chore to a feature.
|
|
6101
|
+
11. Validate the Knowledge Level (K0\u2013K4) and propose a different one if needed.
|
|
6102
|
+
12. Propose acceptance criteria \u2014 include at least one end-to-end criterion for user-facing changes.
|
|
6103
|
+
13. Propose an Out of scope section.
|
|
6104
|
+
14. Propose **how to test it** \u2014 concrete validation steps (commands to run, manual steps, or
|
|
6105
|
+
test cases) that prove the change works once implemented. This is mandatory.
|
|
6106
|
+
15. Propose a Definition of Done.
|
|
6107
|
+
16. Identify open questions, assumptions, and scope unknowns.
|
|
6108
|
+
17. Determine scope confidence (high, medium, low) with reasons.
|
|
6109
|
+
18. Suggest ownership candidates (code globs) if evident.
|
|
5952
6110
|
|
|
5953
6111
|
## Constraints
|
|
5954
6112
|
|
|
@@ -5956,19 +6114,49 @@ A refined Work Item intended to be saved under the lifecycle workspace:
|
|
|
5956
6114
|
- Do not invent business facts.
|
|
5957
6115
|
- Do not assign a Knowledge Level higher than the change requires.
|
|
5958
6116
|
- Mark assumptions explicitly.
|
|
6117
|
+
- Do not reduce a product intent to the first technical implementation found.
|
|
6118
|
+
- Inspect the observable outcome before proposing files.
|
|
6119
|
+
- For user-facing changes, assess the entry point, interaction surface, backend behavior, and
|
|
6120
|
+
final user-visible result.
|
|
6121
|
+
- For multirepo projects, assess each plausibly related mapped module.
|
|
6122
|
+
- Do not mark the Work Item ready while material scope remains unknown.
|
|
6123
|
+
- Ask focused questions instead of silently narrowing the request.
|
|
6124
|
+
- Preserve unsupported assumptions as assumptions.
|
|
5959
6125
|
|
|
5960
6126
|
## Output Format
|
|
5961
6127
|
|
|
5962
6128
|
\`\`\`markdown
|
|
5963
6129
|
# <Work Item title>
|
|
5964
6130
|
|
|
6131
|
+
**Actor and outcome:**
|
|
6132
|
+
|
|
6133
|
+
**Current behavior:**
|
|
6134
|
+
|
|
6135
|
+
**Target behavior:**
|
|
6136
|
+
|
|
6137
|
+
**Entry points:**
|
|
6138
|
+
|
|
6139
|
+
**End-to-end flow:**
|
|
6140
|
+
|
|
5965
6141
|
**Problem:**
|
|
5966
6142
|
|
|
5967
6143
|
**Expected result:**
|
|
5968
6144
|
|
|
5969
6145
|
**Suggested Knowledge Level:** K1 / K2 / K3 / K4
|
|
5970
6146
|
|
|
6147
|
+
**Impact analysis:**
|
|
6148
|
+
<!-- surfaces: affected / reviewed-not-affected / unknown / not-applicable -->
|
|
6149
|
+
|
|
6150
|
+
**Module coverage:**
|
|
6151
|
+
<!-- for multirepo: each module as affected / reviewed-not-affected / unknown / not-applicable -->
|
|
6152
|
+
|
|
6153
|
+
**Scope unknowns:**
|
|
6154
|
+
|
|
6155
|
+
**Scope confidence:** high / medium / low
|
|
6156
|
+
<!-- reasons: -->
|
|
6157
|
+
|
|
5971
6158
|
**Acceptance criteria:**
|
|
6159
|
+
<!-- include at least one end-to-end criterion for user-facing changes -->
|
|
5972
6160
|
|
|
5973
6161
|
**Out of scope:**
|
|
5974
6162
|
|
|
@@ -6705,6 +6893,20 @@ Working code, tests and migrations, plus updated knowledge (ADR / capabilities /
|
|
|
6705
6893
|
when the change affects them. You also produce a suggested branch name and a suggested
|
|
6706
6894
|
Conventional Commit message \u2014 as suggestions, never executed.
|
|
6707
6895
|
|
|
6896
|
+
## Pre-implementation Scope Review (VS-095)
|
|
6897
|
+
|
|
6898
|
+
Before implementing, review the Work Item's scope coverage:
|
|
6899
|
+
- Check that expected result, current behavior, and target behavior are documented.
|
|
6900
|
+
- Verify the journey covers the full user-facing flow when applicable.
|
|
6901
|
+
- Confirm affected surfaces and modules are declared.
|
|
6902
|
+
- Check module_coverage: if a mapped module is plausibly related but not assessed, flag it.
|
|
6903
|
+
- Verify acceptance criteria include end-to-end validation for user-facing changes.
|
|
6904
|
+
- Check for unresolved scope unknowns that could change the implementation.
|
|
6905
|
+
|
|
6906
|
+
If you find a contradiction (e.g., target behavior describes a user-facing registration flow but
|
|
6907
|
+
the mapped frontend module was not assessed), explain the finding, propose updating the Work Item,
|
|
6908
|
+
and wait for confirmation before proceeding. Do not silently expand scope.
|
|
6909
|
+
|
|
6708
6910
|
## Instructions
|
|
6709
6911
|
|
|
6710
6912
|
1. **Suggest a branch first** (do not run it). Follow the Git strategy
|
|
@@ -7627,7 +7829,7 @@ var refineWorkItem = {
|
|
|
7627
7829
|
id: "refine-work-item",
|
|
7628
7830
|
label: "Refine Work Item",
|
|
7629
7831
|
evaluate: (ctx) => {
|
|
7630
|
-
if (ctx.readyWorkItems > 0 || ctx.inProgressWorkItems > 0) return { status: "done" };
|
|
7832
|
+
if (ctx.readyWorkItems > 0 || ctx.inProgressWorkItems > 0 || ctx.blockedWorkItems > 0 || ctx.completedWorkItems > 0 || ctx.archivedWorkItems > 0) return { status: "done" };
|
|
7631
7833
|
if (ctx.draftWorkItems > 0) {
|
|
7632
7834
|
return {
|
|
7633
7835
|
status: "current",
|
|
@@ -7878,7 +8080,9 @@ function buildRouteContext(dir) {
|
|
|
7878
8080
|
draftWorkItems: byState("draft"),
|
|
7879
8081
|
readyWorkItems: byState("ready"),
|
|
7880
8082
|
inProgressWorkItems: byState("in-progress"),
|
|
8083
|
+
blockedWorkItems: byState("blocked"),
|
|
7881
8084
|
completedWorkItems: byState("completed"),
|
|
8085
|
+
archivedWorkItems: byState("archived"),
|
|
7882
8086
|
ownershipCoverage: `${withOwnership}/${total}`,
|
|
7883
8087
|
ownershipComplete: total > 0 && withOwnership >= total,
|
|
7884
8088
|
decisionCandidates: td.candidates,
|
|
@@ -8368,6 +8572,30 @@ function buildProjectExplanation(dir) {
|
|
|
8368
8572
|
scanSignals: loadScanSignals(dir),
|
|
8369
8573
|
metadataHealth: analyzeMetadataHealth(dir),
|
|
8370
8574
|
isModuleRepo: config != null && isModule(config),
|
|
8575
|
+
deliverySummary: (() => {
|
|
8576
|
+
const completed = workItemArtifacts.filter((a2) => lifecycleStateOf({ status: a2.status, filePath: a2.filePath }) === "completed");
|
|
8577
|
+
const archived = workItemArtifacts.filter((a2) => lifecycleStateOf({ status: a2.status, filePath: a2.filePath }) === "archived");
|
|
8578
|
+
const active = workItemArtifacts.filter((a2) => isActiveState(lifecycleStateOf({ status: a2.status, filePath: a2.filePath })));
|
|
8579
|
+
if (completed.length === 0 && archived.length === 0) return null;
|
|
8580
|
+
return {
|
|
8581
|
+
completedWorkItems: completed.length,
|
|
8582
|
+
archivedWorkItems: archived.length,
|
|
8583
|
+
activeWorkItems: active.length,
|
|
8584
|
+
implementationCompleted: completed.filter((a2) => a2.implementationStatus === "completed").length,
|
|
8585
|
+
releaseBlocked: completed.filter((a2) => a2.releaseStatus === "blocked").length,
|
|
8586
|
+
releaseReady: completed.filter((a2) => a2.releaseStatus === "ready" || a2.releaseStatus === "released").length
|
|
8587
|
+
};
|
|
8588
|
+
})(),
|
|
8589
|
+
scopeCoverage: workItemArtifacts.filter((a2) => a2.scopeConfidence || a2.moduleCoverage || a2.impactAnalysis).map((a2) => {
|
|
8590
|
+
const unknownModules = a2.moduleCoverage ? Object.entries(a2.moduleCoverage).filter(([, v]) => v.status === "unknown").map(([k2]) => k2) : [];
|
|
8591
|
+
return {
|
|
8592
|
+
id: a2.id || a2.title,
|
|
8593
|
+
scopeConfidence: a2.scopeConfidence,
|
|
8594
|
+
moduleCoverage: a2.moduleCoverage,
|
|
8595
|
+
unknownModules,
|
|
8596
|
+
hasScopeCoverage: true
|
|
8597
|
+
};
|
|
8598
|
+
}),
|
|
8371
8599
|
implementationEvidence: workItemArtifacts.filter((a2) => a2.affectedModules.length > 0).map((a2) => {
|
|
8372
8600
|
const fm = a2.rawFrontmatter;
|
|
8373
8601
|
const evidence = fm.implementation_evidence;
|
|
@@ -8379,11 +8607,13 @@ function buildProjectExplanation(dir) {
|
|
|
8379
8607
|
status: String(data.status ?? "unknown")
|
|
8380
8608
|
};
|
|
8381
8609
|
}
|
|
8610
|
+
const lc = lifecycleStateOf({ status: a2.status, filePath: a2.filePath });
|
|
8611
|
+
const historicalDefault = lc === "completed" || lc === "archived" ? "not-assessed" : "not-started";
|
|
8382
8612
|
return {
|
|
8383
8613
|
id: a2.id || a2.title,
|
|
8384
|
-
lifecycle:
|
|
8385
|
-
implementationStatus: a2.implementationStatus ||
|
|
8386
|
-
validationStatus: a2.validationStatus ||
|
|
8614
|
+
lifecycle: lc,
|
|
8615
|
+
implementationStatus: a2.implementationStatus || historicalDefault,
|
|
8616
|
+
validationStatus: a2.validationStatus || historicalDefault,
|
|
8387
8617
|
releaseStatus: a2.releaseStatus || "not-assessed",
|
|
8388
8618
|
affectedModules: a2.affectedModules,
|
|
8389
8619
|
releaseGates: Array.isArray(fm.release_gates) ? fm.release_gates : [],
|
|
@@ -8546,6 +8776,23 @@ function renderExplanationHuman(exp) {
|
|
|
8546
8776
|
}
|
|
8547
8777
|
lines.push("");
|
|
8548
8778
|
}
|
|
8779
|
+
if (exp.scopeCoverage.length > 0) {
|
|
8780
|
+
lines.push("## Work Item Scope Coverage");
|
|
8781
|
+
for (const sc of exp.scopeCoverage) {
|
|
8782
|
+
lines.push("");
|
|
8783
|
+
lines.push(`### ${sc.id}`);
|
|
8784
|
+
if (sc.scopeConfidence) lines.push(`- Scope confidence: ${sc.scopeConfidence.level}`);
|
|
8785
|
+
if (sc.moduleCoverage) {
|
|
8786
|
+
const affected = Object.entries(sc.moduleCoverage).filter(([, v]) => v.status === "affected").map(([k2]) => k2);
|
|
8787
|
+
const reviewed = Object.entries(sc.moduleCoverage).filter(([, v]) => v.status === "reviewed-not-affected").map(([k2]) => k2);
|
|
8788
|
+
const unknown = Object.entries(sc.moduleCoverage).filter(([, v]) => v.status === "unknown").map(([k2]) => k2);
|
|
8789
|
+
if (affected.length > 0) lines.push(`Affected: ${affected.join(", ")}`);
|
|
8790
|
+
if (reviewed.length > 0) lines.push(`Reviewed, not affected: ${reviewed.join(", ")}`);
|
|
8791
|
+
if (unknown.length > 0) lines.push(`Unknown: ${unknown.join(", ")}`);
|
|
8792
|
+
}
|
|
8793
|
+
}
|
|
8794
|
+
lines.push("");
|
|
8795
|
+
}
|
|
8549
8796
|
if (exp.domains.length > 0) {
|
|
8550
8797
|
lines.push("## Domains");
|
|
8551
8798
|
lines.push(`- ${exp.domains.join(", ")}`);
|
|
@@ -8628,6 +8875,17 @@ function renderExplanationHuman(exp) {
|
|
|
8628
8875
|
}
|
|
8629
8876
|
lines.push(`- Next step: ${exp.readiness.recommended_next_step.label}`);
|
|
8630
8877
|
lines.push("");
|
|
8878
|
+
if (exp.deliverySummary) {
|
|
8879
|
+
const ds = exp.deliverySummary;
|
|
8880
|
+
lines.push("## Delivery Summary");
|
|
8881
|
+
lines.push(`- Completed Work Items: ${ds.completedWorkItems}`);
|
|
8882
|
+
if (ds.archivedWorkItems > 0) lines.push(`- Archived Work Items: ${ds.archivedWorkItems}`);
|
|
8883
|
+
lines.push(`- Active Work Items: ${ds.activeWorkItems}`);
|
|
8884
|
+
if (ds.implementationCompleted > 0) lines.push(`- Implementation completed: ${ds.implementationCompleted}`);
|
|
8885
|
+
if (ds.releaseBlocked > 0) lines.push(`- Release blocked: ${ds.releaseBlocked}`);
|
|
8886
|
+
if (ds.releaseReady > 0) lines.push(`- Release ready: ${ds.releaseReady}`);
|
|
8887
|
+
lines.push("");
|
|
8888
|
+
}
|
|
8631
8889
|
const rec = exp.nextStepRecommendation;
|
|
8632
8890
|
const secondary = rec.secondary ?? [];
|
|
8633
8891
|
const steps = secondary.length > 0 || /Delivery|Active|Maintenance/.test(rec.phase) ? [rec.label, ...secondary.map((s2) => s2.label)] : exp.suggestedNextSteps;
|
|
@@ -8662,6 +8920,10 @@ function renderExplanationHuman(exp) {
|
|
|
8662
8920
|
if (!exp.isModuleRepo) {
|
|
8663
8921
|
lines.push(`- roadmap: ${s.roadmap}`);
|
|
8664
8922
|
lines.push(`- work-items: ${s.work_items}`);
|
|
8923
|
+
if (exp.deliverySummary) {
|
|
8924
|
+
lines.push(`- work-items completed: ${exp.deliverySummary.completedWorkItems}`);
|
|
8925
|
+
lines.push(`- work-items active: ${exp.deliverySummary.activeWorkItems}`);
|
|
8926
|
+
}
|
|
8665
8927
|
lines.push(`- adapters: ${s.adapters.length > 0 ? s.adapters.join(", ") + " installed" : "none installed"}`);
|
|
8666
8928
|
} else {
|
|
8667
8929
|
lines.push("- roadmap: managed-by-core");
|
|
@@ -9709,6 +9971,49 @@ function firstParagraph2(body) {
|
|
|
9709
9971
|
}
|
|
9710
9972
|
return "";
|
|
9711
9973
|
}
|
|
9974
|
+
var VALID_COVERAGE_STATUSES2 = /* @__PURE__ */ new Set(["affected", "reviewed-not-affected", "unknown", "not-applicable"]);
|
|
9975
|
+
function parseScopeMeta(data) {
|
|
9976
|
+
const result = {};
|
|
9977
|
+
const sc = data.scope_confidence;
|
|
9978
|
+
if (sc && typeof sc === "object" && !Array.isArray(sc)) {
|
|
9979
|
+
const obj = sc;
|
|
9980
|
+
const level = String(obj.level ?? "");
|
|
9981
|
+
if (["high", "medium", "low"].includes(level)) {
|
|
9982
|
+
result.scope_confidence = { level, reasons: Array.isArray(obj.reasons) ? obj.reasons.map(String) : [] };
|
|
9983
|
+
}
|
|
9984
|
+
}
|
|
9985
|
+
const mc = data.module_coverage;
|
|
9986
|
+
if (mc && typeof mc === "object" && !Array.isArray(mc)) {
|
|
9987
|
+
const parsed = {};
|
|
9988
|
+
const unknowns = [];
|
|
9989
|
+
for (const [id, val] of Object.entries(mc)) {
|
|
9990
|
+
if (!val || typeof val !== "object" || Array.isArray(val)) continue;
|
|
9991
|
+
const v = val;
|
|
9992
|
+
const status = String(v.status ?? "");
|
|
9993
|
+
if (!VALID_COVERAGE_STATUSES2.has(status)) continue;
|
|
9994
|
+
parsed[id] = { status, ...v.reason ? { reason: String(v.reason) } : {} };
|
|
9995
|
+
if (status === "unknown") unknowns.push(id);
|
|
9996
|
+
}
|
|
9997
|
+
if (Object.keys(parsed).length > 0) result.module_coverage = parsed;
|
|
9998
|
+
if (unknowns.length > 0) result.scope_unknowns = unknowns;
|
|
9999
|
+
}
|
|
10000
|
+
const ia = data.impact_analysis;
|
|
10001
|
+
if (ia && typeof ia === "object" && !Array.isArray(ia)) {
|
|
10002
|
+
const surfaces = ia.surfaces;
|
|
10003
|
+
if (surfaces && typeof surfaces === "object" && !Array.isArray(surfaces)) {
|
|
10004
|
+
const parsed = {};
|
|
10005
|
+
for (const [id, val] of Object.entries(surfaces)) {
|
|
10006
|
+
if (!val || typeof val !== "object" || Array.isArray(val)) continue;
|
|
10007
|
+
const v = val;
|
|
10008
|
+
const status = String(v.status ?? "");
|
|
10009
|
+
if (!VALID_COVERAGE_STATUSES2.has(status)) continue;
|
|
10010
|
+
parsed[id] = { status, ...v.reason ? { reason: String(v.reason) } : {} };
|
|
10011
|
+
}
|
|
10012
|
+
if (Object.keys(parsed).length > 0) result.impact_analysis = parsed;
|
|
10013
|
+
}
|
|
10014
|
+
}
|
|
10015
|
+
return result;
|
|
10016
|
+
}
|
|
9712
10017
|
function listWorkItems(root) {
|
|
9713
10018
|
const files = listFiles(root, "knowledge/delivery/work-items", ".md");
|
|
9714
10019
|
const items = [];
|
|
@@ -9751,7 +10056,8 @@ function listWorkItems(root) {
|
|
|
9751
10056
|
...data.implemented_by ? { implemented_by: String(data.implemented_by) } : {},
|
|
9752
10057
|
...data.closed_by ? { closed_by: String(data.closed_by) } : {},
|
|
9753
10058
|
...Array.isArray(data.release_gates) && data.release_gates.length > 0 ? { release_gates: data.release_gates } : {},
|
|
9754
|
-
...Array.isArray(data.completion_exceptions) && data.completion_exceptions.length > 0 ? { completion_exceptions: data.completion_exceptions } : {}
|
|
10059
|
+
...Array.isArray(data.completion_exceptions) && data.completion_exceptions.length > 0 ? { completion_exceptions: data.completion_exceptions } : {},
|
|
10060
|
+
...parseScopeMeta(data)
|
|
9755
10061
|
});
|
|
9756
10062
|
}
|
|
9757
10063
|
return items.sort((a2, b2) => a2.id.localeCompare(b2.id));
|
|
@@ -10173,6 +10479,16 @@ function projectStatus(root) {
|
|
|
10173
10479
|
agents: "managed-by-core",
|
|
10174
10480
|
skills: "managed-by-core"
|
|
10175
10481
|
};
|
|
10482
|
+
} else {
|
|
10483
|
+
result.readiness = {
|
|
10484
|
+
overall: explain.readiness?.overall ?? "unknown"
|
|
10485
|
+
};
|
|
10486
|
+
}
|
|
10487
|
+
if (explain.deliverySummary) {
|
|
10488
|
+
result.deliverySummary = explain.deliverySummary;
|
|
10489
|
+
}
|
|
10490
|
+
if (explain.scopeCoverage && Array.isArray(explain.scopeCoverage) && explain.scopeCoverage.length > 0) {
|
|
10491
|
+
result.scopeCoverage = explain.scopeCoverage;
|
|
10176
10492
|
}
|
|
10177
10493
|
return ok(result);
|
|
10178
10494
|
}
|
|
@@ -10876,20 +11192,29 @@ var OPERATING_RULES = [
|
|
|
10876
11192
|
"Kaddo itself never calls an LLM and never runs git \u2014 every git action is the human\u2019s."
|
|
10877
11193
|
];
|
|
10878
11194
|
function toContextWorkItem(a2) {
|
|
11195
|
+
const lifecycle = lifecycleStateOf({ status: a2.status, filePath: a2.filePath });
|
|
11196
|
+
const isHistorical = lifecycle === "completed" || lifecycle === "archived";
|
|
10879
11197
|
const wi = {
|
|
10880
11198
|
id: a2.id,
|
|
10881
11199
|
type: a2.type,
|
|
10882
11200
|
title: a2.title,
|
|
10883
11201
|
status: a2.status,
|
|
10884
|
-
lifecycle
|
|
11202
|
+
lifecycle,
|
|
10885
11203
|
knowledgeLevel: a2.knowledgeLevel,
|
|
10886
11204
|
domains: a2.domains,
|
|
10887
11205
|
source: parseWorkItemSource(a2.rawFrontmatter)
|
|
10888
11206
|
};
|
|
10889
|
-
|
|
10890
|
-
|
|
10891
|
-
|
|
11207
|
+
wi.implementationStatus = a2.implementationStatus || (isHistorical ? "not-assessed" : void 0);
|
|
11208
|
+
wi.validationStatus = a2.validationStatus || (isHistorical ? "not-assessed" : void 0);
|
|
11209
|
+
wi.releaseStatus = a2.releaseStatus || (isHistorical ? "not-assessed" : void 0);
|
|
10892
11210
|
if (a2.affectedModules.length > 0) wi.affectedModules = a2.affectedModules;
|
|
11211
|
+
if (a2.scopeConfidence) wi.scopeConfidence = a2.scopeConfidence;
|
|
11212
|
+
if (a2.moduleCoverage) wi.moduleCoverage = a2.moduleCoverage;
|
|
11213
|
+
if (a2.impactAnalysis) wi.impactAnalysis = a2.impactAnalysis;
|
|
11214
|
+
if (a2.moduleCoverage) {
|
|
11215
|
+
const unknowns = Object.entries(a2.moduleCoverage).filter(([, v]) => v.status === "unknown").map(([k2]) => k2);
|
|
11216
|
+
if (unknowns.length > 0) wi.scopeUnknowns = unknowns;
|
|
11217
|
+
}
|
|
10893
11218
|
return wi;
|
|
10894
11219
|
}
|
|
10895
11220
|
function toContextArtifact(a2) {
|
|
@@ -10919,10 +11244,17 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
10919
11244
|
missing.push("No roadmap baseline found.");
|
|
10920
11245
|
}
|
|
10921
11246
|
const allArtifacts = discoverKnowledge(dir);
|
|
10922
|
-
const
|
|
10923
|
-
|
|
11247
|
+
const allWorkItemArtifacts = allArtifacts.filter((a2) => isDeliveryWorkItem(a2));
|
|
11248
|
+
const workItems = allWorkItemArtifacts.filter(
|
|
11249
|
+
(a2) => isActiveState(lifecycleStateOf({ status: a2.status, filePath: a2.filePath }))
|
|
11250
|
+
);
|
|
11251
|
+
const completedWorkItems = allWorkItemArtifacts.filter(
|
|
11252
|
+
(a2) => lifecycleStateOf({ status: a2.status, filePath: a2.filePath }) === "completed"
|
|
10924
11253
|
);
|
|
10925
|
-
|
|
11254
|
+
const archivedWorkItems = allWorkItemArtifacts.filter(
|
|
11255
|
+
(a2) => lifecycleStateOf({ status: a2.status, filePath: a2.filePath }) === "archived"
|
|
11256
|
+
);
|
|
11257
|
+
if (allWorkItemArtifacts.length === 0 && !moduleRepo) {
|
|
10926
11258
|
missing.push("No work items found.");
|
|
10927
11259
|
}
|
|
10928
11260
|
const state = config.project.state;
|
|
@@ -11037,6 +11369,10 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
11037
11369
|
roadmapSummary,
|
|
11038
11370
|
inventoryAvailable,
|
|
11039
11371
|
workItems: workItems.map(toContextWorkItem),
|
|
11372
|
+
activeWorkItems: workItems.map(toContextWorkItem),
|
|
11373
|
+
completedWorkItems: completedWorkItems.map(toContextWorkItem),
|
|
11374
|
+
archivedWorkItems: archivedWorkItems.map(toContextWorkItem),
|
|
11375
|
+
allWorkItems: allWorkItemArtifacts.map(toContextWorkItem),
|
|
11040
11376
|
artifacts: allArtifacts.filter((a2) => a2.codeGlobs.length > 0).map(toContextArtifact)
|
|
11041
11377
|
},
|
|
11042
11378
|
layers,
|
|
@@ -11053,6 +11389,30 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
11053
11389
|
const compact = (a2) => ({ total: a2.total, installed: a2.total - a2.missing, outdated: a2.outdated, unknown_version: a2.unknown_version, modified: a2.modified });
|
|
11054
11390
|
return { version: s.version, agents: compact(s.agents), skills: compact(s.skills) };
|
|
11055
11391
|
})(),
|
|
11392
|
+
workItemSummary: (() => {
|
|
11393
|
+
const lc = (s) => allWorkItemArtifacts.filter(
|
|
11394
|
+
(a2) => lifecycleStateOf({ status: a2.status, filePath: a2.filePath }) === s
|
|
11395
|
+
).length;
|
|
11396
|
+
const draft = lc("draft");
|
|
11397
|
+
const ready = lc("ready");
|
|
11398
|
+
const inProgress = lc("in-progress");
|
|
11399
|
+
const blocked = lc("blocked");
|
|
11400
|
+
const completed = lc("completed");
|
|
11401
|
+
const archived = lc("archived");
|
|
11402
|
+
const active = draft + ready + inProgress + blocked;
|
|
11403
|
+
const total = allWorkItemArtifacts.length;
|
|
11404
|
+
let summary = "none";
|
|
11405
|
+
if (total === 0) summary = "none";
|
|
11406
|
+
else if (active === 0 && completed > 0 && archived === 0) summary = "completed-only";
|
|
11407
|
+
else if (active === 0 && archived > 0 && completed === 0) summary = "archived-only";
|
|
11408
|
+
else if (active === 0 && completed + archived > 0) summary = "historical-only";
|
|
11409
|
+
else if (inProgress > 0) summary = "active";
|
|
11410
|
+
else if (blocked > 0 && ready === 0 && inProgress === 0) summary = "blocked";
|
|
11411
|
+
else if (ready > 0) summary = "ready";
|
|
11412
|
+
else if (draft > 0 && ready === 0) summary = "draft-only";
|
|
11413
|
+
else summary = "mixed-active";
|
|
11414
|
+
return { total, active, draft, ready, in_progress: inProgress, blocked, completed, archived, summary };
|
|
11415
|
+
})(),
|
|
11056
11416
|
deliveryMix,
|
|
11057
11417
|
external: loadExternalCapsules(dir),
|
|
11058
11418
|
graph: loadGraphSummary(dir),
|
package/package.json
CHANGED