@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.
- package/.build-stamp +1 -1
- package/{CodeAgent-6cm97kay.js → CodeAgent-awv258wb.js} +2 -2
- package/{CodeTui-za4jsm41.js → CodeTui-1nqh35ez.js} +20 -22
- package/TunnelShare-scf4e4pd.js +9 -0
- package/{agent.command-e0wpbbyg.js → agent.command-1s9ag7sb.js} +8 -9
- package/akanCode.js +4 -4
- package/{application.command-8wyxqc8q.js → application.command-49hwy6va.js} +25 -56
- package/{applicationBuildRunner-n9gzaxd0.js → applicationBuildRunner-ybyp97pv.js} +33 -59
- package/{applicationReleasePackager-vpggfqgq.js → applicationReleasePackager-esnrphw8.js} +40 -60
- package/buildBatch.proc.js +19 -24
- package/{capacitorApp-q3z0qht0.js → capacitorApp-1synz4en.js} +3 -4
- package/{cloud.command-4zwa5dsx.js → cloud.command-d7rqtzt9.js} +16 -26
- package/cloud.script-bkbpcr96.js +19 -0
- package/{code.command-468c9d7s.js → code.command-nn48xzej.js} +22 -37
- package/context.command-s3mcmvpa.js +48 -0
- package/context.runner-k99nb5pk.js +21 -0
- package/{dependencyScanner-0z2h2tks.js → dependencyScanner-ye2e6pdz.js} +2 -2
- package/{devTui-ffjsarqa.js → devTui-q7k7bakd.js} +5 -9
- package/fileSys-5ngz93ga.js +9 -0
- package/{guideline.command-vhw13pqr.js → guideline.command-sct4qnt5.js} +4 -5
- package/guidelines/conventions/conventions.instruction.md +5 -1
- package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
- package/incrementalBuilder.proc.js +30 -48
- package/{index-s5rhm04y.js → index-0bq14vr1.js} +1 -1
- package/{index-10dkrrww.js → index-13ffe9wp.js} +4 -4
- package/{index-srmay5jw.js → index-22d57v4c.js} +84 -67
- package/{index-53176s7j.js → index-31yr441d.js} +10 -17
- package/index-3hx1z96c.js +87 -0
- package/{index-4m929vvn.js → index-3sq321ak.js} +10 -18
- package/{index-bhtmj233.js → index-3t7g9e4r.js} +41 -78
- package/{index-q0y2jq9j.js → index-5b6tavv3.js} +6 -3
- package/{index-47pj3aee.js → index-5e0n4hqx.js} +11 -12
- package/{index-7ep8qtvp.js → index-5pc1qrbv.js} +5 -8
- package/{index-esk82rvk.js → index-8mna0947.js} +34 -71
- package/{index-sq2dzkzm.js → index-8sf7wmdr.js} +6 -6
- package/{index-crmeqnmf.js → index-9d9bgcx4.js} +283 -722
- package/{index-bwf965h6.js → index-ahemdr5n.js} +6 -6
- package/{index-ab0c38ea.js → index-as7xmyz8.js} +20 -20
- package/{index-bc88j1ry.js → index-axzjaqve.js} +94 -142
- package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
- package/{index-667w0yah.js → index-c6eggbee.js} +2 -5
- package/{index-a1w6934z.js → index-ddxvdd1p.js} +169 -305
- package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
- package/{index-22xtgmhn.js → index-dzf3r49a.js} +1 -1
- package/{index-89hy31kf.js → index-fgq75haa.js} +172 -287
- package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
- package/{index-hwkygn9s.js → index-khpfpcsd.js} +302 -33
- package/{index-vqx8bdxz.js → index-mxav6j3c.js} +78 -231
- package/{index-2446k7b4.js → index-myhc3c1j.js} +512 -588
- package/{index-3jrp517k.js → index-nv5976x3.js} +45 -128
- package/{index-zqgj2rt2.js → index-przybvy5.js} +69 -147
- package/{index-n3cv0tm4.js → index-smme4r47.js} +1 -1
- package/{index-qdgzsnhg.js → index-w2zdcw3k.js} +110 -231
- package/{index-14zrtgfa.js → index-wa5jbxj1.js} +6 -39
- package/{index-bftkz6cp.js → index-ww4z397j.js} +198 -555
- package/{index-kwaq3n9n.js → index-xqjwd384.js} +4 -7
- package/{index-txr7dj2g.js → index-xqpzbab5.js} +106 -240
- package/{index-e4v6vhxq.js → index-xsjh6nzh.js} +178 -165
- package/{index-18zybgkc.js → index-ygn77a5w.js} +47 -99
- package/{index-9d6nvkz2.js → index-ztp3e73t.js} +79 -35
- package/index.js +23 -24
- package/{library.command-cqr175dy.js → library.command-1gx04jgn.js} +4 -5
- package/{localRegistry.command-49z55qqz.js → localRegistry.command-zndxj1q6.js} +21 -42
- package/{module.command-9p8mm3b0.js → module.command-3waddk95.js} +6 -7
- package/{package.command-wxyz909t.js → package.command-zrc7br1y.js} +5 -6
- package/package.json +2 -2
- package/{page.command-gsrsfqqs.js → page.command-vpjgardh.js} +4 -5
- package/{primitive.command-ns1mptje.js → primitive.command-sz84tk4t.js} +9 -20
- package/{prompter-1f8d9pcc.js → prompter-ptaa3nk0.js} +2 -2
- package/{quality.command-e76k2q9k.js → quality.command-g869hafs.js} +129 -363
- package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
- package/{repair.command-pkrsm3cw.js → repair.command-chsnjvvv.js} +11 -35
- package/{scalar.command-0cpt3fc8.js → scalar.command-2v21newx.js} +5 -6
- package/skills/akan-code/SKILL.md +12 -4
- package/{subspace.command-fktpwp0g.js → subspace.command-ckcbwfp1.js} +39 -58
- package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +3 -3
- package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +3 -3
- package/templates/client.ts +7 -30
- package/templates/lib/__lib/lib.dictionary.ts +0 -2
- package/templates/lib/__lib/lib.document.ts +0 -2
- package/templates/lib/sig.ts +8 -30
- package/templates/server.ts +0 -2
- package/{tunnel.command-d5jy9gk8.js → tunnel.command-kd2yr4fx.js} +5 -6
- package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
- package/typecheck.proc.js +1 -1
- package/workflow.command-44252cqv.js +79 -0
- package/{workspace.command-gv84eh1p.js → workspace.command-fqcztt5p.js} +72 -107
- package/TunnelShare-2j6s511d.js +0 -9
- package/cloud.script-fwx3vb34.js +0 -20
- package/context.command-dsnw0jby.js +0 -80
- package/context.runner-rs4rj15d.js +0 -22
- package/devTuiView-1q1mdgrv.js +0 -9
- package/getDirname-dr3jz1xg.js +0 -7
- package/index-6wwzs1bc.js +0 -7
- package/workflow.command-6tkcysmx.js +0 -105
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
AppExecutor,
|
|
4
4
|
LibExecutor
|
|
5
|
-
} from "./index-
|
|
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/
|
|
377
|
-
var
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
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
|
|
623
|
+
...listOr(report.changedFiles, renderFile),
|
|
402
624
|
"",
|
|
403
625
|
"## Generated Files",
|
|
404
|
-
...report.generatedFiles
|
|
626
|
+
...listOr(report.generatedFiles, renderFile),
|
|
405
627
|
"",
|
|
406
628
|
"## Validation Commands",
|
|
407
|
-
...report.validationCommands
|
|
629
|
+
...listOr(report.validationCommands, renderCommand),
|
|
408
630
|
"",
|
|
409
631
|
"## Diagnostics",
|
|
410
|
-
...report.diagnostics
|
|
632
|
+
...listOr(report.diagnostics, renderDiagnostic),
|
|
411
633
|
"",
|
|
412
634
|
"## Next Actions",
|
|
413
|
-
...report.nextActions
|
|
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
|
|
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
|
|
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 (!
|
|
766
|
-
|
|
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) =>
|
|
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
|
-
|
|
1020
|
+
ts2.forEachChild(source, visit);
|
|
776
1021
|
return locator;
|
|
777
1022
|
};
|
|
778
1023
|
var chainMethodsForCall = (node) => {
|
|
779
|
-
if (
|
|
1024
|
+
if (ts2.isAsExpression(node) || ts2.isParenthesizedExpression(node))
|
|
780
1025
|
return chainMethodsForCall(node.expression);
|
|
781
|
-
if (!
|
|
1026
|
+
if (!ts2.isCallExpression(node))
|
|
782
1027
|
return [];
|
|
783
|
-
if (
|
|
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 (
|
|
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 (!
|
|
816
|
-
|
|
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
|
-
|
|
1066
|
+
ts2.forEachChild(node, visit);
|
|
822
1067
|
return;
|
|
823
1068
|
}
|
|
824
|
-
const callback = node.arguments.find((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
|
-
|
|
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 (!
|
|
842
|
-
|
|
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 =
|
|
848
|
-
return
|
|
1092
|
+
const expression = ts2.isAsExpression(arg) ? arg.expression : arg;
|
|
1093
|
+
return ts2.isArrayLiteralExpression(expression);
|
|
849
1094
|
});
|
|
850
|
-
const arrayLiteral = projectionArg ?
|
|
851
|
-
if (!projectionArg || !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) =>
|
|
1101
|
+
fields: arrayLiteral.elements.map((element) => ts2.isStringLiteralLike(element) ? element.text : null).filter((field) => field !== null)
|
|
857
1102
|
};
|
|
858
1103
|
};
|
|
859
|
-
|
|
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 (!
|
|
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 || !
|
|
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 (!
|
|
1125
|
+
if (!ts2.isPropertyAssignment(property))
|
|
881
1126
|
return null;
|
|
882
|
-
const initializer =
|
|
883
|
-
if (!
|
|
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 =
|
|
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 (!
|
|
940
|
-
|
|
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) =>
|
|
945
|
-
if (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
|
-
|
|
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 (!
|
|
961
|
-
|
|
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) =>
|
|
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
|
-
|
|
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 (
|
|
1378
|
+
if (ts2.isClassDeclaration(node) && node.name?.text === className) {
|
|
1134
1379
|
found = node;
|
|
1135
1380
|
return;
|
|
1136
1381
|
}
|
|
1137
|
-
|
|
1382
|
+
ts2.forEachChild(node, visit);
|
|
1138
1383
|
};
|
|
1139
|
-
|
|
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 &&
|
|
1389
|
+
return expression && ts2.isCallExpression(expression) ? expression : null;
|
|
1145
1390
|
};
|
|
1146
1391
|
var factoryArrowOf = (call) => {
|
|
1147
|
-
const arg = call.arguments.find((argument) =>
|
|
1148
|
-
return arg && (
|
|
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) =>
|
|
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 (!
|
|
1440
|
+
if (!ts2.isObjectBindingPattern(param.name))
|
|
1196
1441
|
return null;
|
|
1197
|
-
const names = param.name.elements.map((element) =>
|
|
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}: ${
|
|
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 (
|
|
1537
|
+
if (ts3.isAsExpression(expression))
|
|
1313
1538
|
return expressionSummary(expression.expression);
|
|
1314
|
-
if (
|
|
1315
|
-
return
|
|
1316
|
-
if (
|
|
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 (
|
|
1543
|
+
if (ts3.isObjectLiteralExpression(expression))
|
|
1319
1544
|
return "object-literal";
|
|
1320
|
-
if (
|
|
1545
|
+
if (ts3.isStringLiteralLike(expression))
|
|
1321
1546
|
return "string-literal";
|
|
1322
|
-
if (
|
|
1547
|
+
if (ts3.isNumericLiteral(expression))
|
|
1323
1548
|
return "numeric-literal";
|
|
1324
|
-
if (expression.kind ===
|
|
1549
|
+
if (expression.kind === ts3.SyntaxKind.TrueKeyword || expression.kind === ts3.SyntaxKind.FalseKeyword) {
|
|
1325
1550
|
return "boolean-literal";
|
|
1326
1551
|
}
|
|
1327
|
-
if (
|
|
1328
|
-
const callee =
|
|
1552
|
+
if (ts3.isCallExpression(expression)) {
|
|
1553
|
+
const callee = expressionName(expression.expression);
|
|
1329
1554
|
return callee ? `${callee}(...)` : "call-expression";
|
|
1330
1555
|
}
|
|
1331
|
-
return
|
|
1556
|
+
return ts3.SyntaxKind[expression.kind] ?? "expression";
|
|
1332
1557
|
};
|
|
1333
1558
|
var typeSummaryForInitializer = (initializer) => {
|
|
1334
1559
|
if (!initializer)
|
|
1335
1560
|
return;
|
|
1336
|
-
const expression =
|
|
1337
|
-
if (!
|
|
1561
|
+
const expression = ts3.isAsExpression(initializer) ? initializer.expression : initializer;
|
|
1562
|
+
if (!ts3.isCallExpression(expression))
|
|
1338
1563
|
return expressionSummary(expression);
|
|
1339
|
-
const callee =
|
|
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 =
|
|
1570
|
+
const name = propertyName(property);
|
|
1346
1571
|
if (!name)
|
|
1347
1572
|
return null;
|
|
1348
|
-
const initializer =
|
|
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 =
|
|
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 (!
|
|
1393
|
-
|
|
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 =
|
|
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) =>
|
|
1404
|
-
if (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 =
|
|
1407
|
-
const objectLiteral =
|
|
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 =
|
|
1419
|
-
return
|
|
1620
|
+
const expression = ts3.isAsExpression(arg) ? arg.expression : arg;
|
|
1621
|
+
return ts3.isArrayLiteralExpression(expression);
|
|
1420
1622
|
});
|
|
1421
|
-
const arrayLiteral = projectionArg ?
|
|
1422
|
-
if (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) =>
|
|
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
|
-
|
|
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 =
|
|
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 || !
|
|
1487
|
-
|
|
1687
|
+
if (modelFound || !ts3.isCallExpression(node)) {
|
|
1688
|
+
ts3.forEachChild(node, visit);
|
|
1488
1689
|
return;
|
|
1489
1690
|
}
|
|
1490
|
-
if (
|
|
1491
|
-
|
|
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
|
-
|
|
1697
|
+
ts3.forEachChild(node, visit);
|
|
1497
1698
|
return;
|
|
1498
1699
|
}
|
|
1499
1700
|
modelFound = true;
|
|
1500
|
-
const callback = node.arguments.find((arg) =>
|
|
1501
|
-
if (!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 =
|
|
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:
|
|
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
|
-
|
|
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
|
|
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
|
|
1901
|
+
return ts4.ScriptKind.TSX;
|
|
1708
1902
|
if (filePath.endsWith(".ts"))
|
|
1709
|
-
return
|
|
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 =
|
|
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}: ${
|
|
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
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
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
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
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
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
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
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
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
|
|
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
|
|
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 ${
|
|
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
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
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 ${
|
|
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,
|
|
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 };
|