@akanjs/cli 3.0.0-beta.13 → 3.0.0-beta.15

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 (92) hide show
  1. package/.build-stamp +1 -1
  2. package/CodeAgent-d3wvbq8q.js +9 -0
  3. package/CodeAgentRpcHost-qvwfv0n9.js +7 -0
  4. package/CodeTui-6c9a2wtk.js +1103 -0
  5. package/README.md +3 -0
  6. package/{TunnelShare-2kwqb1j6.js → TunnelShare-r5tc2qk5.js} +2 -2
  7. package/{agent.command-7357vxd8.js → agent.command-9cg8m87z.js} +6 -6
  8. package/akanCode.js +100 -0
  9. package/{application.command-8s8ns95d.js → application.command-x75men32.js} +6 -15
  10. package/{applicationBuildRunner-4f1wrba0.js → applicationBuildRunner-d3702f1w.js} +2 -2
  11. package/{applicationReleasePackager-jkjmy5ee.js → applicationReleasePackager-2kdyj3te.js} +1 -1
  12. package/buildBatch.proc.js +2 -2
  13. package/{capacitorApp-hqvsrec4.js → capacitorApp-qk975zyz.js} +2 -2
  14. package/{cloud.command-p5dnhft9.js → cloud.command-a09wggfq.js} +10 -22
  15. package/cloud.script-qd3hpybf.js +20 -0
  16. package/code.command-ca7rpmez.js +147 -0
  17. package/commandManifest.json +1 -1
  18. package/consoleToStderr-h5bryj94.js +7 -0
  19. package/{context.command-wsjt98c1.js → context.command-9kbm0527.js} +14 -15
  20. package/context.runner-wtqpw7mh.js +22 -0
  21. package/{devTui-myg3pqeg.js → devTui-v19fbnpk.js} +114 -8
  22. package/{devTuiView-gz2fbf4v.js → devTuiView-pa63jrjq.js} +1 -1
  23. package/guideline.command-qvrh5pnx.js +48 -0
  24. package/guidelines/agentRule/agentRule.instruction.md +46 -15
  25. package/guidelines/conventions/conventions.instruction.md +9 -4
  26. package/guidelines/moduleCodegen/moduleCodegen.instruction.md +1 -1
  27. package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +1 -0
  28. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +62 -0
  29. package/incrementalBuilder.proc.js +1 -1
  30. package/{index-bz10w9t2.js → index-0qvq9aeb.js} +6 -16
  31. package/{index-jwjaf9fy.js → index-1p146w4s.js} +44 -44
  32. package/{index-7f4dsf9v.js → index-1sggq0m8.js} +1 -1
  33. package/{index-15r9a10e.js → index-3dmebxnk.js} +2 -2
  34. package/{index-vrwdx0zx.js → index-3hr7cpy1.js} +1 -1
  35. package/{index-s3fvrydw.js → index-5hy11qaq.js} +9 -9
  36. package/{index-8pkvrcv1.js → index-658xafm1.js} +3 -3
  37. package/index-7md2g9vw.js +6 -0
  38. package/{index-ys7dvdb3.js → index-84b080zh.js} +1 -1
  39. package/index-8k16atqy.js +82 -0
  40. package/{index-t3c045et.js → index-91brpnzb.js} +8 -21
  41. package/{index-em4swemt.js → index-bchkysja.js} +3 -3
  42. package/{index-j7rwsd23.js → index-bzjnp9ap.js} +22 -80
  43. package/{index-cnzm1wn5.js → index-chp5gqmm.js} +88 -169
  44. package/{index-h3g1152j.js → index-d35a8vc0.js} +4 -4
  45. package/{index-1nwxbr2y.js → index-ea1smknd.js} +2 -2
  46. package/index-egt4vfgb.js +69 -0
  47. package/index-erzcytap.js +2434 -0
  48. package/{index-sh88vtye.js → index-f4gpcp98.js} +1 -1
  49. package/{index-b3ae16mg.js → index-gca9y01h.js} +1 -1
  50. package/{index-wmb05v4q.js → index-gm76f0qb.js} +1 -1
  51. package/{index-649svkyt.js → index-myj01w9r.js} +8 -15
  52. package/index-sxg87a8f.js +727 -0
  53. package/{index-h7yw2z9n.js → index-twq9p2sp.js} +8 -8
  54. package/index-v156f836.js +234 -0
  55. package/index-v1y3cx0k.js +61 -0
  56. package/{index-t8gvwcrx.js → index-va2je2qm.js} +2 -2
  57. package/index-wfwknnje.js +124 -0
  58. package/index-x7g1qzpt.js +121 -0
  59. package/index.js +21 -20
  60. package/{library.command-1f9h2ex6.js → library.command-n89re6cx.js} +3 -3
  61. package/{localRegistry.command-w6w35j4r.js → localRegistry.command-1mmnegph.js} +9 -9
  62. package/{module.command-8zkq0q9q.js → module.command-4m82zgfp.js} +7 -10
  63. package/{package.command-y2rh4np7.js → package.command-9dv0p6zq.js} +3 -3
  64. package/package.json +9 -5
  65. package/{page.command-e5h29fyt.js → page.command-q86b0m0z.js} +3 -3
  66. package/{primitive.command-qm7tybpn.js → primitive.command-kaneasq6.js} +6 -9
  67. package/prompter-9mn3kp36.js +8 -0
  68. package/{quality.command-5evdd263.js → quality.command-sgapx315.js} +65 -5
  69. package/{repair.command-c2amvt74.js → repair.command-efc5gdbq.js} +5 -5
  70. package/{scalar.command-a1ewkmab.js → scalar.command-e2rpkhqy.js} +6 -9
  71. package/skills/akan-debug/SKILL.md +42 -0
  72. package/skills/akan-deps/SKILL.md +50 -0
  73. package/skills/akan-err/SKILL.md +39 -0
  74. package/skills/akan-module/SKILL.md +45 -0
  75. package/skills/akan-scaffold/SKILL.md +76 -0
  76. package/skills/akan-scalar/SKILL.md +52 -0
  77. package/skills/akan-service/SKILL.md +34 -0
  78. package/skills/akan-store/SKILL.md +63 -0
  79. package/skills/akan-ui/SKILL.md +63 -0
  80. package/skills/akan-validate/SKILL.md +44 -0
  81. package/{subspace.command-3w5x13a1.js → subspace.command-005rz1x6.js} +5 -5
  82. package/{tunnel.command-09n8h4s1.js → tunnel.command-66j9estx.js} +4 -4
  83. package/{workflow.command-y3fct1rq.js → workflow.command-z1xcm4c7.js} +9 -12
  84. package/{workspace.command-p6td4qad.js → workspace.command-4ahrhp3k.js} +23 -22
  85. package/abstractCompactor-g04vqcff.js +0 -102
  86. package/cloud.script-gxpbhras.js +0 -20
  87. package/guideline.command-snqzfyt0.js +0 -360
  88. package/index-5tw8t1ts.js +0 -338
  89. package/index-j1tajctp.js +0 -229
  90. package/index-kpnp2e10.js +0 -841
  91. package/index-meh558jy.js +0 -65
  92. /package/{index-5nyznra1.js → index-p1j0cyvd.js} +0 -0
@@ -2,24 +2,27 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-b3ae16mg.js";
5
+ } from "./index-gca9y01h.js";
6
6
  import {
7
7
  WorkspaceExecutor,
8
8
  AppExecutor,
9
9
  LibExecutor,
10
10
  PkgExecutor
11
- } from "./index-5nyznra1.js";
11
+ } from "./index-p1j0cyvd.js";
12
12
  import {
13
13
  LibraryScript
14
- } from "./index-1nwxbr2y.js";
14
+ } from "./index-ea1smknd.js";
15
15
  import {
16
16
  HmrWatcher,
17
17
  WatchRootResolver
18
18
  } from "./index-hwkygn9s.js";
19
+ import {
20
+ stripAnsi
21
+ } from "./index-7md2g9vw.js";
19
22
  import {
20
23
  SlicePlanner,
21
24
  formatSlicePlan
22
- } from "./index-ys7dvdb3.js";
25
+ } from "./index-84b080zh.js";
23
26
  import {
24
27
  resolveMobileTargets
25
28
  } from "./index-47pj3aee.js";
@@ -34,91 +37,6 @@ function openBrowser(url) {
34
37
  return Promise.resolve();
35
38
  }
36
39
 
37
- // pkgs/@akanjs/cli/application/devLogBuffer.ts
38
- var ansi = new RegExp(`${String.fromCharCode(27)}(?:[@-Z\\\\-_]|\\[[\\s\\S]*?[@-~])`, "g");
39
- var stripAnsi = (text) => text.replace(ansi, "");
40
- var plainTextOf = (lines, { withApp = false } = {}) => {
41
- const width = withApp ? lines.reduce((max, line) => Math.max(max, line.app.length), 0) : 0;
42
- return lines.map((line) => `${withApp ? `${line.app.padEnd(width)} \u2502 ` : ""}${stripAnsi(line.text)}`).join(`
43
- `);
44
- };
45
- var HOST_SOURCE = "host";
46
- var childPrefix = /^\[child:(\d+) ([a-z-]+)\] \[(?:stdout|stderr)\] /;
47
- var sourceOf = (text) => {
48
- const match = childPrefix.exec(text);
49
- return match ? `#${match[1]} ${match[2]}` : HOST_SOURCE;
50
- };
51
-
52
- class DevLogBuffer {
53
- static defaultLimit = 5000;
54
- #limit;
55
- #lines = [];
56
- #partial = new Map;
57
- #sources = new Map;
58
- #seq = 0;
59
- constructor({ limit = DevLogBuffer.defaultLimit } = {}) {
60
- this.#limit = Math.max(1, limit);
61
- }
62
- get size() {
63
- return this.#lines.length;
64
- }
65
- sourcesOf(app) {
66
- return [...this.#sources.get(app) ?? []];
67
- }
68
- push(app, kind, chunk) {
69
- const key = `${app}:${kind}`;
70
- const parts = `${this.#partial.get(key) ?? ""}${chunk}`.split(`
71
- `);
72
- this.#partial.set(key, parts.pop() ?? "");
73
- return this.#append(app, kind, parts);
74
- }
75
- flushPartials() {
76
- const flushed = [];
77
- for (const [key, remainder] of [...this.#partial]) {
78
- this.#partial.set(key, "");
79
- if (!remainder)
80
- continue;
81
- const split = key.lastIndexOf(":");
82
- const app = key.slice(0, split);
83
- const kind = key.slice(split + 1) === "stderr" ? "stderr" : "stdout";
84
- flushed.push(...this.#append(app, kind, [remainder]));
85
- }
86
- return flushed;
87
- }
88
- select({ app = null, source = null, grep, errorsOnly = false } = {}) {
89
- const needle = grep?.trim().toLowerCase();
90
- return this.#lines.filter((line) => {
91
- if (app !== null && line.app !== app)
92
- return false;
93
- if (source !== null && line.source !== source)
94
- return false;
95
- if (errorsOnly && line.kind !== "stderr")
96
- return false;
97
- if (needle && !stripAnsi(line.text).toLowerCase().includes(needle))
98
- return false;
99
- return true;
100
- });
101
- }
102
- clear(app = null) {
103
- const kept = app === null ? [] : this.#lines.filter((line) => line.app !== app);
104
- this.#lines.length = 0;
105
- this.#lines.push(...kept);
106
- }
107
- #append(app, kind, texts) {
108
- const known = this.#sources.get(app) ?? new Set;
109
- this.#sources.set(app, known);
110
- const added = texts.map((text) => {
111
- const source = sourceOf(text);
112
- known.add(source);
113
- return { seq: ++this.#seq, app, source, kind, text };
114
- });
115
- this.#lines.push(...added);
116
- if (this.#lines.length > this.#limit)
117
- this.#lines.splice(0, this.#lines.length - this.#limit);
118
- return added;
119
- }
120
- }
121
-
122
40
  // pkgs/@akanjs/devkit/applicationBuildReporter.ts
123
41
  import { Logger } from "akanjs/common";
124
42
 
@@ -166,7 +84,7 @@ Caused by: ${ApplicationBuildReporter.formatError(error.cause)}` : "";
166
84
 
167
85
  // pkgs/@akanjs/cli/application/application.script.ts
168
86
  import { confirm } from "@inquirer/prompts";
169
- import { Logger as Logger6 } from "akanjs/common";
87
+ import { Logger as Logger7 } from "akanjs/common";
170
88
 
171
89
  // pkgs/@akanjs/cli/application/application.runner.ts
172
90
  import path5 from "path";
@@ -2048,11 +1966,9 @@ ${uniqueCandidates.map((candidate) => ` - ${candidate}`).join(`
2048
1966
 
2049
1967
  // pkgs/@akanjs/cli/application/application.runner.ts
2050
1968
  import { Logger as Logger4 } from "akanjs/common";
2051
- import ora from "ora";
2052
- var loadBuildRunner = async () => (await import("./applicationBuildRunner-4f1wrba0.js")).ApplicationBuildRunner;
2053
- var loadReleasePackager = async () => (await import("./applicationReleasePackager-jkjmy5ee.js")).ApplicationReleasePackager;
2054
- var loadCapacitorApp = async () => (await import("./capacitorApp-hqvsrec4.js")).CapacitorApp;
2055
- var loadAbstractCompactor = async () => (await import("./abstractCompactor-g04vqcff.js")).AbstractCompactor;
1969
+ var loadBuildRunner = async () => (await import("./applicationBuildRunner-d3702f1w.js")).ApplicationBuildRunner;
1970
+ var loadReleasePackager = async () => (await import("./applicationReleasePackager-2kdyj3te.js")).ApplicationReleasePackager;
1971
+ var loadCapacitorApp = async () => (await import("./capacitorApp-qk975zyz.js")).CapacitorApp;
2056
1972
  var loadPrompts = async () => await import("@inquirer/prompts");
2057
1973
 
2058
1974
  class ApplicationRunner extends runner("application") {
@@ -2193,10 +2109,6 @@ try {
2193
2109
  async typecheck(app, options = {}) {
2194
2110
  await new (await loadBuildRunner())(app).typecheck(options);
2195
2111
  }
2196
- async compact(sys, { module, minLines, interactive } = {}) {
2197
- const compactor = new (await loadAbstractCompactor())(sys, { minLines, interactive });
2198
- return await compactor.compactAll({ module });
2199
- }
2200
2112
  async test(exec) {
2201
2113
  const isSignalTarget = exec instanceof AppExecutor || exec instanceof LibExecutor;
2202
2114
  const preloadPath = isSignalTarget ? await resolveSignalTestPreloadPath(exec) : null;
@@ -2434,28 +2346,6 @@ ${detail}`
2434
2346
  });
2435
2347
  return;
2436
2348
  }
2437
- async generateApplicationTemplate(app) {
2438
- const openAIApiKey = process.env.OPENAI_API_KEY;
2439
- if (!openAIApiKey)
2440
- throw new Error("OPENAI_API_KEY is not set");
2441
- const [{ StringOutputParser }, { PromptTemplate }, { RunnableSequence }, { ChatOpenAI }, prompts] = await Promise.all([
2442
- import("@langchain/core/output_parsers"),
2443
- import("@langchain/core/prompts"),
2444
- import("@langchain/core/runnables"),
2445
- import("@langchain/openai"),
2446
- loadPrompts()
2447
- ]);
2448
- const chatModel = new ChatOpenAI({ modelName: "gpt-4o", openAIApiKey });
2449
- const projectName = await prompts.input({ message: "please enter project name." });
2450
- const projectDesc = await prompts.input({
2451
- message: "please enter project description. (40 ~ 60 characters)"
2452
- });
2453
- const spinner = ora("Gerating project files...");
2454
- const mainPrompt = PromptTemplate.fromTemplate(`prompt.requestApplication()`);
2455
- const chain = RunnableSequence.from([mainPrompt, chatModel, new StringOutputParser]);
2456
- await chain.invoke({ projectName, projectDesc });
2457
- spinner.succeed("Loading complete!");
2458
- }
2459
2349
  }
2460
2350
 
2461
2351
  // pkgs/@akanjs/cli/application/devPortReclaimer.ts
@@ -2692,6 +2582,7 @@ class DevBootConcurrency {
2692
2582
  import { mkdir, rename } from "fs/promises";
2693
2583
  import path6 from "path";
2694
2584
  import dayjs from "dayjs";
2585
+
2695
2586
  class DevSessionLog {
2696
2587
  static fileName = "dev.log";
2697
2588
  static previousFileName = "dev.prev.log";
@@ -2865,6 +2756,7 @@ class DevSupervisor {
2865
2756
  name: app.name,
2866
2757
  port,
2867
2758
  url: `http://localhost:${port}`,
2759
+ shareUrl: this.#options.shares?.get(app.name) ?? null,
2868
2760
  state: "starting",
2869
2761
  detail: "queued",
2870
2762
  exitCode: null
@@ -3054,9 +2946,54 @@ var resolveDevUi = (plain, { isTty = !!process.stdout.isTTY, columns = process.s
3054
2946
  return { mode: "tui", downgraded: false };
3055
2947
  };
3056
2948
 
2949
+ // pkgs/@akanjs/cli/application/interruptTeardown.ts
2950
+ import { Logger as Logger6 } from "akanjs/common";
2951
+
2952
+ class InterruptTeardown {
2953
+ #teardowns = [];
2954
+ #exit;
2955
+ #listen;
2956
+ #report;
2957
+ #interrupted = false;
2958
+ ownsExit = true;
2959
+ constructor({ exit, listen, report } = {}) {
2960
+ this.#exit = exit ?? ((code) => process.exit(code));
2961
+ this.#listen = listen ?? ((onSignal) => {
2962
+ process.on("SIGINT", onSignal);
2963
+ });
2964
+ this.#report = report ?? ((message) => Logger6.rawLog(message, undefined, "error"));
2965
+ }
2966
+ add(run, abandoned) {
2967
+ this.#teardowns.push({ run, abandoned, running: false });
2968
+ if (this.#teardowns.length === 1)
2969
+ this.#listen(() => this.#onSignal());
2970
+ }
2971
+ #onSignal() {
2972
+ if (this.#interrupted) {
2973
+ for (const one of this.#teardowns)
2974
+ if (one.running)
2975
+ this.#report(one.abandoned);
2976
+ this.#exit(130);
2977
+ return;
2978
+ }
2979
+ this.#interrupted = true;
2980
+ Promise.all(this.#teardowns.map(async (one) => {
2981
+ one.running = true;
2982
+ await one.run().catch(() => {
2983
+ return;
2984
+ });
2985
+ one.running = false;
2986
+ })).finally(() => {
2987
+ if (this.ownsExit)
2988
+ this.#exit(0);
2989
+ });
2990
+ }
2991
+ }
2992
+
3057
2993
  // pkgs/@akanjs/cli/application/application.script.ts
3058
2994
  class ApplicationScript extends script("application", [ApplicationRunner, LibraryScript]) {
3059
2995
  static dbShutdownTimeoutMs = 20000;
2996
+ #interrupt = new InterruptTeardown;
3060
2997
  async confirmDatabaseModeDependencyInstall(databaseMode, installSpecs) {
3061
2998
  return await confirm({
3062
2999
  message: [
@@ -3148,7 +3085,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3148
3085
  const spinner = app.spinning("Planning distributable slice...");
3149
3086
  const plan = await this.applicationRunner.planSlice(app);
3150
3087
  spinner.succeed(`Slice planned (${plan.libs.length} libs, ${plan.warnings.length} warnings)`);
3151
- Logger6.rawLog(format === "json" ? JSON.stringify(plan, null, 2) : formatSlicePlan(plan));
3088
+ Logger7.rawLog(format === "json" ? JSON.stringify(plan, null, 2) : formatSlicePlan(plan));
3152
3089
  }
3153
3090
  async sync(sys) {
3154
3091
  if (sys.type === "app")
@@ -3156,17 +3093,6 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3156
3093
  else
3157
3094
  await this.libraryScript.syncLibrary(sys);
3158
3095
  }
3159
- async compact(sys, { module = null, minLines, interactive = false } = {}) {
3160
- const { scanned, reports } = await this.applicationRunner.compact(sys, { module, minLines, interactive });
3161
- if (!reports.length) {
3162
- Logger6.rawLog(`No abstract file long enough to compact in ${sys.name} (${scanned} scanned)`);
3163
- return;
3164
- }
3165
- for (const report of reports)
3166
- Logger6.rawLog(`${report.status}: ${report.path} (${report.beforeLines} -> ${report.afterLines} lines)`);
3167
- const compactedNum = reports.filter((report) => report.status === "compacted").length;
3168
- Logger6.rawLog(`Compacted ${compactedNum}/${reports.length} abstract files in ${sys.name}`);
3169
- }
3170
3096
  async script(app, filename) {
3171
3097
  const scriptFilename = filename ?? await this.applicationRunner.getScriptFilename(app);
3172
3098
  await app.scanSync();
@@ -3182,18 +3108,18 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3182
3108
  async build(app, { write = true, fast = false, quiet = false } = {}) {
3183
3109
  await app.scanSync({ write });
3184
3110
  if (!quiet)
3185
- Logger6.rawLog(`Creating an optimized production build for ${app.name}...`);
3111
+ Logger7.rawLog(`Creating an optimized production build for ${app.name}...`);
3186
3112
  try {
3187
3113
  const result = await this.applicationRunner.build(app, {
3188
3114
  fast,
3189
3115
  spinner: !quiet
3190
3116
  });
3191
- Logger6.rawLog(`${app.name} built in dist/apps/${app.name}`);
3117
+ Logger7.rawLog(`${app.name} built in dist/apps/${app.name}`);
3192
3118
  if (!quiet)
3193
3119
  ApplicationBuildReporter.printSummary(result);
3194
3120
  } catch (error) {
3195
- Logger6.rawLog(`${app.name} build failed in dist/apps/${app.name}`, undefined, "error");
3196
- Logger6.rawLog(ApplicationBuildReporter.formatError(error), undefined, "error");
3121
+ Logger7.rawLog(`${app.name} build failed in dist/apps/${app.name}`, undefined, "error");
3122
+ Logger7.rawLog(ApplicationBuildReporter.formatError(error), undefined, "error");
3197
3123
  throw error;
3198
3124
  }
3199
3125
  }
@@ -3205,7 +3131,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3205
3131
  spinner.succeed(`${app.name} typechecked`);
3206
3132
  } catch (error) {
3207
3133
  spinner.fail(`${app.name} typecheck failed`);
3208
- Logger6.rawLog(ApplicationBuildReporter.formatError(error), undefined, "error");
3134
+ Logger7.rawLog(ApplicationBuildReporter.formatError(error), undefined, "error");
3209
3135
  throw error;
3210
3136
  }
3211
3137
  }
@@ -3247,11 +3173,11 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3247
3173
  first.workspace.log("no sized terminal to draw on; printing prefixed lines instead");
3248
3174
  if (kill)
3249
3175
  await this.reclaimDevPorts(apps);
3250
- if (share)
3251
- await this.#shareOnInterrupt(apps);
3176
+ const shares = share ? await this.#shareOnInterrupt(apps) : null;
3252
3177
  if (mode === "stream" && apps.length === 1)
3253
3178
  return await this.startOne(first, { open, dbup, write, ...DevSupervisor.childHooks() });
3254
- await this.#startMany(apps, { open, dbup, write, mode, concurrency });
3179
+ this.#interrupt.ownsExit = false;
3180
+ await this.#startMany(apps, { open, dbup, write, mode, concurrency, shares });
3255
3181
  }
3256
3182
  async startOne(app, { open = false, dbup = true, stdio = "inherit", write = true, onDevEvent } = {}) {
3257
3183
  await app.scanSync({ write });
@@ -3283,7 +3209,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3283
3209
  for (const holder of killed)
3284
3210
  workspace.log(`freed port ${holder.port} \u2014 killed pid ${holder.pid} (${holder.command})`);
3285
3211
  for (const holder of foreign)
3286
- Logger6.rawLog(`port ${holder.port} is held by pid ${holder.pid} and was left alone: ${holder.command}`, undefined, "error");
3212
+ Logger7.rawLog(`port ${holder.port} is held by pid ${holder.pid} and was left alone: ${holder.command}`, undefined, "error");
3287
3213
  if (killed.length === 0 && foreign.length === 0)
3288
3214
  workspace.log("dev ports are free; nothing to kill");
3289
3215
  }
@@ -3292,14 +3218,15 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3292
3218
  dbup,
3293
3219
  write,
3294
3220
  mode,
3295
- concurrency
3221
+ concurrency,
3222
+ shares
3296
3223
  }) {
3297
3224
  const workspace = apps[0]?.workspace;
3298
3225
  if (!workspace)
3299
3226
  throw new Error("No app selected to start");
3300
3227
  const startedDatabase = dbup ? await this.#prepareSharedDatabase(apps) : false;
3301
- const supervisor = new DevSupervisor({ apps, mode, concurrency, open, write });
3302
- const view = mode === "tui" ? await (await import("./devTuiView-gz2fbf4v.js")).createDevTuiView(supervisor) : new DevStreamView(apps.map((app) => app.name));
3228
+ const supervisor = new DevSupervisor({ apps, mode, concurrency, open, write, shares });
3229
+ const view = mode === "tui" ? await (await import("./devTuiView-pa63jrjq.js")).createDevTuiView(supervisor) : new DevStreamView(apps.map((app) => app.name));
3303
3230
  await supervisor.run(view);
3304
3231
  if (startedDatabase)
3305
3232
  await this.#stopDatabase(workspace);
@@ -3417,35 +3344,27 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3417
3344
  }
3418
3345
  spinner.succeed("Local database (/local/docker-compose.yaml) is down");
3419
3346
  }
3420
- #shareOnInterrupt(apps) {
3347
+ async#shareOnInterrupt(apps) {
3421
3348
  const shares = [];
3422
- const open = Promise.all(apps.map(async (app) => {
3423
- const { TunnelShare } = await import("./TunnelShare-2kwqb1j6.js");
3349
+ const urls = new Map;
3350
+ this.#interrupt.add(async () => {
3351
+ await Promise.all(shares.map(async (share) => await share.close()));
3352
+ }, "Abandoning the tunnel release; the shares expire on their own.");
3353
+ await Promise.all(apps.map(async (app) => {
3354
+ const { TunnelShare } = await import("./TunnelShare-r5tc2qk5.js");
3424
3355
  const share = await TunnelShare.open(app, { workspace: app.workspace });
3425
3356
  shares.push(share);
3426
- Logger6.rawLog(`${app.name} is shared at ${share.url}`);
3357
+ urls.set(app.name, share.url);
3358
+ Logger7.rawLog(`${app.name} is shared at ${share.url}`);
3427
3359
  })).catch((error) => {
3428
- Logger6.rawLog(`Could not open the tunnel: ${error instanceof Error ? error.message : String(error)}`, undefined, "error");
3360
+ Logger7.rawLog(`Could not open the tunnel: ${error instanceof Error ? error.message : String(error)}`, undefined, "error");
3429
3361
  });
3430
- let closing = false;
3431
- process.on("SIGINT", () => {
3432
- if (closing)
3433
- return;
3434
- closing = true;
3435
- Promise.all(shares.map(async (share) => await share.close()));
3436
- });
3437
- return open;
3362
+ return urls;
3438
3363
  }
3439
3364
  #stopDatabaseOnInterrupt(workspace) {
3440
- let stopping = false;
3441
- process.on("SIGINT", () => {
3442
- if (stopping) {
3443
- Logger6.rawLog("Abandoning the local database teardown; containers are left running.", undefined, "error");
3444
- process.exit(130);
3445
- }
3446
- stopping = true;
3447
- this.#stopDatabase(workspace).finally(() => process.exit(0));
3448
- });
3365
+ this.#interrupt.add(async () => {
3366
+ await this.#stopDatabase(workspace);
3367
+ }, "Abandoning the local database teardown; containers are left running.");
3449
3368
  }
3450
3369
  async#stopDatabase(workspace) {
3451
3370
  let timer = null;
@@ -3458,7 +3377,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3458
3377
  }), timeout]);
3459
3378
  if (result !== "timeout")
3460
3379
  return;
3461
- Logger6.rawLog(`Local database did not stop within ${ApplicationScript.dbShutdownTimeoutMs}ms; run \`akan dbdown\` once Docker responds.`, undefined, "error");
3380
+ Logger7.rawLog(`Local database did not stop within ${ApplicationScript.dbShutdownTimeoutMs}ms; run \`akan dbdown\` once Docker responds.`, undefined, "error");
3462
3381
  } finally {
3463
3382
  if (timer)
3464
3383
  clearTimeout(timer);
@@ -3466,4 +3385,4 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3466
3385
  }
3467
3386
  }
3468
3387
 
3469
- export { openBrowser, plainTextOf, HOST_SOURCE, DevLogBuffer, ApplicationScript };
3388
+ export { openBrowser, ApplicationScript };
@@ -1,12 +1,12 @@
1
1
  // @bun
2
2
  import {
3
3
  script
4
- } from "./index-b3ae16mg.js";
4
+ } from "./index-gca9y01h.js";
5
5
  import {
6
6
  AppExecutor,
7
7
  LibExecutor,
8
8
  ModuleExecutor
9
- } from "./index-5nyznra1.js";
9
+ } from "./index-p1j0cyvd.js";
10
10
  import {
11
11
  compactDiagnostics,
12
12
  createPrimitiveWriteReport,
@@ -39,10 +39,10 @@ import {
39
39
  hasSignalFactoryEntry,
40
40
  insertSignalFactoryEntry,
41
41
  addFieldUiPolicyForType
42
- } from "./index-jwjaf9fy.js";
42
+ } from "./index-1p146w4s.js";
43
43
  import {
44
44
  ModuleScript
45
- } from "./index-kpnp2e10.js";
45
+ } from "./index-v156f836.js";
46
46
 
47
47
  // pkgs/@akanjs/cli/primitive/primitive.script.ts
48
48
  import { capitalize } from "akanjs/common";
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-b3ae16mg.js";
5
+ } from "./index-gca9y01h.js";
6
6
  import {
7
7
  LibExecutor
8
- } from "./index-5nyznra1.js";
8
+ } from "./index-p1j0cyvd.js";
9
9
  import {
10
10
  LibSource,
11
11
  formatLibStatuses
@@ -0,0 +1,69 @@
1
+ // @bun
2
+ import {
3
+ jsonText
4
+ } from "./index-1p146w4s.js";
5
+ import {
6
+ akanMcpInstallTargets
7
+ } from "./index-3dmebxnk.js";
8
+ import {
9
+ script
10
+ } from "./index-gca9y01h.js";
11
+ import {
12
+ ContextRunner2
13
+ } from "./index-bzjnp9ap.js";
14
+
15
+ // pkgs/@akanjs/cli/context/context.script.ts
16
+ import { Logger } from "akanjs/common";
17
+ var resolveMcpInstallTargets = (target) => {
18
+ if (!target || target === "all")
19
+ return [...akanMcpInstallTargets];
20
+ if (akanMcpInstallTargets.includes(target))
21
+ return [target];
22
+ throw new Error(`Unknown MCP install target: ${target}. Use cursor, claude, codex, or all.`);
23
+ };
24
+ var mcpTargetLabels = {
25
+ cursor: "Cursor",
26
+ claude: "Claude Code",
27
+ codex: "Codex"
28
+ };
29
+
30
+ class ContextScript extends script("context", [ContextRunner2]) {
31
+ async context(workspace, options = {}) {
32
+ Logger.rawLog(await this.contextRunner.getContext(workspace, options));
33
+ }
34
+ async doctor(workspace, options = {}) {
35
+ Logger.rawLog(await this.contextRunner.doctor(workspace, options));
36
+ }
37
+ async mcpInstall(workspace, target, { force = false, mode = "apply" } = {}) {
38
+ const targets = resolveMcpInstallTargets(target);
39
+ const written = [];
40
+ for (const t of targets) {
41
+ const configPath = await this.contextRunner.installMcp(workspace, t, { force, mode });
42
+ written.push(`${mcpTargetLabels[t]}: ${configPath}`);
43
+ }
44
+ Logger.rawLog(`Akan MCP server installed (${mode} mode):
45
+ ${written.map((line) => `- ${line}`).join(`
46
+ `)}`);
47
+ }
48
+ async mcp(workspace, { mode = "apply" } = {}) {
49
+ await this.contextRunner.runMcp(workspace, { mode });
50
+ }
51
+ async mcpCall(workspace, tool, {
52
+ mode = "readonly",
53
+ args = null,
54
+ format = "json"
55
+ } = {}) {
56
+ let parsedArgs = {};
57
+ if (args) {
58
+ const parsed = JSON.parse(args);
59
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
60
+ throw new Error("MCP call args must be a JSON object.");
61
+ }
62
+ parsedArgs = parsed;
63
+ }
64
+ const result = await this.contextRunner.callMcpTool(workspace, tool, parsedArgs, { mode });
65
+ Logger.rawLog(format === "json" ? jsonText(result) : String(result));
66
+ }
67
+ }
68
+
69
+ export { ContextScript };