@akanjs/cli 3.0.0-beta.2 → 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-awv258wb.js +9 -0
- package/CodeAgentRpcHost-p7h6n2hp.js +7 -0
- package/CodeAgentRpcListener-7p7z5dd7.js +97 -0
- package/CodeTui-1nqh35ez.js +1457 -0
- package/README.md +3 -0
- package/TunnelShare-scf4e4pd.js +9 -0
- package/{agent.command-d2gfxfck.js → agent.command-1s9ag7sb.js} +8 -9
- package/akanCode.js +102 -0
- package/{application.command-pj2m7584.js → application.command-49hwy6va.js} +51 -78
- package/{applicationBuildRunner-kxwbssgn.js → applicationBuildRunner-ybyp97pv.js} +63 -64
- package/{applicationReleasePackager-4yasxwv9.js → applicationReleasePackager-esnrphw8.js} +40 -60
- package/buildBatch.proc.js +19 -24
- package/{capacitorApp-36rbr858.js → capacitorApp-1synz4en.js} +3 -4
- package/cloud.command-d7rqtzt9.js +94 -0
- package/cloud.script-bkbpcr96.js +19 -0
- package/code.command-nn48xzej.js +154 -0
- package/commandManifest.json +1 -1
- package/consoleToStderr-h5bryj94.js +7 -0
- package/context.command-s3mcmvpa.js +48 -0
- package/context.runner-k99nb5pk.js +21 -0
- package/{dependencyScanner-shs82ynp.js → dependencyScanner-ye2e6pdz.js} +2 -2
- package/{devTui-40ggmd99.js → devTui-q7k7bakd.js} +122 -40
- package/fileSys-5ngz93ga.js +9 -0
- package/guideline.command-sct4qnt5.js +42 -0
- package/guidelines/agentRule/agentRule.instruction.md +206 -25
- package/guidelines/conventions/conventions.instruction.md +79 -24
- package/guidelines/fieldRule/fieldRule.instruction.md +1 -0
- package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
- package/guidelines/queryRule/queryRule.instruction.md +17 -7
- package/guidelines/runtimeRule/runtimeRule.instruction.md +74 -0
- package/guidelines/ssrRule/ssrRule.instruction.md +4 -2
- package/guidelines/transportRule/transportRule.instruction.md +51 -0
- package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +66 -3
- package/incrementalBuilder.proc.js +31 -48
- package/{index-h7yw2z9n.js → index-0bq14vr1.js} +8 -14
- package/index-13ffe9wp.js +69 -0
- package/index-22d57v4c.js +266 -0
- package/{index-fz5q3gd7.js → index-31yr441d.js} +10 -17
- package/index-3hx1z96c.js +87 -0
- package/index-3sq321ak.js +53 -0
- package/{index-kcxmv48c.js → index-3t7g9e4r.js} +45 -79
- package/{index-q0y2jq9j.js → index-5b6tavv3.js} +6 -3
- package/{index-47pj3aee.js → index-5e0n4hqx.js} +11 -12
- package/{index-259dsnz3.js → index-5pc1qrbv.js} +5 -8
- package/index-7md2g9vw.js +6 -0
- package/index-8mna0947.js +187 -0
- package/{index-zry5nz81.js → index-8sf7wmdr.js} +51 -30
- package/{index-2tv3fdx4.js → index-9d9bgcx4.js} +342 -765
- package/index-9dp031by.js +12 -0
- package/{index-ne2qy0nk.js → index-ahemdr5n.js} +12 -12
- package/{index-ws5e0j51.js → index-as7xmyz8.js} +40 -24
- package/index-axzjaqve.js +1118 -0
- package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
- package/index-c6eggbee.js +123 -0
- package/index-d2242ksy.js +99 -0
- package/{index-a64esmtb.js → index-ddxvdd1p.js} +169 -305
- package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
- package/{index-pnqbkf5p.js → index-dzf3r49a.js} +6 -2
- package/{index-w8kmx1b6.js → index-fgq75haa.js} +198 -290
- package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
- package/{index-hwkygn9s.js → index-khpfpcsd.js} +302 -33
- package/{index-wt7qrtd4.js → index-mxav6j3c.js} +93 -232
- package/{index-gyd220p2.js → index-myhc3c1j.js} +554 -577
- package/{index-600zhnve.js → index-nv5976x3.js} +56 -197
- package/index-p6pbz9n5.js +25 -0
- package/{index-4edzf1gr.js → index-przybvy5.js} +77 -150
- package/index-smme4r47.js +49 -0
- package/{index-mak3cd28.js → index-w2zdcw3k.js} +137 -255
- package/index-wa5jbxj1.js +760 -0
- package/{index-v0qh106m.js → index-ww4z397j.js} +527 -723
- package/{index-j9yhg404.js → index-xqjwd384.js} +4 -7
- package/{index-7737gxcp.js → index-xqpzbab5.js} +107 -241
- package/index-xsjh6nzh.js +2729 -0
- package/{index-ktb5njgy.js → index-ygn77a5w.js} +47 -99
- package/index-ztp3e73t.js +700 -0
- package/index.js +23 -22
- package/{library.command-nbsky672.js → library.command-1gx04jgn.js} +4 -5
- package/{localRegistry.command-yeq57wjr.js → localRegistry.command-zndxj1q6.js} +22 -42
- package/{module.command-29vqzrh8.js → module.command-3waddk95.js} +8 -11
- package/{package.command-axv0abmn.js → package.command-zrc7br1y.js} +6 -7
- package/package.json +14 -5
- package/{page.command-vs9s3zrh.js → page.command-vpjgardh.js} +4 -5
- package/{primitive.command-cbxmqbtc.js → primitive.command-sz84tk4t.js} +9 -22
- package/prompter-ptaa3nk0.js +8 -0
- package/{quality.command-gmbs7nws.js → quality.command-g869hafs.js} +203 -376
- package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
- package/{repair.command-bqsjptsj.js → repair.command-chsnjvvv.js} +11 -35
- package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
- package/{scalar.command-6k1vhe9s.js → scalar.command-2v21newx.js} +7 -10
- 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-fwjfcts7.js → subspace.command-ckcbwfp1.js} +138 -67
- package/templates/__scalar/__model__/__model__.abstract.md.template +8 -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.abstract.ts +12 -32
- package/templates/appSample/lib/task/task.signal.spec.ts +15 -18
- package/templates/appSample/lib/task/task.signal.test.ts +15 -1
- package/templates/appSample/lib/task/task.signal.ts +1 -1
- package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +7 -4
- package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +6 -4
- 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 +0 -2
- package/templates/service/__model__.abstract.md.template +8 -0
- package/tunnel.command-kd2yr4fx.js +129 -0
- 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-8s050m0h.js → workspace.command-fqcztt5p.js} +77 -109
- package/abstractCompactor-mjh5ppsq.js +0 -101
- package/cloud.command-jshwdq22.js +0 -93
- package/context.command-ez8a0zyz.js +0 -80
- package/devTuiView-c08ccbat.js +0 -9
- package/getDirname-dr3jz1xg.js +0 -7
- package/guideline.command-xmqwx8zm.js +0 -359
- 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-2hq52jq3.js +0 -465
- package/index-6wwzs1bc.js +0 -7
- package/index-8pm30m73.js +0 -841
- package/index-kn1h7p1x.js +0 -560
- package/index-meh558jy.js +0 -65
- package/index-rwg2aa4f.js +0 -229
- 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/workflow.command-nwpcdc8p.js +0 -107
|
@@ -7,24 +7,25 @@ import {
|
|
|
7
7
|
isScannedRootEntry,
|
|
8
8
|
AppExecutor,
|
|
9
9
|
LibExecutor
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-9d9bgcx4.js";
|
|
11
11
|
import {
|
|
12
|
-
|
|
13
|
-
} from "./index-
|
|
12
|
+
FileSys2
|
|
13
|
+
} from "./index-5b6tavv3.js";
|
|
14
14
|
import {
|
|
15
15
|
collectRecipeSources2,
|
|
16
16
|
scanRecipes2,
|
|
17
17
|
findInlineRecipeDuplicates2
|
|
18
|
-
} from "./index-
|
|
18
|
+
} from "./index-hj6w4ka1.js";
|
|
19
19
|
import {
|
|
20
|
+
workflowPathsForPlan,
|
|
20
21
|
workflowRunArtifactPath,
|
|
21
22
|
workflowSyncDir
|
|
22
|
-
} from "./index-
|
|
23
|
+
} from "./index-myhc3c1j.js";
|
|
23
24
|
|
|
24
25
|
// pkgs/@akanjs/devkit/akanContext.ts
|
|
25
26
|
import { readdir } from "fs/promises";
|
|
26
27
|
import path from "path";
|
|
27
|
-
import { capitalize } from "akanjs/common";
|
|
28
|
+
import { capitalize, isRecord } from "akanjs/common";
|
|
28
29
|
var guidelineResourceUri = (name) => `akan://guidelines/${name}`;
|
|
29
30
|
var staticResourceList = [
|
|
30
31
|
{ uri: "akan://docs/framework", name: "Akan framework guide", mimeType: "text/markdown" },
|
|
@@ -52,16 +53,13 @@ var akanMcpInstallConfigPaths = {
|
|
|
52
53
|
var cursorWorkspaceFolder = "$" + "{workspaceFolder}";
|
|
53
54
|
var claudeProjectDir = "$CLAUDE_PROJECT_DIR";
|
|
54
55
|
var akanMcpCommand = (mode, { cd } = {}) => cd ? `cd "${cd}" && akan mcp --mode ${mode}` : `akan mcp --mode ${mode}`;
|
|
55
|
-
var
|
|
56
|
+
var bashMcpServer = (mode, cd) => ({
|
|
56
57
|
type: "stdio",
|
|
57
58
|
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 })]
|
|
59
|
+
args: ["-lc", akanMcpCommand(mode, { cd })]
|
|
64
60
|
});
|
|
61
|
+
var createAkanCursorMcpServer = (mode = "readonly") => bashMcpServer(mode, cursorWorkspaceFolder);
|
|
62
|
+
var createAkanClaudeMcpServer = (mode = "readonly") => bashMcpServer(mode, claudeProjectDir);
|
|
65
63
|
var createAkanMcpServer = (target, mode = "readonly") => target === "cursor" ? createAkanCursorMcpServer(mode) : createAkanClaudeMcpServer(mode);
|
|
66
64
|
var akanCursorMcpServer = createAkanCursorMcpServer();
|
|
67
65
|
var codexMcpServerTableHeader = "[mcp_servers.akan]";
|
|
@@ -164,41 +162,13 @@ var moduleShapeFiles = (module) => {
|
|
|
164
162
|
];
|
|
165
163
|
};
|
|
166
164
|
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");
|
|
165
|
+
var safeReadDir = async (dirPath) => (await readdir(dirPath, { withFileTypes: true }).catch(() => [])).sort((a, b) => a.name.localeCompare(b.name));
|
|
166
|
+
var safeReadText = (filePath) => FileSys2.readText(filePath).catch(() => null);
|
|
167
|
+
var safeReadJson = (filePath) => FileSys2.readJson(filePath).catch(() => null);
|
|
168
|
+
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");
|
|
169
|
+
var isPathList = (value) => Array.isArray(value) && value.every((file) => isRecord(file) && typeof file.path === "string");
|
|
170
|
+
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
171
|
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
172
|
var workflowPathsForArtifact = (artifact) => {
|
|
203
173
|
if (isWorkflowPlan(artifact))
|
|
204
174
|
return workflowPathsForPlan(artifact);
|
|
@@ -209,7 +179,7 @@ var workflowPathsForArtifact = (artifact) => {
|
|
|
209
179
|
...workflowPathsForPlan(artifact.plan)
|
|
210
180
|
];
|
|
211
181
|
}
|
|
212
|
-
if ("mode" in artifact && artifact.mode === "validate" && artifact.plan)
|
|
182
|
+
if ("mode" in artifact && artifact.mode === "validate" && isWorkflowPlan(artifact.plan))
|
|
213
183
|
return workflowPathsForPlan(artifact.plan);
|
|
214
184
|
return [];
|
|
215
185
|
};
|
|
@@ -310,13 +280,13 @@ var getSysModules = async (workspace, sys, {
|
|
|
310
280
|
const serviceName = entry.name.replace(/^_+/, "");
|
|
311
281
|
if (moduleFilter && moduleFilter !== serviceName && moduleFilter !== entry.name)
|
|
312
282
|
continue;
|
|
313
|
-
if (!await
|
|
283
|
+
if (!await FileSys2.fileExists(path.join(libPath, entry.name, `${serviceName}.service.ts`)))
|
|
314
284
|
continue;
|
|
315
285
|
modules.push(await createModuleContext(workspace, sys, "service", entry.name, serviceName, includeAbstractContent));
|
|
316
286
|
} else {
|
|
317
287
|
if (moduleFilter && moduleFilter !== entry.name)
|
|
318
288
|
continue;
|
|
319
|
-
if (!await
|
|
289
|
+
if (!await FileSys2.fileExists(path.join(libPath, entry.name, `${entry.name}.constant.ts`)))
|
|
320
290
|
continue;
|
|
321
291
|
modules.push(await createModuleContext(workspace, sys, "domain", entry.name, entry.name, includeAbstractContent));
|
|
322
292
|
}
|
|
@@ -327,7 +297,7 @@ var getSysModules = async (workspace, sys, {
|
|
|
327
297
|
continue;
|
|
328
298
|
if (moduleFilter && moduleFilter !== entry.name)
|
|
329
299
|
continue;
|
|
330
|
-
if (!await
|
|
300
|
+
if (!await FileSys2.fileExists(path.join(scalarRoot, entry.name, `${entry.name}.constant.ts`)))
|
|
331
301
|
continue;
|
|
332
302
|
modules.push(await createModuleContext(workspace, sys, "scalar", entry.name, entry.name, includeAbstractContent));
|
|
333
303
|
}
|
|
@@ -339,7 +309,7 @@ var getSysContext = async (workspace, type, name, options) => {
|
|
|
339
309
|
type,
|
|
340
310
|
name,
|
|
341
311
|
path: `${type}s/${name}`,
|
|
342
|
-
hasConfig: await
|
|
312
|
+
hasConfig: await FileSys2.fileExists(path.join(sys.cwdPath, "akan.config.ts")),
|
|
343
313
|
modules: await getSysModules(workspace, sys, {
|
|
344
314
|
includeAbstractContent: options.includeAbstractContent,
|
|
345
315
|
module: options.module
|
|
@@ -411,62 +381,46 @@ class AkanContextAnalyzer {
|
|
|
411
381
|
repairAction("generated", "akan repair generated --app <app-or-lib>", "Refresh generated Akan files.", true),
|
|
412
382
|
repairAction("format", "akan repair format --target <app-or-lib-or-pkg>", "Run the formatter/linter repair path.", true)
|
|
413
383
|
];
|
|
384
|
+
const report = (diagnostic, action) => {
|
|
385
|
+
diagnostics.push({ ...diagnostic, repairActions: [action] });
|
|
386
|
+
repairActions.push(action);
|
|
387
|
+
};
|
|
414
388
|
for (const sys of [...context.apps, ...context.libs]) {
|
|
415
389
|
const sysPath = path.join(workspace.workspaceRoot, sys.path);
|
|
416
390
|
for (const entry of await safeReadDir(sysPath)) {
|
|
417
391
|
if (!isScannedRootEntry(sys.type, entry.name))
|
|
418
392
|
continue;
|
|
419
393
|
const allowed = entry.isDirectory() ? rootAllowedDirs[sys.type].has(entry.name) : rootAllowedFiles[sys.type].has(entry.name);
|
|
420
|
-
if (!allowed)
|
|
421
|
-
|
|
422
|
-
diagnostics.push({
|
|
394
|
+
if (!allowed)
|
|
395
|
+
report({
|
|
423
396
|
severity: "error",
|
|
424
397
|
code: `${sys.type}-root-unknown-entry`,
|
|
425
398
|
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
|
-
}
|
|
399
|
+
message: `Unexpected ${entry.isDirectory() ? "folder" : "file"} in ${sys.type} root: ${sys.path}/${entry.name}`
|
|
400
|
+
}, repairAction("module-shape", `akan repair module-shape --app ${sys.name}`, `Review ${sys.type} root shape and remove or move the unknown entry.`, false));
|
|
431
401
|
}
|
|
432
402
|
}
|
|
433
403
|
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
|
-
}
|
|
404
|
+
if (agentDrift)
|
|
405
|
+
report({ severity: "warning", code: agentDrift.code, path: "AGENTS.md", message: agentDrift.message }, repairAction("generated", "akan agent install agents-md", agentDrift.hint, true));
|
|
445
406
|
for (const sys of [...context.apps, ...context.libs]) {
|
|
446
407
|
for (const module of sys.modules) {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
408
|
+
const moduleShapeCommand = `akan repair module-shape --app ${sys.name} --module ${module.name}`;
|
|
409
|
+
if (!module.abstract.exists)
|
|
410
|
+
report({
|
|
450
411
|
severity: strict ? "error" : "warning",
|
|
451
412
|
code: "module-abstract-missing",
|
|
452
413
|
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
|
-
}
|
|
414
|
+
message: `${capitalize(module.kind)} module ${sys.name}:${module.name} should include ${module.abstract.path}`
|
|
415
|
+
}, repairAction("module-shape", moduleShapeCommand, "Create the missing module abstract or inspect required source files.", false));
|
|
458
416
|
const missingFiles = moduleShapeFiles(module).filter((filename) => !module.files.includes(filename));
|
|
459
|
-
if (missingFiles.length)
|
|
460
|
-
|
|
461
|
-
diagnostics.push({
|
|
417
|
+
if (missingFiles.length)
|
|
418
|
+
report({
|
|
462
419
|
severity: "error",
|
|
463
420
|
code: "module-shape-invalid",
|
|
464
421
|
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
|
-
}
|
|
422
|
+
message: `${capitalize(module.kind)} module ${sys.name}:${module.name} is missing required files: ${missingFiles.join(", ")}`
|
|
423
|
+
}, repairAction("module-shape", moduleShapeCommand, "Review missing required module source files.", false));
|
|
470
424
|
if (module.kind !== "service" && module.files.includes(`${module.name}.dictionary.ts`)) {
|
|
471
425
|
const constantPath = path.join(workspace.workspaceRoot, module.path, `${module.name}.constant.ts`);
|
|
472
426
|
const dictionaryPath = path.join(workspace.workspaceRoot, module.path, `${module.name}.dictionary.ts`);
|
|
@@ -478,15 +432,12 @@ class AkanContextAnalyzer {
|
|
|
478
432
|
for (const fieldName of constantFieldNames(constantContent)) {
|
|
479
433
|
if (new RegExp(`\\b${fieldName}\\s*:`).test(dictionaryContent))
|
|
480
434
|
continue;
|
|
481
|
-
|
|
482
|
-
diagnostics.push({
|
|
435
|
+
report({
|
|
483
436
|
severity: "warning",
|
|
484
437
|
code: "dictionary-label-missing",
|
|
485
438
|
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);
|
|
439
|
+
message: `Dictionary labels for ${sys.name}:${module.name}.${fieldName} were not found.`
|
|
440
|
+
}, repairAction("dictionary", `akan repair dictionary --app ${sys.name} --module ${module.name}`, "Add missing dictionary labels for source constant fields.", false));
|
|
490
441
|
}
|
|
491
442
|
}
|
|
492
443
|
}
|
|
@@ -554,19 +505,16 @@ class AkanContextAnalyzer {
|
|
|
554
505
|
const pushIndexDiagnostic = (indexPath, missing, stale, repairCommand) => {
|
|
555
506
|
if (missing.length === 0 && stale.length === 0)
|
|
556
507
|
return;
|
|
557
|
-
const action = repairAction("generated", repairCommand, "Regenerate the recipe index from the scanned recipes.", true);
|
|
558
508
|
const parts = [
|
|
559
509
|
missing.length > 0 ? `${missing.length} declared but unlisted (${missing.slice(0, 5).join(", ")})` : "",
|
|
560
510
|
stale.length > 0 ? `${stale.length} listed but gone (${stale.slice(0, 5).join(", ")})` : ""
|
|
561
511
|
].filter(Boolean);
|
|
562
|
-
|
|
512
|
+
report({
|
|
563
513
|
severity: "error",
|
|
564
514
|
code: "recipe-index-stale",
|
|
565
515
|
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);
|
|
516
|
+
message: `${indexPath} recipe index is out of date \u2014 ${parts.join("; ")}. Agents read this list as authoritative.`
|
|
517
|
+
}, repairAction("generated", repairCommand, "Regenerate the recipe index from the scanned recipes.", true));
|
|
570
518
|
};
|
|
571
519
|
const frameworkDeclared = declaredByImport.get("akanjs/ui") ?? new Set;
|
|
572
520
|
if (frameworkDeclared.size > 0) {
|