@kaddo/cli 3.71.0 → 3.72.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/admin-dist/assets/index-D4sr_XCt.css +2 -0
- package/dist/admin-dist/assets/index-DEZExhWd.js +38 -0
- package/dist/admin-dist/index.html +2 -2
- package/dist/admin-server/index.js +138 -1
- package/dist/core.js +269 -0
- package/package.json +1 -1
- package/dist/admin-dist/assets/index-BCR7rExw.css +0 -2
- package/dist/admin-dist/assets/index-rKOFsV1o.js +0 -38
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>admin</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-DEZExhWd.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-D4sr_XCt.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
|
@@ -58,6 +58,9 @@ import {
|
|
|
58
58
|
loadConfig,
|
|
59
59
|
loadMappedModules,
|
|
60
60
|
discoverKnowledge,
|
|
61
|
+
getWorkItems as coreGetWorkItems,
|
|
62
|
+
getWorkItem as coreGetWorkItem,
|
|
63
|
+
WorkItemNotFoundError,
|
|
61
64
|
exists,
|
|
62
65
|
join,
|
|
63
66
|
readFile
|
|
@@ -95,6 +98,22 @@ function getWorkItemSummary(dir) {
|
|
|
95
98
|
}))
|
|
96
99
|
};
|
|
97
100
|
}
|
|
101
|
+
function getWorkItemsList(dir, filters = {}) {
|
|
102
|
+
return coreGetWorkItems(dir, filters);
|
|
103
|
+
}
|
|
104
|
+
function getWorkItemDetail(dir, workItemId) {
|
|
105
|
+
if (!workItemId || workItemId.includes("..") || workItemId.includes("/") || workItemId.includes("\\") || workItemId.startsWith(".")) {
|
|
106
|
+
throw new CoreError("INVALID_WORK_ITEM_ID", "Invalid Work Item identifier.");
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
return coreGetWorkItem(dir, workItemId);
|
|
110
|
+
} catch (err) {
|
|
111
|
+
if (err instanceof WorkItemNotFoundError) {
|
|
112
|
+
throw new CoreError("WORK_ITEM_NOT_FOUND", "This Work Item does not exist in the current project.");
|
|
113
|
+
}
|
|
114
|
+
throw err;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
98
117
|
function getModules(dir) {
|
|
99
118
|
const mapped = loadMappedModules(dir);
|
|
100
119
|
return {
|
|
@@ -288,7 +307,31 @@ async function createAdminServer(opts) {
|
|
|
288
307
|
app.get("/api/v1/admin/overview", coreRoute(getProjectOverview));
|
|
289
308
|
app.get("/api/v1/admin/project", coreRoute(getProjectSummary));
|
|
290
309
|
app.get("/api/v1/admin/knowledge", coreRoute(getKnowledgeSummary));
|
|
291
|
-
app.get(
|
|
310
|
+
app.get(
|
|
311
|
+
"/api/v1/admin/work-items",
|
|
312
|
+
async (request) => {
|
|
313
|
+
try {
|
|
314
|
+
const { status, module, query } = request.query;
|
|
315
|
+
return getWorkItemsList(projectDir, { status, module, query });
|
|
316
|
+
} catch (err) {
|
|
317
|
+
if (err instanceof CoreError) {
|
|
318
|
+
return { error: { code: err.code, message: err.message } };
|
|
319
|
+
}
|
|
320
|
+
throw err;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
);
|
|
324
|
+
app.get("/api/v1/admin/work-items/:workItemId", async (request, reply) => {
|
|
325
|
+
try {
|
|
326
|
+
return getWorkItemDetail(projectDir, request.params.workItemId);
|
|
327
|
+
} catch (err) {
|
|
328
|
+
if (err instanceof CoreError) {
|
|
329
|
+
const code = err.code === "WORK_ITEM_NOT_FOUND" ? 404 : err.code === "INVALID_WORK_ITEM_ID" ? 400 : 500;
|
|
330
|
+
return reply.code(code).send({ error: { code: err.code, message: err.message } });
|
|
331
|
+
}
|
|
332
|
+
throw err;
|
|
333
|
+
}
|
|
334
|
+
});
|
|
292
335
|
app.get("/api/v1/admin/modules", coreRoute(getModules));
|
|
293
336
|
app.get("/api/v1/admin/readiness", coreRoute(getProjectReadiness));
|
|
294
337
|
app.get("/api/v1/admin/route", coreRoute(getProjectRoute));
|
|
@@ -535,6 +578,96 @@ var KnowledgeArtifactDetailSchema = z.object({
|
|
|
535
578
|
content: z.string(),
|
|
536
579
|
type: z.string().optional()
|
|
537
580
|
});
|
|
581
|
+
var WorkItemsSummaryStatsSchema = z.object({
|
|
582
|
+
total: z.number(),
|
|
583
|
+
active: z.number(),
|
|
584
|
+
draft: z.number(),
|
|
585
|
+
ready: z.number(),
|
|
586
|
+
inProgress: z.number(),
|
|
587
|
+
blocked: z.number(),
|
|
588
|
+
completed: z.number(),
|
|
589
|
+
archived: z.number()
|
|
590
|
+
});
|
|
591
|
+
var WorkItemListItemSchema = z.object({
|
|
592
|
+
id: z.string(),
|
|
593
|
+
title: z.string(),
|
|
594
|
+
type: z.string(),
|
|
595
|
+
status: z.string(),
|
|
596
|
+
implementationStatus: z.string().nullable(),
|
|
597
|
+
validationStatus: z.string().nullable(),
|
|
598
|
+
releaseStatus: z.string().nullable(),
|
|
599
|
+
affectedModules: z.array(z.string()),
|
|
600
|
+
scopeConfidenceLevel: z.string().nullable(),
|
|
601
|
+
initiative: z.string().nullable()
|
|
602
|
+
});
|
|
603
|
+
var WorkItemsListSchema = z.object({
|
|
604
|
+
summary: WorkItemsSummaryStatsSchema,
|
|
605
|
+
items: z.array(WorkItemListItemSchema),
|
|
606
|
+
modules: z.array(z.string())
|
|
607
|
+
});
|
|
608
|
+
var CoverageEntrySchema = z.object({ id: z.string(), status: z.string(), reason: z.string().optional() });
|
|
609
|
+
var ImpactEntrySchema = z.object({
|
|
610
|
+
surface: z.string(),
|
|
611
|
+
status: z.string(),
|
|
612
|
+
reason: z.string().optional(),
|
|
613
|
+
question: z.string().optional()
|
|
614
|
+
});
|
|
615
|
+
var AcceptanceCriterionSchema = z.object({ text: z.string(), checked: z.boolean().nullable() });
|
|
616
|
+
var ReleaseGateEntrySchema = z.object({
|
|
617
|
+
id: z.string(),
|
|
618
|
+
status: z.string(),
|
|
619
|
+
reason: z.string().optional(),
|
|
620
|
+
requiredFor: z.string().optional()
|
|
621
|
+
});
|
|
622
|
+
var CompletionExceptionEntrySchema = z.object({
|
|
623
|
+
id: z.string(),
|
|
624
|
+
status: z.string(),
|
|
625
|
+
reason: z.string().optional(),
|
|
626
|
+
category: z.string().optional(),
|
|
627
|
+
impact: z.string().optional()
|
|
628
|
+
});
|
|
629
|
+
var RepoValidationSchema = z.object({ command: z.string(), status: z.string(), reason: z.string().optional() });
|
|
630
|
+
var RepoMigrationSchema = z.object({
|
|
631
|
+
id: z.string(),
|
|
632
|
+
environment: z.string(),
|
|
633
|
+
status: z.string(),
|
|
634
|
+
reason: z.string().optional()
|
|
635
|
+
});
|
|
636
|
+
var EvidenceRepoSchema = z.object({
|
|
637
|
+
module: z.string(),
|
|
638
|
+
role: z.string(),
|
|
639
|
+
status: z.string(),
|
|
640
|
+
changedPaths: z.array(z.string()),
|
|
641
|
+
validations: z.array(RepoValidationSchema),
|
|
642
|
+
migrations: z.array(RepoMigrationSchema)
|
|
643
|
+
});
|
|
644
|
+
var LinkedDecisionSchema = z.object({
|
|
645
|
+
id: z.string(),
|
|
646
|
+
title: z.string().optional(),
|
|
647
|
+
knowledgeId: z.string().optional(),
|
|
648
|
+
knowledgeLayer: z.string().optional()
|
|
649
|
+
});
|
|
650
|
+
var LinkedKnowledgeSchema = z.object({ id: z.string(), title: z.string(), layer: z.string() });
|
|
651
|
+
var WorkItemDetailSchema = WorkItemListItemSchema.extend({
|
|
652
|
+
actor: z.string().nullable(),
|
|
653
|
+
outcome: z.string().nullable(),
|
|
654
|
+
currentBehavior: z.string().nullable(),
|
|
655
|
+
targetBehavior: z.string().nullable(),
|
|
656
|
+
entryPoints: z.string().nullable(),
|
|
657
|
+
endToEndFlow: z.string().nullable(),
|
|
658
|
+
scopeConfidence: z.object({ level: z.string(), reasons: z.array(z.string()) }).nullable(),
|
|
659
|
+
scopeUnknowns: z.array(z.string()),
|
|
660
|
+
moduleCoverage: z.array(CoverageEntrySchema),
|
|
661
|
+
impactAnalysis: z.array(ImpactEntrySchema),
|
|
662
|
+
acceptanceCriteria: z.array(AcceptanceCriterionSchema),
|
|
663
|
+
implementationEvidence: z.array(EvidenceRepoSchema),
|
|
664
|
+
releaseGates: z.array(ReleaseGateEntrySchema),
|
|
665
|
+
completionExceptions: z.array(CompletionExceptionEntrySchema),
|
|
666
|
+
decisions: z.array(LinkedDecisionSchema),
|
|
667
|
+
relatedKnowledge: z.array(LinkedKnowledgeSchema),
|
|
668
|
+
source: z.object({ type: z.string(), id: z.string().optional(), inferred: z.boolean() }).passthrough(),
|
|
669
|
+
path: z.string()
|
|
670
|
+
});
|
|
538
671
|
var ErrorResponseSchema = z.object({
|
|
539
672
|
error: z.object({
|
|
540
673
|
code: z.string(),
|
|
@@ -557,6 +690,10 @@ export {
|
|
|
557
690
|
RouteStepSchema,
|
|
558
691
|
SQLiteAdminStorage,
|
|
559
692
|
SessionManager,
|
|
693
|
+
WorkItemDetailSchema,
|
|
694
|
+
WorkItemListItemSchema,
|
|
560
695
|
WorkItemSummarySchema,
|
|
696
|
+
WorkItemsListSchema,
|
|
697
|
+
WorkItemsSummaryStatsSchema,
|
|
561
698
|
createAdminServer
|
|
562
699
|
};
|
package/dist/core.js
CHANGED
|
@@ -7450,7 +7450,273 @@ function analyzeCrossRepoEvidence(input) {
|
|
|
7450
7450
|
repoEvidence
|
|
7451
7451
|
};
|
|
7452
7452
|
}
|
|
7453
|
+
|
|
7454
|
+
// src/core/work-items.ts
|
|
7455
|
+
import matter6 from "gray-matter";
|
|
7456
|
+
var WorkItemNotFoundError = class extends Error {
|
|
7457
|
+
constructor(workItemId) {
|
|
7458
|
+
super(`Work Item "${workItemId}" was not found.`);
|
|
7459
|
+
this.workItemId = workItemId;
|
|
7460
|
+
this.name = "WorkItemNotFoundError";
|
|
7461
|
+
}
|
|
7462
|
+
workItemId;
|
|
7463
|
+
};
|
|
7464
|
+
function getWorkItemsSummary(dir) {
|
|
7465
|
+
return summarize2(discoverWorkItems(dir));
|
|
7466
|
+
}
|
|
7467
|
+
function summarize2(artifacts) {
|
|
7468
|
+
const states = artifacts.map((a) => lifecycleStateOf({ status: a.status, filePath: a.filePath }));
|
|
7469
|
+
const count = (s) => states.filter((x) => x === s).length;
|
|
7470
|
+
return {
|
|
7471
|
+
total: states.length,
|
|
7472
|
+
active: states.filter((s) => isActiveState(s)).length,
|
|
7473
|
+
draft: count("draft"),
|
|
7474
|
+
ready: count("ready"),
|
|
7475
|
+
inProgress: count("in-progress"),
|
|
7476
|
+
blocked: count("blocked"),
|
|
7477
|
+
completed: count("completed"),
|
|
7478
|
+
archived: count("archived")
|
|
7479
|
+
};
|
|
7480
|
+
}
|
|
7481
|
+
function getWorkItems(dir, filters = {}) {
|
|
7482
|
+
const artifacts = discoverWorkItems(dir);
|
|
7483
|
+
const summary = summarize2(artifacts);
|
|
7484
|
+
const allModules = /* @__PURE__ */ new Set();
|
|
7485
|
+
for (const a of artifacts) for (const m of a.affectedModules) allModules.add(m);
|
|
7486
|
+
let items = artifacts.map(toListItem);
|
|
7487
|
+
if (filters.status && filters.status !== "all") {
|
|
7488
|
+
items = items.filter((i) => i.status === filters.status);
|
|
7489
|
+
}
|
|
7490
|
+
if (filters.module && filters.module !== "all") {
|
|
7491
|
+
items = items.filter((i) => i.affectedModules.includes(filters.module));
|
|
7492
|
+
}
|
|
7493
|
+
if (filters.query && filters.query.trim()) {
|
|
7494
|
+
const q = filters.query.trim().toLowerCase();
|
|
7495
|
+
items = items.filter(
|
|
7496
|
+
(i) => i.id.toLowerCase().includes(q) || i.title.toLowerCase().includes(q) || i.affectedModules.some((m) => m.toLowerCase().includes(q))
|
|
7497
|
+
);
|
|
7498
|
+
}
|
|
7499
|
+
items.sort((a, b) => {
|
|
7500
|
+
const rank = (s) => isActiveState(s) ? 0 : s === "completed" ? 1 : 2;
|
|
7501
|
+
const r = rank(a.status) - rank(b.status);
|
|
7502
|
+
if (r !== 0) return r;
|
|
7503
|
+
return a.id.localeCompare(b.id, void 0, { numeric: true });
|
|
7504
|
+
});
|
|
7505
|
+
return { summary, items, modules: [...allModules].sort() };
|
|
7506
|
+
}
|
|
7507
|
+
function toListItem(a) {
|
|
7508
|
+
return {
|
|
7509
|
+
id: a.id || a.title,
|
|
7510
|
+
title: a.title || a.id,
|
|
7511
|
+
type: a.type,
|
|
7512
|
+
status: lifecycleStateOf({ status: a.status, filePath: a.filePath }),
|
|
7513
|
+
implementationStatus: a.implementationStatus || null,
|
|
7514
|
+
validationStatus: a.validationStatus || null,
|
|
7515
|
+
releaseStatus: a.releaseStatus || null,
|
|
7516
|
+
affectedModules: a.affectedModules,
|
|
7517
|
+
scopeConfidenceLevel: a.scopeConfidence?.level ?? null,
|
|
7518
|
+
initiative: a.initiative || null
|
|
7519
|
+
};
|
|
7520
|
+
}
|
|
7521
|
+
function getWorkItem(dir, workItemId) {
|
|
7522
|
+
const artifacts = discoverWorkItems(dir);
|
|
7523
|
+
const match = artifacts.find((a) => (a.id || a.title) === workItemId);
|
|
7524
|
+
if (!match) throw new WorkItemNotFoundError(workItemId);
|
|
7525
|
+
const base = toListItem(match);
|
|
7526
|
+
const body = readBody(match.filePath);
|
|
7527
|
+
const sections = splitSections(body);
|
|
7528
|
+
const fm = match.rawFrontmatter;
|
|
7529
|
+
const knowledge = discoverKnowledge(dir).filter((a) => !a.isWorkItem);
|
|
7530
|
+
const knowledgeById = new Map(knowledge.filter((k) => k.id).map((k) => [k.id, k]));
|
|
7531
|
+
return {
|
|
7532
|
+
...base,
|
|
7533
|
+
actor: sectionText(sections, ["actor"]),
|
|
7534
|
+
outcome: sectionText(sections, ["actor and outcome", "outcome", "expected result"]),
|
|
7535
|
+
currentBehavior: sectionText(sections, ["current behavior", "current behaviour"]),
|
|
7536
|
+
targetBehavior: sectionText(sections, ["target behavior", "target behaviour"]),
|
|
7537
|
+
entryPoints: sectionText(sections, ["entry points"]),
|
|
7538
|
+
endToEndFlow: sectionText(sections, ["end-to-end flow", "end to end flow", "flow"]),
|
|
7539
|
+
scopeConfidence: match.scopeConfidence,
|
|
7540
|
+
scopeUnknowns: sectionBullets(sections, ["scope unknowns", "open scope questions"]),
|
|
7541
|
+
moduleCoverage: normalizeCoverage(match.moduleCoverage),
|
|
7542
|
+
impactAnalysis: normalizeImpact(match.impactAnalysis),
|
|
7543
|
+
acceptanceCriteria: parseAcceptanceCriteria(sections),
|
|
7544
|
+
implementationEvidence: parseEvidence(fm),
|
|
7545
|
+
releaseGates: parseReleaseGates(fm),
|
|
7546
|
+
completionExceptions: parseExceptions(fm),
|
|
7547
|
+
decisions: parseDecisions(match.decisions, knowledgeById),
|
|
7548
|
+
relatedKnowledge: parseRelatedKnowledge(fm, knowledgeById),
|
|
7549
|
+
source: parseWorkItemSource(fm),
|
|
7550
|
+
path: match.relPath
|
|
7551
|
+
};
|
|
7552
|
+
}
|
|
7553
|
+
function readBody(filePath) {
|
|
7554
|
+
try {
|
|
7555
|
+
const raw = readFile(filePath);
|
|
7556
|
+
return matter6(raw).content;
|
|
7557
|
+
} catch {
|
|
7558
|
+
return "";
|
|
7559
|
+
}
|
|
7560
|
+
}
|
|
7561
|
+
function splitSections(body) {
|
|
7562
|
+
const sections = /* @__PURE__ */ new Map();
|
|
7563
|
+
const lines = body.split(/\r?\n/);
|
|
7564
|
+
let current = null;
|
|
7565
|
+
let buffer = [];
|
|
7566
|
+
const flush = () => {
|
|
7567
|
+
if (current !== null) sections.set(current, buffer.join("\n").trim());
|
|
7568
|
+
buffer = [];
|
|
7569
|
+
};
|
|
7570
|
+
for (const line of lines) {
|
|
7571
|
+
const m = line.match(/^#{1,6}\s+(.*?)\s*$/);
|
|
7572
|
+
if (m) {
|
|
7573
|
+
flush();
|
|
7574
|
+
current = m[1].toLowerCase().replace(/[`*_]/g, "").trim();
|
|
7575
|
+
} else if (current !== null) {
|
|
7576
|
+
buffer.push(line);
|
|
7577
|
+
}
|
|
7578
|
+
}
|
|
7579
|
+
flush();
|
|
7580
|
+
return sections;
|
|
7581
|
+
}
|
|
7582
|
+
function isPlaceholder(text3) {
|
|
7583
|
+
const t = text3.trim();
|
|
7584
|
+
if (!t) return true;
|
|
7585
|
+
if (/^tbd$/i.test(t)) return true;
|
|
7586
|
+
if (/^_[^_]*_$/.test(t) && !t.includes("\n")) return true;
|
|
7587
|
+
return false;
|
|
7588
|
+
}
|
|
7589
|
+
function sectionText(sections, headings) {
|
|
7590
|
+
for (const h of headings) {
|
|
7591
|
+
const body = sections.get(h);
|
|
7592
|
+
if (body != null && !isPlaceholder(body)) return body.trim();
|
|
7593
|
+
}
|
|
7594
|
+
return null;
|
|
7595
|
+
}
|
|
7596
|
+
function sectionBullets(sections, headings) {
|
|
7597
|
+
for (const h of headings) {
|
|
7598
|
+
const body = sections.get(h);
|
|
7599
|
+
if (body == null || isPlaceholder(body)) continue;
|
|
7600
|
+
const bullets = extractBullets(body);
|
|
7601
|
+
if (bullets.length > 0) return bullets.map((b) => b.text);
|
|
7602
|
+
}
|
|
7603
|
+
return [];
|
|
7604
|
+
}
|
|
7605
|
+
function extractBullets(body) {
|
|
7606
|
+
const out = [];
|
|
7607
|
+
for (const line of body.split(/\r?\n/)) {
|
|
7608
|
+
const m = line.match(/^\s*[-*+]\s+(.*)$/);
|
|
7609
|
+
if (!m) continue;
|
|
7610
|
+
let text3 = m[1].trim();
|
|
7611
|
+
let checked = null;
|
|
7612
|
+
const cb = text3.match(/^\[([ xX])\]\s*(.*)$/);
|
|
7613
|
+
if (cb) {
|
|
7614
|
+
checked = cb[1].toLowerCase() === "x";
|
|
7615
|
+
text3 = cb[2].trim();
|
|
7616
|
+
}
|
|
7617
|
+
if (!text3 || isPlaceholder(text3)) continue;
|
|
7618
|
+
out.push({ text: text3, checked });
|
|
7619
|
+
}
|
|
7620
|
+
return out;
|
|
7621
|
+
}
|
|
7622
|
+
function parseAcceptanceCriteria(sections) {
|
|
7623
|
+
const body = sections.get("acceptance criteria");
|
|
7624
|
+
if (body == null || isPlaceholder(body)) return [];
|
|
7625
|
+
return extractBullets(body).map((b) => ({ text: b.text, checked: b.checked }));
|
|
7626
|
+
}
|
|
7627
|
+
function normalizeCoverage(mc) {
|
|
7628
|
+
if (!mc) return [];
|
|
7629
|
+
return Object.entries(mc).map(([id, v]) => ({ id, status: v.status, ...v.reason ? { reason: v.reason } : {} }));
|
|
7630
|
+
}
|
|
7631
|
+
function normalizeImpact(ia) {
|
|
7632
|
+
if (!ia) return [];
|
|
7633
|
+
return Object.entries(ia).map(([surface, v]) => ({
|
|
7634
|
+
surface,
|
|
7635
|
+
status: v.status,
|
|
7636
|
+
...v.reason ? { reason: v.reason } : {},
|
|
7637
|
+
...v.question ? { question: v.question } : {}
|
|
7638
|
+
}));
|
|
7639
|
+
}
|
|
7640
|
+
function optStr2(v) {
|
|
7641
|
+
if (typeof v === "string" && v.trim()) return v.trim();
|
|
7642
|
+
return void 0;
|
|
7643
|
+
}
|
|
7644
|
+
function parseEvidence(fm) {
|
|
7645
|
+
const evidence = fm.implementation_evidence;
|
|
7646
|
+
const repos = evidence?.repositories;
|
|
7647
|
+
if (!repos || typeof repos !== "object" || Array.isArray(repos)) return [];
|
|
7648
|
+
const out = [];
|
|
7649
|
+
for (const [module, val] of Object.entries(repos)) {
|
|
7650
|
+
if (!val || typeof val !== "object" || Array.isArray(val)) continue;
|
|
7651
|
+
const d = val;
|
|
7652
|
+
const validations = Array.isArray(d.validations) ? d.validations.map((v) => ({
|
|
7653
|
+
command: String(v.command ?? ""),
|
|
7654
|
+
status: String(v.status ?? "unknown"),
|
|
7655
|
+
...optStr2(v.reason) ? { reason: optStr2(v.reason) } : {}
|
|
7656
|
+
})) : [];
|
|
7657
|
+
const migrations = Array.isArray(d.migrations) ? d.migrations.map((m) => ({
|
|
7658
|
+
id: String(m.id ?? ""),
|
|
7659
|
+
environment: String(m.environment ?? ""),
|
|
7660
|
+
status: String(m.status ?? "unknown"),
|
|
7661
|
+
...optStr2(m.reason) ? { reason: optStr2(m.reason) } : {}
|
|
7662
|
+
})) : [];
|
|
7663
|
+
out.push({
|
|
7664
|
+
module,
|
|
7665
|
+
role: String(d.role ?? (module === "core" ? "core" : "module")),
|
|
7666
|
+
status: String(d.status ?? "unknown"),
|
|
7667
|
+
changedPaths: Array.isArray(d.changed_paths) ? d.changed_paths.map(String).filter(Boolean) : [],
|
|
7668
|
+
validations,
|
|
7669
|
+
migrations
|
|
7670
|
+
});
|
|
7671
|
+
}
|
|
7672
|
+
return out;
|
|
7673
|
+
}
|
|
7674
|
+
function parseReleaseGates(fm) {
|
|
7675
|
+
if (!Array.isArray(fm.release_gates)) return [];
|
|
7676
|
+
return fm.release_gates.filter((g) => g && typeof g === "object").map((g) => ({
|
|
7677
|
+
id: String(g.id ?? ""),
|
|
7678
|
+
status: String(g.status ?? "pending"),
|
|
7679
|
+
...optStr2(g.reason) ? { reason: optStr2(g.reason) } : {},
|
|
7680
|
+
...optStr2(g.required_for) ? { requiredFor: optStr2(g.required_for) } : {}
|
|
7681
|
+
}));
|
|
7682
|
+
}
|
|
7683
|
+
function parseExceptions(fm) {
|
|
7684
|
+
if (!Array.isArray(fm.completion_exceptions)) return [];
|
|
7685
|
+
return fm.completion_exceptions.filter((e) => e && typeof e === "object").map((e) => ({
|
|
7686
|
+
id: String(e.id ?? ""),
|
|
7687
|
+
status: String(e.status ?? "proposed"),
|
|
7688
|
+
...optStr2(e.reason) ? { reason: optStr2(e.reason) } : {},
|
|
7689
|
+
...optStr2(e.category) ? { category: optStr2(e.category) } : {},
|
|
7690
|
+
...optStr2(e.impact) ? { impact: optStr2(e.impact) } : {}
|
|
7691
|
+
}));
|
|
7692
|
+
}
|
|
7693
|
+
function parseDecisions(decisions, knowledgeById) {
|
|
7694
|
+
return decisions.map((id) => {
|
|
7695
|
+
const k = knowledgeById.get(id);
|
|
7696
|
+
return {
|
|
7697
|
+
id,
|
|
7698
|
+
...k?.title ? { title: k.title } : {},
|
|
7699
|
+
...k ? { knowledgeId: k.id, knowledgeLayer: k.layer } : {}
|
|
7700
|
+
};
|
|
7701
|
+
});
|
|
7702
|
+
}
|
|
7703
|
+
function parseRelatedKnowledge(fm, knowledgeById) {
|
|
7704
|
+
const refs = /* @__PURE__ */ new Set();
|
|
7705
|
+
for (const field of ["related_knowledge", "knowledge", "related"]) {
|
|
7706
|
+
const v = fm[field];
|
|
7707
|
+
if (Array.isArray(v)) {
|
|
7708
|
+
for (const r of v) if (typeof r === "string" && r.trim()) refs.add(r.trim());
|
|
7709
|
+
}
|
|
7710
|
+
}
|
|
7711
|
+
const out = [];
|
|
7712
|
+
for (const ref of refs) {
|
|
7713
|
+
const k = knowledgeById.get(ref);
|
|
7714
|
+
if (k && k.id) out.push({ id: k.id, title: k.title || k.id, layer: k.layer });
|
|
7715
|
+
}
|
|
7716
|
+
return out;
|
|
7717
|
+
}
|
|
7453
7718
|
export {
|
|
7719
|
+
WorkItemNotFoundError,
|
|
7454
7720
|
analyzeCrossRepoEvidence,
|
|
7455
7721
|
analyzeScopeCoverage,
|
|
7456
7722
|
buildProjectExplanation,
|
|
@@ -7460,6 +7726,9 @@ export {
|
|
|
7460
7726
|
discoverKnowledge,
|
|
7461
7727
|
discoverWorkItems,
|
|
7462
7728
|
exists,
|
|
7729
|
+
getWorkItem,
|
|
7730
|
+
getWorkItems,
|
|
7731
|
+
getWorkItemsSummary,
|
|
7463
7732
|
isActiveState,
|
|
7464
7733
|
isModule,
|
|
7465
7734
|
join,
|
package/package.json
CHANGED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.collapse{visibility:collapse}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.border{border-style:var(--tw-border-style);border-width:1px}.font-mono{font-family:var(--font-mono)}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}}:root{--background:#fff;--surface:#f8f9fa;--surface-muted:#f1f3f5;--foreground:#1a1a2e;--foreground-muted:#6c757d;--border:#dee2e6;--border-strong:#adb5bd;--primary:#4361ee;--primary-foreground:#fff;--success:#2d9f5c;--warning:#e9a820;--danger:#dc3545;--info:#3b82f6;--finding-blocking:#dc3545;--finding-warning:#e9a820;--finding-fyi:#6c757d;--work-item-draft:#6c757d;--work-item-ready:#3b82f6;--work-item-progress:#8b5cf6;--work-item-blocked:#dc3545;--work-item-completed:#2d9f5c;--work-item-archived:#adb5bd;--knowledge-ready:#2d9f5c;--knowledge-missing:#dc3545;--knowledge-placeholder:#e9a820;--knowledge-unknown:#6c757d;--module-core:#4361ee;--module-module:#3b82f6;--module-unavailable:#dc3545;--readiness-ready:#2d9f5c;--readiness-warning:#e9a820;--readiness-blocked:#dc3545;--font-sans:"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--font-mono:"JetBrains Mono", "Fira Code", "Cascadia Code", monospace;--radius:6px}@media (prefers-color-scheme:dark){:root:not([data-theme=light]){--background:#0f0f23;--surface:#1a1a2e;--surface-muted:#16213e;--foreground:#e8e8e8;--foreground-muted:#a0a0b0;--border:#2a2a3e;--border-strong:#4a4a5e;--primary:#6580f5;--primary-foreground:#fff;--success:#3cb371;--warning:#f0b840;--danger:#ef4444;--info:#60a5fa;--finding-blocking:#ef4444;--finding-warning:#f0b840;--finding-fyi:#a0a0b0;--work-item-draft:#a0a0b0;--work-item-ready:#60a5fa;--work-item-progress:#a78bfa;--work-item-blocked:#ef4444;--work-item-completed:#3cb371;--work-item-archived:#6a6a7e;--knowledge-ready:#3cb371;--knowledge-missing:#ef4444;--knowledge-placeholder:#f0b840;--knowledge-unknown:#a0a0b0;--module-core:#6580f5;--module-module:#60a5fa;--module-unavailable:#ef4444;--readiness-ready:#3cb371;--readiness-warning:#f0b840;--readiness-blocked:#ef4444}}:root[data-theme=dark]{--background:#0f0f23;--surface:#1a1a2e;--surface-muted:#16213e;--foreground:#e8e8e8;--foreground-muted:#a0a0b0;--border:#2a2a3e;--border-strong:#4a4a5e;--primary:#6580f5;--primary-foreground:#fff;--success:#3cb371;--warning:#f0b840;--danger:#ef4444;--info:#60a5fa;--finding-blocking:#ef4444;--finding-warning:#f0b840;--finding-fyi:#a0a0b0;--work-item-draft:#a0a0b0;--work-item-ready:#60a5fa;--work-item-progress:#a78bfa;--work-item-blocked:#ef4444;--work-item-completed:#3cb371;--work-item-archived:#6a6a7e;--knowledge-ready:#3cb371;--knowledge-missing:#ef4444;--knowledge-placeholder:#f0b840;--knowledge-unknown:#a0a0b0;--module-core:#6580f5;--module-module:#60a5fa;--module-unavailable:#ef4444;--readiness-ready:#3cb371;--readiness-warning:#f0b840;--readiness-blocked:#ef4444}body{font-family:var(--font-sans);background:var(--background);color:var(--foreground);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;margin:0}code,.font-mono{font-family:var(--font-mono)}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}
|