@akanjs/cli 3.0.0-beta.19 → 3.0.0-beta.20

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.
Files changed (95) hide show
  1. package/.build-stamp +1 -1
  2. package/{CodeAgent-6cm97kay.js → CodeAgent-awv258wb.js} +2 -2
  3. package/{CodeTui-za4jsm41.js → CodeTui-1nqh35ez.js} +20 -22
  4. package/TunnelShare-scf4e4pd.js +9 -0
  5. package/{agent.command-e0wpbbyg.js → agent.command-1s9ag7sb.js} +8 -9
  6. package/akanCode.js +4 -4
  7. package/{application.command-8wyxqc8q.js → application.command-49hwy6va.js} +25 -56
  8. package/{applicationBuildRunner-n9gzaxd0.js → applicationBuildRunner-ybyp97pv.js} +33 -59
  9. package/{applicationReleasePackager-vpggfqgq.js → applicationReleasePackager-esnrphw8.js} +40 -60
  10. package/buildBatch.proc.js +19 -24
  11. package/{capacitorApp-q3z0qht0.js → capacitorApp-1synz4en.js} +3 -4
  12. package/{cloud.command-4zwa5dsx.js → cloud.command-d7rqtzt9.js} +16 -26
  13. package/cloud.script-bkbpcr96.js +19 -0
  14. package/{code.command-468c9d7s.js → code.command-nn48xzej.js} +22 -37
  15. package/context.command-s3mcmvpa.js +48 -0
  16. package/context.runner-k99nb5pk.js +21 -0
  17. package/{dependencyScanner-0z2h2tks.js → dependencyScanner-ye2e6pdz.js} +2 -2
  18. package/{devTui-ffjsarqa.js → devTui-q7k7bakd.js} +5 -9
  19. package/fileSys-5ngz93ga.js +9 -0
  20. package/{guideline.command-vhw13pqr.js → guideline.command-sct4qnt5.js} +4 -5
  21. package/guidelines/conventions/conventions.instruction.md +5 -1
  22. package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
  23. package/incrementalBuilder.proc.js +30 -48
  24. package/{index-s5rhm04y.js → index-0bq14vr1.js} +1 -1
  25. package/{index-10dkrrww.js → index-13ffe9wp.js} +4 -4
  26. package/{index-srmay5jw.js → index-22d57v4c.js} +84 -67
  27. package/{index-53176s7j.js → index-31yr441d.js} +10 -17
  28. package/index-3hx1z96c.js +87 -0
  29. package/{index-4m929vvn.js → index-3sq321ak.js} +10 -18
  30. package/{index-bhtmj233.js → index-3t7g9e4r.js} +41 -78
  31. package/{index-q0y2jq9j.js → index-5b6tavv3.js} +6 -3
  32. package/{index-47pj3aee.js → index-5e0n4hqx.js} +11 -12
  33. package/{index-7ep8qtvp.js → index-5pc1qrbv.js} +5 -8
  34. package/{index-esk82rvk.js → index-8mna0947.js} +34 -71
  35. package/{index-sq2dzkzm.js → index-8sf7wmdr.js} +6 -6
  36. package/{index-crmeqnmf.js → index-9d9bgcx4.js} +283 -722
  37. package/{index-bwf965h6.js → index-ahemdr5n.js} +6 -6
  38. package/{index-ab0c38ea.js → index-as7xmyz8.js} +20 -20
  39. package/{index-bc88j1ry.js → index-axzjaqve.js} +94 -142
  40. package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
  41. package/{index-667w0yah.js → index-c6eggbee.js} +2 -5
  42. package/{index-a1w6934z.js → index-ddxvdd1p.js} +169 -305
  43. package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
  44. package/{index-22xtgmhn.js → index-dzf3r49a.js} +1 -1
  45. package/{index-89hy31kf.js → index-fgq75haa.js} +172 -287
  46. package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
  47. package/{index-hwkygn9s.js → index-khpfpcsd.js} +302 -33
  48. package/{index-vqx8bdxz.js → index-mxav6j3c.js} +78 -231
  49. package/{index-2446k7b4.js → index-myhc3c1j.js} +512 -588
  50. package/{index-3jrp517k.js → index-nv5976x3.js} +45 -128
  51. package/{index-zqgj2rt2.js → index-przybvy5.js} +69 -147
  52. package/{index-n3cv0tm4.js → index-smme4r47.js} +1 -1
  53. package/{index-qdgzsnhg.js → index-w2zdcw3k.js} +110 -231
  54. package/{index-14zrtgfa.js → index-wa5jbxj1.js} +6 -39
  55. package/{index-bftkz6cp.js → index-ww4z397j.js} +198 -555
  56. package/{index-kwaq3n9n.js → index-xqjwd384.js} +4 -7
  57. package/{index-txr7dj2g.js → index-xqpzbab5.js} +106 -240
  58. package/{index-e4v6vhxq.js → index-xsjh6nzh.js} +178 -165
  59. package/{index-18zybgkc.js → index-ygn77a5w.js} +47 -99
  60. package/{index-9d6nvkz2.js → index-ztp3e73t.js} +79 -35
  61. package/index.js +23 -24
  62. package/{library.command-cqr175dy.js → library.command-1gx04jgn.js} +4 -5
  63. package/{localRegistry.command-49z55qqz.js → localRegistry.command-zndxj1q6.js} +21 -42
  64. package/{module.command-9p8mm3b0.js → module.command-3waddk95.js} +6 -7
  65. package/{package.command-wxyz909t.js → package.command-zrc7br1y.js} +5 -6
  66. package/package.json +2 -2
  67. package/{page.command-gsrsfqqs.js → page.command-vpjgardh.js} +4 -5
  68. package/{primitive.command-ns1mptje.js → primitive.command-sz84tk4t.js} +9 -20
  69. package/{prompter-1f8d9pcc.js → prompter-ptaa3nk0.js} +2 -2
  70. package/{quality.command-e76k2q9k.js → quality.command-g869hafs.js} +129 -363
  71. package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
  72. package/{repair.command-pkrsm3cw.js → repair.command-chsnjvvv.js} +11 -35
  73. package/{scalar.command-0cpt3fc8.js → scalar.command-2v21newx.js} +5 -6
  74. package/skills/akan-code/SKILL.md +12 -4
  75. package/{subspace.command-fktpwp0g.js → subspace.command-ckcbwfp1.js} +39 -58
  76. package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +3 -3
  77. package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +3 -3
  78. package/templates/client.ts +7 -30
  79. package/templates/lib/__lib/lib.dictionary.ts +0 -2
  80. package/templates/lib/__lib/lib.document.ts +0 -2
  81. package/templates/lib/sig.ts +8 -30
  82. package/templates/server.ts +0 -2
  83. package/{tunnel.command-d5jy9gk8.js → tunnel.command-kd2yr4fx.js} +5 -6
  84. package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
  85. package/typecheck.proc.js +1 -1
  86. package/workflow.command-44252cqv.js +79 -0
  87. package/{workspace.command-gv84eh1p.js → workspace.command-fqcztt5p.js} +72 -107
  88. package/TunnelShare-2j6s511d.js +0 -9
  89. package/cloud.script-fwx3vb34.js +0 -20
  90. package/context.command-dsnw0jby.js +0 -80
  91. package/context.runner-rs4rj15d.js +0 -22
  92. package/devTuiView-1q1mdgrv.js +0 -9
  93. package/getDirname-dr3jz1xg.js +0 -7
  94. package/index-6wwzs1bc.js +0 -7
  95. package/workflow.command-6tkcysmx.js +0 -105
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  AppExecutor,
4
4
  LibExecutor
5
- } from "./index-crmeqnmf.js";
5
+ } from "./index-9d9bgcx4.js";
6
6
 
7
7
  // pkgs/@akanjs/devkit/workflow/utils.ts
8
8
  var jsonText = (value, { trailingNewline = true } = {}) => `${JSON.stringify(value, null, 2)}${trailingNewline ? `
@@ -22,6 +22,7 @@ var uniqueBy = (values, key) => {
22
22
  var compactDiagnostics = (diagnostics) => diagnostics.filter((diagnostic) => !!diagnostic);
23
23
 
24
24
  // pkgs/@akanjs/devkit/workflow/artifacts.ts
25
+ import { capitalize } from "akanjs/common";
25
26
  var sourceChangeBlocked = (diagnostics) => diagnostics.some((diagnostic) => diagnostic.severity === "error" && (diagnostic.failureScope === "source-change" || !diagnostic.failureScope || diagnostic.failureScope === "unknown"));
26
27
  var workflowPlanApproval = {
27
28
  required: true,
@@ -104,6 +105,16 @@ var workflowCommandsForPlan = (plan) => plan.validation.map((validation) => ({
104
105
  reason: validation.reason,
105
106
  kind: validation.kind
106
107
  }));
108
+ var planInputString = (plan, key) => {
109
+ const value = plan.inputs[key];
110
+ return typeof value === "string" ? value : "";
111
+ };
112
+ var workflowPathsForPlan = (plan) => {
113
+ const app = planInputString(plan, "app");
114
+ const module = planInputString(plan, "module");
115
+ const moduleClass = module ? capitalize(module) : "<Module>";
116
+ return plan.predictedChanges.map((change) => change.target.replace(/^\*\//, app ? `apps/${app}/` : "").replaceAll("<module>", module || "<module>").replaceAll("<Module>", moduleClass));
117
+ };
107
118
  var workflowRunsDir = ".akan/workflows/runs";
108
119
  var createWorkflowRunId = (prefix = "run") => `${prefix}-${new Date().toISOString().replace(/[-:.TZ]/g, "").slice(0, 14)}-${Math.random().toString(36).slice(2, 8)}`;
109
120
  var getRunId = (artifact) => {
@@ -373,59 +384,320 @@ var createRepairReport = ({
373
384
  ...syncedAt ? { syncedAt } : {}
374
385
  });
375
386
 
376
- // pkgs/@akanjs/devkit/workflow/primitive.ts
377
- var createPrimitiveWriteReport = ({
378
- command,
379
- status,
380
- changedFiles = [],
381
- generatedFiles = [],
382
- validationCommands = [],
383
- diagnostics = [],
384
- nextActions = []
385
- }) => ({
386
- schemaVersion: 1,
387
- command,
388
- status: status ?? (diagnostics.some((diagnostic) => diagnostic.severity === "error") ? "failed" : "passed"),
389
- changedFiles,
390
- generatedFiles,
391
- validationCommands,
392
- diagnostics,
393
- nextActions
394
- });
387
+ // pkgs/@akanjs/devkit/workflow/render.ts
388
+ var listOr = (items, render, empty = "- none") => items?.length ? items.map(render) : [empty];
389
+ var renderDiagnostic = (diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`;
390
+ var renderCommand = (entry) => `- \`${entry.command}\`: ${entry.reason}`;
391
+ var renderFile = (file) => `- \`${file.action}\` ${file.path}: ${file.reason}`;
392
+ var renderRecommendation = (recommendation) => {
393
+ const target = recommendation.target ? ` ${recommendation.target}` : "";
394
+ const action = recommendation.action ? ` Action: ${recommendation.action}` : "";
395
+ return `- [${recommendation.kind}]${target} ${recommendation.message}${action}`;
396
+ };
397
+ var renderWorkflowList = (specs) => [
398
+ "# Akan Workflows",
399
+ "",
400
+ ...specs.flatMap((spec) => [`- \`${spec.name}\`: ${spec.description}`, ` - When: ${spec.whenToUse}`]),
401
+ ""
402
+ ].join(`
403
+ `);
404
+ var renderWorkflowExplain = (spec) => [
405
+ `# Workflow: ${spec.name}`,
406
+ "",
407
+ spec.description,
408
+ "",
409
+ "## When To Use",
410
+ spec.whenToUse,
411
+ "",
412
+ "## Inputs",
413
+ ...Object.entries(spec.inputs).map(([name, input]) => `- \`${name}\`${input.required ? " (required)" : ""}: ${input.description}${input.allowedValues ? ` Allowed: ${input.allowedValues.join(", ")}.` : ""}`),
414
+ "",
415
+ "## Optional Surfaces",
416
+ ...Object.entries(spec.optionalSurfaces ?? {}).map(([name, mode]) => `- \`${name}\`: ${mode}`),
417
+ "",
418
+ "## Steps",
419
+ ...spec.steps.map((step, index) => `${index + 1}. \`${step.id}\` (${step.tool}): ${step.description}`),
420
+ "",
421
+ "## Validation",
422
+ ...spec.validation.map(renderCommand),
423
+ ""
424
+ ].join(`
425
+ `);
426
+ var renderWorkflowPlan = (plan) => [
427
+ `# Workflow Plan: ${plan.workflow}`,
428
+ "",
429
+ `- Mode: ${plan.mode}`,
430
+ `- Requires approval: ${plan.requiresApproval}`,
431
+ `- Approval: ${plan.approval?.meaning ?? "Review this read-only plan before applying workflow mutations."}`,
432
+ "",
433
+ "## Inputs",
434
+ ...Object.entries(plan.inputs).map(([name, value]) => `- \`${name}\`: ${Array.isArray(value) ? value.join(", ") : value}`),
435
+ "",
436
+ "## Optional Surfaces",
437
+ ...Object.entries(plan.optionalSurfaces).map(([name, mode]) => `- \`${name}\`: ${mode}`),
438
+ "",
439
+ "## Steps",
440
+ ...plan.steps.map((step, index) => `${index + 1}. \`${step.id}\` (${step.tool}): ${step.description}`),
441
+ "",
442
+ "## Predicted Changes",
443
+ ...plan.predictedChanges.map((change) => {
444
+ const scope = change.applyScope ? ` (${change.applyScope})` : "";
445
+ return `- \`${change.action}\`${scope} ${change.target}: ${change.reason}`;
446
+ }),
447
+ "",
448
+ "## Validation",
449
+ ...plan.validation.map(renderCommand),
450
+ "",
451
+ "## Diagnostics",
452
+ ...listOr(plan.diagnostics, renderDiagnostic),
453
+ "",
454
+ "## Recommendations",
455
+ ...listOr(plan.recommendations, (recommendation) => `- [${recommendation.kind}] ${recommendation.message}`),
456
+ ""
457
+ ].join(`
458
+ `);
459
+ var renderWorkflowApplyReport = (report) => {
460
+ const applySummary = {
461
+ sourceFilesChanged: report.summary?.sourceFilesChanged ?? report.changedFiles,
462
+ generatedFilesSynced: report.summary?.generatedFilesSynced ?? report.generatedFiles
463
+ };
464
+ const manualReviewItems = [
465
+ ...report.diagnostics.filter((diagnostic) => diagnostic.severity === "warning").map(renderDiagnostic),
466
+ ...report.recommendations.filter((recommendation) => recommendation.kind === "manual-action").map(renderRecommendation)
467
+ ];
468
+ const validationBlockers = report.diagnostics.filter((diagnostic) => diagnostic.severity === "error" && (diagnostic.failureScope === "workspace-config" || diagnostic.failureScope === "environment")).map(renderDiagnostic);
469
+ const sourceBlockers = report.diagnostics.filter((diagnostic) => diagnostic.severity === "error" && (diagnostic.failureScope === "source-change" || !diagnostic.failureScope || diagnostic.failureScope === "unknown")).map(renderDiagnostic);
470
+ return [
471
+ `# Workflow Apply: ${report.workflow}`,
472
+ "",
473
+ `- Mode: ${report.mode}`,
474
+ `- Status: ${report.status}`,
475
+ `- Source-change status: ${sourceBlockers.length ? "failed" : "passed"}`,
476
+ `- Workspace status: ${validationBlockers.length ? "blocked" : "not blocked during apply"}`,
477
+ `- Source files changed: ${applySummary.sourceFilesChanged.length}`,
478
+ `- Generated files queued for sync: ${applySummary.generatedFilesSynced.length}`,
479
+ ...report.validationTarget ? [`- Validation target: ${report.validationTarget}`] : [],
480
+ "",
481
+ "## Apply Checks",
482
+ ...report.postApplyChecks?.length ? report.postApplyChecks.map((check) => `- [${check.status}] ${check.code} ${check.target}: ${check.message}`) : ["- not run"],
483
+ "",
484
+ "## Source Change Blockers",
485
+ ...sourceBlockers.length ? sourceBlockers : ["- none"],
486
+ "",
487
+ "## Automatically Modified",
488
+ ...listOr(applySummary.sourceFilesChanged, renderFile),
489
+ "",
490
+ "## Generated Sync",
491
+ ...listOr(applySummary.generatedFilesSynced, renderFile),
492
+ "",
493
+ "## Applied Commands",
494
+ ...listOr(report.appliedCommands, renderCommand),
495
+ "",
496
+ "## Recommended Validation Commands",
497
+ ...listOr(report.recommendedValidationCommands, renderCommand),
498
+ "",
499
+ "## User Review Required",
500
+ ...manualReviewItems.length ? manualReviewItems : ["- none"],
501
+ "",
502
+ "## Validation Blockers",
503
+ ...validationBlockers.length ? validationBlockers : report.recommendedValidationCommands.length ? ["- none detected during apply; run validation with the validation target for command-level blockers."] : ["- none"],
504
+ "",
505
+ "## Diagnostics",
506
+ ...listOr(report.diagnostics, renderDiagnostic),
507
+ "",
508
+ "## Recommendations",
509
+ ...listOr(report.recommendations.slice(0, 3), renderRecommendation),
510
+ "",
511
+ "## Next Actions",
512
+ ...listOr(report.nextActions.slice(0, 3), renderCommand),
513
+ ""
514
+ ].join(`
515
+ `);
516
+ };
517
+ var renderWorkflowApply = (report, format = "markdown") => format === "json" ? jsonText(report) : renderWorkflowApplyReport(report);
518
+ var renderWorkflowValidationRunReport = (report) => {
519
+ const baselineSummary = report.baselineSummary ?? {
520
+ status: report.baselineDiagnostics?.some((diagnostic) => diagnostic.severity === "error") ? "failed" : "unknown",
521
+ total: report.baselineDiagnostics?.length ?? 0,
522
+ totalErrors: report.baselineDiagnostics?.filter((diagnostic) => diagnostic.severity === "error").length ?? 0,
523
+ totalWarnings: report.baselineDiagnostics?.filter((diagnostic) => diagnostic.severity === "warning").length ?? 0,
524
+ detailsIncluded: true,
525
+ knownBlockerCount: report.knownBlockers.filter((blocker) => blocker.known).length,
526
+ byCode: []
527
+ };
528
+ return [
529
+ `# Workflow Validation: ${report.workflow}`,
530
+ "",
531
+ `- Run: ${report.runId}`,
532
+ `- Status: ${report.status}`,
533
+ `- Source status: ${report.sourceStatus}`,
534
+ `- Workspace status: ${report.workspaceStatus}`,
535
+ `- Validation commands status: ${report.validationCommandsStatus ?? "unknown"}`,
536
+ `- Baseline status: ${report.baselineStatus ?? baselineSummary.status}`,
537
+ `- Overall status: ${report.overallStatus}`,
538
+ "",
539
+ "## Status Summary",
540
+ `- Source-change: ${report.summary.sourceChange}`,
541
+ `- Generated sync: ${report.summary.generatedSync}`,
542
+ `- Validation commands: ${report.summary.validationCommands ?? "unknown"}`,
543
+ `- Baseline: ${report.summary.baseline ?? baselineSummary.status}`,
544
+ `- Workspace config: ${report.summary.workspaceConfig}`,
545
+ `- Environment: ${report.summary.environment}`,
546
+ "",
547
+ "## Source Change Diagnostics",
548
+ ...listOr(report.workflowDiagnostics, renderDiagnostic),
549
+ "",
550
+ "## Existing Workspace Blockers",
551
+ `- Status: ${baselineSummary.status}`,
552
+ `- Errors: ${baselineSummary.totalErrors}`,
553
+ `- Warnings: ${baselineSummary.totalWarnings}`,
554
+ ...listOr(baselineSummary.byCode, (item) => `- [${item.severity}] ${item.code} (${item.count}x): ${item.sampleMessage}`),
555
+ ...baselineSummary.detailsIncluded ? [] : [
556
+ "- Baseline details are summarized by default. Re-run validation with includeBaselineDetails=true for full baselineDiagnostics."
557
+ ],
558
+ "",
559
+ "## Existing Workspace Blocker Details",
560
+ ...listOr(report.baselineDiagnostics, renderDiagnostic, baselineSummary.detailsIncluded ? "- none" : "- omitted"),
561
+ "",
562
+ "## Known Blockers",
563
+ ...listOr(report.knownBlockers, (blocker) => {
564
+ const command = blocker.command ? ` \`${blocker.command}\`` : "";
565
+ const count = blocker.count > 1 ? ` (${blocker.count}x)` : "";
566
+ const known = blocker.known ? " known" : "";
567
+ return `- [${blocker.failureScope}${known}]${command}${count}: ${blocker.message}`;
568
+ }),
569
+ "",
570
+ "## Commands",
571
+ ...listOr(report.commands, (command) => {
572
+ const scope = command.failureScope ? ` (${command.failureScope})` : "";
573
+ return `- [${command.status}] \`${command.command}\`${scope}: ${command.reason}`;
574
+ }),
575
+ "",
576
+ "## Diagnostics",
577
+ ...listOr(report.diagnostics, renderDiagnostic),
578
+ "",
579
+ "## Repair Actions",
580
+ ...listOr(report.repairActions, renderCommand),
581
+ "",
582
+ "## Next Actions",
583
+ ...listOr(report.nextActions, renderCommand),
584
+ ""
585
+ ].join(`
586
+ `);
587
+ };
588
+ var renderWorkflowValidation = (report, format = "markdown") => format === "json" ? jsonText(report) : renderWorkflowValidationRunReport(report);
589
+ var renderRepairReportMarkdown = (report) => [
590
+ `# Akan Repair: ${report.kind}`,
591
+ "",
592
+ `- Status: ${report.status}`,
593
+ `- Target: ${report.target ?? "none"}`,
594
+ "",
595
+ "## Commands",
596
+ ...listOr(report.commands, (command) => `- [${command.status}] \`${command.command}\`: ${command.reason}`),
597
+ "",
598
+ "## Diagnostics",
599
+ ...listOr(report.diagnostics, renderDiagnostic),
600
+ "",
601
+ "## Next Actions",
602
+ ...listOr(report.nextActions, renderCommand),
603
+ ""
604
+ ].join(`
605
+ `);
606
+ var renderRepairReport = (report, format = "markdown") => format === "json" ? jsonText(report) : renderRepairReportMarkdown(report);
607
+ var renderWorkflowRunArtifact = (artifact, format = "markdown") => {
608
+ if ("kind" in artifact)
609
+ return renderRepairReport(artifact, format);
610
+ if ("mode" in artifact && artifact.mode === "validate")
611
+ return renderWorkflowValidation(artifact, format);
612
+ if ("mode" in artifact && (artifact.mode === "apply" || artifact.mode === "dry-run")) {
613
+ return renderWorkflowApply(artifact, format);
614
+ }
615
+ return jsonText(artifact);
616
+ };
395
617
  var renderPrimitiveWriteReport = (report) => [
396
618
  `# Primitive Write: ${report.command}`,
397
619
  "",
398
620
  `- Status: ${report.status}`,
399
621
  "",
400
622
  "## Changed Files",
401
- ...report.changedFiles.length ? report.changedFiles.map((file) => `- \`${file.action}\` ${file.path}: ${file.reason}`) : ["- none"],
623
+ ...listOr(report.changedFiles, renderFile),
402
624
  "",
403
625
  "## Generated Files",
404
- ...report.generatedFiles.length ? report.generatedFiles.map((file) => `- \`${file.action}\` ${file.path}: ${file.reason}`) : ["- none"],
626
+ ...listOr(report.generatedFiles, renderFile),
405
627
  "",
406
628
  "## Validation Commands",
407
- ...report.validationCommands.length ? report.validationCommands.map((validation) => `- \`${validation.command}\`: ${validation.reason}`) : ["- none"],
629
+ ...listOr(report.validationCommands, renderCommand),
408
630
  "",
409
631
  "## Diagnostics",
410
- ...report.diagnostics.length ? report.diagnostics.map((diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`) : ["- none"],
632
+ ...listOr(report.diagnostics, renderDiagnostic),
411
633
  "",
412
634
  "## Next Actions",
413
- ...report.nextActions.length ? report.nextActions.map((action) => `- \`${action.command}\`: ${action.reason}`) : ["- none"],
635
+ ...listOr(report.nextActions, renderCommand),
414
636
  ""
415
637
  ].join(`
416
638
  `);
417
639
  var renderPrimitiveReport = (report, format = "markdown") => format === "json" ? jsonText(report) : renderPrimitiveWriteReport(report);
418
640
  // pkgs/@akanjs/devkit/workflow/executor.ts
419
- import { capitalize } from "akanjs/common";
420
- import ts3 from "typescript";
641
+ import { capitalize as capitalize2 } from "akanjs/common";
642
+ import ts4 from "typescript";
421
643
 
422
644
  // pkgs/@akanjs/devkit/workflow/moduleIndex.ts
423
645
  import { access } from "fs/promises";
424
646
  import path from "path";
425
- import ts2 from "typescript";
647
+ import ts3 from "typescript";
426
648
 
427
649
  // pkgs/@akanjs/devkit/workflow/source.ts
650
+ import { lowerlize } from "akanjs/common";
651
+ import ts2 from "typescript";
652
+
653
+ // pkgs/@akanjs/devkit/workflow/sourceAst.ts
428
654
  import ts from "typescript";
655
+ var sourceFileFor = (fileName, content) => ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
656
+ var nodeName = (node) => {
657
+ if (!node)
658
+ return null;
659
+ if (ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node))
660
+ return node.text;
661
+ return null;
662
+ };
663
+ var propertyName = (node) => ts.isPropertyAssignment(node) || ts.isShorthandPropertyAssignment(node) || ts.isMethodDeclaration(node) ? nodeName(node.name) : null;
664
+ var expressionName = (expression) => {
665
+ if (ts.isIdentifier(expression))
666
+ return expression.text;
667
+ if (ts.isPropertyAccessExpression(expression))
668
+ return expression.name.text;
669
+ if (ts.isCallExpression(expression))
670
+ return expressionName(expression.expression);
671
+ if (ts.isAsExpression(expression))
672
+ return expressionName(expression.expression);
673
+ return null;
674
+ };
675
+ var callExpressionName = (node) => ts.isPropertyAccessExpression(node.expression) ? node.expression.name.text : expressionName(node.expression);
676
+ var firstObjectReturnedByArrow = (node) => {
677
+ if (!ts.isArrowFunction(node) && !ts.isFunctionExpression(node))
678
+ return null;
679
+ if (ts.isObjectLiteralExpression(node.body))
680
+ return node.body;
681
+ if (ts.isParenthesizedExpression(node.body) && ts.isObjectLiteralExpression(node.body.expression)) {
682
+ return node.body.expression;
683
+ }
684
+ if (!ts.isBlock(node.body))
685
+ return null;
686
+ for (const statement of node.body.statements) {
687
+ if (ts.isReturnStatement(statement) && statement.expression && ts.isObjectLiteralExpression(statement.expression)) {
688
+ return statement.expression;
689
+ }
690
+ }
691
+ return null;
692
+ };
693
+ var isViaCall = (expression) => ts.isCallExpression(expression) && expressionName(expression.expression) === "via";
694
+ var heritageCall = (node) => {
695
+ const heritage = node.heritageClauses?.flatMap((clause) => [...clause.types]) ?? [];
696
+ const expression = heritage.find((clause) => isViaCall(clause.expression))?.expression;
697
+ return expression && ts.isCallExpression(expression) ? expression : null;
698
+ };
699
+
700
+ // pkgs/@akanjs/devkit/workflow/source.ts
429
701
  var getSysRoot = (sys) => `${sys.type}s/${sys.name}`;
430
702
  var sourceFile = (sys, path, action, reason) => ({
431
703
  path: `${getSysRoot(sys)}/${path}`,
@@ -458,6 +730,24 @@ var nextActionsForTarget = (target) => [
458
730
  { command: `akan sync ${target}`, reason: "Refresh generated Akan files after source changes." },
459
731
  { command: `akan lint ${target}`, reason: "Validate the target after generated files are refreshed." }
460
732
  ];
733
+ var createPrimitiveWriteReport = ({
734
+ command,
735
+ status,
736
+ changedFiles = [],
737
+ generatedFiles = [],
738
+ validationCommands = [],
739
+ diagnostics = [],
740
+ nextActions = []
741
+ }) => ({
742
+ schemaVersion: 1,
743
+ command,
744
+ status: status ?? (diagnostics.some((diagnostic) => diagnostic.severity === "error") ? "failed" : "passed"),
745
+ changedFiles,
746
+ generatedFiles,
747
+ validationCommands,
748
+ diagnostics,
749
+ nextActions
750
+ });
461
751
  var createPassedPrimitiveReport = ({
462
752
  command,
463
753
  changedFiles,
@@ -474,7 +764,6 @@ var createPassedPrimitiveReport = ({
474
764
  });
475
765
  var scalarChangedFiles = (sys, scalarName, files) => Object.values(files).map((file) => sourceFile(sys, `lib/__scalar/${scalarName}/${file.filename}`, "create", "Scalar source file was created."));
476
766
  var titleize = (value) => value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[-_]+/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
477
- var lowerlize = (value) => `${value.slice(0, 1).toLowerCase()}${value.slice(1)}`;
478
767
  var koLabels = {
479
768
  amount: "\uAE08\uC561",
480
769
  budget: "\uC608\uC0B0",
@@ -688,7 +977,6 @@ var fieldOrderingPriority = [
688
977
  "createdAt",
689
978
  "updatedAt"
690
979
  ];
691
- var sourceFileFor = (fileName, content, scriptKind = ts.ScriptKind.TS) => ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, true, scriptKind);
692
980
  var hasParseDiagnostics = (source) => (source.parseDiagnostics ?? []).length > 0;
693
981
  var spliceText = (content, start, end, replacement) => `${content.slice(0, start)}${replacement}${content.slice(end)}`;
694
982
  var lineStartAt = (content, position) => content.lastIndexOf(`
@@ -699,49 +987,6 @@ var lineEndAt = (content, position) => {
699
987
  return end < 0 ? content.length : end + 1;
700
988
  };
701
989
  var lineIndentAt = (content, position) => /^[ \t]*/.exec(content.slice(lineStartAt(content, position)))?.[0] ?? "";
702
- var nodeName = (node) => {
703
- if (!node)
704
- return null;
705
- if (ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node))
706
- return node.text;
707
- return null;
708
- };
709
- var propertyName = (node) => ts.isPropertyAssignment(node) || ts.isShorthandPropertyAssignment(node) || ts.isMethodDeclaration(node) ? nodeName(node.name) : null;
710
- var expressionName = (expression) => {
711
- if (ts.isIdentifier(expression))
712
- return expression.text;
713
- if (ts.isPropertyAccessExpression(expression))
714
- return expression.name.text;
715
- if (ts.isCallExpression(expression))
716
- return expressionName(expression.expression);
717
- if (ts.isAsExpression(expression))
718
- return expressionName(expression.expression);
719
- return null;
720
- };
721
- var firstObjectReturnedByArrow = (node) => {
722
- if (!ts.isArrowFunction(node) && !ts.isFunctionExpression(node))
723
- return null;
724
- if (ts.isObjectLiteralExpression(node.body))
725
- return node.body;
726
- if (ts.isParenthesizedExpression(node.body) && ts.isObjectLiteralExpression(node.body.expression)) {
727
- return node.body.expression;
728
- }
729
- if (!ts.isBlock(node.body))
730
- return null;
731
- for (const statement of node.body.statements) {
732
- if (ts.isReturnStatement(statement) && statement.expression && ts.isObjectLiteralExpression(statement.expression)) {
733
- return statement.expression;
734
- }
735
- }
736
- return null;
737
- };
738
- var isViaCall = (expression) => ts.isCallExpression(expression) && expressionName(expression.expression) === "via";
739
- var heritageCall = (node) => {
740
- const heritage = node.heritageClauses?.flatMap((clause) => [...clause.types]) ?? [];
741
- const expression = heritage.find((clause) => isViaCall(clause.expression))?.expression;
742
- return expression && ts.isCallExpression(expression) ? expression : null;
743
- };
744
- var callExpressionName = (node) => ts.isPropertyAccessExpression(node.expression) ? node.expression.name.text : expressionName(node.expression);
745
990
  var locatedObject = (source, objectLiteral) => ({
746
991
  objectStart: objectLiteral.getStart(source),
747
992
  objectEnd: objectLiteral.getEnd(),
@@ -762,25 +1007,25 @@ var findConstantInputObject = (source, className) => {
762
1007
  const visit = (node) => {
763
1008
  if (locator)
764
1009
  return;
765
- if (!ts.isClassDeclaration(node) || node.name?.text !== className) {
766
- ts.forEachChild(node, visit);
1010
+ if (!ts2.isClassDeclaration(node) || node.name?.text !== className) {
1011
+ ts2.forEachChild(node, visit);
767
1012
  return;
768
1013
  }
769
1014
  const viaCall = heritageCall(node);
770
- const callback = viaCall?.arguments.find((arg) => ts.isArrowFunction(arg) || ts.isFunctionExpression(arg));
1015
+ const callback = viaCall?.arguments.find((arg) => ts2.isArrowFunction(arg) || ts2.isFunctionExpression(arg));
771
1016
  const objectLiteral = callback ? firstObjectReturnedByArrow(callback) : null;
772
1017
  if (objectLiteral)
773
1018
  locator = locatedObject(source, objectLiteral);
774
1019
  };
775
- ts.forEachChild(source, visit);
1020
+ ts2.forEachChild(source, visit);
776
1021
  return locator;
777
1022
  };
778
1023
  var chainMethodsForCall = (node) => {
779
- if (ts.isAsExpression(node) || ts.isParenthesizedExpression(node))
1024
+ if (ts2.isAsExpression(node) || ts2.isParenthesizedExpression(node))
780
1025
  return chainMethodsForCall(node.expression);
781
- if (!ts.isCallExpression(node))
1026
+ if (!ts2.isCallExpression(node))
782
1027
  return [];
783
- if (ts.isPropertyAccessExpression(node.expression)) {
1028
+ if (ts2.isPropertyAccessExpression(node.expression)) {
784
1029
  return [...chainMethodsForCall(node.expression.expression), node.expression.name.text];
785
1030
  }
786
1031
  const name = expressionName(node.expression);
@@ -788,7 +1033,7 @@ var chainMethodsForCall = (node) => {
788
1033
  };
789
1034
  var outermostFluentCall = (node) => {
790
1035
  let current = node;
791
- while (ts.isPropertyAccessExpression(current.parent) && current.parent.expression === current && ts.isCallExpression(current.parent.parent) && current.parent.parent.expression === current.parent) {
1036
+ while (ts2.isPropertyAccessExpression(current.parent) && current.parent.expression === current && ts2.isCallExpression(current.parent.parent) && current.parent.parent.expression === current.parent) {
792
1037
  current = current.parent.parent;
793
1038
  }
794
1039
  return current;
@@ -812,16 +1057,16 @@ var findDictionaryModelObject = (source, moduleClassName) => {
812
1057
  const visit = (node) => {
813
1058
  if (locator)
814
1059
  return;
815
- if (!ts.isCallExpression(node) || callExpressionName(node) !== "model") {
816
- ts.forEachChild(node, visit);
1060
+ if (!ts2.isCallExpression(node) || callExpressionName(node) !== "model") {
1061
+ ts2.forEachChild(node, visit);
817
1062
  return;
818
1063
  }
819
1064
  const typeArgument = node.typeArguments?.[0];
820
1065
  if (!typeArgument || typeArgument.getText(source) !== moduleClassName) {
821
- ts.forEachChild(node, visit);
1066
+ ts2.forEachChild(node, visit);
822
1067
  return;
823
1068
  }
824
- const callback = node.arguments.find((arg) => ts.isArrowFunction(arg) || ts.isFunctionExpression(arg));
1069
+ const callback = node.arguments.find((arg) => ts2.isArrowFunction(arg) || ts2.isFunctionExpression(arg));
825
1070
  const objectLiteral = callback ? firstObjectReturnedByArrow(callback) : null;
826
1071
  if (objectLiteral) {
827
1072
  locator = {
@@ -830,7 +1075,7 @@ var findDictionaryModelObject = (source, moduleClassName) => {
830
1075
  };
831
1076
  }
832
1077
  };
833
- ts.forEachChild(source, visit);
1078
+ ts2.forEachChild(source, visit);
834
1079
  return locator;
835
1080
  };
836
1081
  var findLightProjectionArray = (source, moduleClassName) => {
@@ -838,35 +1083,35 @@ var findLightProjectionArray = (source, moduleClassName) => {
838
1083
  const visit = (node) => {
839
1084
  if (locator)
840
1085
  return;
841
- if (!ts.isClassDeclaration(node) || node.name?.text !== `Light${moduleClassName}`) {
842
- ts.forEachChild(node, visit);
1086
+ if (!ts2.isClassDeclaration(node) || node.name?.text !== `Light${moduleClassName}`) {
1087
+ ts2.forEachChild(node, visit);
843
1088
  return;
844
1089
  }
845
1090
  const viaCall = heritageCall(node);
846
1091
  const projectionArg = viaCall?.arguments.find((arg) => {
847
- const expression = ts.isAsExpression(arg) ? arg.expression : arg;
848
- return ts.isArrayLiteralExpression(expression);
1092
+ const expression = ts2.isAsExpression(arg) ? arg.expression : arg;
1093
+ return ts2.isArrayLiteralExpression(expression);
849
1094
  });
850
- const arrayLiteral = projectionArg ? ts.isAsExpression(projectionArg) ? projectionArg.expression : projectionArg : null;
851
- if (!projectionArg || !arrayLiteral || !ts.isArrayLiteralExpression(arrayLiteral))
1095
+ const arrayLiteral = projectionArg ? ts2.isAsExpression(projectionArg) ? projectionArg.expression : projectionArg : null;
1096
+ if (!projectionArg || !arrayLiteral || !ts2.isArrayLiteralExpression(arrayLiteral))
852
1097
  return;
853
1098
  locator = {
854
1099
  projectionStart: projectionArg.getStart(source),
855
1100
  projectionEnd: projectionArg.getEnd(),
856
- fields: arrayLiteral.elements.map((element) => ts.isStringLiteralLike(element) ? element.text : null).filter((field) => field !== null)
1101
+ fields: arrayLiteral.elements.map((element) => ts2.isStringLiteralLike(element) ? element.text : null).filter((field) => field !== null)
857
1102
  };
858
1103
  };
859
- ts.forEachChild(source, visit);
1104
+ ts2.forEachChild(source, visit);
860
1105
  return locator;
861
1106
  };
862
1107
  var findNamedImport = (source, moduleSpecifier) => {
863
1108
  for (const statement of source.statements) {
864
- if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier))
1109
+ if (!ts2.isImportDeclaration(statement) || !ts2.isStringLiteral(statement.moduleSpecifier))
865
1110
  continue;
866
1111
  if (statement.moduleSpecifier.text !== moduleSpecifier)
867
1112
  continue;
868
1113
  const namedBindings = statement.importClause?.namedBindings;
869
- if (!namedBindings || !ts.isNamedImports(namedBindings))
1114
+ if (!namedBindings || !ts2.isNamedImports(namedBindings))
870
1115
  continue;
871
1116
  return {
872
1117
  names: namedBindings.elements.map((element) => element.name.text),
@@ -877,10 +1122,10 @@ var findNamedImport = (source, moduleSpecifier) => {
877
1122
  return null;
878
1123
  };
879
1124
  var fieldExpressionBuilder = (property) => {
880
- if (!ts.isPropertyAssignment(property))
1125
+ if (!ts2.isPropertyAssignment(property))
881
1126
  return null;
882
- const initializer = ts.isAsExpression(property.initializer) ? property.initializer.expression : property.initializer;
883
- if (!ts.isCallExpression(initializer))
1127
+ const initializer = ts2.isAsExpression(property.initializer) ? property.initializer.expression : property.initializer;
1128
+ if (!ts2.isCallExpression(initializer))
884
1129
  return null;
885
1130
  return expressionName(initializer.expression);
886
1131
  };
@@ -918,7 +1163,7 @@ ${options.closingIndent}}`);
918
1163
  }
919
1164
  const beforeField = locator.fields[insertIndex];
920
1165
  if (beforeField) {
921
- const leadingComments = ts.getLeadingCommentRanges(content, beforeField.fullStart) ?? [];
1166
+ const leadingComments = ts2.getLeadingCommentRanges(content, beforeField.fullStart) ?? [];
922
1167
  const insertAt = lineStartAt(content, leadingComments[0]?.pos ?? beforeField.start);
923
1168
  const indent = lineIndentAt(content, beforeField.start) || options.fieldIndent;
924
1169
  return spliceText(content, insertAt, insertAt, `${indent}${formattedLine}
@@ -936,17 +1181,17 @@ var viaBuilderParameterName = (content, className) => {
936
1181
  const visit = (node) => {
937
1182
  if (builderName !== null)
938
1183
  return;
939
- if (!ts.isClassDeclaration(node) || node.name?.text !== className) {
940
- ts.forEachChild(node, visit);
1184
+ if (!ts2.isClassDeclaration(node) || node.name?.text !== className) {
1185
+ ts2.forEachChild(node, visit);
941
1186
  return;
942
1187
  }
943
1188
  const viaCall = heritageCall(node);
944
- const callback = viaCall?.arguments.find((arg) => ts.isArrowFunction(arg) || ts.isFunctionExpression(arg));
945
- if (callback && (ts.isArrowFunction(callback) || ts.isFunctionExpression(callback))) {
1189
+ const callback = viaCall?.arguments.find((arg) => ts2.isArrowFunction(arg) || ts2.isFunctionExpression(arg));
1190
+ if (callback && (ts2.isArrowFunction(callback) || ts2.isFunctionExpression(callback))) {
946
1191
  builderName = nodeName(callback.parameters[0]?.name);
947
1192
  }
948
1193
  };
949
- ts.forEachChild(source, visit);
1194
+ ts2.forEachChild(source, visit);
950
1195
  return builderName;
951
1196
  };
952
1197
  var inspectConstantStructure = (content, className, moduleClassName) => {
@@ -957,12 +1202,12 @@ var inspectConstantStructure = (content, className, moduleClassName) => {
957
1202
  const fields = [];
958
1203
  if (inputObject) {
959
1204
  const visit = (node) => {
960
- if (!ts.isClassDeclaration(node) || node.name?.text !== className) {
961
- ts.forEachChild(node, visit);
1205
+ if (!ts2.isClassDeclaration(node) || node.name?.text !== className) {
1206
+ ts2.forEachChild(node, visit);
962
1207
  return;
963
1208
  }
964
1209
  const viaCall = heritageCall(node);
965
- const callback = viaCall?.arguments.find((arg) => ts.isArrowFunction(arg) || ts.isFunctionExpression(arg));
1210
+ const callback = viaCall?.arguments.find((arg) => ts2.isArrowFunction(arg) || ts2.isFunctionExpression(arg));
966
1211
  const objectLiteral = callback ? firstObjectReturnedByArrow(callback) : null;
967
1212
  if (!objectLiteral)
968
1213
  return;
@@ -973,7 +1218,7 @@ var inspectConstantStructure = (content, className, moduleClassName) => {
973
1218
  return { name, expressionBuilder: fieldExpressionBuilder(property) };
974
1219
  }).filter((field) => field !== null));
975
1220
  };
976
- ts.forEachChild(source, visit);
1221
+ ts2.forEachChild(source, visit);
977
1222
  }
978
1223
  return {
979
1224
  parseValid: !hasParseDiagnostics(source),
@@ -1130,26 +1375,26 @@ var findClassDeclaration = (source, className) => {
1130
1375
  const visit = (node) => {
1131
1376
  if (found)
1132
1377
  return;
1133
- if (ts.isClassDeclaration(node) && node.name?.text === className) {
1378
+ if (ts2.isClassDeclaration(node) && node.name?.text === className) {
1134
1379
  found = node;
1135
1380
  return;
1136
1381
  }
1137
- ts.forEachChild(node, visit);
1382
+ ts2.forEachChild(node, visit);
1138
1383
  };
1139
- ts.forEachChild(source, visit);
1384
+ ts2.forEachChild(source, visit);
1140
1385
  return found;
1141
1386
  };
1142
1387
  var firstHeritageCall = (node) => {
1143
1388
  const expression = (node.heritageClauses?.flatMap((clause) => [...clause.types]) ?? [])[0]?.expression;
1144
- return expression && ts.isCallExpression(expression) ? expression : null;
1389
+ return expression && ts2.isCallExpression(expression) ? expression : null;
1145
1390
  };
1146
1391
  var factoryArrowOf = (call) => {
1147
- const arg = call.arguments.find((argument) => ts.isArrowFunction(argument) || ts.isFunctionExpression(argument));
1148
- return arg && (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg)) ? arg : null;
1392
+ const arg = call.arguments.find((argument) => ts2.isArrowFunction(argument) || ts2.isFunctionExpression(argument));
1393
+ return arg && (ts2.isArrowFunction(arg) || ts2.isFunctionExpression(arg)) ? arg : null;
1149
1394
  };
1150
1395
  var hasClassMethod = (content, className, methodName) => {
1151
1396
  const node = findClassDeclaration(sourceFileFor("service.ts", content), className);
1152
- return Boolean(node?.members.some((member) => ts.isMethodDeclaration(member) && nodeName(member.name) === methodName));
1397
+ return Boolean(node?.members.some((member) => ts2.isMethodDeclaration(member) && nodeName(member.name) === methodName));
1153
1398
  };
1154
1399
  var insertClassMethod = (content, className, methodBlock) => {
1155
1400
  const source = sourceFileFor("service.ts", content);
@@ -1192,9 +1437,9 @@ var factoryParamEdit = (content, source, arrow, plan) => {
1192
1437
  const param = arrow.parameters[0];
1193
1438
  if (plan.mode === "positional")
1194
1439
  return nodeName(param.name) === plan.name ? "unchanged" : null;
1195
- if (!ts.isObjectBindingPattern(param.name))
1440
+ if (!ts2.isObjectBindingPattern(param.name))
1196
1441
  return null;
1197
- const names = param.name.elements.map((element) => ts.isIdentifier(element.name) ? element.name.text : null);
1442
+ const names = param.name.elements.map((element) => ts2.isIdentifier(element.name) ? element.name.text : null);
1198
1443
  if (names.some((name) => name === null))
1199
1444
  return null;
1200
1445
  if (names.includes(plan.name))
@@ -1265,13 +1510,12 @@ var fileExists = async (filePath) => {
1265
1510
  return false;
1266
1511
  }
1267
1512
  };
1268
- var sourceFileFor2 = (filePath, content) => ts2.createSourceFile(filePath, content, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TS);
1269
1513
  var parseDiagnosticsFor = (source, filePath) => {
1270
1514
  const parseDiagnostics = source.parseDiagnostics ?? [];
1271
1515
  return parseDiagnostics.map((diagnostic) => ({
1272
1516
  severity: "error",
1273
1517
  code: "module-index-typescript-parse-error",
1274
- message: `TypeScript parse diagnostic TS${diagnostic.code} in ${filePath}: ${ts2.flattenDiagnosticMessageText(diagnostic.messageText, `
1518
+ message: `TypeScript parse diagnostic TS${diagnostic.code} in ${filePath}: ${ts3.flattenDiagnosticMessageText(diagnostic.messageText, `
1275
1519
  `)}`,
1276
1520
  context: { target: filePath, paths: [filePath] }
1277
1521
  }));
@@ -1289,63 +1533,44 @@ var spanFor = (source, file, node) => {
1289
1533
  endOffset
1290
1534
  };
1291
1535
  };
1292
- var nodeName2 = (node) => {
1293
- if (!node)
1294
- return null;
1295
- if (ts2.isIdentifier(node) || ts2.isStringLiteral(node) || ts2.isNumericLiteral(node))
1296
- return node.text;
1297
- return null;
1298
- };
1299
- var propertyName2 = (node) => ts2.isPropertyAssignment(node) || ts2.isShorthandPropertyAssignment(node) || ts2.isMethodDeclaration(node) ? nodeName2(node.name) : null;
1300
- var expressionName2 = (expression) => {
1301
- if (ts2.isIdentifier(expression))
1302
- return expression.text;
1303
- if (ts2.isPropertyAccessExpression(expression))
1304
- return expression.name.text;
1305
- if (ts2.isCallExpression(expression))
1306
- return expressionName2(expression.expression);
1307
- if (ts2.isAsExpression(expression))
1308
- return expressionName2(expression.expression);
1309
- return null;
1310
- };
1311
1536
  var expressionSummary = (expression) => {
1312
- if (ts2.isAsExpression(expression))
1537
+ if (ts3.isAsExpression(expression))
1313
1538
  return expressionSummary(expression.expression);
1314
- if (ts2.isIdentifier(expression) || ts2.isPropertyAccessExpression(expression))
1315
- return expressionName2(expression) ?? "expression";
1316
- if (ts2.isArrayLiteralExpression(expression))
1539
+ if (ts3.isIdentifier(expression) || ts3.isPropertyAccessExpression(expression))
1540
+ return expressionName(expression) ?? "expression";
1541
+ if (ts3.isArrayLiteralExpression(expression))
1317
1542
  return "array-literal";
1318
- if (ts2.isObjectLiteralExpression(expression))
1543
+ if (ts3.isObjectLiteralExpression(expression))
1319
1544
  return "object-literal";
1320
- if (ts2.isStringLiteralLike(expression))
1545
+ if (ts3.isStringLiteralLike(expression))
1321
1546
  return "string-literal";
1322
- if (ts2.isNumericLiteral(expression))
1547
+ if (ts3.isNumericLiteral(expression))
1323
1548
  return "numeric-literal";
1324
- if (expression.kind === ts2.SyntaxKind.TrueKeyword || expression.kind === ts2.SyntaxKind.FalseKeyword) {
1549
+ if (expression.kind === ts3.SyntaxKind.TrueKeyword || expression.kind === ts3.SyntaxKind.FalseKeyword) {
1325
1550
  return "boolean-literal";
1326
1551
  }
1327
- if (ts2.isCallExpression(expression)) {
1328
- const callee = expressionName2(expression.expression);
1552
+ if (ts3.isCallExpression(expression)) {
1553
+ const callee = expressionName(expression.expression);
1329
1554
  return callee ? `${callee}(...)` : "call-expression";
1330
1555
  }
1331
- return ts2.SyntaxKind[expression.kind] ?? "expression";
1556
+ return ts3.SyntaxKind[expression.kind] ?? "expression";
1332
1557
  };
1333
1558
  var typeSummaryForInitializer = (initializer) => {
1334
1559
  if (!initializer)
1335
1560
  return;
1336
- const expression = ts2.isAsExpression(initializer) ? initializer.expression : initializer;
1337
- if (!ts2.isCallExpression(expression))
1561
+ const expression = ts3.isAsExpression(initializer) ? initializer.expression : initializer;
1562
+ if (!ts3.isCallExpression(expression))
1338
1563
  return expressionSummary(expression);
1339
- const callee = expressionName2(expression.expression);
1564
+ const callee = expressionName(expression.expression);
1340
1565
  const firstArg = expression.arguments[0];
1341
1566
  const argSummary = firstArg ? expressionSummary(firstArg) : "";
1342
1567
  return [callee, argSummary ? `(${argSummary})` : ""].filter(Boolean).join("");
1343
1568
  };
1344
1569
  var fieldsFromObject = (source, file, objectLiteral, kind) => objectLiteral.properties.map((property, index) => {
1345
- const name = propertyName2(property);
1570
+ const name = propertyName(property);
1346
1571
  if (!name)
1347
1572
  return null;
1348
- const initializer = ts2.isPropertyAssignment(property) ? property.initializer : undefined;
1573
+ const initializer = ts3.isPropertyAssignment(property) ? property.initializer : undefined;
1349
1574
  return {
1350
1575
  name,
1351
1576
  kind,
@@ -1354,31 +1579,8 @@ var fieldsFromObject = (source, file, objectLiteral, kind) => objectLiteral.prop
1354
1579
  sourceSpan: spanFor(source, file, property)
1355
1580
  };
1356
1581
  }).filter((field) => field !== null);
1357
- var firstObjectReturnedByArrow2 = (node) => {
1358
- if (!ts2.isArrowFunction(node) && !ts2.isFunctionExpression(node))
1359
- return null;
1360
- if (ts2.isObjectLiteralExpression(node.body))
1361
- return node.body;
1362
- if (ts2.isParenthesizedExpression(node.body) && ts2.isObjectLiteralExpression(node.body.expression)) {
1363
- return node.body.expression;
1364
- }
1365
- if (!ts2.isBlock(node.body))
1366
- return null;
1367
- for (const statement of node.body.statements) {
1368
- if (ts2.isReturnStatement(statement) && statement.expression && ts2.isObjectLiteralExpression(statement.expression)) {
1369
- return statement.expression;
1370
- }
1371
- }
1372
- return null;
1373
- };
1374
- var isViaCall2 = (expression) => ts2.isCallExpression(expression) && expressionName2(expression.expression) === "via";
1375
- var heritageCall2 = (node) => {
1376
- const heritage = node.heritageClauses?.flatMap((clause) => [...clause.types]) ?? [];
1377
- const expression = heritage.find((clause) => isViaCall2(clause.expression))?.expression;
1378
- return expression && ts2.isCallExpression(expression) ? expression : null;
1379
- };
1380
1582
  var parseConstantIndex = (filePath, content, moduleClassName) => {
1381
- const source = sourceFileFor2(filePath, content);
1583
+ const source = sourceFileFor(filePath, content);
1382
1584
  const diagnostics = parseDiagnosticsFor(source, filePath);
1383
1585
  const inputClassName = `${moduleClassName}Input`;
1384
1586
  let inputClass = null;
@@ -1389,22 +1591,22 @@ var parseConstantIndex = (filePath, content, moduleClassName) => {
1389
1591
  let fields = [];
1390
1592
  let lightProjection;
1391
1593
  const visit = (node) => {
1392
- if (!ts2.isClassDeclaration(node) || !node.name) {
1393
- ts2.forEachChild(node, visit);
1594
+ if (!ts3.isClassDeclaration(node) || !node.name) {
1595
+ ts3.forEachChild(node, visit);
1394
1596
  return;
1395
1597
  }
1396
1598
  const className = node.name.text;
1397
- const viaCall = heritageCall2(node);
1599
+ const viaCall = heritageCall(node);
1398
1600
  if (className === inputClassName) {
1399
1601
  inputClass = node;
1400
1602
  if (!viaCall)
1401
1603
  return;
1402
1604
  inputViaFound = true;
1403
- const callback = viaCall.arguments.find((arg) => ts2.isArrowFunction(arg) || ts2.isFunctionExpression(arg));
1404
- if (callback && (ts2.isArrowFunction(callback) || ts2.isFunctionExpression(callback))) {
1605
+ const callback = viaCall.arguments.find((arg) => ts3.isArrowFunction(arg) || ts3.isFunctionExpression(arg));
1606
+ if (callback && (ts3.isArrowFunction(callback) || ts3.isFunctionExpression(callback))) {
1405
1607
  inputBuilderFound = true;
1406
- builderName = nodeName2(callback.parameters[0]?.name) ?? null;
1407
- const objectLiteral = firstObjectReturnedByArrow2(callback);
1608
+ builderName = nodeName(callback.parameters[0]?.name) ?? null;
1609
+ const objectLiteral = firstObjectReturnedByArrow(callback);
1408
1610
  if (objectLiteral) {
1409
1611
  inputBuilderObjectFound = true;
1410
1612
  fields = fieldsFromObject(source, filePath, objectLiteral, "constant");
@@ -1415,15 +1617,15 @@ var parseConstantIndex = (filePath, content, moduleClassName) => {
1415
1617
  return;
1416
1618
  if (className === `Light${moduleClassName}`) {
1417
1619
  const projectionArg = viaCall.arguments.find((arg) => {
1418
- const expression = ts2.isAsExpression(arg) ? arg.expression : arg;
1419
- return ts2.isArrayLiteralExpression(expression);
1620
+ const expression = ts3.isAsExpression(arg) ? arg.expression : arg;
1621
+ return ts3.isArrayLiteralExpression(expression);
1420
1622
  });
1421
- const arrayLiteral = projectionArg ? ts2.isAsExpression(projectionArg) ? projectionArg.expression : projectionArg : null;
1422
- if (arrayLiteral && ts2.isArrayLiteralExpression(arrayLiteral)) {
1623
+ const arrayLiteral = projectionArg ? ts3.isAsExpression(projectionArg) ? projectionArg.expression : projectionArg : null;
1624
+ if (arrayLiteral && ts3.isArrayLiteralExpression(arrayLiteral)) {
1423
1625
  lightProjection = {
1424
1626
  className,
1425
1627
  sourceSpan: spanFor(source, filePath, arrayLiteral),
1426
- fields: arrayLiteral.elements.map((element, order) => ts2.isStringLiteralLike(element) ? {
1628
+ fields: arrayLiteral.elements.map((element, order) => ts3.isStringLiteralLike(element) ? {
1427
1629
  name: element.text,
1428
1630
  kind: "lightProjection",
1429
1631
  order,
@@ -1434,7 +1636,7 @@ var parseConstantIndex = (filePath, content, moduleClassName) => {
1434
1636
  }
1435
1637
  }
1436
1638
  };
1437
- ts2.forEachChild(source, visit);
1639
+ ts3.forEachChild(source, visit);
1438
1640
  if (!inputClass) {
1439
1641
  diagnostics.push({
1440
1642
  severity: "error",
@@ -1476,29 +1678,28 @@ var parseConstantIndex = (filePath, content, moduleClassName) => {
1476
1678
  diagnostics
1477
1679
  };
1478
1680
  };
1479
- var callExpressionName2 = (node) => ts2.isPropertyAccessExpression(node.expression) ? node.expression.name.text : expressionName2(node.expression);
1480
1681
  var parseDictionaryIndex = (filePath, content, moduleClassName) => {
1481
- const source = sourceFileFor2(filePath, content);
1682
+ const source = sourceFileFor(filePath, content);
1482
1683
  const diagnostics = parseDiagnosticsFor(source, filePath);
1483
1684
  let index;
1484
1685
  let modelFound = false;
1485
1686
  const visit = (node) => {
1486
- if (modelFound || !ts2.isCallExpression(node)) {
1487
- ts2.forEachChild(node, visit);
1687
+ if (modelFound || !ts3.isCallExpression(node)) {
1688
+ ts3.forEachChild(node, visit);
1488
1689
  return;
1489
1690
  }
1490
- if (callExpressionName2(node) !== "model") {
1491
- ts2.forEachChild(node, visit);
1691
+ if (callExpressionName(node) !== "model") {
1692
+ ts3.forEachChild(node, visit);
1492
1693
  return;
1493
1694
  }
1494
1695
  const typeArgument = node.typeArguments?.[0];
1495
1696
  if (!typeArgument || typeArgument.getText(source) !== moduleClassName) {
1496
- ts2.forEachChild(node, visit);
1697
+ ts3.forEachChild(node, visit);
1497
1698
  return;
1498
1699
  }
1499
1700
  modelFound = true;
1500
- const callback = node.arguments.find((arg) => ts2.isArrowFunction(arg) || ts2.isFunctionExpression(arg));
1501
- if (!callback || !ts2.isArrowFunction(callback) && !ts2.isFunctionExpression(callback)) {
1701
+ const callback = node.arguments.find((arg) => ts3.isArrowFunction(arg) || ts3.isFunctionExpression(arg));
1702
+ if (!callback || !ts3.isArrowFunction(callback) && !ts3.isFunctionExpression(callback)) {
1502
1703
  diagnostics.push({
1503
1704
  severity: "error",
1504
1705
  code: "module-index-dictionary-builder-missing",
@@ -1507,7 +1708,7 @@ var parseDictionaryIndex = (filePath, content, moduleClassName) => {
1507
1708
  });
1508
1709
  return;
1509
1710
  }
1510
- const objectLiteral = firstObjectReturnedByArrow2(callback);
1711
+ const objectLiteral = firstObjectReturnedByArrow(callback);
1511
1712
  if (!objectLiteral) {
1512
1713
  diagnostics.push({
1513
1714
  severity: "error",
@@ -1519,12 +1720,12 @@ var parseDictionaryIndex = (filePath, content, moduleClassName) => {
1519
1720
  index = {
1520
1721
  path: filePath,
1521
1722
  modelClassName: moduleClassName,
1522
- translatorName: nodeName2(callback.parameters[0]?.name),
1723
+ translatorName: nodeName(callback.parameters[0]?.name),
1523
1724
  fields: objectLiteral ? fieldsFromObject(source, filePath, objectLiteral, "dictionary") : [],
1524
1725
  sourceSpan: spanFor(source, filePath, node)
1525
1726
  };
1526
1727
  };
1527
- ts2.forEachChild(source, visit);
1728
+ ts3.forEachChild(source, visit);
1528
1729
  return { index, diagnostics, modelFound };
1529
1730
  };
1530
1731
  var expectedFilesFor = (module) => {
@@ -1688,15 +1889,8 @@ var workflowStringInput = (value) => typeof value === "string" ? value : null;
1688
1889
  var workflowStringListInput = (value) => Array.isArray(value) ? value.join(",") : null;
1689
1890
  var workflowStringArrayInput = (value) => Array.isArray(value) ? value : null;
1690
1891
  var workflowBooleanInput = (value) => typeof value === "boolean" ? value : null;
1691
- var postApplyDiagnostic = (code, message, target) => ({
1692
- severity: "error",
1693
- code,
1694
- message,
1695
- failureScope: "source-change",
1696
- context: { target }
1697
- });
1698
- var postApplyWarning = (code, message, target) => ({
1699
- severity: "warning",
1892
+ var postApplyDiagnostic = (code, message, target, severity = "error") => ({
1893
+ severity,
1700
1894
  code,
1701
1895
  message,
1702
1896
  failureScope: "source-change",
@@ -1704,9 +1898,9 @@ var postApplyWarning = (code, message, target) => ({
1704
1898
  });
1705
1899
  var sourceKindForPath = (filePath) => {
1706
1900
  if (filePath.endsWith(".tsx"))
1707
- return ts3.ScriptKind.TSX;
1901
+ return ts4.ScriptKind.TSX;
1708
1902
  if (filePath.endsWith(".ts"))
1709
- return ts3.ScriptKind.TS;
1903
+ return ts4.ScriptKind.TS;
1710
1904
  return null;
1711
1905
  };
1712
1906
  var checkPathCasing = async (workspace, filePath) => {
@@ -1734,7 +1928,7 @@ var checkTypeScriptSyntax = async (workspace, filePath) => {
1734
1928
  if (!scriptKind)
1735
1929
  return null;
1736
1930
  const content = await workspace.readFile(filePath);
1737
- const source = ts3.createSourceFile(filePath, content, ts3.ScriptTarget.Latest, true, scriptKind);
1931
+ const source = ts4.createSourceFile(filePath, content, ts4.ScriptTarget.Latest, true, scriptKind);
1738
1932
  const diagnostic = (source.parseDiagnostics ?? [])[0];
1739
1933
  if (!diagnostic)
1740
1934
  return null;
@@ -1742,33 +1936,29 @@ var checkTypeScriptSyntax = async (workspace, filePath) => {
1742
1936
  const location = position ? `:${position.line + 1}:${position.character + 1}` : "";
1743
1937
  return {
1744
1938
  code: "workflow-post-apply-syntax-error",
1745
- message: `Generated source has a TypeScript syntax error at ${filePath}${location}: ${ts3.flattenDiagnosticMessageText(diagnostic.messageText, " ")}`
1939
+ message: `Generated source has a TypeScript syntax error at ${filePath}${location}: ${ts4.flattenDiagnosticMessageText(diagnostic.messageText, " ")}`
1746
1940
  };
1747
1941
  };
1748
1942
  var checkChangedFile = async (workspace, file) => {
1749
1943
  if (file.action === "remove")
1750
1944
  return { postApplyChecks: [] };
1751
- const diagnostics = [];
1752
- const checks = [];
1753
- const pathIssue = await checkPathCasing(workspace, file.path);
1754
- if (pathIssue) {
1755
- diagnostics.push(postApplyDiagnostic(pathIssue.code, pathIssue.message, file.path));
1756
- checks.push({ ...pathIssue, target: file.path, status: "failed" });
1757
- return { diagnostics, postApplyChecks: checks };
1758
- }
1759
- const syntaxIssue = await checkTypeScriptSyntax(workspace, file.path);
1760
- if (syntaxIssue) {
1761
- diagnostics.push(postApplyDiagnostic(syntaxIssue.code, syntaxIssue.message, file.path));
1762
- checks.push({ ...syntaxIssue, target: file.path, status: "failed" });
1763
- return { diagnostics, postApplyChecks: checks };
1945
+ const issue = await checkPathCasing(workspace, file.path) ?? await checkTypeScriptSyntax(workspace, file.path);
1946
+ if (issue) {
1947
+ return {
1948
+ diagnostics: [postApplyDiagnostic(issue.code, issue.message, file.path)],
1949
+ postApplyChecks: [{ ...issue, target: file.path, status: "failed" }]
1950
+ };
1764
1951
  }
1765
- checks.push({
1766
- code: "workflow-post-apply-file-valid",
1767
- target: file.path,
1768
- status: "passed",
1769
- message: "Changed file exists with exact casing and parses as source when applicable."
1770
- });
1771
- return { postApplyChecks: checks };
1952
+ return {
1953
+ postApplyChecks: [
1954
+ {
1955
+ code: "workflow-post-apply-file-valid",
1956
+ target: file.path,
1957
+ status: "passed",
1958
+ message: "Changed file exists with exact casing and parses as source when applicable."
1959
+ }
1960
+ ]
1961
+ };
1772
1962
  };
1773
1963
  var checkRecommendationPath = async (workspace, recommendation) => {
1774
1964
  if (!recommendation.target || recommendation.target.includes("*") || recommendation.target.startsWith("<"))
@@ -1820,12 +2010,6 @@ var workflowModuleContext = async (workspace, plan) => {
1820
2010
  files
1821
2011
  };
1822
2012
  };
1823
- var structureCheck = (code, target, status, message) => ({
1824
- code,
1825
- target,
1826
- status,
1827
- message
1828
- });
1829
2013
  var checkAddFieldStructure = async (workspace, plan) => {
1830
2014
  if (plan.workflow !== "add-field" && plan.workflow !== "add-enum-field")
1831
2015
  return {};
@@ -1862,7 +2046,12 @@ var checkAddFieldStructure = async (workspace, plan) => {
1862
2046
  ...index.diagnostics.filter((diagnostic) => diagnostic.severity === "error" && diagnostic.context?.paths?.includes(constantPath)).map((diagnostic) => diagnostic.message)
1863
2047
  ].filter((failure) => failure !== null);
1864
2048
  const constantValid = constantFailures.length === 0;
1865
- postApplyChecks.push(structureCheck(constantValid ? "workflow-post-apply-constant-shape-valid" : "workflow-post-apply-structure-invalid", constantPath, constantValid ? "passed" : "failed", constantValid ? `${inputClassName} keeps via structure, builder usage, imports, and requested field presence.` : constantFailures.join(" ")));
2049
+ postApplyChecks.push({
2050
+ code: constantValid ? "workflow-post-apply-constant-shape-valid" : "workflow-post-apply-structure-invalid",
2051
+ target: constantPath,
2052
+ status: constantValid ? "passed" : "failed",
2053
+ message: constantValid ? `${inputClassName} keeps via structure, builder usage, imports, and requested field presence.` : constantFailures.join(" ")
2054
+ });
1866
2055
  if (!constantValid) {
1867
2056
  diagnostics.push(postApplyDiagnostic("workflow-post-apply-structure-invalid", constantFailures.join(" "), constantPath));
1868
2057
  }
@@ -1876,16 +2065,26 @@ var checkAddFieldStructure = async (workspace, plan) => {
1876
2065
  ...index.diagnostics.filter((diagnostic) => diagnostic.severity === "error" && diagnostic.context?.paths?.includes(dictionaryPath)).map((diagnostic) => diagnostic.message)
1877
2066
  ].filter((failure) => failure !== null);
1878
2067
  const dictionaryValid = dictionaryFailures.length === 0;
1879
- postApplyChecks.push(structureCheck(dictionaryValid ? "workflow-post-apply-dictionary-shape-valid" : "workflow-post-apply-structure-invalid", dictionaryPath, dictionaryValid ? "passed" : "failed", dictionaryValid ? `.model<${moduleClassName}> keeps the requested field inside the model object and preserves dictionary chain order.` : dictionaryFailures.join(" ")));
2068
+ postApplyChecks.push({
2069
+ code: dictionaryValid ? "workflow-post-apply-dictionary-shape-valid" : "workflow-post-apply-structure-invalid",
2070
+ target: dictionaryPath,
2071
+ status: dictionaryValid ? "passed" : "failed",
2072
+ message: dictionaryValid ? `.model<${moduleClassName}> keeps the requested field inside the model object and preserves dictionary chain order.` : dictionaryFailures.join(" ")
2073
+ });
1880
2074
  if (!dictionaryValid) {
1881
2075
  diagnostics.push(postApplyDiagnostic("workflow-post-apply-structure-invalid", dictionaryFailures.join(" "), dictionaryPath));
1882
2076
  }
1883
2077
  const constantOrderValid = fieldOrderValid(constantNames, fieldName);
1884
2078
  const dictionaryOrderValid = fieldOrderValid(dictionaryStructure.fields, fieldName);
1885
2079
  const orderValid = constantOrderValid && dictionaryOrderValid;
1886
- postApplyChecks.push(structureCheck("workflow-post-apply-field-order-valid", `${constantPath}, ${dictionaryPath}`, orderValid ? "passed" : "failed", orderValid ? `Field "${fieldName}" follows the shared priority ordering policy.` : `Field "${fieldName}" is present but does not match the shared priority ordering policy.`));
2080
+ postApplyChecks.push({
2081
+ code: "workflow-post-apply-field-order-valid",
2082
+ target: `${constantPath}, ${dictionaryPath}`,
2083
+ status: orderValid ? "passed" : "failed",
2084
+ message: orderValid ? `Field "${fieldName}" follows the shared priority ordering policy.` : `Field "${fieldName}" is present but does not match the shared priority ordering policy.`
2085
+ });
1887
2086
  if (!orderValid) {
1888
- diagnostics.push(postApplyWarning("workflow-post-apply-field-order-mismatch", `Field "${fieldName}" is present but does not match the shared priority ordering policy.`, `${constantPath}, ${dictionaryPath}`));
2087
+ diagnostics.push(postApplyDiagnostic("workflow-post-apply-field-order-mismatch", `Field "${fieldName}" is present but does not match the shared priority ordering policy.`, `${constantPath}, ${dictionaryPath}`, "warning"));
1889
2088
  }
1890
2089
  return { diagnostics, postApplyChecks };
1891
2090
  };
@@ -1917,6 +2116,10 @@ var unsupportedInput = (input, message) => ({
1917
2116
  input,
1918
2117
  message
1919
2118
  });
2119
+ var surfaceReview = (plan, { code, target, action, message, reason }) => ({
2120
+ recommendations: [{ code, kind: "manual-action", target, action, confidence: "medium", message }],
2121
+ nextActions: [{ command: `akan workflow explain ${plan.workflow}`, reason }]
2122
+ });
1920
2123
  var addFieldUiSurfaceInspection = (plan) => {
1921
2124
  const app = workflowStringInput(plan.inputs.app);
1922
2125
  const module = workflowStringInput(plan.inputs.module) ?? "<module>";
@@ -1926,71 +2129,37 @@ var addFieldUiSurfaceInspection = (plan) => {
1926
2129
  const surfaces = workflowStringArrayInput(plan.inputs.surfaces);
1927
2130
  const templateRequested = surfaces?.includes("template") ?? false;
1928
2131
  const moduleClassName = moduleComponentName(module);
1929
- const target = `${app ? `apps/${app}` : "*"}/${moduleSourcePaths(module).template}`;
1930
- return {
1931
- recommendations: [
1932
- {
1933
- code: "add-field-ui-surface-review",
1934
- kind: "manual-action",
1935
- target,
1936
- action: templateRequested ? `Template was requested for ${field}. If no Template file changed, users will not see the field in the form yet because the file was missing, the generated ${module}Form/Layout.Template pattern was not found, or ${policy.component} needs option binding. Add it inside Layout.Template near existing Field components.` : `Template was not selected, so users will not see ${field} in the form from this apply. If list/card display is needed, include ${field} in Light${moduleClassName} projection data and place it in the local Unit/View card layout.`,
1937
- confidence: "medium",
1938
- message: `Review user-visible UI for ${module}.${field}; recommended component is ${policy.component}.`
1939
- }
1940
- ],
1941
- nextActions: [
1942
- {
1943
- command: `akan workflow explain ${plan.workflow}`,
1944
- reason: "Review UI surface guidance before manually editing ambiguous UI files."
1945
- }
1946
- ]
1947
- };
2132
+ return surfaceReview(plan, {
2133
+ code: "add-field-ui-surface-review",
2134
+ target: `${app ? `apps/${app}` : "*"}/${moduleSourcePaths(module).template}`,
2135
+ action: templateRequested ? `Template was requested for ${field}. If no Template file changed, users will not see the field in the form yet because the file was missing, the generated ${module}Form/Layout.Template pattern was not found, or ${policy.component} needs option binding. Add it inside Layout.Template near existing Field components.` : `Template was not selected, so users will not see ${field} in the form from this apply. If list/card display is needed, include ${field} in Light${moduleClassName} projection data and place it in the local Unit/View card layout.`,
2136
+ message: `Review user-visible UI for ${module}.${field}; recommended component is ${policy.component}.`,
2137
+ reason: "Review UI surface guidance before manually editing ambiguous UI files."
2138
+ });
1948
2139
  };
1949
2140
  var addMutationActionSurfaceInspection = (plan) => {
1950
- const module = workflowStringInput(plan.inputs.module) ?? "<module>";
1951
- const mutation = workflowStringInput(plan.inputs.mutation) ?? "<mutation>";
1952
- const moduleClassName = moduleComponentName(module);
1953
- return {
1954
- recommendations: [
1955
- {
1956
- code: "add-mutation-action-surface-review",
1957
- kind: "manual-action",
1958
- target: `*/${moduleSourcePaths(module).store}`,
1959
- action: `Name the endpoint's guards and add its dictionary .endpoint() entry with a .desc(). After sync, fetch.${mutation} exists; write a store action only for a toast, an optimistic update, or a multi-field write, and put the control that calls it in ${moduleClassName}.Util.tsx.`,
1960
- confidence: "medium",
1961
- message: `Workflow apply does not write store or UI code for ${module}.${mutation}; review whether a screen should call it.`
1962
- }
1963
- ],
1964
- nextActions: [
1965
- {
1966
- command: `akan workflow explain ${plan.workflow}`,
1967
- reason: "Review action surface guidance before manually editing store or UI files."
1968
- }
1969
- ]
1970
- };
1971
- };
1972
- var addSliceViewSurfaceInspection = (plan) => {
1973
- const module = workflowStringInput(plan.inputs.module) ?? "<module>";
1974
- const slice = workflowStringInput(plan.inputs.slice) ?? "<slice>";
1975
- const moduleClassName = moduleComponentName(module);
1976
- return {
1977
- recommendations: [
1978
- {
1979
- code: "add-slice-view-surface-review",
1980
- kind: "manual-action",
1981
- target: `*/${moduleSourcePaths(module).zone}`,
1982
- action: `Fill in the service query stub and add the dictionary .slice() entry. After sync, load fetch.init${moduleClassName}${capitalize(slice)}() in the page and pass the result to a ${moduleClassName}.Zone as an init prop.`,
1983
- confidence: "medium",
1984
- message: `Workflow apply does not write page or Zone code for ${module}.${slice}; review where the list should render.`
1985
- }
1986
- ],
1987
- nextActions: [
1988
- {
1989
- command: `akan workflow explain ${plan.workflow}`,
1990
- reason: "Review view surface guidance before manually editing Zone or page files."
1991
- }
1992
- ]
1993
- };
2141
+ const module = workflowStringInput(plan.inputs.module) ?? "<module>";
2142
+ const mutation = workflowStringInput(plan.inputs.mutation) ?? "<mutation>";
2143
+ const moduleClassName = moduleComponentName(module);
2144
+ return surfaceReview(plan, {
2145
+ code: "add-mutation-action-surface-review",
2146
+ target: `*/${moduleSourcePaths(module).store}`,
2147
+ action: `Name the endpoint's guards and add its dictionary .endpoint() entry with a .desc(). After sync, fetch.${mutation} exists; write a store action only for a toast, an optimistic update, or a multi-field write, and put the control that calls it in ${moduleClassName}.Util.tsx.`,
2148
+ message: `Workflow apply does not write store or UI code for ${module}.${mutation}; review whether a screen should call it.`,
2149
+ reason: "Review action surface guidance before manually editing store or UI files."
2150
+ });
2151
+ };
2152
+ var addSliceViewSurfaceInspection = (plan) => {
2153
+ const module = workflowStringInput(plan.inputs.module) ?? "<module>";
2154
+ const slice = workflowStringInput(plan.inputs.slice) ?? "<slice>";
2155
+ const moduleClassName = moduleComponentName(module);
2156
+ return surfaceReview(plan, {
2157
+ code: "add-slice-view-surface-review",
2158
+ target: `*/${moduleSourcePaths(module).zone}`,
2159
+ action: `Fill in the service query stub and add the dictionary .slice() entry. After sync, load fetch.init${moduleClassName}${capitalize2(slice)}() in the page and pass the result to a ${moduleClassName}.Zone as an init prop.`,
2160
+ message: `Workflow apply does not write page or Zone code for ${module}.${slice}; review where the list should render.`,
2161
+ reason: "Review view surface guidance before manually editing Zone or page files."
2162
+ });
1994
2163
  };
1995
2164
  var createWorkflowStepRegistry = ({
1996
2165
  workspace,
@@ -2108,20 +2277,20 @@ class WorkflowExecutor {
2108
2277
  const postApplyChecks = [];
2109
2278
  const recommendations = [...plan.recommendations];
2110
2279
  const nextActions = [];
2111
- if (diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
2112
- return createWorkflowApplyReport({
2113
- workflow: plan.workflow,
2114
- mode: "apply",
2115
- changedFiles,
2116
- generatedFiles,
2117
- recommendedValidationCommands,
2118
- diagnostics,
2119
- postApplyChecks,
2120
- recommendations,
2121
- nextActions,
2122
- plan
2123
- });
2124
- }
2280
+ const report = () => createWorkflowApplyReport({
2281
+ workflow: plan.workflow,
2282
+ mode: "apply",
2283
+ changedFiles,
2284
+ generatedFiles,
2285
+ recommendedValidationCommands,
2286
+ diagnostics,
2287
+ postApplyChecks,
2288
+ recommendations,
2289
+ nextActions,
2290
+ plan
2291
+ });
2292
+ if (diagnostics.some((diagnostic) => diagnostic.severity === "error"))
2293
+ return report();
2125
2294
  recommendedValidationCommands.push(...workflowCommandsForPlan(plan));
2126
2295
  nextActions.push(...workflowCommandsForPlan(plan));
2127
2296
  for (const step of plan.steps) {
@@ -2164,22 +2333,11 @@ class WorkflowExecutor {
2164
2333
  const recommendationDiagnostics = await Promise.all(recommendations.map((recommendation) => checkRecommendationPath(this.workspace, recommendation)));
2165
2334
  diagnostics.push(...recommendationDiagnostics.filter((diagnostic) => !!diagnostic));
2166
2335
  }
2167
- return createWorkflowApplyReport({
2168
- workflow: plan.workflow,
2169
- mode: "apply",
2170
- changedFiles,
2171
- generatedFiles,
2172
- recommendedValidationCommands,
2173
- diagnostics,
2174
- postApplyChecks,
2175
- recommendations,
2176
- nextActions,
2177
- plan
2178
- });
2336
+ return report();
2179
2337
  }
2180
2338
  }
2181
2339
  // pkgs/@akanjs/devkit/workflow/plan.ts
2182
- import { capitalize as capitalize2 } from "akanjs/common";
2340
+ import { capitalize as capitalize3 } from "akanjs/common";
2183
2341
  var surfaceModes = new Set(["infer", "include", "skip"]);
2184
2342
  var parseStringList = (value) => {
2185
2343
  if (Array.isArray(value)) {
@@ -2322,7 +2480,7 @@ var createAddFieldRecommendations = (inputs) => {
2322
2480
  kind: "placement",
2323
2481
  target: paths.constant,
2324
2482
  confidence: "high",
2325
- message: `Insert ${field}: field(${normalizedType}) in ${capitalize2(module)}Input.`
2483
+ message: `Insert ${field}: field(${normalizedType}) in ${capitalize3(module)}Input.`
2326
2484
  },
2327
2485
  {
2328
2486
  code: "add-field-placement-dictionary",
@@ -2349,25 +2507,20 @@ var createAddFieldRecommendations = (inputs) => {
2349
2507
  message: `Template exposure for ${module}.${field} is not selected yet.`
2350
2508
  }
2351
2509
  ] : [],
2352
- ...!includeInLight ? [
2353
- {
2354
- code: "add-field-light-projection-choice",
2355
- kind: "manual-action",
2356
- target: paths.constant,
2357
- action: `Pass includeInLight=true when users should see ${field} in list/card data. Without it, the field can exist on ${capitalize2(module)}Input but stay absent from Light${capitalize2(module)} projections.`,
2358
- confidence: "medium",
2359
- message: `${module}.${field} is not selected for list/card projection data.`
2360
- }
2361
- ] : [],
2362
- ...includeInLight ? [
2363
- {
2364
- code: "add-field-light-projection",
2365
- kind: "placement",
2366
- target: paths.constant,
2367
- confidence: "high",
2368
- message: `Add ${field} to Light${capitalize2(module)} projection fields.`
2369
- }
2370
- ] : [],
2510
+ includeInLight ? {
2511
+ code: "add-field-light-projection",
2512
+ kind: "placement",
2513
+ target: paths.constant,
2514
+ confidence: "high",
2515
+ message: `Add ${field} to Light${capitalize3(module)} projection fields.`
2516
+ } : {
2517
+ code: "add-field-light-projection-choice",
2518
+ kind: "manual-action",
2519
+ target: paths.constant,
2520
+ action: `Pass includeInLight=true when users should see ${field} in list/card data. Without it, the field can exist on ${capitalize3(module)}Input but stay absent from Light${capitalize3(module)} projections.`,
2521
+ confidence: "medium",
2522
+ message: `${module}.${field} is not selected for list/card projection data.`
2523
+ },
2371
2524
  ...surfaces && !templateRequested ? [
2372
2525
  {
2373
2526
  code: "add-field-ui-surface-skip",
@@ -2382,7 +2535,7 @@ var createAddFieldRecommendations = (inputs) => {
2382
2535
  code: "add-field-ui-manual-review",
2383
2536
  kind: "manual-action",
2384
2537
  target: paths.template,
2385
- action: `After apply, verify what users can see: Template form auto-edit only runs when a generated ${module}Form hook and Layout.Template field list are present. Unit/View cards are not auto-edited, so ${field} may be stored on ${capitalize2(module)} but not shown in list/card UI until you place it in the local card layout.`,
2538
+ action: `After apply, verify what users can see: Template form auto-edit only runs when a generated ${module}Form hook and Layout.Template field list are present. Unit/View cards are not auto-edited, so ${field} may be stored on ${capitalize3(module)} but not shown in list/card UI until you place it in the local card layout.`,
2386
2539
  confidence: "medium",
2387
2540
  message: `${app}:${module}.${field} may need UI review for user-visible Template, Unit, and View behavior.`
2388
2541
  },
@@ -2534,235 +2687,6 @@ var createWorkflowPlan = (spec, rawInputs) => {
2534
2687
  approval: workflowPlanApproval
2535
2688
  };
2536
2689
  };
2537
- // pkgs/@akanjs/devkit/workflow/render.ts
2538
- var renderWorkflowList = (specs) => [
2539
- "# Akan Workflows",
2540
- "",
2541
- ...specs.flatMap((spec) => [`- \`${spec.name}\`: ${spec.description}`, ` - When: ${spec.whenToUse}`]),
2542
- ""
2543
- ].join(`
2544
- `);
2545
- var renderWorkflowExplain = (spec) => [
2546
- `# Workflow: ${spec.name}`,
2547
- "",
2548
- spec.description,
2549
- "",
2550
- "## When To Use",
2551
- spec.whenToUse,
2552
- "",
2553
- "## Inputs",
2554
- ...Object.entries(spec.inputs).map(([name, input]) => `- \`${name}\`${input.required ? " (required)" : ""}: ${input.description}${input.allowedValues ? ` Allowed: ${input.allowedValues.join(", ")}.` : ""}`),
2555
- "",
2556
- "## Optional Surfaces",
2557
- ...Object.entries(spec.optionalSurfaces ?? {}).map(([name, mode]) => `- \`${name}\`: ${mode}`),
2558
- "",
2559
- "## Steps",
2560
- ...spec.steps.map((step, index) => `${index + 1}. \`${step.id}\` (${step.tool}): ${step.description}`),
2561
- "",
2562
- "## Validation",
2563
- ...spec.validation.map((validation) => `- \`${validation.command}\`: ${validation.reason}`),
2564
- ""
2565
- ].join(`
2566
- `);
2567
- var renderWorkflowPlan = (plan) => [
2568
- `# Workflow Plan: ${plan.workflow}`,
2569
- "",
2570
- `- Mode: ${plan.mode}`,
2571
- `- Requires approval: ${plan.requiresApproval}`,
2572
- `- Approval: ${plan.approval?.meaning ?? "Review this read-only plan before applying workflow mutations."}`,
2573
- "",
2574
- "## Inputs",
2575
- ...Object.entries(plan.inputs).map(([name, value]) => `- \`${name}\`: ${Array.isArray(value) ? value.join(", ") : value}`),
2576
- "",
2577
- "## Optional Surfaces",
2578
- ...Object.entries(plan.optionalSurfaces).map(([name, mode]) => `- \`${name}\`: ${mode}`),
2579
- "",
2580
- "## Steps",
2581
- ...plan.steps.map((step, index) => `${index + 1}. \`${step.id}\` (${step.tool}): ${step.description}`),
2582
- "",
2583
- "## Predicted Changes",
2584
- ...plan.predictedChanges.map((change) => {
2585
- const scope = change.applyScope ? ` (${change.applyScope})` : "";
2586
- return `- \`${change.action}\`${scope} ${change.target}: ${change.reason}`;
2587
- }),
2588
- "",
2589
- "## Validation",
2590
- ...plan.validation.map((validation) => `- \`${validation.command}\`: ${validation.reason}`),
2591
- "",
2592
- "## Diagnostics",
2593
- ...plan.diagnostics.length ? plan.diagnostics.map((diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`) : ["- none"],
2594
- "",
2595
- "## Recommendations",
2596
- ...plan.recommendations.length ? plan.recommendations.map((recommendation) => `- [${recommendation.kind}] ${recommendation.message}`) : ["- none"],
2597
- ""
2598
- ].join(`
2599
- `);
2600
- var renderRecommendation = (recommendation) => {
2601
- const target = recommendation.target ? ` ${recommendation.target}` : "";
2602
- const action = recommendation.action ? ` Action: ${recommendation.action}` : "";
2603
- return `- [${recommendation.kind}]${target} ${recommendation.message}${action}`;
2604
- };
2605
- var renderDiagnostic = (diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`;
2606
- var renderNextAction = (action) => `- \`${action.command}\`: ${action.reason}`;
2607
- var applySourceStatus = (report) => report.diagnostics.some((diagnostic) => diagnostic.severity === "error" && (diagnostic.failureScope === "source-change" || !diagnostic.failureScope || diagnostic.failureScope === "unknown")) ? "failed" : "passed";
2608
- var renderWorkflowApplyReport = (report) => {
2609
- const applySummary = {
2610
- sourceFilesChanged: report.summary?.sourceFilesChanged ?? report.changedFiles,
2611
- generatedFilesSynced: report.summary?.generatedFilesSynced ?? report.generatedFiles
2612
- };
2613
- const manualReviewItems = [
2614
- ...report.diagnostics.filter((diagnostic) => diagnostic.severity === "warning").map(renderDiagnostic),
2615
- ...report.recommendations.filter((recommendation) => recommendation.kind === "manual-action").map(renderRecommendation)
2616
- ];
2617
- const validationBlockers = report.diagnostics.filter((diagnostic) => diagnostic.severity === "error" && (diagnostic.failureScope === "workspace-config" || diagnostic.failureScope === "environment")).map(renderDiagnostic);
2618
- const sourceBlockers = report.diagnostics.filter((diagnostic) => diagnostic.severity === "error" && (diagnostic.failureScope === "source-change" || !diagnostic.failureScope || diagnostic.failureScope === "unknown")).map(renderDiagnostic);
2619
- return [
2620
- `# Workflow Apply: ${report.workflow}`,
2621
- "",
2622
- `- Mode: ${report.mode}`,
2623
- `- Status: ${report.status}`,
2624
- `- Source-change status: ${applySourceStatus(report)}`,
2625
- `- Workspace status: ${validationBlockers.length ? "blocked" : "not blocked during apply"}`,
2626
- `- Source files changed: ${applySummary.sourceFilesChanged.length}`,
2627
- `- Generated files queued for sync: ${applySummary.generatedFilesSynced.length}`,
2628
- ...report.validationTarget ? [`- Validation target: ${report.validationTarget}`] : [],
2629
- "",
2630
- "## Apply Checks",
2631
- ...report.postApplyChecks?.length ? report.postApplyChecks.map((check) => `- [${check.status}] ${check.code} ${check.target}: ${check.message}`) : ["- not run"],
2632
- "",
2633
- "## Source Change Blockers",
2634
- ...sourceBlockers.length ? sourceBlockers : ["- none"],
2635
- "",
2636
- "## Automatically Modified",
2637
- ...applySummary.sourceFilesChanged.length ? applySummary.sourceFilesChanged.map((file) => `- \`${file.action}\` ${file.path}: ${file.reason}`) : ["- none"],
2638
- "",
2639
- "## Generated Sync",
2640
- ...applySummary.generatedFilesSynced.length ? applySummary.generatedFilesSynced.map((file) => `- \`${file.action}\` ${file.path}: ${file.reason}`) : ["- none"],
2641
- "",
2642
- "## Applied Commands",
2643
- ...report.appliedCommands.length ? report.appliedCommands.map((command) => `- \`${command.command}\`: ${command.reason}`) : ["- none"],
2644
- "",
2645
- "## Recommended Validation Commands",
2646
- ...report.recommendedValidationCommands.length ? report.recommendedValidationCommands.map((command) => `- \`${command.command}\`: ${command.reason}`) : ["- none"],
2647
- "",
2648
- "## User Review Required",
2649
- ...manualReviewItems.length ? manualReviewItems : ["- none"],
2650
- "",
2651
- "## Validation Blockers",
2652
- ...validationBlockers.length ? validationBlockers : report.recommendedValidationCommands.length ? ["- none detected during apply; run validation with the validation target for command-level blockers."] : ["- none"],
2653
- "",
2654
- "## Diagnostics",
2655
- ...report.diagnostics.length ? report.diagnostics.map(renderDiagnostic) : ["- none"],
2656
- "",
2657
- "## Recommendations",
2658
- ...report.recommendations.length ? report.recommendations.slice(0, 3).map(renderRecommendation) : ["- none"],
2659
- "",
2660
- "## Next Actions",
2661
- ...report.nextActions.length ? report.nextActions.slice(0, 3).map(renderNextAction) : ["- none"],
2662
- ""
2663
- ].join(`
2664
- `);
2665
- };
2666
- var renderWorkflowApply = (report, format = "markdown") => format === "json" ? jsonText(report) : renderWorkflowApplyReport(report);
2667
- var renderWorkflowValidationRunReport = (report) => {
2668
- const baselineSummary = report.baselineSummary ?? {
2669
- status: report.baselineDiagnostics?.some((diagnostic) => diagnostic.severity === "error") ? "failed" : "unknown",
2670
- total: report.baselineDiagnostics?.length ?? 0,
2671
- totalErrors: report.baselineDiagnostics?.filter((diagnostic) => diagnostic.severity === "error").length ?? 0,
2672
- totalWarnings: report.baselineDiagnostics?.filter((diagnostic) => diagnostic.severity === "warning").length ?? 0,
2673
- detailsIncluded: true,
2674
- knownBlockerCount: report.knownBlockers.filter((blocker) => blocker.known).length,
2675
- byCode: []
2676
- };
2677
- return [
2678
- `# Workflow Validation: ${report.workflow}`,
2679
- "",
2680
- `- Run: ${report.runId}`,
2681
- `- Status: ${report.status}`,
2682
- `- Source status: ${report.sourceStatus}`,
2683
- `- Workspace status: ${report.workspaceStatus}`,
2684
- `- Validation commands status: ${report.validationCommandsStatus ?? "unknown"}`,
2685
- `- Baseline status: ${report.baselineStatus ?? baselineSummary.status}`,
2686
- `- Overall status: ${report.overallStatus}`,
2687
- "",
2688
- "## Status Summary",
2689
- `- Source-change: ${report.summary.sourceChange}`,
2690
- `- Generated sync: ${report.summary.generatedSync}`,
2691
- `- Validation commands: ${report.summary.validationCommands ?? "unknown"}`,
2692
- `- Baseline: ${report.summary.baseline ?? baselineSummary.status}`,
2693
- `- Workspace config: ${report.summary.workspaceConfig}`,
2694
- `- Environment: ${report.summary.environment}`,
2695
- "",
2696
- "## Source Change Diagnostics",
2697
- ...report.workflowDiagnostics?.length ? report.workflowDiagnostics.map((diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`) : ["- none"],
2698
- "",
2699
- "## Existing Workspace Blockers",
2700
- `- Status: ${baselineSummary.status}`,
2701
- `- Errors: ${baselineSummary.totalErrors}`,
2702
- `- Warnings: ${baselineSummary.totalWarnings}`,
2703
- ...baselineSummary.byCode.length ? baselineSummary.byCode.map((item) => `- [${item.severity}] ${item.code} (${item.count}x): ${item.sampleMessage}`) : ["- none"],
2704
- ...baselineSummary.detailsIncluded ? [] : [
2705
- "- Baseline details are summarized by default. Re-run validation with includeBaselineDetails=true for full baselineDiagnostics."
2706
- ],
2707
- "",
2708
- "## Existing Workspace Blocker Details",
2709
- ...report.baselineDiagnostics?.length ? report.baselineDiagnostics.map((diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`) : baselineSummary.detailsIncluded ? ["- none"] : ["- omitted"],
2710
- "",
2711
- "## Known Blockers",
2712
- ...report.knownBlockers.length ? report.knownBlockers.map((blocker) => {
2713
- const command = blocker.command ? ` \`${blocker.command}\`` : "";
2714
- const count = blocker.count > 1 ? ` (${blocker.count}x)` : "";
2715
- const known = blocker.known ? " known" : "";
2716
- return `- [${blocker.failureScope}${known}]${command}${count}: ${blocker.message}`;
2717
- }) : ["- none"],
2718
- "",
2719
- "## Commands",
2720
- ...report.commands.length ? report.commands.map((command) => {
2721
- const scope = command.failureScope ? ` (${command.failureScope})` : "";
2722
- return `- [${command.status}] \`${command.command}\`${scope}: ${command.reason}`;
2723
- }) : ["- none"],
2724
- "",
2725
- "## Diagnostics",
2726
- ...report.diagnostics.length ? report.diagnostics.map((diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`) : ["- none"],
2727
- "",
2728
- "## Repair Actions",
2729
- ...report.repairActions.length ? report.repairActions.map((action) => `- \`${action.command}\`: ${action.reason}`) : ["- none"],
2730
- "",
2731
- "## Next Actions",
2732
- ...report.nextActions.length ? report.nextActions.map((action) => `- \`${action.command}\`: ${action.reason}`) : ["- none"],
2733
- ""
2734
- ].join(`
2735
- `);
2736
- };
2737
- var renderWorkflowValidation = (report, format = "markdown") => format === "json" ? jsonText(report) : renderWorkflowValidationRunReport(report);
2738
- var renderRepairReportMarkdown = (report) => [
2739
- `# Akan Repair: ${report.kind}`,
2740
- "",
2741
- `- Status: ${report.status}`,
2742
- `- Target: ${report.target ?? "none"}`,
2743
- "",
2744
- "## Commands",
2745
- ...report.commands.length ? report.commands.map((command) => `- [${command.status}] \`${command.command}\`: ${command.reason}`) : ["- none"],
2746
- "",
2747
- "## Diagnostics",
2748
- ...report.diagnostics.length ? report.diagnostics.map((diagnostic) => `- [${diagnostic.severity}] ${diagnostic.code}: ${diagnostic.message}`) : ["- none"],
2749
- "",
2750
- "## Next Actions",
2751
- ...report.nextActions.length ? report.nextActions.map((action) => `- \`${action.command}\`: ${action.reason}`) : ["- none"],
2752
- ""
2753
- ].join(`
2754
- `);
2755
- var renderRepairReport = (report, format = "markdown") => format === "json" ? jsonText(report) : renderRepairReportMarkdown(report);
2756
- var renderWorkflowRunArtifact = (artifact, format = "markdown") => {
2757
- if ("kind" in artifact)
2758
- return renderRepairReport(artifact, format);
2759
- if ("mode" in artifact && artifact.mode === "validate")
2760
- return renderWorkflowValidation(artifact, format);
2761
- if ("mode" in artifact && (artifact.mode === "apply" || artifact.mode === "dry-run")) {
2762
- return renderWorkflowApply(artifact, format);
2763
- }
2764
- return jsonText(artifact);
2765
- };
2766
2690
  // pkgs/@akanjs/devkit/workflow/rolloutGate.ts
2767
2691
  var toolingRolloutCandidates = [
2768
2692
  {
@@ -2827,4 +2751,4 @@ for (const candidate of toolingRolloutCandidates) {
2827
2751
  if (isRestrictedCandidate(candidate))
2828
2752
  restrictedCandidates.set(candidate.packageName, candidate);
2829
2753
  }
2830
- export { jsonText, compactDiagnostics, workflowPlanApproval, createWorkflowApplyReport, workflowCommandsForPlan, workflowRunArtifactPath, writeWorkflowRunArtifact, workflowSyncDir, generatedFilePathsForTarget, writeGeneratedSyncState, readWorkflowRunArtifact, createWorkflowBaselineSummary, createWorkflowValidationRunReport, createDryRunWorkflowApplyReport, createRepairReport, createPrimitiveWriteReport, renderPrimitiveReport, sourceFile, moduleComponentName, moduleSourcePaths, generatedFilesForSync, validationCommandsForTarget, nextActionsForTarget, createPassedPrimitiveReport, scalarChangedFiles, lowerlize, bilingualLabelForField, bilingualDescriptionForField, normalizeFieldType, ensureNamedImport, ensureBaseImport, ensureBaseTypeImport, coerceFieldDefault, fieldExpression, viaBuilderParameterName, insertIntoObject, insertLightProjectionField, insertTemplateField, ensureEnumImport, insertEnumClass, insertDictionaryModelField, hasConstantInputField, hasDictionaryModelField, ensureConstantTypeImport, insertDictionaryEnum, parseValues, hasSourceParseErrors, hasClassMethod, insertClassMethod, hasSignalFactoryEntry, insertSignalFactoryEntry, buildAkanModuleContextIndex, addFieldUiPolicyForType, createWorkflowStepRegistry, WorkflowExecutor, listWorkflowSpecs, getWorkflowSpec, compactWorkflowInputs, createWorkflowPlan, renderWorkflowList, renderWorkflowExplain, renderWorkflowPlan, renderWorkflowApply, renderWorkflowValidation, renderRepairReport, renderWorkflowRunArtifact, toolingRolloutGate };
2754
+ export { jsonText, workflowStatus, compactDiagnostics, workflowPlanApproval, createWorkflowApplyReport, workflowCommandsForPlan, workflowPathsForPlan, workflowRunArtifactPath, writeWorkflowRunArtifact, workflowSyncDir, generatedFilePathsForTarget, writeGeneratedSyncState, readWorkflowRunArtifact, createWorkflowBaselineSummary, createWorkflowValidationRunReport, createDryRunWorkflowApplyReport, createRepairReport, sourceFile, moduleComponentName, moduleSourcePaths, generatedFilesForSync, validationCommandsForTarget, nextActionsForTarget, createPrimitiveWriteReport, createPassedPrimitiveReport, scalarChangedFiles, bilingualLabelForField, bilingualDescriptionForField, normalizeFieldType, ensureNamedImport, ensureBaseImport, ensureBaseTypeImport, coerceFieldDefault, fieldExpression, viaBuilderParameterName, insertIntoObject, insertLightProjectionField, insertTemplateField, ensureEnumImport, insertEnumClass, insertDictionaryModelField, hasConstantInputField, hasDictionaryModelField, ensureConstantTypeImport, insertDictionaryEnum, parseValues, hasSourceParseErrors, hasClassMethod, insertClassMethod, hasSignalFactoryEntry, insertSignalFactoryEntry, buildAkanModuleContextIndex, addFieldUiPolicyForType, createWorkflowStepRegistry, WorkflowExecutor, listWorkflowSpecs, getWorkflowSpec, compactWorkflowInputs, createWorkflowPlan, renderWorkflowList, renderWorkflowExplain, renderWorkflowPlan, renderWorkflowApply, renderWorkflowValidation, renderRepairReport, renderWorkflowRunArtifact, renderPrimitiveReport, toolingRolloutGate };