@kaddo/cli 3.9.0 → 3.9.1
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 +142 -122
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4044,9 +4044,11 @@ function parseArtifact(filePath, raw) {
|
|
|
4044
4044
|
knowledgeLevel: String(data.knowledge_level ?? ""),
|
|
4045
4045
|
codeGlobs: globs,
|
|
4046
4046
|
domains: Array.isArray(data.domains) ? data.domains : [],
|
|
4047
|
+
capabilities: Array.isArray(data.capabilities) ? data.capabilities.map(String).filter(Boolean) : [],
|
|
4047
4048
|
status: String(data.status ?? ""),
|
|
4048
4049
|
phase: String(data.phase ?? ""),
|
|
4049
|
-
initiative: String(data.initiative ?? data.source_initiative ?? "")
|
|
4050
|
+
initiative: String(data.initiative ?? data.source_initiative ?? ""),
|
|
4051
|
+
source: data.source ? String(data.source) : ""
|
|
4050
4052
|
};
|
|
4051
4053
|
} catch {
|
|
4052
4054
|
return null;
|
|
@@ -4071,6 +4073,94 @@ function readArtifacts(archDir) {
|
|
|
4071
4073
|
return artifacts;
|
|
4072
4074
|
}
|
|
4073
4075
|
|
|
4076
|
+
// src/core/lifecycle.ts
|
|
4077
|
+
var LIFECYCLE_STATES = [
|
|
4078
|
+
"draft",
|
|
4079
|
+
"ready",
|
|
4080
|
+
"in-progress",
|
|
4081
|
+
"blocked",
|
|
4082
|
+
"completed",
|
|
4083
|
+
"archived"
|
|
4084
|
+
];
|
|
4085
|
+
var ACTIVE_STATES = ["draft", "ready", "in-progress", "blocked"];
|
|
4086
|
+
var LEGACY_STATUS_MAP = {
|
|
4087
|
+
done: "completed",
|
|
4088
|
+
cancelled: "archived",
|
|
4089
|
+
canceled: "archived",
|
|
4090
|
+
"in-progress": "in-progress"
|
|
4091
|
+
};
|
|
4092
|
+
var STATE_SET = new Set(LIFECYCLE_STATES);
|
|
4093
|
+
function isLifecycleState(s) {
|
|
4094
|
+
return STATE_SET.has(s);
|
|
4095
|
+
}
|
|
4096
|
+
function isActiveState(s) {
|
|
4097
|
+
return ACTIVE_STATES.includes(s);
|
|
4098
|
+
}
|
|
4099
|
+
function lifecycleFolderOf(filePath) {
|
|
4100
|
+
const p2 = filePath.replace(/\\/g, "/");
|
|
4101
|
+
const m = p2.match(/\/delivery\/work-items\/([^/]+)\//);
|
|
4102
|
+
if (m && isLifecycleState(m[1])) return m[1];
|
|
4103
|
+
return null;
|
|
4104
|
+
}
|
|
4105
|
+
function lifecycleStateOf(item) {
|
|
4106
|
+
const status = (item.status ?? "").trim().toLowerCase();
|
|
4107
|
+
if (isLifecycleState(status)) return status;
|
|
4108
|
+
if (status && LEGACY_STATUS_MAP[status]) return LEGACY_STATUS_MAP[status];
|
|
4109
|
+
const folder = lifecycleFolderOf(item.filePath ?? "");
|
|
4110
|
+
if (folder) return folder;
|
|
4111
|
+
return "ready";
|
|
4112
|
+
}
|
|
4113
|
+
function emptyLifecycleCounts() {
|
|
4114
|
+
return Object.fromEntries(LIFECYCLE_STATES.map((s) => [s, 0]));
|
|
4115
|
+
}
|
|
4116
|
+
function lifecycleCounts(states) {
|
|
4117
|
+
const counts = emptyLifecycleCounts();
|
|
4118
|
+
for (const s of states) counts[s]++;
|
|
4119
|
+
return counts;
|
|
4120
|
+
}
|
|
4121
|
+
|
|
4122
|
+
// src/services/knowledge-artifacts.ts
|
|
4123
|
+
var ARCH_DIR2 = "knowledge";
|
|
4124
|
+
function toPosix(p2) {
|
|
4125
|
+
return p2.replace(/\\/g, "/");
|
|
4126
|
+
}
|
|
4127
|
+
function relativeTo(dir, filePath) {
|
|
4128
|
+
const base = toPosix(dir).replace(/\/+$/, "");
|
|
4129
|
+
const full = toPosix(filePath);
|
|
4130
|
+
return full.startsWith(base + "/") ? full.slice(base.length + 1) : full;
|
|
4131
|
+
}
|
|
4132
|
+
function isWorkItemArtifact(a) {
|
|
4133
|
+
return toPosix(a.filePath).includes("/delivery/work-items/") && Boolean(a.type);
|
|
4134
|
+
}
|
|
4135
|
+
function classifyLayer(posixPath) {
|
|
4136
|
+
if (posixPath.includes("/knowledge/business/")) return "business";
|
|
4137
|
+
if (posixPath.includes("/knowledge/product/")) return "product";
|
|
4138
|
+
if (posixPath.includes("/knowledge/tech/modules/") || posixPath.includes("/knowledge/modules/"))
|
|
4139
|
+
return "module";
|
|
4140
|
+
if (posixPath.includes("/knowledge/tech/")) return "tech";
|
|
4141
|
+
if (posixPath.includes("/knowledge/delivery/")) return "delivery";
|
|
4142
|
+
return "unknown";
|
|
4143
|
+
}
|
|
4144
|
+
function enrich(dir, a) {
|
|
4145
|
+
const posix = toPosix(a.filePath);
|
|
4146
|
+
const isWi = isWorkItemArtifact(a);
|
|
4147
|
+
return {
|
|
4148
|
+
...a,
|
|
4149
|
+
relPath: relativeTo(dir, a.filePath),
|
|
4150
|
+
layer: classifyLayer(posix),
|
|
4151
|
+
isWorkItem: isWi,
|
|
4152
|
+
lifecycle: isWi ? lifecycleStateOf({ status: a.status, filePath: a.filePath }) : void 0
|
|
4153
|
+
};
|
|
4154
|
+
}
|
|
4155
|
+
function discoverKnowledge(dir) {
|
|
4156
|
+
const archDir = join(dir, ARCH_DIR2);
|
|
4157
|
+
if (!exists(archDir)) return [];
|
|
4158
|
+
return readArtifacts(archDir).map((a) => enrich(dir, a));
|
|
4159
|
+
}
|
|
4160
|
+
function discoverWorkItems(dir) {
|
|
4161
|
+
return discoverKnowledge(dir).filter((a) => a.isWorkItem);
|
|
4162
|
+
}
|
|
4163
|
+
|
|
4074
4164
|
// src/core/diff-analysis.ts
|
|
4075
4165
|
import { minimatch } from "minimatch";
|
|
4076
4166
|
function normalizePath(p2) {
|
|
@@ -4463,7 +4553,7 @@ function collectMatchedDomains(matchedArtifactDomains) {
|
|
|
4463
4553
|
}
|
|
4464
4554
|
|
|
4465
4555
|
// src/commands/guard.ts
|
|
4466
|
-
var
|
|
4556
|
+
var ARCH_DIR3 = "knowledge";
|
|
4467
4557
|
var CONFIG_PATH2 = ".kaddo/config.yml";
|
|
4468
4558
|
function loadConfig2(dir) {
|
|
4469
4559
|
const configPath = join(dir, CONFIG_PATH2);
|
|
@@ -4607,12 +4697,12 @@ async function runGuard(opts = {}) {
|
|
|
4607
4697
|
console.log("kaddo guard: no modified files detected.");
|
|
4608
4698
|
return;
|
|
4609
4699
|
}
|
|
4610
|
-
const archDir = join(dir,
|
|
4700
|
+
const archDir = join(dir, ARCH_DIR3);
|
|
4611
4701
|
if (!exists(archDir)) {
|
|
4612
4702
|
console.log("kaddo guard: no knowledge/ directory found. Run `kaddo init` first.");
|
|
4613
4703
|
return;
|
|
4614
4704
|
}
|
|
4615
|
-
const artifacts =
|
|
4705
|
+
const artifacts = discoverKnowledge(dir);
|
|
4616
4706
|
const result = analyzeGuard(touchedFiles, artifacts, silentWithoutOwnership);
|
|
4617
4707
|
const pluginSignals = runPlugins(plugins, currentFiles, (filePath) => {
|
|
4618
4708
|
const abs = join(dir, filePath);
|
|
@@ -4881,54 +4971,8 @@ function renderLayersMarkdown(layers) {
|
|
|
4881
4971
|
return lines.join("\n").trimEnd();
|
|
4882
4972
|
}
|
|
4883
4973
|
|
|
4884
|
-
// src/core/lifecycle.ts
|
|
4885
|
-
var LIFECYCLE_STATES = [
|
|
4886
|
-
"draft",
|
|
4887
|
-
"ready",
|
|
4888
|
-
"in-progress",
|
|
4889
|
-
"blocked",
|
|
4890
|
-
"completed",
|
|
4891
|
-
"archived"
|
|
4892
|
-
];
|
|
4893
|
-
var ACTIVE_STATES = ["draft", "ready", "in-progress", "blocked"];
|
|
4894
|
-
var LEGACY_STATUS_MAP = {
|
|
4895
|
-
done: "completed",
|
|
4896
|
-
cancelled: "archived",
|
|
4897
|
-
canceled: "archived",
|
|
4898
|
-
"in-progress": "in-progress"
|
|
4899
|
-
};
|
|
4900
|
-
var STATE_SET = new Set(LIFECYCLE_STATES);
|
|
4901
|
-
function isLifecycleState(s) {
|
|
4902
|
-
return STATE_SET.has(s);
|
|
4903
|
-
}
|
|
4904
|
-
function isActiveState(s) {
|
|
4905
|
-
return ACTIVE_STATES.includes(s);
|
|
4906
|
-
}
|
|
4907
|
-
function lifecycleFolderOf(filePath) {
|
|
4908
|
-
const p2 = filePath.replace(/\\/g, "/");
|
|
4909
|
-
const m = p2.match(/\/delivery\/work-items\/([^/]+)\//);
|
|
4910
|
-
if (m && isLifecycleState(m[1])) return m[1];
|
|
4911
|
-
return null;
|
|
4912
|
-
}
|
|
4913
|
-
function lifecycleStateOf(item) {
|
|
4914
|
-
const status = (item.status ?? "").trim().toLowerCase();
|
|
4915
|
-
if (isLifecycleState(status)) return status;
|
|
4916
|
-
if (status && LEGACY_STATUS_MAP[status]) return LEGACY_STATUS_MAP[status];
|
|
4917
|
-
const folder = lifecycleFolderOf(item.filePath ?? "");
|
|
4918
|
-
if (folder) return folder;
|
|
4919
|
-
return "ready";
|
|
4920
|
-
}
|
|
4921
|
-
function emptyLifecycleCounts() {
|
|
4922
|
-
return Object.fromEntries(LIFECYCLE_STATES.map((s) => [s, 0]));
|
|
4923
|
-
}
|
|
4924
|
-
function lifecycleCounts(states) {
|
|
4925
|
-
const counts = emptyLifecycleCounts();
|
|
4926
|
-
for (const s of states) counts[s]++;
|
|
4927
|
-
return counts;
|
|
4928
|
-
}
|
|
4929
|
-
|
|
4930
4974
|
// src/core/project-explain.ts
|
|
4931
|
-
var
|
|
4975
|
+
var ARCH_DIR4 = "knowledge";
|
|
4932
4976
|
function first(values) {
|
|
4933
4977
|
if (Array.isArray(values)) {
|
|
4934
4978
|
const v = values.find((x) => typeof x === "string" && x);
|
|
@@ -4959,7 +5003,7 @@ function loadScan(dir) {
|
|
|
4959
5003
|
}
|
|
4960
5004
|
}
|
|
4961
5005
|
function hasAgents(dir) {
|
|
4962
|
-
const agentsDir = join(dir,
|
|
5006
|
+
const agentsDir = join(dir, ARCH_DIR4, "agents");
|
|
4963
5007
|
if (!exists(agentsDir)) return false;
|
|
4964
5008
|
function hasAgentMd(d) {
|
|
4965
5009
|
for (const e of readDir(d)) {
|
|
@@ -4996,7 +5040,7 @@ function buildProjectExplanation(dir) {
|
|
|
4996
5040
|
const layerStatus = (name) => layers.find((l) => l.layer === name)?.status ?? "Missing";
|
|
4997
5041
|
const knowledge = {
|
|
4998
5042
|
hasScan: scan2 !== null,
|
|
4999
|
-
hasInventory: exists(join(dir,
|
|
5043
|
+
hasInventory: exists(join(dir, ARCH_DIR4, "inventory.md")),
|
|
5000
5044
|
hasContextPack: exists(join(dir, ".kaddo", "context-pack.md")),
|
|
5001
5045
|
hasUnderstand: exists(join(dir, ".kaddo", "understand.md")),
|
|
5002
5046
|
hasCapabilities: layerStatus("Product") !== "Missing",
|
|
@@ -5004,12 +5048,7 @@ function buildProjectExplanation(dir) {
|
|
|
5004
5048
|
hasRoadmap: layerStatus("Delivery") !== "Missing",
|
|
5005
5049
|
hasAgents: hasAgents(dir)
|
|
5006
5050
|
};
|
|
5007
|
-
const
|
|
5008
|
-
const allArtifacts = exists(archDir) ? readArtifacts(archDir) : [];
|
|
5009
|
-
const workItemArtifacts = allArtifacts.filter((a) => {
|
|
5010
|
-
const p2 = a.filePath.replace(/\\/g, "/");
|
|
5011
|
-
return p2.includes("/delivery/work-items/") && Boolean(a.type);
|
|
5012
|
-
});
|
|
5051
|
+
const workItemArtifacts = discoverWorkItems(dir);
|
|
5013
5052
|
const items = workItemArtifacts.map((a) => ({
|
|
5014
5053
|
id: a.id || a.title,
|
|
5015
5054
|
title: a.title,
|
|
@@ -5051,7 +5090,7 @@ function buildProjectExplanation(dir) {
|
|
|
5051
5090
|
workItemsMissingOwnership: items.length - withOwnership
|
|
5052
5091
|
};
|
|
5053
5092
|
const domains = [...new Set(workItemArtifacts.flatMap((a) => a.domains))].filter(Boolean);
|
|
5054
|
-
const roadmapPath = join(dir,
|
|
5093
|
+
const roadmapPath = join(dir, ARCH_DIR4, "delivery", "roadmap.md");
|
|
5055
5094
|
const roadmapMd = exists(roadmapPath) ? readFile(roadmapPath) : null;
|
|
5056
5095
|
const roadmap = roadmapStats(roadmapMd, items.length);
|
|
5057
5096
|
const mappedModules = loadMappedModules(dir);
|
|
@@ -5245,10 +5284,10 @@ function renderExplanationAgent(exp) {
|
|
|
5245
5284
|
}
|
|
5246
5285
|
|
|
5247
5286
|
// src/commands/explain.ts
|
|
5248
|
-
var
|
|
5287
|
+
var ARCH_DIR5 = "knowledge";
|
|
5249
5288
|
var CONFIG_PATH3 = ".kaddo/config.yml";
|
|
5250
5289
|
function readKnowledge(dir) {
|
|
5251
|
-
const knowledgePath = join(dir,
|
|
5290
|
+
const knowledgePath = join(dir, ARCH_DIR5, "knowledge.md");
|
|
5252
5291
|
if (!exists(knowledgePath)) return null;
|
|
5253
5292
|
try {
|
|
5254
5293
|
const raw = readFile(knowledgePath);
|
|
@@ -5259,7 +5298,7 @@ function readKnowledge(dir) {
|
|
|
5259
5298
|
}
|
|
5260
5299
|
}
|
|
5261
5300
|
function readRoadmap(dir) {
|
|
5262
|
-
const roadmapPath = join(dir,
|
|
5301
|
+
const roadmapPath = join(dir, ARCH_DIR5, "roadmap.md");
|
|
5263
5302
|
if (!exists(roadmapPath)) return null;
|
|
5264
5303
|
try {
|
|
5265
5304
|
const raw = readFile(roadmapPath);
|
|
@@ -5408,7 +5447,7 @@ function runExplain(opts) {
|
|
|
5408
5447
|
explainProject(dir, mode);
|
|
5409
5448
|
return;
|
|
5410
5449
|
}
|
|
5411
|
-
const archDir = join(dir,
|
|
5450
|
+
const archDir = join(dir, ARCH_DIR5);
|
|
5412
5451
|
if (!exists(archDir)) {
|
|
5413
5452
|
console.error("No knowledge/ directory found. Run `kaddo init` first.");
|
|
5414
5453
|
process.exit(1);
|
|
@@ -5433,7 +5472,7 @@ function runExplain(opts) {
|
|
|
5433
5472
|
// src/core/context-pack.ts
|
|
5434
5473
|
import matter3 from "gray-matter";
|
|
5435
5474
|
var CONTEXT_PACK_VERSION = "1";
|
|
5436
|
-
var
|
|
5475
|
+
var ARCH_DIR6 = "knowledge";
|
|
5437
5476
|
function readScanJson(dir) {
|
|
5438
5477
|
const scanPath = join(dir, ".kaddo", "scan.json");
|
|
5439
5478
|
if (!exists(scanPath)) return null;
|
|
@@ -5449,7 +5488,7 @@ function firstParagraph(markdown) {
|
|
|
5449
5488
|
return para ?? "";
|
|
5450
5489
|
}
|
|
5451
5490
|
function readMarkdownSummary(dir, file) {
|
|
5452
|
-
const p2 = join(dir,
|
|
5491
|
+
const p2 = join(dir, ARCH_DIR6, file);
|
|
5453
5492
|
if (!exists(p2)) return null;
|
|
5454
5493
|
try {
|
|
5455
5494
|
return firstParagraph(readFile(p2));
|
|
@@ -5527,7 +5566,7 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
5527
5566
|
missing.push("Scan baseline missing. Run `kaddo scan` for better context.");
|
|
5528
5567
|
}
|
|
5529
5568
|
const detected = scanJson?.detected ?? {};
|
|
5530
|
-
const inventoryAvailable = exists(join(dir,
|
|
5569
|
+
const inventoryAvailable = exists(join(dir, ARCH_DIR6, "inventory.md"));
|
|
5531
5570
|
if (!inventoryAvailable) {
|
|
5532
5571
|
missing.push("No technical inventory found. Run `kaddo scan` to generate it.");
|
|
5533
5572
|
}
|
|
@@ -5539,8 +5578,7 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
5539
5578
|
if (!roadmapSummary) {
|
|
5540
5579
|
missing.push("No roadmap baseline found.");
|
|
5541
5580
|
}
|
|
5542
|
-
const
|
|
5543
|
-
const allArtifacts = exists(archPath) ? readArtifacts(archPath) : [];
|
|
5581
|
+
const allArtifacts = discoverKnowledge(dir);
|
|
5544
5582
|
const workItems = allArtifacts.filter(
|
|
5545
5583
|
(a) => isDeliveryWorkItem(a) && isActiveState(lifecycleStateOf({ status: a.status, filePath: a.filePath }))
|
|
5546
5584
|
);
|
|
@@ -5548,7 +5586,7 @@ function buildContextPack(dir, config, now = /* @__PURE__ */ new Date()) {
|
|
|
5548
5586
|
missing.push("No work items found.");
|
|
5549
5587
|
}
|
|
5550
5588
|
const state = config.project.state;
|
|
5551
|
-
const roadmapPath = join(dir,
|
|
5589
|
+
const roadmapPath = join(dir, ARCH_DIR6, "delivery", "roadmap.md");
|
|
5552
5590
|
const materialized = allArtifacts.filter(
|
|
5553
5591
|
(a) => a.filePath.replace(/\\/g, "/").includes("/delivery/work-items/") && Boolean(a.type)
|
|
5554
5592
|
).length;
|
|
@@ -5942,19 +5980,12 @@ import { parse as parseYaml9 } from "yaml";
|
|
|
5942
5980
|
function slugify2(s) {
|
|
5943
5981
|
return s.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
5944
5982
|
}
|
|
5945
|
-
function isWorkItem(a) {
|
|
5946
|
-
return a.filePath.replace(/\\/g, "/").includes("/delivery/work-items/") && Boolean(a.type);
|
|
5947
|
-
}
|
|
5948
5983
|
function toActive(a) {
|
|
5949
5984
|
const id = a.id || a.title || "WI";
|
|
5950
5985
|
return { id, title: a.title || id, type: a.type, slug: slugify2(a.title || id) };
|
|
5951
5986
|
}
|
|
5952
5987
|
function activeWorkItems(dir) {
|
|
5953
|
-
|
|
5954
|
-
if (!exists(archDir)) return [];
|
|
5955
|
-
return readArtifacts(archDir).filter(
|
|
5956
|
-
(a) => isWorkItem(a) && lifecycleStateOf({ status: a.status, filePath: a.filePath }) === "in-progress"
|
|
5957
|
-
).map(toActive);
|
|
5988
|
+
return discoverWorkItems(dir).filter((a) => a.lifecycle === "in-progress").map(toActive);
|
|
5958
5989
|
}
|
|
5959
5990
|
function branchPrefix(type) {
|
|
5960
5991
|
switch (type) {
|
|
@@ -6257,9 +6288,9 @@ function classify(declaredType, declaredLevel, touchedFiles) {
|
|
|
6257
6288
|
}
|
|
6258
6289
|
|
|
6259
6290
|
// src/commands/classify.ts
|
|
6260
|
-
var
|
|
6291
|
+
var ARCH_DIR7 = "knowledge";
|
|
6261
6292
|
function findActiveWorkItem(dir) {
|
|
6262
|
-
const archDir = join(dir,
|
|
6293
|
+
const archDir = join(dir, ARCH_DIR7);
|
|
6263
6294
|
if (!exists(archDir)) return null;
|
|
6264
6295
|
const artifacts = readArtifacts(archDir);
|
|
6265
6296
|
return artifacts.filter((a) => a.status === "in-progress" && a.type !== "current-state" && a.type !== "roadmap").sort((a, b) => {
|
|
@@ -6325,7 +6356,7 @@ async function runClassify(opts = {}) {
|
|
|
6325
6356
|
|
|
6326
6357
|
// src/commands/status.ts
|
|
6327
6358
|
import { parse as parseYaml10 } from "yaml";
|
|
6328
|
-
var
|
|
6359
|
+
var ARCH_DIR8 = "knowledge";
|
|
6329
6360
|
var CONFIG_PATH4 = ".kaddo/config.yml";
|
|
6330
6361
|
function loadConfig3(dir) {
|
|
6331
6362
|
const p2 = join(dir, CONFIG_PATH4);
|
|
@@ -6338,12 +6369,12 @@ function loadConfig3(dir) {
|
|
|
6338
6369
|
}
|
|
6339
6370
|
function runStatus() {
|
|
6340
6371
|
const dir = cwd();
|
|
6341
|
-
if (!exists(join(dir,
|
|
6372
|
+
if (!exists(join(dir, ARCH_DIR8))) {
|
|
6342
6373
|
console.error("No knowledge/ directory found. Run `kaddo init` first.");
|
|
6343
6374
|
process.exit(1);
|
|
6344
6375
|
}
|
|
6345
6376
|
const config = loadConfig3(dir);
|
|
6346
|
-
const artifacts = readArtifacts(join(dir,
|
|
6377
|
+
const artifacts = readArtifacts(join(dir, ARCH_DIR8));
|
|
6347
6378
|
const ignores = loadIgnores(dir);
|
|
6348
6379
|
const workItems = artifacts.filter(
|
|
6349
6380
|
(a) => a.type !== "current-state" && a.type !== "roadmap"
|
|
@@ -6389,7 +6420,7 @@ function runStatus() {
|
|
|
6389
6420
|
|
|
6390
6421
|
// src/commands/learn.ts
|
|
6391
6422
|
import matter4 from "gray-matter";
|
|
6392
|
-
var
|
|
6423
|
+
var ARCH_DIR9 = "knowledge";
|
|
6393
6424
|
var WORK_ITEMS_DIR2 = "knowledge/delivery/work-items";
|
|
6394
6425
|
function findWorkItemFile(dir, id) {
|
|
6395
6426
|
const wiDir = join(dir, WORK_ITEMS_DIR2);
|
|
@@ -6430,12 +6461,12 @@ ${learning.trim()}
|
|
|
6430
6461
|
}
|
|
6431
6462
|
async function runLearn(artifactId) {
|
|
6432
6463
|
const dir = cwd();
|
|
6433
|
-
if (!exists(join(dir,
|
|
6464
|
+
if (!exists(join(dir, ARCH_DIR9))) {
|
|
6434
6465
|
console.error("No knowledge/ directory found. Run `kaddo init` first.");
|
|
6435
6466
|
process.exit(1);
|
|
6436
6467
|
}
|
|
6437
6468
|
intro2("kaddo learn");
|
|
6438
|
-
const artifacts = readArtifacts(join(dir,
|
|
6469
|
+
const artifacts = readArtifacts(join(dir, ARCH_DIR9));
|
|
6439
6470
|
const inProgress = artifacts.filter(
|
|
6440
6471
|
(a) => a.status === "in-progress" && a.type !== "current-state" && a.type !== "roadmap"
|
|
6441
6472
|
);
|
|
@@ -6478,7 +6509,7 @@ async function runLearn(artifactId) {
|
|
|
6478
6509
|
}
|
|
6479
6510
|
|
|
6480
6511
|
// src/commands/history.ts
|
|
6481
|
-
var
|
|
6512
|
+
var ARCH_DIR10 = "knowledge";
|
|
6482
6513
|
function formatRow(a) {
|
|
6483
6514
|
const id = (a.id || "").padEnd(8);
|
|
6484
6515
|
const type = a.type.padEnd(18);
|
|
@@ -6489,11 +6520,11 @@ function formatRow(a) {
|
|
|
6489
6520
|
}
|
|
6490
6521
|
function runHistory(opts = {}) {
|
|
6491
6522
|
const dir = cwd();
|
|
6492
|
-
if (!exists(join(dir,
|
|
6523
|
+
if (!exists(join(dir, ARCH_DIR10))) {
|
|
6493
6524
|
console.error("No knowledge/ directory found. Run `kaddo init` first.");
|
|
6494
6525
|
process.exit(1);
|
|
6495
6526
|
}
|
|
6496
|
-
let artifacts = readArtifacts(join(dir,
|
|
6527
|
+
let artifacts = readArtifacts(join(dir, ARCH_DIR10)).filter(
|
|
6497
6528
|
(a) => a.type !== "current-state" && a.type !== "roadmap"
|
|
6498
6529
|
);
|
|
6499
6530
|
if (opts.domain) {
|
|
@@ -6654,42 +6685,23 @@ function runAdd(moduleName, opts = {}, dir = cwd()) {
|
|
|
6654
6685
|
|
|
6655
6686
|
// src/core/ownership-suggest.ts
|
|
6656
6687
|
import matter5 from "gray-matter";
|
|
6657
|
-
var WORK_ITEMS_DIR3 = "knowledge/delivery/work-items";
|
|
6658
6688
|
var SCAN_PATH = ".kaddo/scan.json";
|
|
6659
6689
|
function toStringArray3(value) {
|
|
6660
6690
|
return Array.isArray(value) ? value.map((v) => String(v)).filter(Boolean) : [];
|
|
6661
6691
|
}
|
|
6662
|
-
function parseOwnershipArtifact(filePath, relPath, raw) {
|
|
6663
|
-
try {
|
|
6664
|
-
const { data } = matter5(raw);
|
|
6665
|
-
const codeGlobs = toStringArray3(data.code);
|
|
6666
|
-
return {
|
|
6667
|
-
filePath,
|
|
6668
|
-
relPath: relPath.split("\\").join("/"),
|
|
6669
|
-
id: String(data.id ?? ""),
|
|
6670
|
-
title: String(data.title ?? ""),
|
|
6671
|
-
type: String(data.type ?? ""),
|
|
6672
|
-
domains: toStringArray3(data.domains),
|
|
6673
|
-
capabilities: toStringArray3(data.capabilities),
|
|
6674
|
-
codeGlobs,
|
|
6675
|
-
source: data.source ? String(data.source) : void 0,
|
|
6676
|
-
hasOwnership: codeGlobs.length > 0
|
|
6677
|
-
};
|
|
6678
|
-
} catch {
|
|
6679
|
-
return null;
|
|
6680
|
-
}
|
|
6681
|
-
}
|
|
6682
6692
|
function findWorkItemArtifacts(dir) {
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
+
return discoverWorkItems(dir).map((a) => ({
|
|
6694
|
+
filePath: a.filePath,
|
|
6695
|
+
relPath: a.relPath,
|
|
6696
|
+
id: a.id,
|
|
6697
|
+
title: a.title,
|
|
6698
|
+
type: a.type,
|
|
6699
|
+
domains: a.domains,
|
|
6700
|
+
capabilities: a.capabilities,
|
|
6701
|
+
codeGlobs: a.codeGlobs,
|
|
6702
|
+
source: a.source || void 0,
|
|
6703
|
+
hasOwnership: a.codeGlobs.length > 0
|
|
6704
|
+
}));
|
|
6693
6705
|
}
|
|
6694
6706
|
function artifactsMissingOwnership(artifacts) {
|
|
6695
6707
|
return artifacts.filter((a) => !a.hasOwnership);
|
|
@@ -6833,16 +6845,24 @@ async function runOwnersSuggest() {
|
|
|
6833
6845
|
intro2("kaddo owners suggest");
|
|
6834
6846
|
const artifacts = findWorkItemArtifacts(dir);
|
|
6835
6847
|
if (artifacts.length === 0) {
|
|
6836
|
-
log2.warn(
|
|
6848
|
+
log2.warn(
|
|
6849
|
+
"No Work Items found under knowledge/delivery/work-items/ (searched recursively, including draft/ ready/ in-progress/ \u2026)."
|
|
6850
|
+
);
|
|
6851
|
+
log2.info("Create one with `kaddo create` or `kaddo create --from roadmap`.");
|
|
6837
6852
|
outro2("Nothing to do.");
|
|
6838
6853
|
return;
|
|
6839
6854
|
}
|
|
6840
6855
|
const missing = artifactsMissingOwnership(artifacts);
|
|
6841
6856
|
if (missing.length === 0) {
|
|
6842
|
-
log2.
|
|
6857
|
+
log2.success(
|
|
6858
|
+
`Found ${artifacts.length} Work Item${artifacts.length === 1 ? "" : "s"}; all already declare code ownership.`
|
|
6859
|
+
);
|
|
6843
6860
|
outro2("Nothing to do.");
|
|
6844
6861
|
return;
|
|
6845
6862
|
}
|
|
6863
|
+
log2.info(
|
|
6864
|
+
`Found ${artifacts.length} Work Item${artifacts.length === 1 ? "" : "s"}; ${missing.length} missing code ownership.`
|
|
6865
|
+
);
|
|
6846
6866
|
const relPath = missing.length === 1 ? missing[0].relPath : await select2({
|
|
6847
6867
|
message: "Which artifact needs ownership?",
|
|
6848
6868
|
options: missing.map((a) => ({
|