@akanjs/cli 3.0.0-beta.9 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.build-stamp +1 -1
- package/CodeAgent-zfab7pkn.js +9 -0
- package/CodeAgentRpcHost-p7h6n2hp.js +7 -0
- package/CodeAgentRpcListener-7p7z5dd7.js +97 -0
- package/CodeTui-0zhnr0pw.js +1457 -0
- package/README.ko.md +83 -28
- package/README.md +70 -27
- package/TunnelShare-cwh9ezsm.js +9 -0
- package/{agent.command-0q17pnrs.js → agent.command-aja6z9mn.js} +8 -9
- package/akanCode.js +102 -0
- package/application.command-049ehgx3.js +246 -0
- package/{applicationBuildRunner-kxwbssgn.js → applicationBuildRunner-75n5rpwp.js} +121 -77
- package/buildBatch.proc.js +120 -32
- package/cloud.command-gw4kqxt8.js +95 -0
- package/cloud.script-c723cpcb.js +20 -0
- package/code.command-x9t6z5nw.js +154 -0
- package/commandManifest.json +1 -1
- package/consoleToStderr-h5bryj94.js +7 -0
- package/context.command-yfbe1rtd.js +48 -0
- package/context.runner-erfe68j5.js +21 -0
- package/{dependencyScanner-shs82ynp.js → dependencyScanner-06z2dmrr.js} +2 -2
- package/{devTui-m1atgkc9.js → devTui-q7k7bakd.js} +122 -40
- package/fileSys-wzzrntkw.js +9 -0
- package/guideline.command-kq9gp690.js +42 -0
- package/guidelines/agentRule/agentRule.instruction.md +154 -26
- package/guidelines/conventions/conventions.instruction.md +138 -48
- package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
- package/guidelines/queryRule/queryRule.instruction.md +21 -7
- package/guidelines/runtimeRule/runtimeRule.instruction.md +291 -6
- package/guidelines/ssrRule/ssrRule.instruction.md +4 -2
- package/guidelines/transportRule/transportRule.instruction.md +10 -8
- package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +20 -0
- package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +66 -3
- package/incrementalBuilder.proc.js +564 -109
- package/{index-2tv3fdx4.js → index-150s07n8.js} +1230 -1459
- package/{index-vyvre9en.js → index-25fvrxmy.js} +6 -2
- package/{index-kcxmv48c.js → index-2ahj896a.js} +45 -79
- package/index-2wc41k5w.js +49 -0
- package/index-3hx1z96c.js +87 -0
- package/{index-q0y2jq9j.js → index-52w0fvh8.js} +21 -4
- package/{index-04bk599g.js → index-5g4rkrvt.js} +10 -17
- package/index-5pvxf7z0.js +53 -0
- package/index-5q14pwzd.js +69 -0
- package/{index-vxtad5bd.js → index-66yspb67.js} +5 -8
- package/index-7md2g9vw.js +6 -0
- package/index-7p4c0yer.js +1058 -0
- package/{index-d43r08tf.js → index-8b639zes.js} +77 -150
- package/{index-ktb5njgy.js → index-8kvy8qb4.js} +49 -99
- package/index-94s080qm.js +266 -0
- package/index-9dp031by.js +12 -0
- package/{index-0g7r8xz3.js → index-a37by9hn.js} +114 -232
- package/{index-k2j1hc4r.js → index-b95yhqjr.js} +12 -12
- package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
- package/{index-2xp0kfkt.js → index-br8pkrk1.js} +37 -25
- package/index-c14nsvnv.js +700 -0
- package/index-c6eggbee.js +123 -0
- package/index-d2242ksy.js +99 -0
- package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
- package/{index-a64esmtb.js → index-fkvb79qe.js} +523 -1022
- package/index-h54yj9wr.js +1119 -0
- package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
- package/{index-y6n8nmny.js → index-kn5d4jmg.js} +75 -203
- package/index-m3xsb1ms.js +4300 -0
- package/{index-gyd220p2.js → index-mb59b8x0.js} +554 -577
- package/{index-j9yhg404.js → index-mzjb6zp4.js} +4 -7
- package/index-p6pbz9n5.js +25 -0
- package/{index-sj5vxr8f.js → index-qe71g4ze.js} +983 -898
- package/index-rfcz04w9.js +187 -0
- package/{index-hwkygn9s.js → index-senscydg.js} +331 -36
- package/{index-ffvk10zz.js → index-vs8mefhy.js} +107 -241
- package/index-wa5jbxj1.js +760 -0
- package/index-y5ga5w9t.js +2729 -0
- package/{index-9077wzd2.js → index-y7hx1ygz.js} +43 -26
- package/{index-h7yw2z9n.js → index-zzvvc845.js} +8 -14
- package/index.js +23 -22
- package/{library.command-qzzbj6d8.js → library.command-keqjevpp.js} +4 -5
- package/{localRegistry.command-vyrgg4xw.js → localRegistry.command-pydeq5zf.js} +23 -43
- package/{module.command-rq5hq3ax.js → module.command-dkrnqx3v.js} +8 -12
- package/{package.command-d9hd6v9n.js → package.command-wmc0ys5y.js} +6 -7
- package/package.json +15 -7
- package/{page.command-126d56te.js → page.command-tf3erhrv.js} +4 -5
- package/{primitive.command-taxd1538.js → primitive.command-7hqpegj4.js} +9 -23
- package/prompter-76k56b37.js +8 -0
- package/{quality.command-6gsna0a3.js → quality.command-8122axq3.js} +205 -377
- package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
- package/{repair.command-tq2dgy72.js → repair.command-mcy12h0n.js} +11 -35
- package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
- package/{scalar.command-3bcmrrkv.js → scalar.command-vvvbzttc.js} +7 -11
- package/skills/akan-code/SKILL.md +130 -0
- package/skills/akan-debug/SKILL.md +42 -0
- package/skills/akan-deps/SKILL.md +50 -0
- package/skills/akan-err/SKILL.md +39 -0
- package/skills/akan-module/SKILL.md +45 -0
- package/skills/akan-scaffold/SKILL.md +76 -0
- package/skills/akan-scalar/SKILL.md +52 -0
- package/skills/akan-service/SKILL.md +34 -0
- package/skills/akan-store/SKILL.md +67 -0
- package/skills/akan-ui/SKILL.md +63 -0
- package/skills/akan-validate/SKILL.md +44 -0
- package/{subspace.command-eddzqpx3.js → subspace.command-pzvqfy5h.js} +53 -62
- package/templates/__scalar/__model__/__model__.abstract.md.template +8 -0
- package/templates/app/page/_index.tsx +257 -258
- package/templates/app/page/_layout.tsx +5 -1
- package/templates/app/page/_overrides.tsx +12 -0
- package/templates/app/page/styles.css.template +316 -14
- package/templates/app/public/apple-touch-icon.png +0 -0
- package/templates/app/public/favicon.ico +0 -0
- package/templates/app/public/jelly/cloud.webp +0 -0
- package/templates/app/public/jelly/comet.webp +0 -0
- package/templates/app/public/jelly/moon.webp +0 -0
- package/templates/app/public/jelly/planet.webp +0 -0
- package/templates/app/public/jelly/rocket.webp +0 -0
- package/templates/app/public/jelly/star.webp +0 -0
- package/templates/app/public/jelly/sugar.webp +0 -0
- package/templates/app/public/logo.png +0 -0
- package/templates/app/ui/Recipe/index.ts +9 -0
- package/templates/app/ui/Recipe/jellyButton.ts +63 -0
- package/templates/appSample/lib/__scalar/workHistory/workHistory.abstract.ts +8 -39
- package/templates/appSample/lib/_noti/noti.abstract.ts +6 -29
- package/templates/appSample/lib/task/Task.Unit.tsx +1 -1
- package/templates/appSample/lib/task/Task.Util.tsx +10 -13
- package/templates/appSample/lib/task/Task.View.tsx +2 -2
- package/templates/appSample/lib/task/Task.Zone.tsx +5 -2
- package/templates/appSample/lib/task/task.abstract.ts +12 -32
- package/templates/appSample/lib/task/task.signal.spec.ts +1 -15
- package/templates/appSample/lib/task/task.signal.test.ts +15 -1
- package/templates/appSample/lib/task/task.signal.ts +10 -8
- package/templates/appSample/page/task/[taskId]/_index.tsx +6 -6
- package/templates/appSample/page/task/[taskId]/edit.tsx +5 -4
- package/templates/appSample/page/task/_index.tsx +4 -3
- package/templates/appSample/page/task/_layout.tsx +1 -1
- package/templates/appSample/page/task/new.tsx +5 -4
- package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +7 -4
- package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +6 -4
- package/templates/appSample/ui/GlobalLoading.tsx +2 -1
- package/templates/appSample/ui/QuantityControl.tsx +3 -3
- package/templates/client.ts +7 -30
- package/templates/crudPages/[__model__Id]/edit/page.tsx +2 -1
- package/templates/crudPages/[__model__Id]/page.tsx +2 -1
- package/templates/crudPages/new/page.tsx +2 -1
- package/templates/crudPages/page.tsx +2 -1
- package/templates/crudSinglePage/page.tsx +2 -1
- 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/localDev/docker-compose.yaml.template +3 -14
- package/templates/module/__model__.signal.ts +12 -4
- package/templates/pkgRoot/tsconfig.json.template +2 -7
- package/templates/server.ts +1 -3
- package/templates/service/__model__.abstract.md.template +8 -0
- package/templates/workspaceRoot/.gitignore.template +0 -1
- package/templates/workspaceRoot/AGENTS.md.template +6 -0
- package/templates/workspaceRoot/package.json.template +1 -3
- package/tunnel.command-82zz5xnq.js +129 -0
- package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
- package/typecheck.proc.js +1 -1
- package/workflow.command-y8x3kgjv.js +79 -0
- package/{workspace.command-06wvstgr.js → workspace.command-jvsb7brc.js} +79 -109
- package/abstractCompactor-gmkc0z8j.js +0 -102
- package/application.command-18y0s485.js +0 -204
- package/applicationReleasePackager-4yasxwv9.js +0 -244
- package/capacitorApp-36rbr858.js +0 -12
- package/cloud.command-av97ndh6.js +0 -94
- package/cloud.script-cm11xjdz.js +0 -20
- package/context.command-5v37ef3n.js +0 -81
- package/devTuiView-0hc2emhe.js +0 -9
- package/getDirname-dr3jz1xg.js +0 -7
- package/guideline.command-4pz9g1rt.js +0 -360
- package/guidelines/agentRule/agentRule.generate.json +0 -31
- package/guidelines/componentRule/componentRule.generate.json +0 -31
- package/guidelines/conventions/conventions.generate.json +0 -25
- package/guidelines/cssRule/cssRule.generate.json +0 -31
- package/guidelines/docPageRule/docPageRule.generate.json +0 -31
- package/guidelines/docPageRule/docPageRule.instruction.md +0 -25
- package/guidelines/docSyncRule/docSyncRule.generate.json +0 -31
- package/guidelines/docSyncRule/docSyncRule.instruction.md +0 -25
- package/guidelines/enumConstant/enumConstant.generate.json +0 -31
- package/guidelines/enumConstant/enumConstant.instruction.md +0 -28
- package/guidelines/fieldRule/fieldRule.generate.json +0 -31
- package/guidelines/framework/framework.generate.json +0 -32
- package/guidelines/mcpRule/mcpRule.generate.json +0 -35
- package/guidelines/modelConstant/modelConstant.generate.json +0 -32
- package/guidelines/modelDictionary/modelDictionary.generate.json +0 -32
- package/guidelines/modelDocument/modelDocument.generate.json +0 -31
- package/guidelines/modelService/modelService.generate.json +0 -31
- package/guidelines/modelSignal/modelSignal.generate.json +0 -31
- package/guidelines/modelStore/modelStore.generate.json +0 -31
- package/guidelines/modelTemplate/modelTemplate.generate.json +0 -31
- package/guidelines/modelUnit/modelUnit.generate.json +0 -31
- package/guidelines/modelUtil/modelUtil.generate.json +0 -31
- package/guidelines/modelView/modelView.generate.json +0 -31
- package/guidelines/modelZone/modelZone.generate.json +0 -31
- package/guidelines/moduleCodegen/moduleCodegen.generate.json +0 -31
- package/guidelines/moduleCodegen/moduleCodegen.instruction.md +0 -28
- package/guidelines/moduleOverview/moduleOverview.generate.json +0 -31
- package/guidelines/queryRule/queryRule.generate.json +0 -31
- package/guidelines/recipeRule/recipeRule.generate.json +0 -31
- package/guidelines/runtimeRule/runtimeRule.generate.json +0 -25
- package/guidelines/scalarConstant/scalarConstant.generate.json +0 -32
- package/guidelines/scalarDictionary/scalarDictionary.generate.json +0 -32
- package/guidelines/scalarModule/scalarModule.generate.json +0 -31
- package/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -31
- package/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +0 -25
- package/guidelines/ssrRule/ssrRule.generate.json +0 -31
- package/guidelines/transportRule/transportRule.generate.json +0 -31
- package/guidelines/utilUiUsage/utilUiUsage.generate.json +0 -31
- package/guidelines/utilUiUsage/utilUiUsage.instruction.md +0 -25
- package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +0 -24
- package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +0 -33
- package/index-47pj3aee.js +0 -76
- package/index-5ystnsd5.js +0 -841
- package/index-6wwzs1bc.js +0 -7
- package/index-a17x49vg.js +0 -229
- package/index-m0xccmmm.js +0 -228
- package/index-meh558jy.js +0 -65
- package/index-rtxxan88.js +0 -471
- package/index-te54x9zm.js +0 -338
- package/index-w8kmx1b6.js +0 -2176
- package/index-wt7qrtd4.js +0 -1516
- package/templates/__scalar/__model__/__model__.abstract.md +0 -28
- package/templates/module/__model__.abstract.md +0 -28
- package/templates/service/__model__.abstract.md +0 -28
- package/templates/workspaceRoot/patches/react-dom@19.2.7.patch.template +0 -62
- package/workflow.command-gtdnzvbz.js +0 -108
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
script
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-a37by9hn.js";
|
|
5
5
|
import {
|
|
6
6
|
AppExecutor,
|
|
7
7
|
LibExecutor,
|
|
8
8
|
ModuleExecutor
|
|
9
|
-
} from "./index-
|
|
9
|
+
} from "./index-150s07n8.js";
|
|
10
10
|
import {
|
|
11
|
+
workflowStatus,
|
|
11
12
|
compactDiagnostics,
|
|
12
|
-
createPrimitiveWriteReport,
|
|
13
13
|
sourceFile,
|
|
14
14
|
moduleComponentName,
|
|
15
15
|
moduleSourcePaths,
|
|
16
16
|
generatedFilesForSync,
|
|
17
17
|
validationCommandsForTarget,
|
|
18
18
|
nextActionsForTarget,
|
|
19
|
-
|
|
19
|
+
createPrimitiveWriteReport,
|
|
20
20
|
normalizeFieldType,
|
|
21
|
+
ensureNamedImport,
|
|
22
|
+
ensureBaseImport,
|
|
21
23
|
ensureBaseTypeImport,
|
|
22
24
|
coerceFieldDefault,
|
|
23
25
|
fieldExpression,
|
|
@@ -39,13 +41,13 @@ import {
|
|
|
39
41
|
hasSignalFactoryEntry,
|
|
40
42
|
insertSignalFactoryEntry,
|
|
41
43
|
addFieldUiPolicyForType
|
|
42
|
-
} from "./index-
|
|
44
|
+
} from "./index-mb59b8x0.js";
|
|
43
45
|
import {
|
|
44
46
|
ModuleScript
|
|
45
|
-
} from "./index-
|
|
47
|
+
} from "./index-rfcz04w9.js";
|
|
46
48
|
|
|
47
49
|
// pkgs/@akanjs/cli/primitive/primitive.script.ts
|
|
48
|
-
import { capitalize } from "akanjs/common";
|
|
50
|
+
import { capitalize, lowerlize } from "akanjs/common";
|
|
49
51
|
class PrimitiveScript extends script("primitive", [ModuleScript]) {
|
|
50
52
|
async resolveSys(workspace, target) {
|
|
51
53
|
if (!target)
|
|
@@ -59,28 +61,11 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
|
|
|
59
61
|
}
|
|
60
62
|
async createUi(workspace, input) {
|
|
61
63
|
const sys = await this.resolveSys(workspace, input.app);
|
|
62
|
-
if (!sys || !input.module)
|
|
63
|
-
return
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
validationCommands: [],
|
|
68
|
-
diagnostics: compactDiagnostics([
|
|
69
|
-
!sys && {
|
|
70
|
-
severity: "error",
|
|
71
|
-
code: "primitive-target-missing",
|
|
72
|
-
message: "Target app or library was not found."
|
|
73
|
-
},
|
|
74
|
-
!input.module && {
|
|
75
|
-
severity: "error",
|
|
76
|
-
code: "primitive-input-missing",
|
|
77
|
-
message: "Module is required.",
|
|
78
|
-
input: "module"
|
|
79
|
-
}
|
|
80
|
-
]),
|
|
81
|
-
nextActions: []
|
|
82
|
-
});
|
|
83
|
-
}
|
|
64
|
+
if (!sys || !input.module)
|
|
65
|
+
return PrimitiveScript.#refuse("create-ui", compactDiagnostics([
|
|
66
|
+
!sys && PrimitiveScript.#targetMissing(),
|
|
67
|
+
!input.module && PrimitiveScript.#inputMissing("module")
|
|
68
|
+
]));
|
|
84
69
|
const mod = ModuleExecutor.from(sys, input.module);
|
|
85
70
|
if (input.surface === "view")
|
|
86
71
|
return await this.moduleScript.createView(mod);
|
|
@@ -96,30 +81,16 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
|
|
|
96
81
|
return await this.addFieldToSources(workspace, { ...input, type: `${capitalize(input.field ?? "")}` }, { enumValues: values });
|
|
97
82
|
}
|
|
98
83
|
async addFieldToSources(workspace, input, { enumValues }) {
|
|
84
|
+
const command = enumValues ? "add-enum-field" : "add-field";
|
|
99
85
|
const sys = await this.resolveSys(workspace, input.app);
|
|
100
86
|
const ambiguousNumberTypes = new Set(["number", "numeric"]);
|
|
101
87
|
const normalizedType = input.type ? normalizeFieldType(input.type) : null;
|
|
102
88
|
const diagnostics = compactDiagnostics([
|
|
103
|
-
!sys &&
|
|
104
|
-
!input.module &&
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
input: "module"
|
|
109
|
-
},
|
|
110
|
-
!input.field && {
|
|
111
|
-
severity: "error",
|
|
112
|
-
code: "primitive-input-missing",
|
|
113
|
-
message: "Field is required.",
|
|
114
|
-
input: "field"
|
|
115
|
-
},
|
|
116
|
-
!input.type && {
|
|
117
|
-
severity: "error",
|
|
118
|
-
code: "primitive-input-missing",
|
|
119
|
-
message: "Type is required.",
|
|
120
|
-
input: "type"
|
|
121
|
-
},
|
|
122
|
-
enumValues && enumValues.length === 0 ? { severity: "error", code: "primitive-input-missing", message: "Enum values are required.", input: "values" } : null,
|
|
89
|
+
!sys && PrimitiveScript.#targetMissing(),
|
|
90
|
+
!input.module && PrimitiveScript.#inputMissing("module"),
|
|
91
|
+
!input.field && PrimitiveScript.#inputMissing("field"),
|
|
92
|
+
!input.type && PrimitiveScript.#inputMissing("type"),
|
|
93
|
+
enumValues?.length === 0 && PrimitiveScript.#inputMissing("values", "Enum values are required."),
|
|
123
94
|
input.type && ambiguousNumberTypes.has(input.type.toLowerCase()) ? {
|
|
124
95
|
severity: "error",
|
|
125
96
|
code: "primitive-field-type-unsupported",
|
|
@@ -133,16 +104,8 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
|
|
|
133
104
|
input: "type"
|
|
134
105
|
} : null
|
|
135
106
|
]);
|
|
136
|
-
if (!sys || !input.module || !input.field || !input.type || diagnostics
|
|
137
|
-
return
|
|
138
|
-
command: enumValues ? "add-enum-field" : "add-field",
|
|
139
|
-
changedFiles: [],
|
|
140
|
-
generatedFiles: [],
|
|
141
|
-
validationCommands: [],
|
|
142
|
-
diagnostics,
|
|
143
|
-
nextActions: []
|
|
144
|
-
});
|
|
145
|
-
}
|
|
107
|
+
if (!sys || !input.module || !input.field || !input.type || workflowStatus(diagnostics) === "failed")
|
|
108
|
+
return PrimitiveScript.#refuse(command, diagnostics);
|
|
146
109
|
const moduleClassName = moduleComponentName(input.module);
|
|
147
110
|
const inputClassName = `${moduleClassName}Input`;
|
|
148
111
|
const paths = moduleSourcePaths(input.module);
|
|
@@ -150,32 +113,13 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
|
|
|
150
113
|
const dictionaryPath = paths.dictionary;
|
|
151
114
|
const templatePath = paths.template;
|
|
152
115
|
const changedFiles = [];
|
|
153
|
-
const generatedFiles = generatedFilesForSync(sys);
|
|
154
116
|
const [hasConstant, hasDictionary] = await Promise.all([sys.exists(constantPath), sys.exists(dictionaryPath)]);
|
|
155
|
-
if (!hasConstant)
|
|
156
|
-
diagnostics.push(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
if (!hasDictionary) {
|
|
163
|
-
diagnostics.push({
|
|
164
|
-
severity: "error",
|
|
165
|
-
code: "primitive-source-missing",
|
|
166
|
-
message: `Dictionary source file was not found: ${dictionaryPath}.`
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
if (diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
|
|
170
|
-
return createPrimitiveWriteReport({
|
|
171
|
-
command: enumValues ? "add-enum-field" : "add-field",
|
|
172
|
-
changedFiles,
|
|
173
|
-
generatedFiles,
|
|
174
|
-
validationCommands: validationCommandsForTarget(sys.name),
|
|
175
|
-
diagnostics,
|
|
176
|
-
nextActions: nextActionsForTarget(sys.name)
|
|
177
|
-
});
|
|
178
|
-
}
|
|
117
|
+
if (!hasConstant)
|
|
118
|
+
diagnostics.push(PrimitiveScript.#sourceMissing("Constant", constantPath));
|
|
119
|
+
if (!hasDictionary)
|
|
120
|
+
diagnostics.push(PrimitiveScript.#sourceMissing("Dictionary", dictionaryPath));
|
|
121
|
+
if (workflowStatus(diagnostics) === "failed")
|
|
122
|
+
return PrimitiveScript.#report(command, sys, changedFiles, diagnostics);
|
|
179
123
|
let constantContent = await sys.readFile(constantPath);
|
|
180
124
|
let dictionaryContent = await sys.readFile(dictionaryPath);
|
|
181
125
|
const fieldBuilderName = viaBuilderParameterName(constantContent, inputClassName) ?? "field";
|
|
@@ -210,6 +154,8 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
|
|
|
210
154
|
if (defaultCoercion.diagnostic)
|
|
211
155
|
diagnostics.push(defaultCoercion.diagnostic);
|
|
212
156
|
constantContent = ensureBaseTypeImport(constantContent, input.type);
|
|
157
|
+
if (input.type === "Date" && defaultCoercion.expression)
|
|
158
|
+
constantContent = ensureBaseImport(constantContent, "dayjs");
|
|
213
159
|
}
|
|
214
160
|
if (enumValues) {
|
|
215
161
|
const defaultCoercion = coerceFieldDefault("enum", input.defaultValue, { enumValues });
|
|
@@ -311,7 +257,7 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
|
|
|
311
257
|
}
|
|
312
258
|
}
|
|
313
259
|
}
|
|
314
|
-
if (
|
|
260
|
+
if (workflowStatus(diagnostics) === "passed" && nextConstantContentWithLight && nextDictionaryContent) {
|
|
315
261
|
await sys.writeFile(constantPath, nextConstantContentWithLight);
|
|
316
262
|
await sys.writeFile(dictionaryPath, nextDictionaryContent);
|
|
317
263
|
changedFiles.push(sourceFile(sys, constantPath, "modify", "Field source shape was updated."), sourceFile(sys, dictionaryPath, "modify", "Field dictionary labels were updated."));
|
|
@@ -320,14 +266,7 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
|
|
|
320
266
|
changedFiles.push(sourceFile(sys, templatePath, "modify", "Template field surface was updated."));
|
|
321
267
|
}
|
|
322
268
|
}
|
|
323
|
-
return
|
|
324
|
-
command: enumValues ? "add-enum-field" : "add-field",
|
|
325
|
-
changedFiles,
|
|
326
|
-
generatedFiles,
|
|
327
|
-
validationCommands: validationCommandsForTarget(sys.name),
|
|
328
|
-
diagnostics,
|
|
329
|
-
nextActions: nextActionsForTarget(sys.name)
|
|
330
|
-
});
|
|
269
|
+
return PrimitiveScript.#report(command, sys, changedFiles, diagnostics);
|
|
331
270
|
}
|
|
332
271
|
async addMutation(workspace, input) {
|
|
333
272
|
const moduleClassName = input.module ? moduleComponentName(input.module) : "";
|
|
@@ -353,7 +292,7 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
|
|
|
353
292
|
signal: name ? {
|
|
354
293
|
className: `${moduleClassName}Endpoint`,
|
|
355
294
|
entryLine: [
|
|
356
|
-
`${name}: mutation(Boolean)`,
|
|
295
|
+
`${name}: mutation(Boolean, { guards: [None] })`,
|
|
357
296
|
` .exec(async function () {`,
|
|
358
297
|
` return await this.${serviceRef}Service.${name}();`,
|
|
359
298
|
` }),`
|
|
@@ -388,7 +327,7 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
|
|
|
388
327
|
signal: name && queryName ? {
|
|
389
328
|
className: `${moduleClassName}Slice`,
|
|
390
329
|
entryLine: [
|
|
391
|
-
`${name}: init()`,
|
|
330
|
+
`${name}: init({ guards: [None] })`,
|
|
392
331
|
` .exec(function () {`,
|
|
393
332
|
` return this.${serviceRef}Service.${queryName}();`,
|
|
394
333
|
` }),`
|
|
@@ -401,60 +340,21 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
|
|
|
401
340
|
async#writeServiceSignalEntry(workspace, spec) {
|
|
402
341
|
const sys = await this.resolveSys(workspace, spec.app);
|
|
403
342
|
const diagnostics = compactDiagnostics([
|
|
404
|
-
!sys &&
|
|
405
|
-
!spec.module &&
|
|
406
|
-
|
|
407
|
-
code: "primitive-input-missing",
|
|
408
|
-
message: "Module is required.",
|
|
409
|
-
input: "module"
|
|
410
|
-
},
|
|
411
|
-
!spec.entryName && {
|
|
412
|
-
severity: "error",
|
|
413
|
-
code: "primitive-input-missing",
|
|
414
|
-
message: `${capitalize(spec.requiredInput)} name is required.`,
|
|
415
|
-
input: spec.requiredInput
|
|
416
|
-
}
|
|
343
|
+
!sys && PrimitiveScript.#targetMissing(),
|
|
344
|
+
!spec.module && PrimitiveScript.#inputMissing("module"),
|
|
345
|
+
!spec.entryName && PrimitiveScript.#inputMissing(spec.requiredInput, `${capitalize(spec.requiredInput)} name is required.`)
|
|
417
346
|
]);
|
|
418
|
-
if (!sys || !spec.module || !spec.entryName || !spec.serviceMethod || !spec.signal)
|
|
419
|
-
return
|
|
420
|
-
|
|
421
|
-
changedFiles: [],
|
|
422
|
-
generatedFiles: [],
|
|
423
|
-
validationCommands: [],
|
|
424
|
-
diagnostics,
|
|
425
|
-
nextActions: []
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
const paths = moduleSourcePaths(spec.module);
|
|
429
|
-
const servicePath = paths.service;
|
|
430
|
-
const signalPath = paths.signal;
|
|
347
|
+
if (!sys || !spec.module || !spec.entryName || !spec.serviceMethod || !spec.signal)
|
|
348
|
+
return PrimitiveScript.#refuse(spec.command, diagnostics);
|
|
349
|
+
const { service: servicePath, signal: signalPath } = moduleSourcePaths(spec.module);
|
|
431
350
|
const changedFiles = [];
|
|
432
|
-
const generatedFiles = generatedFilesForSync(sys);
|
|
433
351
|
const [hasServiceFile, hasSignalFile] = await Promise.all([sys.exists(servicePath), sys.exists(signalPath)]);
|
|
434
|
-
if (!hasServiceFile)
|
|
435
|
-
diagnostics.push(
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
}
|
|
441
|
-
if (!hasSignalFile) {
|
|
442
|
-
diagnostics.push({
|
|
443
|
-
severity: "error",
|
|
444
|
-
code: "primitive-source-missing",
|
|
445
|
-
message: `Signal source file was not found: ${signalPath}.`
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
if (diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
|
|
449
|
-
return createPrimitiveWriteReport({
|
|
450
|
-
command: spec.command,
|
|
451
|
-
changedFiles,
|
|
452
|
-
generatedFiles,
|
|
453
|
-
validationCommands: validationCommandsForTarget(sys.name),
|
|
454
|
-
diagnostics,
|
|
455
|
-
nextActions: nextActionsForTarget(sys.name)
|
|
456
|
-
});
|
|
457
|
-
}
|
|
352
|
+
if (!hasServiceFile)
|
|
353
|
+
diagnostics.push(PrimitiveScript.#sourceMissing("Service", servicePath));
|
|
354
|
+
if (!hasSignalFile)
|
|
355
|
+
diagnostics.push(PrimitiveScript.#sourceMissing("Signal", signalPath));
|
|
356
|
+
if (workflowStatus(diagnostics) === "failed")
|
|
357
|
+
return PrimitiveScript.#report(spec.command, sys, changedFiles, diagnostics);
|
|
458
358
|
const serviceClassName = `${moduleComponentName(spec.module)}Service`;
|
|
459
359
|
const serviceContent = await sys.readFile(servicePath);
|
|
460
360
|
const signalContent = await sys.readFile(signalPath);
|
|
@@ -476,7 +376,8 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
|
|
|
476
376
|
});
|
|
477
377
|
}
|
|
478
378
|
const nextServiceContent = serviceMethodExists ? serviceContent : insertClassMethod(serviceContent, serviceClassName, spec.serviceMethod.block);
|
|
479
|
-
const
|
|
379
|
+
const insertedSignalContent = insertSignalFactoryEntry(signalContent, spec.signal.className, spec.entryName, spec.signal.entryLine, spec.signal.param);
|
|
380
|
+
const nextSignalContent = insertedSignalContent ? ensureNamedImport(insertedSignalContent, "akanjs/signal", "None") : insertedSignalContent;
|
|
480
381
|
if (!nextServiceContent) {
|
|
481
382
|
diagnostics.push({
|
|
482
383
|
severity: "error",
|
|
@@ -515,20 +416,46 @@ class PrimitiveScript extends script("primitive", [ModuleScript]) {
|
|
|
515
416
|
message: `Edited ${signalPath} did not contain entry "${spec.entryName}" in ${spec.signal.className}.`
|
|
516
417
|
});
|
|
517
418
|
}
|
|
518
|
-
if (
|
|
419
|
+
if (workflowStatus(diagnostics) === "passed" && nextServiceContent && nextSignalContent) {
|
|
519
420
|
await sys.writeFile(servicePath, nextServiceContent);
|
|
520
421
|
await sys.writeFile(signalPath, nextSignalContent);
|
|
521
422
|
changedFiles.push(sourceFile(sys, servicePath, "modify", `Service ${spec.entryKind} was added.`), sourceFile(sys, signalPath, "modify", `Signal ${spec.entryKind} was added.`));
|
|
522
423
|
}
|
|
424
|
+
return PrimitiveScript.#report(spec.command, sys, changedFiles, diagnostics);
|
|
425
|
+
}
|
|
426
|
+
static #refuse(command, diagnostics) {
|
|
427
|
+
return createPrimitiveWriteReport({
|
|
428
|
+
command,
|
|
429
|
+
changedFiles: [],
|
|
430
|
+
generatedFiles: [],
|
|
431
|
+
validationCommands: [],
|
|
432
|
+
diagnostics,
|
|
433
|
+
nextActions: []
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
static #report(command, sys, changedFiles, diagnostics) {
|
|
523
437
|
return createPrimitiveWriteReport({
|
|
524
|
-
command
|
|
438
|
+
command,
|
|
525
439
|
changedFiles,
|
|
526
|
-
generatedFiles,
|
|
440
|
+
generatedFiles: generatedFilesForSync(sys),
|
|
527
441
|
validationCommands: validationCommandsForTarget(sys.name),
|
|
528
442
|
diagnostics,
|
|
529
443
|
nextActions: nextActionsForTarget(sys.name)
|
|
530
444
|
});
|
|
531
445
|
}
|
|
446
|
+
static #targetMissing() {
|
|
447
|
+
return { severity: "error", code: "primitive-target-missing", message: "Target app or library was not found." };
|
|
448
|
+
}
|
|
449
|
+
static #inputMissing(input, message = `${capitalize(input)} is required.`) {
|
|
450
|
+
return { severity: "error", code: "primitive-input-missing", message, input };
|
|
451
|
+
}
|
|
452
|
+
static #sourceMissing(kind, path) {
|
|
453
|
+
return {
|
|
454
|
+
severity: "error",
|
|
455
|
+
code: "primitive-source-missing",
|
|
456
|
+
message: `${kind} source file was not found: ${path}.`
|
|
457
|
+
};
|
|
458
|
+
}
|
|
532
459
|
}
|
|
533
460
|
|
|
534
461
|
export { PrimitiveScript };
|
|
@@ -4,27 +4,29 @@ import {
|
|
|
4
4
|
readDevkitVersion,
|
|
5
5
|
rootAllowedFiles,
|
|
6
6
|
rootAllowedDirs,
|
|
7
|
+
rootEntryHintOf,
|
|
7
8
|
isScannedRootEntry,
|
|
8
9
|
AppExecutor,
|
|
9
10
|
LibExecutor
|
|
10
|
-
} from "./index-
|
|
11
|
+
} from "./index-150s07n8.js";
|
|
11
12
|
import {
|
|
12
|
-
|
|
13
|
-
} from "./index-
|
|
13
|
+
FileSys2
|
|
14
|
+
} from "./index-52w0fvh8.js";
|
|
14
15
|
import {
|
|
15
16
|
collectRecipeSources2,
|
|
16
17
|
scanRecipes2,
|
|
17
18
|
findInlineRecipeDuplicates2
|
|
18
|
-
} from "./index-
|
|
19
|
+
} from "./index-hj6w4ka1.js";
|
|
19
20
|
import {
|
|
21
|
+
workflowPathsForPlan,
|
|
20
22
|
workflowRunArtifactPath,
|
|
21
23
|
workflowSyncDir
|
|
22
|
-
} from "./index-
|
|
24
|
+
} from "./index-mb59b8x0.js";
|
|
23
25
|
|
|
24
26
|
// pkgs/@akanjs/devkit/akanContext.ts
|
|
25
27
|
import { readdir } from "fs/promises";
|
|
26
28
|
import path from "path";
|
|
27
|
-
import { capitalize } from "akanjs/common";
|
|
29
|
+
import { capitalize, isRecord } from "akanjs/common";
|
|
28
30
|
var guidelineResourceUri = (name) => `akan://guidelines/${name}`;
|
|
29
31
|
var staticResourceList = [
|
|
30
32
|
{ uri: "akan://docs/framework", name: "Akan framework guide", mimeType: "text/markdown" },
|
|
@@ -52,16 +54,13 @@ var akanMcpInstallConfigPaths = {
|
|
|
52
54
|
var cursorWorkspaceFolder = "$" + "{workspaceFolder}";
|
|
53
55
|
var claudeProjectDir = "$CLAUDE_PROJECT_DIR";
|
|
54
56
|
var akanMcpCommand = (mode, { cd } = {}) => cd ? `cd "${cd}" && akan mcp --mode ${mode}` : `akan mcp --mode ${mode}`;
|
|
55
|
-
var
|
|
57
|
+
var bashMcpServer = (mode, cd) => ({
|
|
56
58
|
type: "stdio",
|
|
57
59
|
command: "bash",
|
|
58
|
-
args: ["-lc", akanMcpCommand(mode, { cd
|
|
59
|
-
});
|
|
60
|
-
var createAkanClaudeMcpServer = (mode = "readonly") => ({
|
|
61
|
-
type: "stdio",
|
|
62
|
-
command: "bash",
|
|
63
|
-
args: ["-lc", akanMcpCommand(mode, { cd: claudeProjectDir })]
|
|
60
|
+
args: ["-lc", akanMcpCommand(mode, { cd })]
|
|
64
61
|
});
|
|
62
|
+
var createAkanCursorMcpServer = (mode = "readonly") => bashMcpServer(mode, cursorWorkspaceFolder);
|
|
63
|
+
var createAkanClaudeMcpServer = (mode = "readonly") => bashMcpServer(mode, claudeProjectDir);
|
|
65
64
|
var createAkanMcpServer = (target, mode = "readonly") => target === "cursor" ? createAkanCursorMcpServer(mode) : createAkanClaudeMcpServer(mode);
|
|
66
65
|
var akanCursorMcpServer = createAkanCursorMcpServer();
|
|
67
66
|
var codexMcpServerTableHeader = "[mcp_servers.akan]";
|
|
@@ -164,41 +163,13 @@ var moduleShapeFiles = (module) => {
|
|
|
164
163
|
];
|
|
165
164
|
};
|
|
166
165
|
var constantFieldNames = (content) => [...content.matchAll(/\b([A-Za-z_$][\w$]*)\s*:\s*field\(/g)].map((match) => match[1]).filter(Boolean);
|
|
167
|
-
var safeReadDir = async (dirPath) => {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
};
|
|
174
|
-
var safeReadText = async (filePath) => {
|
|
175
|
-
try {
|
|
176
|
-
return await FileSys.readText(filePath);
|
|
177
|
-
} catch {
|
|
178
|
-
return null;
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
var safeReadJson = async (filePath) => {
|
|
182
|
-
try {
|
|
183
|
-
return await FileSys.readJson(filePath);
|
|
184
|
-
} catch {
|
|
185
|
-
return null;
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
|
-
var isWorkflowPlan = (value) => typeof value === "object" && value !== null && ("schemaVersion" in value) && value.schemaVersion === 1 && ("mode" in value) && value.mode === "plan";
|
|
189
|
-
var isWorkflowApplyReport = (value) => typeof value === "object" && value !== null && ("schemaVersion" in value) && value.schemaVersion === 1 && ("mode" in value) && (value.mode === "apply" || value.mode === "dry-run");
|
|
166
|
+
var safeReadDir = async (dirPath) => (await readdir(dirPath, { withFileTypes: true }).catch(() => [])).sort((a, b) => a.name.localeCompare(b.name));
|
|
167
|
+
var safeReadText = (filePath) => FileSys2.readText(filePath).catch(() => null);
|
|
168
|
+
var safeReadJson = (filePath) => FileSys2.readJson(filePath).catch(() => null);
|
|
169
|
+
var isWorkflowPlan = (value) => typeof value === "object" && value !== null && ("schemaVersion" in value) && value.schemaVersion === 1 && ("mode" in value) && value.mode === "plan" && ("inputs" in value) && isRecord(value.inputs) && ("predictedChanges" in value) && Array.isArray(value.predictedChanges) && value.predictedChanges.every((change) => isRecord(change) && typeof change.target === "string");
|
|
170
|
+
var isPathList = (value) => Array.isArray(value) && value.every((file) => isRecord(file) && typeof file.path === "string");
|
|
171
|
+
var isWorkflowApplyReport = (value) => typeof value === "object" && value !== null && ("schemaVersion" in value) && value.schemaVersion === 1 && ("mode" in value) && (value.mode === "apply" || value.mode === "dry-run") && ("changedFiles" in value) && isPathList(value.changedFiles) && ("generatedFiles" in value) && isPathList(value.generatedFiles) && ("plan" in value) && isWorkflowPlan(value.plan);
|
|
190
172
|
var isWorkflowRunArtifact = (value) => typeof value === "object" && value !== null && ("schemaVersion" in value) && value.schemaVersion === 1;
|
|
191
|
-
var planInputString = (plan, key) => {
|
|
192
|
-
const value = plan.inputs[key];
|
|
193
|
-
return typeof value === "string" ? value : "";
|
|
194
|
-
};
|
|
195
|
-
var expandWorkflowTarget = (target, plan) => {
|
|
196
|
-
const app = planInputString(plan, "app");
|
|
197
|
-
const module = planInputString(plan, "module");
|
|
198
|
-
const moduleClass = module ? capitalize(module) : "<Module>";
|
|
199
|
-
return target.replace(/^\*\//, app ? `apps/${app}/` : "").replaceAll("<module>", module || "<module>").replaceAll("<Module>", moduleClass);
|
|
200
|
-
};
|
|
201
|
-
var workflowPathsForPlan = (plan) => plan.predictedChanges.map((change) => expandWorkflowTarget(change.target, plan));
|
|
202
173
|
var workflowPathsForArtifact = (artifact) => {
|
|
203
174
|
if (isWorkflowPlan(artifact))
|
|
204
175
|
return workflowPathsForPlan(artifact);
|
|
@@ -209,7 +180,7 @@ var workflowPathsForArtifact = (artifact) => {
|
|
|
209
180
|
...workflowPathsForPlan(artifact.plan)
|
|
210
181
|
];
|
|
211
182
|
}
|
|
212
|
-
if ("mode" in artifact && artifact.mode === "validate" && artifact.plan)
|
|
183
|
+
if ("mode" in artifact && artifact.mode === "validate" && isWorkflowPlan(artifact.plan))
|
|
213
184
|
return workflowPathsForPlan(artifact.plan);
|
|
214
185
|
return [];
|
|
215
186
|
};
|
|
@@ -310,13 +281,13 @@ var getSysModules = async (workspace, sys, {
|
|
|
310
281
|
const serviceName = entry.name.replace(/^_+/, "");
|
|
311
282
|
if (moduleFilter && moduleFilter !== serviceName && moduleFilter !== entry.name)
|
|
312
283
|
continue;
|
|
313
|
-
if (!await
|
|
284
|
+
if (!await FileSys2.fileExists(path.join(libPath, entry.name, `${serviceName}.service.ts`)))
|
|
314
285
|
continue;
|
|
315
286
|
modules.push(await createModuleContext(workspace, sys, "service", entry.name, serviceName, includeAbstractContent));
|
|
316
287
|
} else {
|
|
317
288
|
if (moduleFilter && moduleFilter !== entry.name)
|
|
318
289
|
continue;
|
|
319
|
-
if (!await
|
|
290
|
+
if (!await FileSys2.fileExists(path.join(libPath, entry.name, `${entry.name}.constant.ts`)))
|
|
320
291
|
continue;
|
|
321
292
|
modules.push(await createModuleContext(workspace, sys, "domain", entry.name, entry.name, includeAbstractContent));
|
|
322
293
|
}
|
|
@@ -327,7 +298,7 @@ var getSysModules = async (workspace, sys, {
|
|
|
327
298
|
continue;
|
|
328
299
|
if (moduleFilter && moduleFilter !== entry.name)
|
|
329
300
|
continue;
|
|
330
|
-
if (!await
|
|
301
|
+
if (!await FileSys2.fileExists(path.join(scalarRoot, entry.name, `${entry.name}.constant.ts`)))
|
|
331
302
|
continue;
|
|
332
303
|
modules.push(await createModuleContext(workspace, sys, "scalar", entry.name, entry.name, includeAbstractContent));
|
|
333
304
|
}
|
|
@@ -339,7 +310,7 @@ var getSysContext = async (workspace, type, name, options) => {
|
|
|
339
310
|
type,
|
|
340
311
|
name,
|
|
341
312
|
path: `${type}s/${name}`,
|
|
342
|
-
hasConfig: await
|
|
313
|
+
hasConfig: await FileSys2.fileExists(path.join(sys.cwdPath, "akan.config.ts")),
|
|
343
314
|
modules: await getSysModules(workspace, sys, {
|
|
344
315
|
includeAbstractContent: options.includeAbstractContent,
|
|
345
316
|
module: options.module
|
|
@@ -411,62 +382,47 @@ class AkanContextAnalyzer {
|
|
|
411
382
|
repairAction("generated", "akan repair generated --app <app-or-lib>", "Refresh generated Akan files.", true),
|
|
412
383
|
repairAction("format", "akan repair format --target <app-or-lib-or-pkg>", "Run the formatter/linter repair path.", true)
|
|
413
384
|
];
|
|
385
|
+
const report = (diagnostic, action) => {
|
|
386
|
+
diagnostics.push({ ...diagnostic, repairActions: [action] });
|
|
387
|
+
repairActions.push(action);
|
|
388
|
+
};
|
|
414
389
|
for (const sys of [...context.apps, ...context.libs]) {
|
|
415
390
|
const sysPath = path.join(workspace.workspaceRoot, sys.path);
|
|
416
391
|
for (const entry of await safeReadDir(sysPath)) {
|
|
417
392
|
if (!isScannedRootEntry(sys.type, entry.name))
|
|
418
393
|
continue;
|
|
419
394
|
const allowed = entry.isDirectory() ? rootAllowedDirs[sys.type].has(entry.name) : rootAllowedFiles[sys.type].has(entry.name);
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
395
|
+
const rootEntryHint = rootEntryHintOf(sys.type, entry.name);
|
|
396
|
+
if (!allowed)
|
|
397
|
+
report({
|
|
423
398
|
severity: "error",
|
|
424
399
|
code: `${sys.type}-root-unknown-entry`,
|
|
425
400
|
path: `${sys.path}/${entry.name}`,
|
|
426
|
-
message: `Unexpected ${entry.isDirectory() ? "folder" : "file"} in ${sys.type} root: ${sys.path}/${entry.name}
|
|
427
|
-
|
|
428
|
-
});
|
|
429
|
-
repairActions.push(action);
|
|
430
|
-
}
|
|
401
|
+
message: `Unexpected ${entry.isDirectory() ? "folder" : "file"} in ${sys.type} root: ${sys.path}/${entry.name}${rootEntryHint ? ` (${rootEntryHint})` : ""}`
|
|
402
|
+
}, repairAction("module-shape", `akan repair module-shape --app ${sys.name}`, `Review ${sys.type} root shape and remove or move the unknown entry.`, false));
|
|
431
403
|
}
|
|
432
404
|
}
|
|
433
405
|
const agentDrift = await AkanContextAnalyzer.#agentGuideDrift(workspace);
|
|
434
|
-
if (agentDrift)
|
|
435
|
-
|
|
436
|
-
diagnostics.push({
|
|
437
|
-
severity: "warning",
|
|
438
|
-
code: agentDrift.code,
|
|
439
|
-
path: "AGENTS.md",
|
|
440
|
-
message: agentDrift.message,
|
|
441
|
-
repairActions: [action]
|
|
442
|
-
});
|
|
443
|
-
repairActions.push(action);
|
|
444
|
-
}
|
|
406
|
+
if (agentDrift)
|
|
407
|
+
report({ severity: "warning", code: agentDrift.code, path: "AGENTS.md", message: agentDrift.message }, repairAction("generated", "akan agent install agents-md", agentDrift.hint, true));
|
|
445
408
|
for (const sys of [...context.apps, ...context.libs]) {
|
|
446
409
|
for (const module of sys.modules) {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
410
|
+
const moduleShapeCommand = `akan repair module-shape --app ${sys.name} --module ${module.name}`;
|
|
411
|
+
if (!module.abstract.exists)
|
|
412
|
+
report({
|
|
450
413
|
severity: strict ? "error" : "warning",
|
|
451
414
|
code: "module-abstract-missing",
|
|
452
415
|
path: module.abstract.path,
|
|
453
|
-
message: `${capitalize(module.kind)} module ${sys.name}:${module.name} should include ${module.abstract.path}
|
|
454
|
-
|
|
455
|
-
});
|
|
456
|
-
repairActions.push(action);
|
|
457
|
-
}
|
|
416
|
+
message: `${capitalize(module.kind)} module ${sys.name}:${module.name} should include ${module.abstract.path}`
|
|
417
|
+
}, repairAction("module-shape", moduleShapeCommand, "Create the missing module abstract or inspect required source files.", false));
|
|
458
418
|
const missingFiles = moduleShapeFiles(module).filter((filename) => !module.files.includes(filename));
|
|
459
|
-
if (missingFiles.length)
|
|
460
|
-
|
|
461
|
-
diagnostics.push({
|
|
419
|
+
if (missingFiles.length)
|
|
420
|
+
report({
|
|
462
421
|
severity: "error",
|
|
463
422
|
code: "module-shape-invalid",
|
|
464
423
|
path: module.path,
|
|
465
|
-
message: `${capitalize(module.kind)} module ${sys.name}:${module.name} is missing required files: ${missingFiles.join(", ")}
|
|
466
|
-
|
|
467
|
-
});
|
|
468
|
-
repairActions.push(action);
|
|
469
|
-
}
|
|
424
|
+
message: `${capitalize(module.kind)} module ${sys.name}:${module.name} is missing required files: ${missingFiles.join(", ")}`
|
|
425
|
+
}, repairAction("module-shape", moduleShapeCommand, "Review missing required module source files.", false));
|
|
470
426
|
if (module.kind !== "service" && module.files.includes(`${module.name}.dictionary.ts`)) {
|
|
471
427
|
const constantPath = path.join(workspace.workspaceRoot, module.path, `${module.name}.constant.ts`);
|
|
472
428
|
const dictionaryPath = path.join(workspace.workspaceRoot, module.path, `${module.name}.dictionary.ts`);
|
|
@@ -478,15 +434,12 @@ class AkanContextAnalyzer {
|
|
|
478
434
|
for (const fieldName of constantFieldNames(constantContent)) {
|
|
479
435
|
if (new RegExp(`\\b${fieldName}\\s*:`).test(dictionaryContent))
|
|
480
436
|
continue;
|
|
481
|
-
|
|
482
|
-
diagnostics.push({
|
|
437
|
+
report({
|
|
483
438
|
severity: "warning",
|
|
484
439
|
code: "dictionary-label-missing",
|
|
485
440
|
path: `${module.path}/${module.name}.dictionary.ts`,
|
|
486
|
-
message: `Dictionary labels for ${sys.name}:${module.name}.${fieldName} were not found
|
|
487
|
-
|
|
488
|
-
});
|
|
489
|
-
repairActions.push(action);
|
|
441
|
+
message: `Dictionary labels for ${sys.name}:${module.name}.${fieldName} were not found.`
|
|
442
|
+
}, repairAction("dictionary", `akan repair dictionary --app ${sys.name} --module ${module.name}`, "Add missing dictionary labels for source constant fields.", false));
|
|
490
443
|
}
|
|
491
444
|
}
|
|
492
445
|
}
|
|
@@ -554,19 +507,16 @@ class AkanContextAnalyzer {
|
|
|
554
507
|
const pushIndexDiagnostic = (indexPath, missing, stale, repairCommand) => {
|
|
555
508
|
if (missing.length === 0 && stale.length === 0)
|
|
556
509
|
return;
|
|
557
|
-
const action = repairAction("generated", repairCommand, "Regenerate the recipe index from the scanned recipes.", true);
|
|
558
510
|
const parts = [
|
|
559
511
|
missing.length > 0 ? `${missing.length} declared but unlisted (${missing.slice(0, 5).join(", ")})` : "",
|
|
560
512
|
stale.length > 0 ? `${stale.length} listed but gone (${stale.slice(0, 5).join(", ")})` : ""
|
|
561
513
|
].filter(Boolean);
|
|
562
|
-
|
|
514
|
+
report({
|
|
563
515
|
severity: "error",
|
|
564
516
|
code: "recipe-index-stale",
|
|
565
517
|
path: indexPath,
|
|
566
|
-
message: `${indexPath} recipe index is out of date \u2014 ${parts.join("; ")}. Agents read this list as authoritative
|
|
567
|
-
|
|
568
|
-
});
|
|
569
|
-
repairActions.push(action);
|
|
518
|
+
message: `${indexPath} recipe index is out of date \u2014 ${parts.join("; ")}. Agents read this list as authoritative.`
|
|
519
|
+
}, repairAction("generated", repairCommand, "Regenerate the recipe index from the scanned recipes.", true));
|
|
570
520
|
};
|
|
571
521
|
const frameworkDeclared = declaredByImport.get("akanjs/ui") ?? new Set;
|
|
572
522
|
if (frameworkDeclared.size > 0) {
|