@kaddo/cli 3.71.0 → 3.72.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.
@@ -0,0 +1,2 @@
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}.block{display:block}.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)}.break-all{word-break:break-all}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.italic{font-style:italic}.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}
@@ -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-rKOFsV1o.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-BCR7rExw.css">
8
+ <script type="module" crossorigin src="/assets/index-Bz7DGBBm.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-J0BnLZHW.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("/api/v1/admin/work-items", coreRoute(getWorkItemSummary));
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaddo/cli",
3
- "version": "3.71.0",
3
+ "version": "3.72.0",
4
4
  "description": "Knowledge Driven Development toolkit",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -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}