@akanjs/cli 3.0.0-alpha.70 → 3.0.0-alpha.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/.build-stamp +1 -1
  2. package/{abstractCompactor-20e0cwbs.js → abstractCompactor-8yjc9sj4.js} +1 -1
  3. package/{agent.command-964bf8qg.js → agent.command-z0cam80t.js} +6 -6
  4. package/{application.command-n45n18sc.js → application.command-2dct57za.js} +34 -12
  5. package/{applicationBuildRunner-af0wtspv.js → applicationBuildRunner-ds8acdfz.js} +3 -3
  6. package/{applicationReleasePackager-93nzdfsy.js → applicationReleasePackager-0jf6ejr4.js} +2 -2
  7. package/buildBatch.proc.js +4 -4
  8. package/{capacitorApp-vnvnvdhf.js → capacitorApp-md7dnt25.js} +2 -2
  9. package/{cloud.command-kx1bh5yq.js → cloud.command-8j7xrxsm.js} +10 -10
  10. package/commandManifest.json +1 -1
  11. package/{context.command-g1a65x6j.js → context.command-xjf4y7em.js} +14 -14
  12. package/{dependencyScanner-rbs2407b.js → dependencyScanner-aqg3dkks.js} +1 -1
  13. package/{guideline.command-xphyhvwh.js → guideline.command-yzm0qevv.js} +4 -4
  14. package/guidelines/conventions/conventions.instruction.md +267 -440
  15. package/guidelines/framework/framework.generate.json +3 -2
  16. package/guidelines/framework/framework.instruction.md +0 -9
  17. package/guidelines/mcpRule/mcpRule.instruction.md +5 -8
  18. package/guidelines/queryRule/queryRule.generate.json +31 -0
  19. package/guidelines/queryRule/queryRule.instruction.md +143 -0
  20. package/guidelines/runtimeRule/runtimeRule.generate.json +25 -0
  21. package/guidelines/runtimeRule/runtimeRule.instruction.md +176 -0
  22. package/guidelines/ssrRule/ssrRule.instruction.md +49 -5
  23. package/guidelines/transportRule/transportRule.generate.json +31 -0
  24. package/guidelines/transportRule/transportRule.instruction.md +60 -0
  25. package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +17 -392
  26. package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +33 -0
  27. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +402 -0
  28. package/incrementalBuilder.proc.js +5 -5
  29. package/{index-4rw4qhe6.js → index-116w1dap.js} +4 -4
  30. package/{index-mkn5qagt.js → index-5r4e65hb.js} +128 -59
  31. package/{index-abyjt72y.js → index-61x7qthy.js} +17 -21
  32. package/{index-bqqts262.js → index-763h7h9g.js} +1 -1
  33. package/{index-wnp7hwq7.js → index-94hdqqka.js} +1 -1
  34. package/{index-v5fdxdre.js → index-9gqzgfsd.js} +4 -4
  35. package/{index-fahkq20v.js → index-a341yqdh.js} +3 -3
  36. package/{index-e31ghfp5.js → index-akz5xvyw.js} +17 -5
  37. package/{index-va15r8h5.js → index-bmz9crym.js} +13 -6
  38. package/{index-qt4nfr0n.js → index-eed7vc38.js} +66 -33
  39. package/{index-46tjzh6s.js → index-h5sr2nnj.js} +24 -24
  40. package/{index-nkwmnqwn.js → index-h9cybjep.js} +92 -19
  41. package/{index-p681w089.js → index-hvbdre8z.js} +4 -10
  42. package/{index-qnv0aqmm.js → index-jcm6zr20.js} +3 -1
  43. package/{index-j37qq1f2.js → index-k7731a4v.js} +4 -4
  44. package/{index-ytaqtc04.js → index-q0s2dp3y.js} +1 -1
  45. package/{index-nj3w0r34.js → index-q13s3e01.js} +3 -3
  46. package/{index-0ngvvgry.js → index-qge1hc70.js} +5 -5
  47. package/{index-sh01r3pm.js → index-safgeq9a.js} +3 -2
  48. package/{index-xjd3rqzj.js → index-scemmfpj.js} +6 -15
  49. package/{index-rbnpe8cp.js → index-te6r1b79.js} +19 -23
  50. package/{index-yg3hxk2k.js → index-vrra4ttx.js} +6 -6
  51. package/{index-8gybxemv.js → index-y3wyqcsp.js} +6 -6
  52. package/{index-hee7egtm.js → index-ym9g9ggs.js} +21 -21
  53. package/{index-fgc8r6dj.js → index-ynf37b66.js} +3 -1
  54. package/{index-rb65xnw9.js → index-z52nhkjs.js} +4 -4
  55. package/index.js +18 -18
  56. package/{library.command-rfpd27yv.js → library.command-w8b53vtt.js} +4 -4
  57. package/{localRegistry.command-pyxfe0fs.js → localRegistry.command-ymrgda7e.js} +9 -9
  58. package/{module.command-qhaxad0p.js → module.command-7pje37dv.js} +7 -7
  59. package/{package.command-2k22q9nt.js → package.command-jg4qk8ts.js} +4 -4
  60. package/package.json +3 -4
  61. package/{page.command-ymk9dqh4.js → page.command-abbpj96j.js} +3 -3
  62. package/{primitive.command-9k45zpc1.js → primitive.command-jw4yv918.js} +8 -8
  63. package/{quality.command-bf6vkxe5.js → quality.command-06j6qy6n.js} +34 -4
  64. package/{repair.command-egvvm6xf.js → repair.command-x6resn10.js} +5 -5
  65. package/{scalar.command-bt1facyj.js → scalar.command-mj2vx6rj.js} +6 -6
  66. package/templates/appSample/lib/task/task.signal.ts +11 -6
  67. package/templates/crudPages/[__model__Id]/edit/page.tsx +5 -5
  68. package/templates/crudPages/[__model__Id]/page.tsx +10 -13
  69. package/templates/crudPages/new/page.tsx +5 -5
  70. package/templates/crudPages/page.tsx +9 -9
  71. package/templates/crudSinglePage/page.tsx +11 -7
  72. package/templates/module/__model__.dictionary.ts +4 -1
  73. package/templates/module/__model__.signal.ts +2 -3
  74. package/templates/module/__model__.store.ts +1 -2
  75. package/templates/workspaceRoot/AGENTS.md.template +4 -0
  76. package/{typeChecker-g6bh0xfv.js → typeChecker-yhs4eht8.js} +1 -1
  77. package/typecheck.proc.js +1 -1
  78. package/{workflow.command-v1n3wg7v.js → workflow.command-pmw2tere.js} +11 -11
  79. package/{workspace.command-yvvqvhzz.js → workspace.command-x32k2vma.js} +29 -26
@@ -1,43 +1,43 @@
1
1
  // @bun
2
2
  import {
3
3
  RepairRunner
4
- } from "./index-nj3w0r34.js";
4
+ } from "./index-q13s3e01.js";
5
5
  import {
6
6
  WorkflowRunner
7
- } from "./index-fahkq20v.js";
7
+ } from "./index-a341yqdh.js";
8
8
  import {
9
9
  ScalarScript
10
- } from "./index-v5fdxdre.js";
10
+ } from "./index-9gqzgfsd.js";
11
11
  import {
12
12
  PrimitiveScript
13
- } from "./index-rb65xnw9.js";
13
+ } from "./index-z52nhkjs.js";
14
14
  import {
15
15
  ModuleScript
16
- } from "./index-yg3hxk2k.js";
16
+ } from "./index-vrra4ttx.js";
17
17
  import {
18
18
  isPlaceholderAppId
19
- } from "./index-hee7egtm.js";
19
+ } from "./index-ym9g9ggs.js";
20
20
  import {
21
21
  AkanContextAnalyzer,
22
22
  akanMcpInstallConfigPaths,
23
23
  akanMcpInstallTargets,
24
+ buildResourceList,
24
25
  codexMcpConfigPath,
25
26
  createAkanCodexMcpServerBlock,
26
27
  createAkanMcpServer,
27
28
  renderDoctorText,
28
- resourceList,
29
29
  upsertCodexMcpServerBlock
30
- } from "./index-va15r8h5.js";
30
+ } from "./index-bmz9crym.js";
31
31
  import {
32
32
  buildAkanModuleContextIndex,
33
33
  createWorkflowBaselineSummary,
34
34
  createWorkflowStepRegistry,
35
35
  jsonText,
36
36
  toolingRolloutGate
37
- } from "./index-ytaqtc04.js";
37
+ } from "./index-q0s2dp3y.js";
38
38
  import {
39
39
  Prompter
40
- } from "./index-j37qq1f2.js";
40
+ } from "./index-k7731a4v.js";
41
41
  import {
42
42
  getMobileTargets
43
43
  } from "./index-76rn3g2c.js";
@@ -45,10 +45,10 @@ import {
45
45
  CommandContainer,
46
46
  runner,
47
47
  script
48
- } from "./index-e31ghfp5.js";
48
+ } from "./index-akz5xvyw.js";
49
49
  import {
50
50
  AppExecutor
51
- } from "./index-nkwmnqwn.js";
51
+ } from "./index-h9cybjep.js";
52
52
 
53
53
  // pkgs/@akanjs/cli/context/context.script.ts
54
54
  import { Logger } from "akanjs/common";
@@ -380,12 +380,15 @@ var applyMcpTools = [
380
380
  }
381
381
  }
382
382
  ];
383
- var listAkanMcpTools = (mode = "readonly") => {
384
- if (mode === "readonly")
385
- return readonlyMcpTools;
386
- if (mode === "plan")
387
- return [...readonlyMcpTools, ...planMcpTools];
388
- return [...readonlyMcpTools, ...planMcpTools, ...applyMcpTools];
383
+ var listAkanMcpTools = (mode = "readonly", { guidelineNames = [] } = {}) => {
384
+ const tools = mode === "readonly" ? readonlyMcpTools : mode === "plan" ? [...readonlyMcpTools, ...planMcpTools] : [...readonlyMcpTools, ...planMcpTools, ...applyMcpTools];
385
+ if (guidelineNames.length === 0)
386
+ return tools;
387
+ return tools.map((tool) => tool.name === "get_guideline" ? {
388
+ ...tool,
389
+ description: `${tool.description ?? ""} One of: ${guidelineNames.join(", ")}.`.trim(),
390
+ inputSchema: { ...tool.inputSchema, properties: { name: { type: "string", enum: [...guidelineNames] } } }
391
+ } : tool);
389
392
  };
390
393
  var createAkanValidationContract = (listTools = listAkanMcpTools) => ({
391
394
  schemaVersion: 1,
@@ -604,6 +607,10 @@ var createCliWorkflowStepRegistry = (workspace) => createWorkflowStepRegistry({
604
607
  });
605
608
 
606
609
  // pkgs/@akanjs/cli/context/context.runner.ts
610
+ var toolErrorText = (error) => {
611
+ const message = error instanceof Error ? error.message : String(error);
612
+ return message.replace(/\/(?:[^\s"'/]+\/)*(?=(?:pkgs|apps|libs|infra)\/)/g, "<workspace>/");
613
+ };
607
614
  var workflowDiagnosticFromContext = (diagnostic) => ({
608
615
  severity: diagnostic.severity,
609
616
  code: diagnostic.code,
@@ -720,8 +727,8 @@ class ContextRunner extends runner("context") {
720
727
  await workspace.writeFile(codexMcpConfigPath, merged);
721
728
  return codexMcpConfigPath;
722
729
  }
723
- listMcpTools(mode = "readonly") {
724
- return listAkanMcpTools(mode);
730
+ listMcpTools(mode = "readonly", { guidelineNames = [] } = {}) {
731
+ return listAkanMcpTools(mode, { guidelineNames });
725
732
  }
726
733
  async callMcpTool(workspace, name, args = {}, { mode = "readonly" } = {}) {
727
734
  const availableTools = this.listMcpTools(mode);
@@ -851,17 +858,20 @@ class ContextRunner extends runner("context") {
851
858
  ${payload}`);
852
859
  };
853
860
  const respond = (id, result, framing) => {
854
- writeMessage({ jsonrpc: "2.0", id, result }, framing);
861
+ writeMessage({ jsonrpc: "2.0", id: id ?? null, result }, framing);
855
862
  };
856
863
  const respondError = (id, code, message, framing) => {
857
- writeMessage({ jsonrpc: "2.0", id, error: { code, message } }, framing);
864
+ writeMessage({ jsonrpc: "2.0", id: id ?? null, error: { code, message } }, framing);
858
865
  };
866
+ const guidelineNames = await Prompter.listGuidelines();
867
+ const resources = buildResourceList(guidelineNames);
859
868
  const readResource = async (uri) => {
860
- const context = await AkanContextAnalyzer.analyze(workspace);
861
- if (uri === "akan://docs/framework" || uri === "akan://guidelines/framework")
869
+ if (uri === "akan://docs/framework")
862
870
  return { uri, mimeType: "text/markdown", text: await Prompter.getInstruction("framework") };
863
- if (uri === "akan://guidelines/modelSignal")
864
- return { uri, mimeType: "text/markdown", text: await Prompter.getInstruction("modelSignal") };
871
+ const guideline = /^akan:\/\/guidelines\/(.+)$/.exec(uri)?.[1];
872
+ if (guideline)
873
+ return { uri, mimeType: "text/markdown", text: await Prompter.getInstruction(guideline) };
874
+ const context = await AkanContextAnalyzer.analyze(workspace);
865
875
  if (uri === "akan://workspace/summary")
866
876
  return { uri, mimeType: "application/json", text: jsonText(context, { trailingNewline: false }) };
867
877
  if (uri === "akan://workspace/apps")
@@ -883,7 +893,7 @@ ${payload}`);
883
893
  }
884
894
  throw new Error(`Unknown resource: ${uri}`);
885
895
  };
886
- const handle = async (request, framing) => {
896
+ const handleRequest = async (request, framing) => {
887
897
  const params = request.params ?? {};
888
898
  if (request.method === "initialize") {
889
899
  respond(request.id, {
@@ -893,7 +903,7 @@ ${payload}`);
893
903
  }, framing);
894
904
  } else if (request.method === "tools/list") {
895
905
  respond(request.id, {
896
- tools: this.listMcpTools(mode)
906
+ tools: this.listMcpTools(mode, { guidelineNames })
897
907
  }, framing);
898
908
  } else if (request.method === "tools/call") {
899
909
  const name = params.name;
@@ -909,16 +919,39 @@ ${payload}`);
909
919
  ]
910
920
  }, framing);
911
921
  } catch (error) {
912
- respondError(request.id, -32602, error instanceof Error ? error.message : String(error), framing);
922
+ respond(request.id, { content: [{ type: "text", text: toolErrorText(error) }], isError: true }, framing);
913
923
  }
914
924
  } else if (request.method === "resources/list") {
915
- respond(request.id, { resources: resourceList }, framing);
925
+ respond(request.id, { resources }, framing);
916
926
  } else if (request.method === "resources/read") {
917
927
  respond(request.id, { contents: [await readResource(params.uri)] }, framing);
918
- } else if (!request.method.endsWith("/initialized")) {
928
+ } else {
919
929
  respondError(request.id, -32601, `Unknown method: ${request.method}`, framing);
920
930
  }
921
931
  };
932
+ const handle = async (request, framing) => {
933
+ if (request.id === undefined || request.id === null)
934
+ return;
935
+ try {
936
+ await handleRequest(request, framing);
937
+ } catch (error) {
938
+ respondError(request.id, -32603, error instanceof Error ? error.message : String(error), framing);
939
+ }
940
+ };
941
+ const handleFrame = async (payload, framing) => {
942
+ let request;
943
+ try {
944
+ request = JSON.parse(payload);
945
+ } catch (error) {
946
+ respondError(null, -32700, error instanceof Error ? error.message : String(error), framing);
947
+ return;
948
+ }
949
+ if (!request || typeof request !== "object" || typeof request.method !== "string") {
950
+ respondError(null, -32600, "Invalid Request: expected a JSON-RPC 2.0 object with a method", framing);
951
+ return;
952
+ }
953
+ await handle(request, framing);
954
+ };
922
955
  const parseContentLengthMessage = async () => {
923
956
  const headerEnd = buffer.indexOf(`\r
924
957
  \r
@@ -938,7 +971,7 @@ ${payload}`);
938
971
  return false;
939
972
  const body = buffer.slice(bodyStart, bodyEnd);
940
973
  buffer = buffer.slice(bodyEnd);
941
- await handle(JSON.parse(body), "content-length");
974
+ await handleFrame(body, "content-length");
942
975
  return true;
943
976
  };
944
977
  const parseLineMessage = async () => {
@@ -950,7 +983,7 @@ ${payload}`);
950
983
  buffer = buffer.slice(lineEnd + 1);
951
984
  if (!line)
952
985
  return true;
953
- await handle(JSON.parse(line), "newline");
986
+ await handleFrame(line, "newline");
954
987
  return true;
955
988
  };
956
989
  const parse = async () => {
@@ -9,6 +9,8 @@ import * as path from "path";
9
9
  import ignore from "ignore";
10
10
  import ts from "typescript";
11
11
  var testFileRegex = /\.(?:test|spec)\.[cm]?[tj]sx?$/;
12
+ var skipDirs = ["node_modules", "dist", "build", ".git", ".next", "public", "ios", "android", "__fixtures__"];
13
+ var isSkippedPath = (filePath) => skipDirs.some((dir) => filePath.includes(`/${dir}/`) || filePath.startsWith(`${dir}/`));
12
14
  var builtinModuleSet = new Set([...builtinModules, ...builtinModules.map((mod) => `node:${mod}`)]);
13
15
  var stripShebang = (source) => source.replace(/^#!.*(?:\r?\n|$)/, "");
14
16
 
@@ -19,22 +21,22 @@ class TypeScriptDependencyScanner {
19
21
  #visitedFiles = new Set;
20
22
  #tsTranspiler = new Bun.Transpiler({ loader: "ts" });
21
23
  #tsxTranspiler = new Bun.Transpiler({ loader: "tsx" });
22
- directory;
23
- rootPackageJson;
24
- ig;
25
- workspaceRoot;
24
+ #directory;
25
+ #rootPackageJson;
26
+ #ig;
27
+ #workspaceRoot;
26
28
  constructor(directory, {
27
29
  workspaceRoot,
28
30
  rootPackageJson,
29
31
  gitignorePatterns = []
30
32
  }) {
31
- this.directory = directory;
32
- this.rootPackageJson = rootPackageJson;
33
- this.ig = ignore().add(gitignorePatterns);
34
- this.workspaceRoot = workspaceRoot;
33
+ this.#directory = directory;
34
+ this.#rootPackageJson = rootPackageJson;
35
+ this.#ig = ignore().add(gitignorePatterns);
36
+ this.#workspaceRoot = workspaceRoot;
35
37
  }
36
38
  async getMonorepoDependencies(projectName, { pkgs = [], libs = [] } = {}) {
37
- const npmSet = new Set(Object.keys({ ...this.rootPackageJson.dependencies, ...this.rootPackageJson.devDependencies }));
39
+ const npmSet = new Set(Object.keys({ ...this.#rootPackageJson.dependencies, ...this.#rootPackageJson.devDependencies }));
38
40
  const pkgPathSet = new Set(pkgs);
39
41
  const libPathSet = new Set(libs.map((lib) => `@libs/${lib}`));
40
42
  await this.getDependencies();
@@ -52,11 +54,11 @@ class TypeScriptDependencyScanner {
52
54
  async getPackageBuildDependencies(projectName) {
53
55
  const runtimeDeps = new Set;
54
56
  const devDeps = new Set;
55
- const sourceFiles = await this.#findTypeScriptFiles(this.directory, {
57
+ const sourceFiles = await this.#findTypeScriptFiles(this.#directory, {
56
58
  excludeBuildFiles: true,
57
59
  excludeTestFiles: true
58
60
  });
59
- const cssFiles = await this.#findCssFiles(this.directory);
61
+ const cssFiles = await this.#findCssFiles(this.#directory);
60
62
  for (const filePath of sourceFiles) {
61
63
  const fileContent = await FileSys.readText(filePath);
62
64
  const { imports, typeImports } = this.#extractImports(fileContent, filePath);
@@ -67,7 +69,7 @@ class TypeScriptDependencyScanner {
67
69
  const fileContent = await FileSys.readText(filePath);
68
70
  this.#addNormalizedImports(runtimeDeps, this.#extractCssPluginImports(fileContent), projectName);
69
71
  }
70
- const buildFilePath = path.join(this.directory, "build.ts");
72
+ const buildFilePath = path.join(this.#directory, "build.ts");
71
73
  if (await FileSys.fileExists(buildFilePath)) {
72
74
  const fileContent = await FileSys.readText(buildFilePath);
73
75
  const { imports, typeImports } = this.#extractImports(fileContent, buildFilePath);
@@ -75,7 +77,7 @@ class TypeScriptDependencyScanner {
75
77
  }
76
78
  for (const dep of runtimeDeps)
77
79
  devDeps.delete(dep);
78
- const rootDeps = { ...this.rootPackageJson.dependencies, ...this.rootPackageJson.devDependencies };
80
+ const rootDeps = { ...this.#rootPackageJson.dependencies, ...this.#rootPackageJson.devDependencies };
79
81
  const missingDeps = [];
80
82
  for (const dep of [...runtimeDeps, ...devDeps]) {
81
83
  if (rootDeps[dep] || await this.#hasWorkspacePackage(dep))
@@ -89,7 +91,7 @@ class TypeScriptDependencyScanner {
89
91
  };
90
92
  }
91
93
  async#hasWorkspacePackage(dep) {
92
- const packageJsonPath = path.join(this.workspaceRoot, "pkgs", dep, "package.json");
94
+ const packageJsonPath = path.join(this.#workspaceRoot, "pkgs", dep, "package.json");
93
95
  if (!await Bun.file(packageJsonPath).exists())
94
96
  return false;
95
97
  try {
@@ -132,9 +134,9 @@ class TypeScriptDependencyScanner {
132
134
  this.#fileRuntimeDependencies.clear();
133
135
  this.#fileTypeDependencies.clear();
134
136
  this.#visitedFiles.clear();
135
- const files = await this.#findTypeScriptFiles(this.directory);
137
+ const files = await this.#findTypeScriptFiles(this.#directory);
136
138
  for (const file of files)
137
- await this.#analyzeFile(file, this.directory);
139
+ await this.#analyzeFile(file, this.#directory);
138
140
  return this.#fileDependencies;
139
141
  }
140
142
  async#findTypeScriptFiles(directory, {
@@ -142,18 +144,17 @@ class TypeScriptDependencyScanner {
142
144
  excludeTestFiles = false
143
145
  } = {}) {
144
146
  const files = [];
145
- const skipDirs = ["node_modules", "dist", "build", ".git", ".next", "public", "ios", "android"];
146
147
  const glob = new Bun.Glob("**/*.{ts,tsx}");
147
148
  for await (const filePath of glob.scan({ cwd: directory, onlyFiles: true })) {
148
- if (skipDirs.some((dir) => filePath.includes(`/${dir}/`) || filePath.startsWith(`${dir}/`)))
149
+ if (isSkippedPath(filePath))
149
150
  continue;
150
151
  if (excludeBuildFiles && filePath === "build.ts")
151
152
  continue;
152
153
  if (excludeTestFiles && testFileRegex.test(filePath))
153
154
  continue;
154
155
  const fullPath = path.join(directory, filePath);
155
- const relativePath = path.relative(this.workspaceRoot, fullPath);
156
- if (this.ig.ignores(relativePath))
156
+ const relativePath = path.relative(this.#workspaceRoot, fullPath);
157
+ if (this.#ig.ignores(relativePath))
157
158
  continue;
158
159
  files.push(fullPath);
159
160
  }
@@ -161,14 +162,13 @@ class TypeScriptDependencyScanner {
161
162
  }
162
163
  async#findCssFiles(directory) {
163
164
  const files = [];
164
- const skipDirs = ["node_modules", "dist", "build", ".git", ".next", "public", "ios", "android"];
165
165
  const glob = new Bun.Glob("**/*.css");
166
166
  for await (const filePath of glob.scan({ cwd: directory, onlyFiles: true })) {
167
- if (skipDirs.some((dir) => filePath.includes(`/${dir}/`) || filePath.startsWith(`${dir}/`)))
167
+ if (isSkippedPath(filePath))
168
168
  continue;
169
169
  const fullPath = path.join(directory, filePath);
170
- const relativePath = path.relative(this.workspaceRoot, fullPath);
171
- if (this.ig.ignores(relativePath))
170
+ const relativePath = path.relative(this.#workspaceRoot, fullPath);
171
+ if (this.#ig.ignores(relativePath))
172
172
  continue;
173
173
  files.push(fullPath);
174
174
  }
@@ -551,6 +551,7 @@ ${this.basePaths.size ? `ENV AKAN_PUBLIC_BASE_PATHS=${[...this.basePaths].join("
551
551
  ENV AKAN_PUBLIC_DEFAULT_LOCALE=${this.i18n.defaultLocale}
552
552
  ENV AKAN_PUBLIC_LOCALES=${this.i18n.locales.join(",")}
553
553
  ENV AKAN_PUBLIC_OPERATION_MODE=cloud
554
+ ENV AKAN_LOG_TO_FILE=0
554
555
  ${webEnvLines}
555
556
  CMD [${command.map((c) => `"${c}"`).join(",")}]`;
556
557
  }
@@ -719,6 +720,53 @@ import { spawn } from "child_process";
719
720
  import { existsSync, readFileSync } from "fs";
720
721
  import path2 from "path";
721
722
  import chalk from "chalk";
723
+ var parseBiomeReport = (output) => {
724
+ for (let start = output.indexOf("{");start !== -1; start = output.indexOf("{", start + 1)) {
725
+ const end = objectEndAt(output, start);
726
+ if (end === -1)
727
+ break;
728
+ const report = asBiomeReport(output.slice(start, end + 1));
729
+ if (report)
730
+ return report;
731
+ }
732
+ throw new Error(output.trim() || "No Biome JSON output");
733
+ };
734
+ var objectEndAt = (output, start) => {
735
+ let depth = 0;
736
+ let inString = false;
737
+ let escaped = false;
738
+ for (let idx = start;idx < output.length; idx += 1) {
739
+ const char = output[idx];
740
+ if (inString) {
741
+ if (escaped)
742
+ escaped = false;
743
+ else if (char === "\\")
744
+ escaped = true;
745
+ else if (char === '"')
746
+ inString = false;
747
+ continue;
748
+ }
749
+ if (char === '"')
750
+ inString = true;
751
+ else if (char === "{")
752
+ depth += 1;
753
+ else if (char === "}" && --depth === 0)
754
+ return idx;
755
+ }
756
+ return -1;
757
+ };
758
+ var asBiomeReport = (candidate) => {
759
+ try {
760
+ const parsed = JSON.parse(candidate);
761
+ if (!parsed || typeof parsed !== "object")
762
+ return null;
763
+ if (!("diagnostics" in parsed) && !("summary" in parsed))
764
+ return null;
765
+ return parsed;
766
+ } catch {
767
+ return null;
768
+ }
769
+ };
722
770
  var BIOME_CONFIG_FILES = ["biome.json", "biome.jsonc"];
723
771
 
724
772
  class Linter {
@@ -775,13 +823,6 @@ class Linter {
775
823
  proc.stdin.end(input);
776
824
  });
777
825
  }
778
- #parseBiomeReport(output) {
779
- const jsonStart = output.indexOf("{");
780
- const jsonEnd = output.lastIndexOf("}");
781
- if (jsonStart === -1 || jsonEnd === -1 || jsonEnd < jsonStart)
782
- throw new Error(output.trim() || "No Biome JSON output");
783
- return JSON.parse(output.slice(jsonStart, jsonEnd + 1));
784
- }
785
826
  #diagnosticFilePath(diagnostic, fallbackFilePath) {
786
827
  const diagnosticPath = diagnostic.location?.path;
787
828
  if (!diagnosticPath)
@@ -854,7 +895,7 @@ class Linter {
854
895
  this.configPath,
855
896
  this.#toBiomePath(filePath)
856
897
  ]);
857
- const report = this.#parseBiomeReport(stdout || stderr);
898
+ const report = parseBiomeReport(stdout || stderr);
858
899
  const results = this.#toLintResults(report, filePath);
859
900
  const { errors, warnings } = this.#splitMessages(results);
860
901
  const output = write && existsSync(filePath) ? readFileSync(filePath, "utf8") : undefined;
@@ -976,6 +1017,25 @@ ${errorText}, ${warningText} found`];
976
1017
  const lintResult = await this.lintFile(resolvedFilePath);
977
1018
  return { ...lintResult, fixed: stdout !== source, output: stdout };
978
1019
  }
1020
+ async fixFiles(filePaths) {
1021
+ const resolved = filePaths.map((filePath) => this.#resolveFilePath(filePath)).filter(existsSync);
1022
+ if (resolved.length === 0)
1023
+ return { fixed: [] };
1024
+ const before = new Map(resolved.map((filePath) => [filePath, readFileSync(filePath, "utf8")]));
1025
+ await this.#runBiome([
1026
+ "check",
1027
+ "--write",
1028
+ "--reporter=json",
1029
+ "--max-diagnostics=none",
1030
+ "--no-errors-on-unmatched",
1031
+ "--config-path",
1032
+ this.configPath,
1033
+ ...resolved.map((filePath) => this.#toBiomePath(filePath))
1034
+ ]);
1035
+ return {
1036
+ fixed: resolved.filter((filePath) => readFileSync(filePath, "utf8") !== before.get(filePath))
1037
+ };
1038
+ }
979
1039
  async getConfigForFile(filePath) {
980
1040
  const resolvedFilePath = this.#resolveFilePath(filePath);
981
1041
  if (!existsSync(resolvedFilePath))
@@ -1126,7 +1186,7 @@ var moduleUiFileTypes = {
1126
1186
  scalar: new Set(["Template", "Unit"])
1127
1187
  };
1128
1188
  var testFilePattern = /\.(test|spec)\.(ts|tsx)$/;
1129
- var createDependencyScanner = async (exec) => (await import("./dependencyScanner-rbs2407b.js")).TypeScriptDependencyScanner.from(exec);
1189
+ var createDependencyScanner = async (exec) => (await import("./dependencyScanner-aqg3dkks.js")).TypeScriptDependencyScanner.from(exec);
1130
1190
  var isAllowedTestFile = (filename) => testFilePattern.test(filename);
1131
1191
  var getScanPath = (exec, relativePath) => path4.posix.join(`${exec.type}s`, exec.name, relativePath.split(path4.sep).join("/"));
1132
1192
  async function clearGeneratedRootCapacitorConfigs(exec) {
@@ -1543,7 +1603,7 @@ class LibInfo extends ScanInfo {
1543
1603
  class PkgInfo {
1544
1604
  exec;
1545
1605
  name;
1546
- scanResult;
1606
+ #scanResult;
1547
1607
  static async scanExecutor(exec) {
1548
1608
  const [tsconfig, rootPackageJson] = await Promise.all([exec.getTsConfig(), exec.workspace.getPackageJson()]);
1549
1609
  const scanner = await createDependencyScanner(exec);
@@ -1574,10 +1634,10 @@ class PkgInfo {
1574
1634
  constructor(exec, scanResult) {
1575
1635
  this.exec = exec;
1576
1636
  this.name = exec.name;
1577
- this.scanResult = scanResult;
1637
+ this.#scanResult = scanResult;
1578
1638
  }
1579
1639
  getScanResult() {
1580
- return this.scanResult;
1640
+ return this.#scanResult;
1581
1641
  }
1582
1642
  }
1583
1643
 
@@ -2167,10 +2227,24 @@ class Executor {
2167
2227
  ...options.dict ?? {},
2168
2228
  ...Object.fromEntries(Object.entries(options.dict ?? {}).map(([key, value]) => [capitalize(key), capitalize(value)]))
2169
2229
  };
2170
- return this._applyTemplate({ ...options, dict });
2230
+ const fileContents = await this._applyTemplate({ ...options, dict });
2231
+ await this.#formatAppliedTemplate(fileContents);
2232
+ return fileContents;
2233
+ }
2234
+ async#formatAppliedTemplate(fileContents) {
2235
+ const filePaths = fileContents.map((fileContent) => fileContent.filePath).filter((filePath) => filePath.endsWith(".ts") || filePath.endsWith(".tsx"));
2236
+ if (filePaths.length === 0)
2237
+ return;
2238
+ try {
2239
+ const { fixed } = await this.getLinter().fixFiles(filePaths);
2240
+ if (fixed.length > 0)
2241
+ this.logger.verbose(`Formatted ${fixed.length} scaffolded file(s)`);
2242
+ } catch (err) {
2243
+ this.logger.verbose(`Skipped formatting scaffolded files: ${err instanceof Error ? err.message : String(err)}`);
2244
+ }
2171
2245
  }
2172
2246
  async getTypeChecker() {
2173
- const { TypeChecker } = await import("./typeChecker-g6bh0xfv.js");
2247
+ const { TypeChecker } = await import("./typeChecker-yhs4eht8.js");
2174
2248
  this.typeChecker ??= new TypeChecker(this);
2175
2249
  return this.typeChecker;
2176
2250
  }
@@ -2356,10 +2430,10 @@ class WorkspaceExecutor extends Executor {
2356
2430
  }
2357
2431
  async commit(message, { init = false, add = true } = {}) {
2358
2432
  if (init)
2359
- await this.exec(`git init --quiet`);
2433
+ await this.spawn("git", ["init", "--quiet"]);
2360
2434
  if (add)
2361
- await this.exec(`git add .`);
2362
- await this.exec(`git commit --quiet -m "${message}"`);
2435
+ await this.spawn("git", ["add", "."]);
2436
+ await this.spawn("git", ["commit", "--quiet", "-m", message]);
2363
2437
  }
2364
2438
  async#getDirHasFile(basePath, targetFilename) {
2365
2439
  const AVOID_DIRS = ["node_modules", "dist", "public", "webkit"];
@@ -2698,8 +2772,7 @@ class AppExecutor extends SysExecutor {
2698
2772
  if (type === "build") {
2699
2773
  this.#excludeDevOnlyPages = true;
2700
2774
  this.#pageKeys = null;
2701
- if (await this.exists(this.dist.cwdPath))
2702
- await this.dist.exec(`rm -rf ${this.dist.cwdPath}`);
2775
+ await this.dist.removeDir(this.dist.cwdPath);
2703
2776
  await Promise.all([this.dist.mkdir("private"), this.dist.mkdir("public")]);
2704
2777
  await Promise.all([
2705
2778
  this.cp("private", `${this.dist.cwdPath}/private`, { dereference: true }),
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-e31ghfp5.js";
5
+ } from "./index-akz5xvyw.js";
6
6
  import {
7
7
  LibExecutor
8
- } from "./index-nkwmnqwn.js";
8
+ } from "./index-h9cybjep.js";
9
9
 
10
10
  // pkgs/@akanjs/cli/semver.ts
11
11
  var stripRangeOperator = (version) => version.replace(/^[\s^~>=<v]+/, "").trim();
@@ -34,13 +34,13 @@ var compareSemver = (a, b) => {
34
34
  // pkgs/@akanjs/cli/library/library.runner.ts
35
35
  class LibraryRunner extends runner("library") {
36
36
  async createLibrary(libName, workspace) {
37
- await workspace.exec(`mkdir -p libs/${libName}`);
37
+ await workspace.mkdir(`libs/${libName}`);
38
38
  await workspace.applyTemplate({ basePath: `libs/${libName}`, template: "libRoot", dict: { libName } });
39
39
  const lib = LibExecutor.from(workspace, libName);
40
40
  return lib;
41
41
  }
42
42
  async removeLibrary(lib) {
43
- await lib.workspace.exec(`rm -rf libs/${lib.name}`);
43
+ await lib.workspace.removeDir(`libs/${lib.name}`);
44
44
  }
45
45
  async#copyInstalledLibrary(workspace, libName) {
46
46
  const installedPackageJson = `node_modules/akanjs/libs/${libName}/package.json`;
@@ -88,7 +88,6 @@ class LibraryRunner extends runner("library") {
88
88
  await lib.workspace.spawn("bun", ["install"]);
89
89
  await lib.workspace.commit(`Merge ${lib.name} library dependencies`);
90
90
  }
91
- async testLibrary(lib) {}
92
91
  }
93
92
 
94
93
  // pkgs/@akanjs/cli/library/library.script.ts
@@ -118,11 +117,6 @@ class LibraryScript extends script("library", [LibraryRunner]) {
118
117
  await this.libraryRunner.mergeLibraryDependencies(lib);
119
118
  mergeSpinner.succeed(`${libName} library (libs/${libName}) dependencies merged to root package.json`);
120
119
  }
121
- async testLibrary(lib) {
122
- const spinner = lib.spinning("Testing library...");
123
- await this.libraryRunner.testLibrary(lib);
124
- spinner.succeed(`Library ${lib.name} (libs/${lib.name}) test is successful`);
125
- }
126
120
  }
127
121
 
128
122
  export { LibraryScript };
@@ -349,7 +349,7 @@ var resolveNodePackageExport = async (workspaceRoot, specifier) => {
349
349
  const subpath = specifier === packageName ? "." : `.${specifier.slice(packageName.length)}`;
350
350
  const exported = resolvePackageExport(pkgJson.exports, subpath);
351
351
  const rel = exported ?? (subpath === "." ? pkgJson.module ?? pkgJson.main ?? "index.js" : null);
352
- if (!rel || !rel.startsWith("."))
352
+ if (!rel?.startsWith("."))
353
353
  return null;
354
354
  const entryFile = await resolveFileCandidate(path2.resolve(pkgDir, rel));
355
355
  if (!entryFile)
@@ -1518,6 +1518,8 @@ class AutoImportSync {
1518
1518
  const [scope, project, facet] = parts;
1519
1519
  if (scope !== "apps" && scope !== "libs" || !project || !facet)
1520
1520
  return null;
1521
+ if (facet === "lib" && parts[3] === "__lib")
1522
+ return null;
1521
1523
  const role = roleFor(facet, base);
1522
1524
  if (!role)
1523
1525
  return null;
@@ -19,7 +19,6 @@ class Prompter {
19
19
  return candidates[0];
20
20
  }
21
21
  static async selectGuideline() {
22
- const guidelineRoot = await Prompter.#getGuidelineRoot();
23
22
  const guideNames = await Prompter.listGuidelines();
24
23
  return await select({
25
24
  message: "Select a guideline",
@@ -37,10 +36,11 @@ class Prompter {
37
36
  return JSON.parse(guideJson);
38
37
  }
39
38
  static async getInstruction(guideName) {
39
+ const guideNames = await Prompter.listGuidelines();
40
+ if (!guideNames.includes(guideName))
41
+ throw new Error(`Unknown guideline "${guideName}". Available: ${guideNames.join(", ")}`);
40
42
  const guidelineRoot = await Prompter.#getGuidelineRoot();
41
- const filePath = `${guidelineRoot}/${guideName}/${guideName}.instruction.md`;
42
- const content = await fsPromise.readFile(filePath, "utf-8");
43
- return content;
43
+ return await fsPromise.readFile(`${guidelineRoot}/${guideName}/${guideName}.instruction.md`, "utf-8");
44
44
  }
45
45
  static async getUpdateRequest(guideName) {
46
46
  return await input({
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  AppExecutor,
4
4
  LibExecutor
5
- } from "./index-nkwmnqwn.js";
5
+ } from "./index-h9cybjep.js";
6
6
 
7
7
  // pkgs/@akanjs/devkit/workflow/utils.ts
8
8
  var jsonText = (value, { trailingNewline = true } = {}) => `${JSON.stringify(value, null, 2)}${trailingNewline ? `
@@ -1,17 +1,17 @@
1
1
  // @bun
2
2
  import {
3
3
  AkanContextAnalyzer
4
- } from "./index-va15r8h5.js";
4
+ } from "./index-bmz9crym.js";
5
5
  import {
6
6
  createRepairReport,
7
7
  generatedFilePathsForTarget,
8
8
  renderRepairReport,
9
9
  writeGeneratedSyncState,
10
10
  writeWorkflowRunArtifact
11
- } from "./index-ytaqtc04.js";
11
+ } from "./index-q0s2dp3y.js";
12
12
  import {
13
13
  runner
14
- } from "./index-e31ghfp5.js";
14
+ } from "./index-akz5xvyw.js";
15
15
 
16
16
  // pkgs/@akanjs/cli/repair/repair.runner.ts
17
17
  var commandForShell = (command) => command.startsWith("akan ") ? `bun run ${command}` : command;