@akanjs/cli 3.0.0-alpha.1 → 3.0.0-alpha.100

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 (162) hide show
  1. package/.build-stamp +1 -1
  2. package/README.ko.md +1 -1
  3. package/README.md +1 -1
  4. package/{abstractCompactor-e5yq60qz.js → abstractCompactor-byytxs22.js} +3 -5
  5. package/{agent.command-yv00p0s0.js → agent.command-v1a4746v.js} +11 -12
  6. package/{application.command-0qsczf4k.js → application.command-fzdcnzhg.js} +65 -37
  7. package/{applicationBuildRunner-ct2pxyvw.js → applicationBuildRunner-s4gsk728.js} +28 -24
  8. package/{applicationReleasePackager-gg8ccbeh.js → applicationReleasePackager-28v9vbzk.js} +8 -9
  9. package/buildBatch.proc.js +12 -13
  10. package/capacitorApp-8d6d4zkm.js +12 -0
  11. package/{cloud.command-dxfv18sa.js → cloud.command-wygy2z05.js} +15 -17
  12. package/commandManifest.json +1 -1
  13. package/{context.command-8d9e3k6b.js → context.command-4vdt1aqq.js} +19 -22
  14. package/dependencyScanner-shs82ynp.js +8 -0
  15. package/devTui-qnf1txdz.js +553 -0
  16. package/devTuiView-yzct2cq6.js +9 -0
  17. package/getDirname-dr3jz1xg.js +7 -0
  18. package/{guideline.command-3jbkxzh6.js → guideline.command-p92dq6ts.js} +16 -17
  19. package/guidelines/agentRule/agentRule.generate.json +31 -0
  20. package/guidelines/agentRule/agentRule.instruction.md +533 -0
  21. package/guidelines/conventions/conventions.generate.json +25 -0
  22. package/guidelines/conventions/conventions.instruction.md +908 -0
  23. package/guidelines/cssRule/cssRule.instruction.md +7 -0
  24. package/guidelines/framework/framework.generate.json +3 -2
  25. package/guidelines/framework/framework.instruction.md +1 -9
  26. package/guidelines/mcpRule/mcpRule.generate.json +25 -0
  27. package/guidelines/mcpRule/mcpRule.instruction.md +217 -0
  28. package/guidelines/modelStore/modelStore.instruction.md +12 -0
  29. package/guidelines/modelTemplate/modelTemplate.instruction.md +5 -0
  30. package/guidelines/queryRule/queryRule.generate.json +31 -0
  31. package/guidelines/queryRule/queryRule.instruction.md +175 -0
  32. package/guidelines/runtimeRule/runtimeRule.generate.json +25 -0
  33. package/guidelines/runtimeRule/runtimeRule.instruction.md +220 -0
  34. package/guidelines/ssrRule/ssrRule.instruction.md +49 -5
  35. package/guidelines/transportRule/transportRule.generate.json +31 -0
  36. package/guidelines/transportRule/transportRule.instruction.md +60 -0
  37. package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +24 -0
  38. package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +263 -0
  39. package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +33 -0
  40. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +402 -0
  41. package/incrementalBuilder.proc.js +26 -24
  42. package/{index-mr5s7mqd.js → index-0amdxycf.js} +8 -8
  43. package/{index-t3723f99.js → index-1yxtbmbj.js} +111 -42
  44. package/{index-ej426mcr.js → index-29sxqfaw.js} +65 -38
  45. package/index-3d9y066c.js +76 -0
  46. package/{index-76rn3g2c.js → index-47pj3aee.js} +4 -4
  47. package/index-5svjba73.js +159 -0
  48. package/index-6wwzs1bc.js +7 -0
  49. package/{index-k95xkh4p.js → index-7d6vny25.js} +16 -12
  50. package/{index-ec09pws3.js → index-8p8p0cf8.js} +14 -14
  51. package/{index-wnp7hwq7.js → index-92zztqy1.js} +7 -7
  52. package/{index-fgc8r6dj.js → index-a5vmm6x4.js} +3 -1
  53. package/{index-xys926f2.js → index-by5gpp8x.js} +4 -4
  54. package/{index-0cj2zxbm.js → index-c69j78kk.js} +12 -11
  55. package/{index-rzwcpcc3.js → index-fc1bh0a7.js} +4 -4
  56. package/{index-7c6k4yvg.js → index-gq44bqjt.js} +58 -25
  57. package/{index-a00jg8x8.js → index-gtmz74tj.js} +79 -55
  58. package/{index-tdbas9r0.js → index-h7yw2z9n.js} +7 -7
  59. package/{index-bjpxzr6s.js → index-hwkygn9s.js} +51 -3
  60. package/{index-bbkek1bp.js → index-hyywke0f.js} +1 -1
  61. package/{index-46tjzh6s.js → index-kcxmv48c.js} +29 -29
  62. package/{index-xjd3rqzj.js → index-n68jx79w.js} +6 -15
  63. package/{index-pyt2b4nw.js → index-p5neav9b.js} +1129 -1356
  64. package/{index-67546d0j.js → index-q0y2jq9j.js} +14 -2
  65. package/{index-bekddz9q.js → index-qkk27bk6.js} +32 -32
  66. package/{index-hgna5rjy.js → index-qsq3q8fy.js} +1034 -257
  67. package/{index-2q1f5j9k.js → index-srdssqj7.js} +18 -18
  68. package/{index-rh16j3c7.js → index-w8kmx1b6.js} +23 -13
  69. package/{index-nm6wghb6.js → index-yks023mb.js} +13 -13
  70. package/{index-1pvex4az.js → index-yza7zkpt.js} +94 -61
  71. package/{index-yzmhasdb.js → index-zmjppp25.js} +57 -57
  72. package/{index-8hsbnyes.js → index-znynzt5w.js} +100 -30
  73. package/{index-zasydjxd.js → index-zxgr3s8s.js} +31 -30
  74. package/{index-e16gnn26.js → index-zz5jyd94.js} +1002 -128
  75. package/index.js +22 -24
  76. package/{library.command-ebdj1vnm.js → library.command-s4fszngs.js} +11 -9
  77. package/{localRegistry.command-gb178ne8.js → localRegistry.command-gyw4da9z.js} +20 -22
  78. package/{module.command-9c1bnsx4.js → module.command-6n7dwvav.js} +13 -15
  79. package/{package.command-t93p4jkj.js → package.command-gr82ypnr.js} +8 -9
  80. package/package.json +5 -7
  81. package/{page.command-k3k0meh2.js → page.command-7gvgb3jb.js} +7 -8
  82. package/{primitive.command-de6nktdt.js → primitive.command-tk5ckw38.js} +13 -15
  83. package/{quality.command-z5kth2wa.js → quality.command-38v81baf.js} +229 -138
  84. package/recipeScanner-fpagtgc1.js +11 -0
  85. package/{repair.command-ehf2g112.js → repair.command-5xbwvsxp.js} +12 -13
  86. package/{routeSourceValidator-cncd92fv.js → routeSourceValidator-ze6x894c.js} +2 -40
  87. package/{scalar.command-7a2jtv33.js → scalar.command-0epwcr5k.js} +11 -13
  88. package/subspace.command-e2t36xb2.js +755 -0
  89. package/templates/app/env/env.client.debug.ts.template +1 -5
  90. package/templates/app/env/env.client.develop.ts.template +1 -5
  91. package/templates/app/env/env.client.local.ts.template +1 -5
  92. package/templates/app/env/env.client.main.ts.template +1 -5
  93. package/templates/app/env/env.client.testing.ts.template +1 -5
  94. package/templates/app/env/env.client.type.ts +2 -6
  95. package/templates/app/env/env.server.debug.ts.template +1 -5
  96. package/templates/app/env/env.server.develop.ts.template +1 -5
  97. package/templates/app/env/env.server.local.ts.template +1 -5
  98. package/templates/app/env/env.server.main.ts.template +1 -5
  99. package/templates/app/main.ts +3 -1
  100. package/templates/app/page/styles.css.template +3 -3
  101. package/templates/appSample/lib/task/task.signal.ts +11 -6
  102. package/templates/appSample/srvkit/AuthGuard.ts +9 -5
  103. package/templates/appSample/srvkit/SessionInternalArg.ts +4 -3
  104. package/templates/crudPages/[__model__Id]/edit/page.tsx +6 -6
  105. package/templates/crudPages/[__model__Id]/page.tsx +10 -13
  106. package/templates/crudPages/new/page.tsx +6 -6
  107. package/templates/crudPages/page.tsx +9 -9
  108. package/templates/crudSinglePage/page.tsx +11 -7
  109. package/templates/env/_env.server.type.ts +7 -5
  110. package/templates/lib/db.ts +4 -2
  111. package/templates/lib/dict.ts +1 -1
  112. package/templates/lib/sig.ts +5 -1
  113. package/templates/lib/srv.ts +6 -2
  114. package/templates/lib/useClient.ts +9 -3
  115. package/templates/module/__Model__.Util.tsx +1 -1
  116. package/templates/module/__Model__.Zone.tsx +3 -5
  117. package/templates/module/__model__.dictionary.ts +4 -1
  118. package/templates/module/__model__.signal.ts +2 -3
  119. package/templates/module/__model__.store.ts +1 -2
  120. package/templates/workspaceRoot/.gitignore.template +0 -1
  121. package/templates/workspaceRoot/.husky/pre-commit.template +16 -0
  122. package/templates/workspaceRoot/.vscode/settings.json.template +1 -1
  123. package/templates/workspaceRoot/AGENTS.md.template +4 -948
  124. package/templates/workspaceRoot/CLAUDE.md.template +19 -0
  125. package/templates/workspaceRoot/biome.json.template +4 -198
  126. package/templates/workspaceRoot/docs/AI-DEVELOPMENT.md.template +15 -16
  127. package/templates/workspaceRoot/docs/GENERATED.md.template +12 -10
  128. package/templates/workspaceRoot/package.json.template +2 -4
  129. package/typeChecker-3xgrzc2v.js +7 -0
  130. package/typecheck.proc.js +4 -5
  131. package/{workflow.command-e0tt0vk2.js → workflow.command-kphbr7eh.js} +21 -23
  132. package/{workspace.command-fpda0evj.js → workspace.command-j1gatz3d.js} +108 -91
  133. package/capacitorApp-4r9sm3qg.js +0 -58
  134. package/dependencyScanner-f6grrep3.js +0 -9
  135. package/index-mxvakhsm.js +0 -66
  136. package/index-r24hmh0q.js +0 -4
  137. package/recipeScanner-tghkzrrt.js +0 -12
  138. package/templates/libRoot/base/baseLogic.ts +0 -14
  139. package/templates/libRoot/base/index.ts +0 -8
  140. package/templates/workspaceRoot/.cursor/rules/akan-page-routing.mdc.template +0 -43
  141. package/templates/workspaceRoot/.cursor/rules/akan-sync-conventions.mdc.template +0 -33
  142. package/templates/workspaceRoot/.cursor/rules/application-test-commands.mdc.template +0 -16
  143. package/templates/workspaceRoot/.cursor/rules/change-scope.mdc.template +0 -12
  144. package/templates/workspaceRoot/.cursor/rules/client-server-boundaries.mdc.template +0 -18
  145. package/templates/workspaceRoot/.cursor/rules/coding-comments.mdc.template +0 -25
  146. package/templates/workspaceRoot/.cursor/rules/coding-style.mdc.template +0 -44
  147. package/templates/workspaceRoot/.cursor/rules/domain-module-conventions.mdc.template +0 -17
  148. package/templates/workspaceRoot/.cursor/rules/format-lint.mdc.template +0 -12
  149. package/templates/workspaceRoot/.cursor/rules/lint-enforced-rules.mdc.template +0 -18
  150. package/templates/workspaceRoot/.cursor/rules/module-file-playbook.mdc.template +0 -61
  151. package/templates/workspaceRoot/.cursor/rules/naming-conventions.mdc.template +0 -15
  152. package/templates/workspaceRoot/.cursor/rules/react-component-style.mdc.template +0 -21
  153. package/templates/workspaceRoot/.cursor/rules/repo-overview.mdc.template +0 -17
  154. package/templates/workspaceRoot/.cursor/rules/scalar-modeling.mdc.template +0 -58
  155. package/templates/workspaceRoot/.cursor/rules/secrets-and-env.mdc.template +0 -13
  156. package/templates/workspaceRoot/.cursor/rules/service-signal-conventions.mdc.template +0 -83
  157. package/templates/workspaceRoot/.cursor/rules/srvkit-adapters-and-guards.mdc.template +0 -50
  158. package/templates/workspaceRoot/.cursor/rules/ssr-first.mdc.template +0 -59
  159. package/templates/workspaceRoot/.cursor/rules/typescript-imports.mdc.template +0 -16
  160. package/typeChecker-kravn7ns.js +0 -8
  161. /package/{index-0wae5ebk.js → index-meh558jy.js} +0 -0
  162. /package/{index-ss469dec.js → index-nz8prx9g.js} +0 -0
@@ -0,0 +1,159 @@
1
+ // @bun
2
+ import {
3
+ AppInfo
4
+ } from "./index-qsq3q8fy.js";
5
+
6
+ // pkgs/@akanjs/devkit/slicePlanner.ts
7
+ class SlicePlanner {
8
+ static memberDirs = ["apps", "libs", "pkgs"];
9
+ static toolchainDependencies = [
10
+ "@akanjs/cli",
11
+ "@akanjs/devkit",
12
+ "@biomejs/biome",
13
+ "@types/bun",
14
+ "akanjs",
15
+ "tailwindcss",
16
+ "typescript"
17
+ ];
18
+ static akanPackages = ["akanjs", "@akanjs/devkit", "@akanjs/cli"];
19
+ static async#frameworkPeers(workspace) {
20
+ const peers = new Set;
21
+ let found = false;
22
+ for (const akanPackage of SlicePlanner.akanPackages) {
23
+ for (const prefix of ["node_modules", "pkgs"]) {
24
+ const manifestPath = `${prefix}/${akanPackage}/package.json`;
25
+ if (!await workspace.exists(manifestPath))
26
+ continue;
27
+ const manifest = await workspace.readJson(manifestPath);
28
+ for (const peer of Object.keys(manifest.peerDependencies ?? {}))
29
+ peers.add(peer);
30
+ found = true;
31
+ break;
32
+ }
33
+ }
34
+ return found ? peers : null;
35
+ }
36
+ static typesPackageOf(dependency) {
37
+ return dependency.startsWith("@") ? `@types/${dependency.slice(1).replace("/", "__")}` : `@types/${dependency}`;
38
+ }
39
+ static async pruneDependencies(workspace, rootPackageJson, required) {
40
+ const peers = await SlicePlanner.#frameworkPeers(workspace);
41
+ const { workspaces: _workspaces, ...rest } = rootPackageJson;
42
+ if (!peers)
43
+ return {
44
+ packageJson: rest,
45
+ pruned: [],
46
+ warnings: [`dependencies carried whole \u2014 none of ${SlicePlanner.akanPackages.join(", ")} is installed`]
47
+ };
48
+ const keep = new Set([...SlicePlanner.toolchainDependencies, ...peers, ...required]);
49
+ for (const dependency of [...keep])
50
+ keep.add(SlicePlanner.typesPackageOf(dependency));
51
+ const pick = (entries) => Object.fromEntries(Object.entries(entries ?? {}).filter(([name]) => keep.has(name)));
52
+ const patched = rootPackageJson.patchedDependencies ?? {};
53
+ const packageJson = {
54
+ ...rest,
55
+ dependencies: pick(rootPackageJson.dependencies),
56
+ devDependencies: pick(rootPackageJson.devDependencies),
57
+ ...Object.keys(patched).length ? {
58
+ patchedDependencies: Object.fromEntries(Object.entries(patched).filter(([spec]) => keep.has(spec.slice(0, spec.lastIndexOf("@")))))
59
+ } : {}
60
+ };
61
+ const pruned = Object.keys({ ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies }).filter((name) => !keep.has(name)).sort();
62
+ return { packageJson, pruned, warnings: [] };
63
+ }
64
+ #app;
65
+ constructor(app) {
66
+ this.#app = app;
67
+ }
68
+ async#trackedFiles(paths) {
69
+ return await this.#app.workspace.listGitFiles(paths);
70
+ }
71
+ async#untrackedFiles(paths) {
72
+ const [tracked, all] = await Promise.all([
73
+ this.#app.workspace.listGitFiles(paths),
74
+ this.#app.workspace.listGitFiles(paths, { untracked: true })
75
+ ]);
76
+ const trackedSet = new Set(tracked);
77
+ return all.filter((file) => !trackedSet.has(file));
78
+ }
79
+ #isMemberFile(file) {
80
+ return SlicePlanner.memberDirs.includes(file.split("/")[0] ?? "");
81
+ }
82
+ static #requiredDependencies(appInfo) {
83
+ const scanResults = [
84
+ appInfo.getScanResult(),
85
+ ...[...appInfo.getLibInfos().values()].map((lib) => lib.getScanResult())
86
+ ];
87
+ return new Set([
88
+ ...scanResults.flatMap((scanResult) => [
89
+ ...scanResult.dependencies,
90
+ ...scanResult.devDependencies,
91
+ ...scanResult.pkgDeps
92
+ ])
93
+ ]);
94
+ }
95
+ async#patchWarnings(packageJson) {
96
+ const patchedDependencies = packageJson.patchedDependencies ?? {};
97
+ const missing = (await Promise.all(Object.entries(patchedDependencies).map(async ([spec, patchPath]) => await this.#app.workspace.exists(patchPath) ? null : `${spec} -> ${patchPath}`))).filter((entry) => !!entry);
98
+ return missing.length ? [`patchedDependencies references a missing patch file: ${missing.join(", ")}`] : [];
99
+ }
100
+ async plan() {
101
+ const appInfo = await AppInfo.fromExecutor(this.#app);
102
+ const libs = appInfo.getLibs();
103
+ const slicePaths = [`apps/${this.#app.name}`, ...libs.map((lib) => `libs/${lib}`)];
104
+ const [appFiles, allTracked, untracked, rootPackageJson] = await Promise.all([
105
+ this.#trackedFiles([`apps/${this.#app.name}`]),
106
+ this.#trackedFiles(["."]),
107
+ this.#untrackedFiles(slicePaths),
108
+ this.#app.workspace.getPackageJson()
109
+ ]);
110
+ const libFiles = Object.fromEntries(await Promise.all(libs.map(async (lib) => [lib, await this.#trackedFiles([`libs/${lib}`])])));
111
+ const rootFiles = allTracked.filter((file) => !this.#isMemberFile(file));
112
+ const required = SlicePlanner.#requiredDependencies(appInfo);
113
+ const {
114
+ packageJson,
115
+ pruned,
116
+ warnings: manifestWarnings
117
+ } = await SlicePlanner.pruneDependencies(this.#app.workspace, rootPackageJson, required);
118
+ const warnings = [
119
+ ...untracked.length ? [`${untracked.length} untracked file(s) under the slice paths: ${untracked.join(", ")}`] : [],
120
+ ...rootPackageJson.workspaces ? ["root `workspaces` dropped \u2014 a slice consumes akanjs from the registry"] : [],
121
+ ...manifestWarnings,
122
+ ...await this.#patchWarnings(rootPackageJson)
123
+ ];
124
+ return {
125
+ app: this.#app.name,
126
+ libs,
127
+ appFiles,
128
+ libFiles,
129
+ rootFiles,
130
+ packageJson,
131
+ requiredDependencies: [...required].sort(),
132
+ unusedDependencies: pruned,
133
+ warnings
134
+ };
135
+ }
136
+ }
137
+ var rootEntriesOf = (rootFiles) => [...new Set(rootFiles.map((file) => file.split("/")[0] ?? file))].sort();
138
+ function formatSlicePlan(plan) {
139
+ const libCounts = Object.entries(plan.libFiles).map(([lib, files]) => ` - libs/${lib}: ${files.length} files`);
140
+ const sections = [
141
+ "Akan Slice Plan",
142
+ `app: ${plan.app} (apps/${plan.app}: ${plan.appFiles.length} files)`,
143
+ `libs: ${plan.libs.length ? plan.libs.join(", ") : "(none)"}`,
144
+ ...libCounts,
145
+ `workspace shell: ${plan.rootFiles.length} files across ${rootEntriesOf(plan.rootFiles).join(", ")}`,
146
+ "",
147
+ `Root dependencies this slice does not use (${plan.unusedDependencies.length}) \u2014 pruned:`,
148
+ "",
149
+ ...plan.unusedDependencies.length ? plan.unusedDependencies.map((dep) => ` - ${dep}`) : [" (none)"],
150
+ "",
151
+ `Warnings (${plan.warnings.length}):`,
152
+ "",
153
+ ...plan.warnings.length ? plan.warnings.map((warning) => ` - ${warning}`) : [" (none)"]
154
+ ];
155
+ return sections.join(`
156
+ `);
157
+ }
158
+
159
+ export { SlicePlanner, formatSlicePlan };
@@ -0,0 +1,7 @@
1
+ // @bun
2
+ // pkgs/@akanjs/devkit/getDirname.ts
3
+ import path from "path";
4
+ import { fileURLToPath } from "url";
5
+ var getDirname2 = (url) => path.dirname(fileURLToPath(url));
6
+
7
+ export { getDirname2 };
@@ -2,16 +2,16 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-8hsbnyes.js";
5
+ } from "./index-znynzt5w.js";
6
6
  import {
7
- PkgExecutor
8
- } from "./index-hgna5rjy.js";
7
+ FileSys
8
+ } from "./index-q0y2jq9j.js";
9
9
  import {
10
- TypeScriptDependencyScanner
11
- } from "./index-46tjzh6s.js";
10
+ PkgExecutor
11
+ } from "./index-qsq3q8fy.js";
12
12
  import {
13
- FileSys
14
- } from "./index-67546d0j.js";
13
+ TypeScriptDependencyScanner2
14
+ } from "./index-kcxmv48c.js";
15
15
 
16
16
  // pkgs/@akanjs/cli/package/package.runner.ts
17
17
  import path2 from "path";
@@ -140,7 +140,7 @@ class PackageRunner extends runner("package") {
140
140
  await workspace.setPkgTsPaths(pkgName);
141
141
  }
142
142
  async removePackage(pkg) {
143
- await pkg.workspace.exec(`rm -rf pkgs/${pkg.name}`);
143
+ await pkg.workspace.removeDir(`pkgs/${pkg.name}`);
144
144
  await pkg.workspace.unsetPkgTsPaths(pkg.name);
145
145
  }
146
146
  async scanSync(pkg) {
@@ -150,7 +150,7 @@ class PackageRunner extends runner("package") {
150
150
  async buildPackage(pkg) {
151
151
  await $`rm -rf ${pkg.dist.cwdPath}`;
152
152
  await pkg.dist.mkdir(pkg.dist.cwdPath);
153
- const scanner = await TypeScriptDependencyScanner.from(pkg);
153
+ const scanner = await TypeScriptDependencyScanner2.from(pkg);
154
154
  const { npmDeps, npmDevDeps, missingDeps } = await scanner.getPackageBuildDependencies(pkg.name);
155
155
  const packageRuntimeDependencies = {
156
156
  "@akanjs/devkit": ["tailwind-scrollbar"]
@@ -163,13 +163,17 @@ class PackageRunner extends runner("package") {
163
163
  "tailwind-scrollbar"
164
164
  ].filter((dep) => dep !== "akanjs" && dep !== "@akanjs/devkit");
165
165
  }
166
- const bundledRuntimeDeps = new Set(pkg.name === "@akanjs/cli" ? ["@akanjs/devkit"] : []);
166
+ const packageBundledRuntimeDependencies = {
167
+ "@akanjs/cli": ["@akanjs/devkit"],
168
+ akanjs: ["use-agentic"]
169
+ };
170
+ const bundledRuntimeDeps = new Set(packageBundledRuntimeDependencies[pkg.name] ?? []);
167
171
  const forcedRuntimeDeps = packageRuntimeDependencies[pkg.name] ?? [];
168
172
  const forcedRuntimeDevDeps = packageRuntimeDevDependencies[pkg.name] ?? [];
169
173
  const [rootPackageJson, pkgJson] = await Promise.all([pkg.workspace.getPackageJson(), pkg.getPackageJson()]);
170
174
  const optionalPeerDeps = new Set(Object.entries(pkgJson.peerDependenciesMeta ?? {}).filter(([, meta]) => meta.optional).map(([dep]) => dep));
171
175
  const packageRuntimeDeps = [...new Set([...npmDeps, ...forcedRuntimeDeps])].filter((dep) => !optionalPeerDeps.has(dep) && !bundledRuntimeDeps.has(dep));
172
- const packageRuntimeDevDeps = [...new Set([...npmDevDeps, ...forcedRuntimeDevDeps])].filter((dep) => !optionalPeerDeps.has(dep));
176
+ const packageRuntimeDevDeps = [...new Set([...npmDevDeps, ...forcedRuntimeDevDeps])].filter((dep) => !optionalPeerDeps.has(dep) && !bundledRuntimeDeps.has(dep));
173
177
  const rootDeps = { ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies };
174
178
  const missingForcedDeps = forcedRuntimeDeps.filter((dep) => !rootDeps[dep]);
175
179
  const missingForcedDevDeps = forcedRuntimeDevDeps.filter((dep) => !rootDeps[dep]);
@@ -268,7 +272,7 @@ class PackageRunner extends runner("package") {
268
272
  }
269
273
  if (!pkgJson.version)
270
274
  throw new Error(`[package] dist package version is missing for ${pkg.name}`);
271
- if (!pkgJson.publishConfig || pkgJson.publishConfig.access !== "public") {
275
+ if (pkgJson.publishConfig?.access !== "public") {
272
276
  throw new Error(`[package] ${pkg.name} must publish with publishConfig.access=public`);
273
277
  }
274
278
  if (!await Bun.file(`${pkg.dist.cwdPath}/README.md`).exists()) {
@@ -1,22 +1,22 @@
1
1
  // @bun
2
2
  import {
3
- pluralizeName
4
- } from "./index-ss469dec.js";
5
- import {
6
- AiSession
7
- } from "./index-0cj2zxbm.js";
3
+ runner,
4
+ script
5
+ } from "./index-znynzt5w.js";
8
6
  import {
9
- createPassedPrimitiveReport,
10
7
  generatedFilesForSync,
8
+ createPassedPrimitiveReport,
11
9
  scalarChangedFiles
12
- } from "./index-rzwcpcc3.js";
10
+ } from "./index-fc1bh0a7.js";
11
+ import {
12
+ AiSession
13
+ } from "./index-c69j78kk.js";
13
14
  import {
14
15
  Prompter
15
- } from "./index-tdbas9r0.js";
16
+ } from "./index-h7yw2z9n.js";
16
17
  import {
17
- runner,
18
- script
19
- } from "./index-8hsbnyes.js";
18
+ pluralizeName
19
+ } from "./index-nz8prx9g.js";
20
20
 
21
21
  // pkgs/@akanjs/cli/scalar/scalar.prompt.ts
22
22
  import { input } from "@inquirer/prompts";
@@ -192,9 +192,9 @@ class ScalarRunner extends runner("scalar") {
192
192
  const { request, validate } = await prompt.requestUpdateDictonaryWithInstruction();
193
193
  await session.writeTypescripts(request, sys, { validate });
194
194
  for (const scalarName of followingScalarNames) {
195
- const prompt2 = new ScalarPrompt(sys, scalarName);
196
- const { request: request2, validate: validate2 } = await prompt2.requestUpdateDictonaryWithFollowing();
197
- await session.writeTypescripts(request2, sys, { validate: validate2 });
195
+ const prompt = new ScalarPrompt(sys, scalarName);
196
+ const { request, validate } = await prompt.requestUpdateDictonaryWithFollowing();
197
+ await session.writeTypescripts(request, sys, { validate });
198
198
  }
199
199
  }
200
200
  }
@@ -5,7 +5,7 @@ import * as path from "path";
5
5
  import chalk from "chalk";
6
6
  import * as ts from "typescript";
7
7
 
8
- class TypeChecker {
8
+ class TypeChecker2 {
9
9
  configPath;
10
10
  configFile;
11
11
  config;
@@ -143,12 +143,12 @@ ${summary.join(", ")} found${output.join(`
143
143
  try {
144
144
  const { diagnostics } = this.check(filePath);
145
145
  return diagnostics.length === 0;
146
- } catch (error) {
146
+ } catch (_error) {
147
147
  return false;
148
148
  }
149
149
  }
150
150
  static checkProject(configPath) {
151
- const parsedConfig = TypeChecker.parseConfig(configPath);
151
+ const parsedConfig = TypeChecker2.parseConfig(configPath);
152
152
  const host = ts.createIncrementalCompilerHost(parsedConfig.options);
153
153
  const builderProgram = ts.createIncrementalProgram({
154
154
  rootNames: parsedConfig.fileNames,
@@ -166,19 +166,19 @@ ${summary.join(", ")} found${output.join(`
166
166
  diagnostics,
167
167
  errors,
168
168
  warnings,
169
- message: TypeChecker.formatDiagnosticMessages(diagnostics)
169
+ message: TypeChecker2.formatDiagnosticMessages(diagnostics)
170
170
  };
171
171
  }
172
172
  static parseConfig(configPath) {
173
173
  const configFile = ts.readConfigFile(configPath, (fileName) => ts.sys.readFile(fileName));
174
174
  const configDiagnostics = configFile.error ? [configFile.error] : [];
175
175
  if (!configFile.config) {
176
- const message = TypeChecker.formatDiagnosticMessages(configDiagnostics);
176
+ const message = TypeChecker2.formatDiagnosticMessages(configDiagnostics);
177
177
  throw new Error(message || `Error reading tsconfig.json: ${configPath}`);
178
178
  }
179
179
  const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath), undefined, configPath);
180
180
  if (parsedConfig.errors.length > 0)
181
- throw new Error(TypeChecker.formatDiagnosticMessages(parsedConfig.errors));
181
+ throw new Error(TypeChecker2.formatDiagnosticMessages(parsedConfig.errors));
182
182
  return parsedConfig;
183
183
  }
184
184
  static formatDiagnosticMessages(diagnostics) {
@@ -190,4 +190,4 @@ ${summary.join(", ")} found${output.join(`
190
190
  }
191
191
  }
192
192
 
193
- export { TypeChecker };
193
+ export { TypeChecker2 };
@@ -19,12 +19,14 @@ var prepareDevWatchBatch = ({
19
19
  generatedFiles: indexSync.changedFiles
20
20
  });
21
21
  if (indexSync.errors.length > 0 && !devPlan.actions.includes("report-error")) {
22
- devPlan.actions = [...devPlan.actions, "report-error"].sort();
22
+ const withReport = [...devPlan.actions, "report-error"];
23
+ devPlan.actions = withReport.sort();
23
24
  }
24
25
  return {
25
26
  files,
26
27
  kinds,
27
28
  expandedBatch,
29
+ devPlan,
28
30
  event: { type: "invalidate", kinds, files, generation, devPlan },
29
31
  hasSyncErrors: indexSync.errors.length > 0
30
32
  };
@@ -2,7 +2,7 @@
2
2
  // pkgs/@akanjs/devkit/recipeScanner.ts
3
3
  import { readdir } from "fs/promises";
4
4
  import ts from "typescript";
5
- var collectRecipeSources = async (uiDirPath, importFrom, basename = "Recipe") => {
5
+ var collectRecipeSources2 = async (uiDirPath, importFrom, basename = "Recipe") => {
6
6
  const read = async (filePath) => {
7
7
  const content = await Bun.file(filePath).text().catch(() => "");
8
8
  return content ? { path: filePath, content, importFrom } : null;
@@ -12,7 +12,7 @@ var collectRecipeSources = async (uiDirPath, importFrom, basename = "Recipe") =>
12
12
  const fromDir = await Promise.all(dirEntries.filter((entry) => entry.endsWith(".ts") && entry !== "index.ts" && !/\.(test|spec)\.ts$/.test(entry)).sort().map((entry) => read(`${uiDirPath}/${basename}/${entry}`)));
13
13
  return [flat, ...fromDir].filter((source) => !!source);
14
14
  };
15
- var scanRecipes = (sources) => {
15
+ var scanRecipes2 = (sources) => {
16
16
  const recipes = [];
17
17
  for (const source of sources) {
18
18
  const sourceFile = ts.createSourceFile(source.path, source.content, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
@@ -87,7 +87,7 @@ var isNamed = (name) => ts.isIdentifier(name) || ts.isStringLiteral(name);
87
87
  var propName = (name) => name.text;
88
88
  var DUPLICATE_TOKEN_RATIO = 0.7;
89
89
  var MIN_FINGERPRINT_TOKENS = 3;
90
- var findInlineRecipeDuplicates = (recipes, files) => {
90
+ var findInlineRecipeDuplicates2 = (recipes, files) => {
91
91
  const fingerprints = recipes.map((recipe) => ({ recipe: recipe.name, tokens: (recipe.base ?? "").split(/\s+/).filter(Boolean) })).filter((fingerprint) => fingerprint.tokens.length >= MIN_FINGERPRINT_TOKENS).map((fingerprint) => ({ ...fingerprint, needed: Math.ceil(fingerprint.tokens.length * DUPLICATE_TOKEN_RATIO) }));
92
92
  if (fingerprints.length === 0)
93
93
  return [];
@@ -133,4 +133,4 @@ var getLeadingDoc = (fullText, node) => {
133
133
  return line || undefined;
134
134
  };
135
135
 
136
- export { collectRecipeSources, scanRecipes, findInlineRecipeDuplicates };
136
+ export { collectRecipeSources2, scanRecipes2, findInlineRecipeDuplicates2 };
@@ -1,13 +1,13 @@
1
1
  // @bun
2
- import {
3
- Spinner
4
- } from "./index-mxvakhsm.js";
5
2
  import {
6
3
  FileSys
7
- } from "./index-67546d0j.js";
4
+ } from "./index-q0y2jq9j.js";
5
+ import {
6
+ Spinner
7
+ } from "./index-qsq3q8fy.js";
8
8
 
9
9
  // pkgs/@akanjs/devkit/cloud/globalConfig.ts
10
- import { mkdir } from "fs/promises";
10
+ import { chmod, mkdir } from "fs/promises";
11
11
  import dayjs from "dayjs";
12
12
 
13
13
  // pkgs/@akanjs/devkit/cloud/constants.ts
@@ -34,8 +34,9 @@ class GlobalConfig {
34
34
  };
35
35
  }
36
36
  static async#setAkanGlobalConfig(akanConfig) {
37
- await mkdir(basePath, { recursive: true });
37
+ await mkdir(basePath, { recursive: true, mode: 448 });
38
38
  await Bun.write(configPath, JSON.stringify(akanConfig, null, 2));
39
+ await chmod(configPath, 384);
39
40
  }
40
41
  static async getHostConfig(host = GlobalConfig.akanCloudHost) {
41
42
  const akanConfig = await GlobalConfig.#getAkanGlobalConfig();
@@ -240,7 +241,7 @@ import { ChatOpenAI } from "@langchain/openai";
240
241
  import { Logger } from "akanjs/common";
241
242
  import chalk from "chalk";
242
243
  var MAX_ASK_TRY = 300;
243
- var deepSeekLlmModels = ["deepseek-chat", "deepseek-reasoner"];
244
+ var deepSeekLlmModels = ["deepseek-v4-flash", "deepseek-v4-pro"];
244
245
  var openAiLlmModels = ["gpt-5.5"];
245
246
  var supportedLlmModels = [...deepSeekLlmModels, ...openAiLlmModels];
246
247
  var isOpenAiLlmModel = (model) => openAiLlmModels.includes(model);
@@ -275,10 +276,10 @@ class AiSession {
275
276
  static #chat = null;
276
277
  static async init({ temperature = 0, useExisting = true } = {}) {
277
278
  if (useExisting) {
278
- const llmConfig2 = await AiSession.getLlmConfig();
279
- if (llmConfig2) {
280
- AiSession.#setChatModel(llmConfig2.model, llmConfig2.apiKey);
281
- Logger.rawLog(chalk.dim(`\uD83E\uDD16akan editor uses existing LLM config (${llmConfig2.model})`));
279
+ const llmConfig = await AiSession.getLlmConfig();
280
+ if (llmConfig) {
281
+ AiSession.#setChatModel(llmConfig.model, llmConfig.apiKey);
282
+ Logger.rawLog(chalk.dim(`\uD83E\uDD16akan editor uses existing LLM config (${llmConfig.model})`));
282
283
  return AiSession;
283
284
  }
284
285
  } else
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  AppExecutor,
4
4
  LibExecutor
5
- } from "./index-hgna5rjy.js";
5
+ } from "./index-qsq3q8fy.js";
6
6
 
7
7
  // pkgs/@akanjs/devkit/workflow/utils.ts
8
8
  var jsonText = (value, { trailingNewline = true } = {}) => `${JSON.stringify(value, null, 2)}${trailingNewline ? `
@@ -914,9 +914,9 @@ ${options.closingIndent}}`);
914
914
  const beforeField = locator.fields[insertIndex];
915
915
  if (beforeField) {
916
916
  const leadingComments = ts.getLeadingCommentRanges(content, beforeField.fullStart) ?? [];
917
- const insertAt2 = lineStartAt(content, leadingComments[0]?.pos ?? beforeField.start);
918
- const indent2 = lineIndentAt(content, beforeField.start) || options.fieldIndent;
919
- return spliceText(content, insertAt2, insertAt2, `${indent2}${formattedLine}
917
+ const insertAt = lineStartAt(content, leadingComments[0]?.pos ?? beforeField.start);
918
+ const indent = lineIndentAt(content, beforeField.start) || options.fieldIndent;
919
+ return spliceText(content, insertAt, insertAt, `${indent}${formattedLine}
920
920
  `);
921
921
  }
922
922
  const afterField = locator.fields[locator.fields.length - 1];
@@ -2,16 +2,24 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-8hsbnyes.js";
5
+ } from "./index-znynzt5w.js";
6
6
  import {
7
7
  LibExecutor
8
- } from "./index-hgna5rjy.js";
8
+ } from "./index-qsq3q8fy.js";
9
+ import {
10
+ LibSource,
11
+ formatLibStatuses
12
+ } from "./index-3d9y066c.js";
13
+
14
+ // pkgs/@akanjs/cli/library/library.script.ts
15
+ import { Logger } from "akanjs/common";
9
16
 
10
- // pkgs/@akanjs/cli/semver.ts
11
- function parseVersion(version) {
17
+ // pkgs/@akanjs/devkit/semver.ts
18
+ var stripRangeOperator = (version) => version.replace(/^[\s^~>=<v]+/, "").trim();
19
+ var parseVersion = (version) => {
12
20
  return version.replace(/^[^\d]*/, "").split(/[.-]/).map((part) => Number.parseInt(part, 10)).map((part) => Number.isFinite(part) ? part : 0);
13
- }
14
- function compareSemver(a, b) {
21
+ };
22
+ var compareNumeric = (a, b) => {
15
23
  const left = parseVersion(a);
16
24
  const right = parseVersion(b);
17
25
  const length = Math.max(left.length, right.length);
@@ -21,40 +29,64 @@ function compareSemver(a, b) {
21
29
  return diff > 0 ? 1 : -1;
22
30
  }
23
31
  return 0;
24
- }
32
+ };
33
+ var compareSemver = (a, b) => {
34
+ try {
35
+ return Bun.semver.order(stripRangeOperator(a), stripRangeOperator(b));
36
+ } catch {
37
+ return compareNumeric(a, b);
38
+ }
39
+ };
25
40
 
26
41
  // pkgs/@akanjs/cli/library/library.runner.ts
27
42
  class LibraryRunner extends runner("library") {
43
+ static libraryRepository = "https://github.com/akan-team/akanjs.git";
28
44
  async createLibrary(libName, workspace) {
29
- await workspace.exec(`mkdir -p libs/${libName}`);
45
+ await workspace.mkdir(`libs/${libName}`);
30
46
  await workspace.applyTemplate({ basePath: `libs/${libName}`, template: "libRoot", dict: { libName } });
31
47
  const lib = LibExecutor.from(workspace, libName);
32
48
  return lib;
33
49
  }
34
50
  async removeLibrary(lib) {
35
- await lib.workspace.exec(`rm -rf libs/${lib.name}`);
51
+ await lib.workspace.removeDir(`libs/${lib.name}`);
36
52
  }
37
53
  async#copyInstalledLibrary(workspace, libName) {
38
54
  const installedPackageJson = `node_modules/akanjs/libs/${libName}/package.json`;
39
55
  if (!await workspace.exists(installedPackageJson))
40
- return false;
56
+ return null;
41
57
  await workspace.cp(`node_modules/akanjs/libs/${libName}`, `libs/${libName}`);
42
- return true;
58
+ return { origin: "akanjs", sha: await this.#installedAkanVersion(workspace) };
59
+ }
60
+ async#installedAkanVersion(workspace) {
61
+ const manifestPath = "node_modules/akanjs/package.json";
62
+ if (!await workspace.exists(manifestPath))
63
+ return "unknown";
64
+ const { version } = await workspace.readJson(manifestPath);
65
+ return version ?? "unknown";
43
66
  }
44
67
  async#copyLibraryFromRepository(workspace, libName) {
45
68
  await workspace.mkdir("node_modules/.akan");
46
69
  if (await workspace.exists("node_modules/.akan/akanjs"))
47
70
  await workspace.removeDir("node_modules/.akan/akanjs");
48
- await workspace.exec(`cd node_modules/.akan && git clone https://github.com/akan-team/akanjs.git`);
71
+ await workspace.exec(`cd node_modules/.akan && git clone ${LibraryRunner.libraryRepository}`);
49
72
  await workspace.cp(`node_modules/.akan/akanjs/libs/${libName}`, `libs/${libName}`);
73
+ const sha = await workspace.spawn("git", ["-C", "node_modules/.akan/akanjs", "rev-parse", "HEAD"]);
74
+ return { origin: LibraryRunner.libraryRepository, sha: sha.trim().slice(0, 12) };
50
75
  }
51
76
  async installLibrary(workspace, libName) {
52
- const copiedFromInstalledPackage = await this.#copyInstalledLibrary(workspace, libName);
53
- if (!copiedFromInstalledPackage)
54
- await this.#copyLibraryFromRepository(workspace, libName);
55
- await workspace.cp(`libs/${libName}/env/env.server.example.ts`, `libs/${libName}/env/env.server.testing.ts`);
56
- await workspace.commit(`Add ${libName} library`);
57
- return LibExecutor.from(workspace, libName);
77
+ const source = await this.#copyInstalledLibrary(workspace, libName) ?? await this.#copyLibraryFromRepository(workspace, libName);
78
+ const testingEnv = `libs/${libName}/env/env.server.testing.ts`;
79
+ if (!await workspace.exists(testingEnv))
80
+ await workspace.cp(`libs/${libName}/env/env.server.example.ts`, testingEnv);
81
+ const lib = LibExecutor.from(workspace, libName);
82
+ const stamp = await new LibSource(lib).write(source);
83
+ if (await workspace.hasChanges())
84
+ await workspace.commit(`Install ${libName} library from ${stamp.origin}`);
85
+ return lib;
86
+ }
87
+ async libraryStatuses(workspace) {
88
+ const libNames = await workspace.getLibs();
89
+ return await Promise.all(libNames.map((libName) => new LibSource(LibExecutor.from(workspace, libName)).status()));
58
90
  }
59
91
  async mergeLibraryDependencies(lib) {
60
92
  const libPackageJson = await lib.getPackageJson();
@@ -70,7 +102,7 @@ class LibraryRunner extends runner("library") {
70
102
  return [dep, newerVersion];
71
103
  }));
72
104
  Object.keys(allDependencies).sort().forEach((dep) => {
73
- if (!!libPackageJson.dependencies?.[dep] || !!rootPackageJson.dependencies?.[dep])
105
+ if (libPackageJson.dependencies?.[dep] || rootPackageJson.dependencies?.[dep])
74
106
  dependencies[dep] = allDependencies[dep];
75
107
  else
76
108
  devDependencies[dep] = allDependencies[dep];
@@ -80,7 +112,6 @@ class LibraryRunner extends runner("library") {
80
112
  await lib.workspace.spawn("bun", ["install"]);
81
113
  await lib.workspace.commit(`Merge ${lib.name} library dependencies`);
82
114
  }
83
- async testLibrary(lib) {}
84
115
  }
85
116
 
86
117
  // pkgs/@akanjs/cli/library/library.script.ts
@@ -102,6 +133,13 @@ class LibraryScript extends script("library", [LibraryRunner]) {
102
133
  await this.libraryRunner.removeLibrary(lib);
103
134
  spinner.succeed(`Library ${lib.name} (libs/${lib.name}) is removed`);
104
135
  }
136
+ async libraryStatus(workspace, format = "text") {
137
+ const spinner = workspace.spinning("Checking library sources...");
138
+ const statuses = await this.libraryRunner.libraryStatuses(workspace);
139
+ const drifted = statuses.filter((status) => status.drift === "drifted").length;
140
+ spinner.succeed(`Checked ${statuses.length} libraries (${drifted} drifted)`);
141
+ Logger.rawLog(format === "json" ? JSON.stringify(statuses, null, 2) : formatLibStatuses(statuses));
142
+ }
105
143
  async installLibrary(workspace, libName) {
106
144
  const installSpinner = workspace.spinning(`Installing ${libName} library`);
107
145
  const lib = await this.libraryRunner.installLibrary(workspace, libName);
@@ -110,11 +148,6 @@ class LibraryScript extends script("library", [LibraryRunner]) {
110
148
  await this.libraryRunner.mergeLibraryDependencies(lib);
111
149
  mergeSpinner.succeed(`${libName} library (libs/${libName}) dependencies merged to root package.json`);
112
150
  }
113
- async testLibrary(lib) {
114
- const spinner = lib.spinning("Testing library...");
115
- await this.libraryRunner.testLibrary(lib);
116
- spinner.succeed(`Library ${lib.name} (libs/${lib.name}) test is successful`);
117
- }
118
151
  }
119
152
 
120
153
  export { LibraryScript };