@akanjs/cli 3.0.0-beta.14 → 3.0.0-beta.16

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 (80) hide show
  1. package/.build-stamp +1 -1
  2. package/CodeAgent-zgccwajm.js +9 -0
  3. package/CodeAgentRpcHost-qvwfv0n9.js +7 -0
  4. package/CodeTui-993tx7gf.js +1103 -0
  5. package/README.md +3 -0
  6. package/{agent.command-bhwsc2aj.js → agent.command-n664dtcv.js} +6 -6
  7. package/akanCode.js +100 -0
  8. package/{application.command-436y543n.js → application.command-t5542jte.js} +6 -5
  9. package/{applicationBuildRunner-4f1wrba0.js → applicationBuildRunner-x4gbfn7y.js} +2 -2
  10. package/{applicationReleasePackager-jkjmy5ee.js → applicationReleasePackager-z61ep017.js} +1 -1
  11. package/buildBatch.proc.js +2 -2
  12. package/{capacitorApp-hqvsrec4.js → capacitorApp-shv3ajh5.js} +2 -2
  13. package/{cloud.command-3xn0xpz8.js → cloud.command-4x35k1z6.js} +9 -8
  14. package/cloud.script-3k8nbbpn.js +20 -0
  15. package/code.command-mrfb7a1g.js +147 -0
  16. package/commandManifest.json +1 -1
  17. package/consoleToStderr-h5bryj94.js +7 -0
  18. package/{context.command-hxh96cc3.js → context.command-pqsm5jrk.js} +14 -13
  19. package/context.runner-bys6ykcp.js +22 -0
  20. package/{devTui-4ted58a6.js → devTui-gy6mendg.js} +114 -8
  21. package/{devTuiView-1dj2yq7t.js → devTuiView-y1548wy6.js} +1 -1
  22. package/{guideline.command-cyw8c0m0.js → guideline.command-rpc2emw8.js} +6 -6
  23. package/guidelines/agentRule/agentRule.instruction.md +22 -2
  24. package/guidelines/conventions/conventions.instruction.md +3 -1
  25. package/incrementalBuilder.proc.js +1 -1
  26. package/{index-t8gvwcrx.js → index-018dszb3.js} +13 -4
  27. package/{index-8pkvrcv1.js → index-2pm1j01n.js} +3 -3
  28. package/{index-7f4dsf9v.js → index-3cymrzsb.js} +1 -1
  29. package/{index-1nwxbr2y.js → index-3mg4h788.js} +2 -2
  30. package/{index-em4swemt.js → index-4cvpzkq6.js} +3 -3
  31. package/index-4n4821gp.js +69 -0
  32. package/index-5405kc0x.js +2434 -0
  33. package/{index-tt6kzwj5.js → index-57p9p179.js} +3 -3
  34. package/{index-b3ae16mg.js → index-6na0sd2b.js} +1 -1
  35. package/index-7md2g9vw.js +6 -0
  36. package/index-8k16atqy.js +82 -0
  37. package/{index-fad0hhty.js → index-g9zghs4h.js} +22 -80
  38. package/index-jgrnpt6y.js +121 -0
  39. package/{index-31hmq4ys.js → index-kvzjda3v.js} +8 -8
  40. package/{index-sg1bgdhe.js → index-ns128c4q.js} +27 -105
  41. package/{index-5nyznra1.js → index-p4p9t45x.js} +3 -0
  42. package/{index-sh88vtye.js → index-qh7brn20.js} +1 -1
  43. package/{index-jwjaf9fy.js → index-qhtj9y6j.js} +44 -44
  44. package/{index-ys7dvdb3.js → index-sn7dnzq4.js} +1 -1
  45. package/index-sxg87a8f.js +727 -0
  46. package/{index-r73ha1rf.js → index-te0y1c0m.js} +4 -4
  47. package/{index-h7yw2z9n.js → index-twq9p2sp.js} +8 -8
  48. package/{index-15r9a10e.js → index-v17gj504.js} +2 -2
  49. package/{index-1mrmve4s.js → index-vpx68e4x.js} +2 -2
  50. package/index-wfwknnje.js +124 -0
  51. package/{index-9fbk3dbh.js → index-xjc7gg65.js} +4 -4
  52. package/{index-8tcj5wk8.js → index-zg0v1zte.js} +5 -5
  53. package/{index-vrwdx0zx.js → index-zn8qgeqx.js} +1 -1
  54. package/index.js +21 -20
  55. package/{library.command-1f9h2ex6.js → library.command-m8p2r1dh.js} +3 -3
  56. package/{localRegistry.command-4cbgz63s.js → localRegistry.command-tt00nwwg.js} +8 -7
  57. package/{module.command-ew0484va.js → module.command-mfzvqt0n.js} +5 -5
  58. package/{package.command-y2rh4np7.js → package.command-8sy6jjwy.js} +3 -3
  59. package/package.json +12 -2
  60. package/{page.command-e5h29fyt.js → page.command-taenb02b.js} +3 -3
  61. package/{primitive.command-50ecfzg4.js → primitive.command-7kpncmkk.js} +6 -6
  62. package/prompter-9mn3kp36.js +8 -0
  63. package/{quality.command-a2jytczs.js → quality.command-1ar94hrw.js} +2 -2
  64. package/{repair.command-c2amvt74.js → repair.command-n08t6j8p.js} +5 -5
  65. package/{scalar.command-bptz6aj6.js → scalar.command-mq8qfp4t.js} +4 -4
  66. package/skills/akan-debug/SKILL.md +42 -0
  67. package/skills/akan-deps/SKILL.md +50 -0
  68. package/skills/akan-err/SKILL.md +39 -0
  69. package/skills/akan-module/SKILL.md +45 -0
  70. package/skills/akan-scaffold/SKILL.md +76 -0
  71. package/skills/akan-scalar/SKILL.md +52 -0
  72. package/skills/akan-service/SKILL.md +34 -0
  73. package/skills/akan-store/SKILL.md +63 -0
  74. package/skills/akan-ui/SKILL.md +63 -0
  75. package/skills/akan-validate/SKILL.md +44 -0
  76. package/{subspace.command-kmemx1vm.js → subspace.command-x9897gj4.js} +4 -4
  77. package/{tunnel.command-67q8vsg5.js → tunnel.command-ht2es78c.js} +2 -2
  78. package/{workflow.command-2ze5y2xp.js → workflow.command-tvz4nm9n.js} +9 -9
  79. package/{workspace.command-2n385jkt.js → workspace.command-ayqa1rgt.js} +22 -20
  80. package/cloud.script-0a76c2g8.js +0 -19
@@ -6,14 +6,14 @@ import {
6
6
  } from "./index-myj01w9r.js";
7
7
  import {
8
8
  runner
9
- } from "./index-b3ae16mg.js";
9
+ } from "./index-6na0sd2b.js";
10
10
  import {
11
11
  WorkspaceExecutor,
12
12
  AppExecutor
13
- } from "./index-5nyznra1.js";
13
+ } from "./index-p4p9t45x.js";
14
14
  import {
15
15
  openBrowser
16
- } from "./index-sg1bgdhe.js";
16
+ } from "./index-ns128c4q.js";
17
17
 
18
18
  // pkgs/@akanjs/cli/cloud/cloud.runner.ts
19
19
  import path from "path";
@@ -9,7 +9,7 @@ import {
9
9
  LibExecutor,
10
10
  PkgExecutor,
11
11
  ModuleExecutor
12
- } from "./index-5nyznra1.js";
12
+ } from "./index-p4p9t45x.js";
13
13
  import {
14
14
  getDirname2
15
15
  } from "./index-6wwzs1bc.js";
@@ -0,0 +1,6 @@
1
+ // @bun
2
+ // pkgs/@akanjs/devkit/stripAnsi.ts
3
+ var ansi = new RegExp(`${String.fromCharCode(27)}(?:[@-Z\\\\-_]|\\[[\\s\\S]*?[@-~])`, "g");
4
+ var stripAnsi = (text) => text.replace(ansi, "");
5
+
6
+ export { stripAnsi };
@@ -0,0 +1,82 @@
1
+ // @bun
2
+ // pkgs/@akanjs/devkit/codeAgent/agent/CodeAgentRpcHost.ts
3
+ class CodeAgentRpcHost2 {
4
+ #agent;
5
+ #write;
6
+ #buffer = "";
7
+ constructor(agent, write = (line) => process.stdout.write(line)) {
8
+ this.#agent = agent;
9
+ this.#write = write;
10
+ }
11
+ async serve(input = process.stdin) {
12
+ this.#agent.on((event) => this.#emit(event));
13
+ this.#agent.announce();
14
+ const decoder = new TextDecoder;
15
+ for await (const chunk of input)
16
+ await this.#push(decoder.decode(chunk, { stream: true }));
17
+ await this.#agent.abort().catch(() => {});
18
+ }
19
+ async#push(text) {
20
+ this.#buffer += text;
21
+ let index = this.#buffer.indexOf(`
22
+ `);
23
+ while (index >= 0) {
24
+ const line = this.#buffer.slice(0, index).trim();
25
+ this.#buffer = this.#buffer.slice(index + 1);
26
+ if (line)
27
+ await this.#handle(line);
28
+ index = this.#buffer.indexOf(`
29
+ `);
30
+ }
31
+ }
32
+ async#handle(line) {
33
+ let request;
34
+ try {
35
+ request = JSON.parse(line);
36
+ } catch {
37
+ return this.#emit({ type: "error", message: "malformed command frame", fatal: false, seq: -1 });
38
+ }
39
+ try {
40
+ this.#reply({ type: "reply", id: request.id, ok: true, data: await this.#run(request.command) });
41
+ } catch (error) {
42
+ this.#reply({ type: "reply", id: request.id, ok: false, error: String(error) });
43
+ }
44
+ }
45
+ async#run(command) {
46
+ switch (command.type) {
47
+ case "prompt":
48
+ this.#agent.prompt(command.message, command.images);
49
+ return { accepted: true };
50
+ case "answer":
51
+ return { handled: await this.#agent.answer(command.questionId, command.answer) };
52
+ case "approve":
53
+ return { handled: await this.#agent.approve(command.approvalId, command.approved) };
54
+ case "abort":
55
+ await this.#agent.abort();
56
+ return { aborted: true };
57
+ case "compact":
58
+ await this.#agent.compact(command.instructions);
59
+ return { compacted: true };
60
+ case "set_model":
61
+ await this.#agent.setModel({ provider: command.provider, id: command.modelId });
62
+ return await this.#agent.state();
63
+ case "get_state":
64
+ return await this.#agent.state(command.sinceSeq === undefined ? {} : { sinceSeq: command.sinceSeq });
65
+ case "shutdown":
66
+ this.#agent.dispose();
67
+ return { shutdown: true };
68
+ default:
69
+ throw new Error(`Unsupported command: ${command.type}`);
70
+ }
71
+ }
72
+ #emit(event) {
73
+ this.#write(`${JSON.stringify({ type: "event", event })}
74
+ `);
75
+ }
76
+ #reply(reply) {
77
+ this.#write(`${JSON.stringify(reply)}
78
+ `);
79
+ }
80
+ }
81
+
82
+ export { CodeAgentRpcHost2 };
@@ -1,58 +1,53 @@
1
1
  // @bun
2
2
  import {
3
3
  AppExecutor
4
- } from "./index-5nyznra1.js";
4
+ } from "./index-p4p9t45x.js";
5
5
  import {
6
6
  jsonText,
7
7
  createWorkflowBaselineSummary,
8
8
  buildAkanModuleContextIndex,
9
9
  createWorkflowStepRegistry,
10
10
  toolingRolloutGate
11
- } from "./index-jwjaf9fy.js";
11
+ } from "./index-qhtj9y6j.js";
12
12
  import {
13
13
  buildResourceList,
14
14
  codexMcpConfigPath,
15
- akanMcpInstallTargets,
16
15
  akanMcpInstallConfigPaths,
17
16
  createAkanMcpServer,
18
17
  createAkanCodexMcpServerBlock,
19
18
  upsertCodexMcpServerBlock,
20
19
  renderDoctorText,
21
20
  AkanContextAnalyzer
22
- } from "./index-15r9a10e.js";
23
- import {
24
- CommandContainer,
25
- runner,
26
- script
27
- } from "./index-b3ae16mg.js";
21
+ } from "./index-v17gj504.js";
28
22
  import {
29
23
  isPlaceholderAppId2
30
- } from "./index-7f4dsf9v.js";
24
+ } from "./index-3cymrzsb.js";
31
25
  import {
32
- Prompter
33
- } from "./index-h7yw2z9n.js";
26
+ CommandContainer,
27
+ runner
28
+ } from "./index-6na0sd2b.js";
29
+ import {
30
+ Prompter2
31
+ } from "./index-twq9p2sp.js";
34
32
  import {
35
33
  RepairRunner
36
- } from "./index-em4swemt.js";
34
+ } from "./index-4cvpzkq6.js";
37
35
  import {
38
36
  WorkflowRunner
39
- } from "./index-8pkvrcv1.js";
37
+ } from "./index-2pm1j01n.js";
40
38
  import {
41
39
  ModuleScript
42
- } from "./index-9fbk3dbh.js";
40
+ } from "./index-xjc7gg65.js";
43
41
  import {
44
42
  PrimitiveScript
45
- } from "./index-r73ha1rf.js";
43
+ } from "./index-te0y1c0m.js";
46
44
  import {
47
45
  ScalarScript
48
- } from "./index-1mrmve4s.js";
46
+ } from "./index-vpx68e4x.js";
49
47
  import {
50
48
  getMobileTargets
51
49
  } from "./index-47pj3aee.js";
52
50
 
53
- // pkgs/@akanjs/cli/context/context.script.ts
54
- import { Logger } from "akanjs/common";
55
-
56
51
  // pkgs/@akanjs/devkit/akanMcpContract.ts
57
52
  import path from "path";
58
53
  var emptySchema = { type: "object", properties: {} };
@@ -637,7 +632,7 @@ var compactDoctorWorkspaceResult = (result, includeBaselineDetails) => {
637
632
  };
638
633
  };
639
634
 
640
- class ContextRunner extends runner("context") {
635
+ class ContextRunner2 extends runner("context") {
641
636
  async getContext(workspace, {
642
637
  format = "markdown",
643
638
  app = null,
@@ -694,7 +689,7 @@ class ContextRunner extends runner("context") {
694
689
  `);
695
690
  }
696
691
  async getGuidelineResource(name) {
697
- return await Prompter.getInstruction(name);
692
+ return await Prompter2.getInstruction(name);
698
693
  }
699
694
  async installMcp(workspace, target, { force = false, mode = "readonly" } = {}) {
700
695
  if (target === "codex")
@@ -773,7 +768,7 @@ class ContextRunner extends runner("context") {
773
768
  return modules;
774
769
  }
775
770
  if (name === "get_guideline")
776
- return await Prompter.getInstruction(stringArg(args, "name"));
771
+ return await Prompter2.getInstruction(stringArg(args, "name"));
777
772
  if (name === "doctor_workspace")
778
773
  return compactDoctorWorkspaceResult(await AkanContextAnalyzer.doctor(workspace, {
779
774
  strict: !!args.strict,
@@ -863,14 +858,14 @@ ${payload}`);
863
858
  const respondError = (id, code, message, framing) => {
864
859
  writeMessage({ jsonrpc: "2.0", id: id ?? null, error: { code, message } }, framing);
865
860
  };
866
- const guidelineNames = await Prompter.listGuidelines();
861
+ const guidelineNames = await Prompter2.listGuidelines();
867
862
  const resources = buildResourceList(guidelineNames);
868
863
  const readResource = async (uri) => {
869
864
  if (uri === "akan://docs/framework")
870
- return { uri, mimeType: "text/markdown", text: await Prompter.getInstruction("framework") };
865
+ return { uri, mimeType: "text/markdown", text: await Prompter2.getInstruction("framework") };
871
866
  const guideline = /^akan:\/\/guidelines\/(.+)$/.exec(uri)?.[1];
872
867
  if (guideline)
873
- return { uri, mimeType: "text/markdown", text: await Prompter.getInstruction(guideline) };
868
+ return { uri, mimeType: "text/markdown", text: await Prompter2.getInstruction(guideline) };
874
869
  const context = await AkanContextAnalyzer.analyze(workspace);
875
870
  if (uri === "akan://workspace/summary")
876
871
  return { uri, mimeType: "application/json", text: jsonText(context, { trailingNewline: false }) };
@@ -1049,57 +1044,4 @@ ${payload}`);
1049
1044
  }
1050
1045
  }
1051
1046
 
1052
- // pkgs/@akanjs/cli/context/context.script.ts
1053
- var resolveMcpInstallTargets = (target) => {
1054
- if (!target || target === "all")
1055
- return [...akanMcpInstallTargets];
1056
- if (akanMcpInstallTargets.includes(target))
1057
- return [target];
1058
- throw new Error(`Unknown MCP install target: ${target}. Use cursor, claude, codex, or all.`);
1059
- };
1060
- var mcpTargetLabels = {
1061
- cursor: "Cursor",
1062
- claude: "Claude Code",
1063
- codex: "Codex"
1064
- };
1065
-
1066
- class ContextScript extends script("context", [ContextRunner]) {
1067
- async context(workspace, options = {}) {
1068
- Logger.rawLog(await this.contextRunner.getContext(workspace, options));
1069
- }
1070
- async doctor(workspace, options = {}) {
1071
- Logger.rawLog(await this.contextRunner.doctor(workspace, options));
1072
- }
1073
- async mcpInstall(workspace, target, { force = false, mode = "apply" } = {}) {
1074
- const targets = resolveMcpInstallTargets(target);
1075
- const written = [];
1076
- for (const t of targets) {
1077
- const configPath = await this.contextRunner.installMcp(workspace, t, { force, mode });
1078
- written.push(`${mcpTargetLabels[t]}: ${configPath}`);
1079
- }
1080
- Logger.rawLog(`Akan MCP server installed (${mode} mode):
1081
- ${written.map((line) => `- ${line}`).join(`
1082
- `)}`);
1083
- }
1084
- async mcp(workspace, { mode = "apply" } = {}) {
1085
- await this.contextRunner.runMcp(workspace, { mode });
1086
- }
1087
- async mcpCall(workspace, tool, {
1088
- mode = "readonly",
1089
- args = null,
1090
- format = "json"
1091
- } = {}) {
1092
- let parsedArgs = {};
1093
- if (args) {
1094
- const parsed = JSON.parse(args);
1095
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
1096
- throw new Error("MCP call args must be a JSON object.");
1097
- }
1098
- parsedArgs = parsed;
1099
- }
1100
- const result = await this.contextRunner.callMcpTool(workspace, tool, parsedArgs, { mode });
1101
- Logger.rawLog(format === "json" ? jsonText(result) : String(result));
1102
- }
1103
- }
1104
-
1105
- export { ContextScript };
1047
+ export { ContextRunner2 };
@@ -0,0 +1,121 @@
1
+ // @bun
2
+ // pkgs/@akanjs/devkit/codeAgent/agent/SubagentPool.ts
3
+ import { codeAgentReadOnlyBuiltins } from "akanjs/common";
4
+ import { Type } from "typebox";
5
+ var maxResultChars = 8000;
6
+
7
+ class SubagentPool2 {
8
+ static kinds = {
9
+ explore: {
10
+ readOnly: true,
11
+ desc: "reads, searches and reports back. It cannot write a file or run a command."
12
+ },
13
+ code: {
14
+ readOnly: false,
15
+ desc: "makes the change itself, with the same tools as this session."
16
+ }
17
+ };
18
+ static defaultKind = "explore";
19
+ #options;
20
+ #running = 0;
21
+ #spent = 0;
22
+ constructor(options) {
23
+ this.#options = options;
24
+ }
25
+ static extensionFor(options) {
26
+ if (!options.parent.tools.subagent)
27
+ return;
28
+ if (options.depth >= options.parent.tools.subagent.maxDepth)
29
+ return;
30
+ const pool = new SubagentPool2(options);
31
+ return { name: "akan-subagent", factory: (pi) => pool.#register(pi) };
32
+ }
33
+ static toolName = "task";
34
+ #register(pi) {
35
+ pi.registerTool({
36
+ name: SubagentPool2.toolName,
37
+ label: "Task",
38
+ description: "Run a focused sub-agent on one self-contained question and get back its answer. Use it for searching and reading that would otherwise fill this conversation \u2014 the sub-agent's own reading does not come back, only its answer. Give it everything it needs: it cannot see this conversation.",
39
+ promptSnippet: "task: run a sub-agent on one self-contained question and get back only its answer",
40
+ parameters: Type.Object({
41
+ description: Type.String({ description: "Three to five words naming the task, for the activity log." }),
42
+ prompt: Type.String({
43
+ description: "The complete instruction. The sub-agent sees nothing of this conversation."
44
+ }),
45
+ type: Type.Optional(Type.Union(Object.entries(SubagentPool2.kinds).map(([kind, spec]) => Type.Literal(kind, { description: spec.desc })), { description: `What the sub-agent may do. Defaults to ${SubagentPool2.defaultKind}.` }))
46
+ }),
47
+ execute: async (_id, params, signal) => {
48
+ const kind = params.type ?? SubagentPool2.defaultKind;
49
+ const refusal = this.#refuse();
50
+ if (refusal)
51
+ return { content: [{ type: "text", text: refusal }], details: undefined, isError: true };
52
+ this.#running += 1;
53
+ this.#options.onNotice?.(`${kind} sub-agent \xB7 ${params.description}`);
54
+ try {
55
+ const text = await this.#run(kind, params.prompt, signal);
56
+ return { content: [{ type: "text", text }], details: undefined };
57
+ } finally {
58
+ this.#running -= 1;
59
+ }
60
+ }
61
+ });
62
+ }
63
+ #refuse() {
64
+ const budget = this.#options.parent.tools.subagent;
65
+ if (!budget)
66
+ return "Sub-agents are disabled by this profile.";
67
+ if (this.#running >= budget.maxConcurrent)
68
+ return `Too many sub-agents are already running (limit ${budget.maxConcurrent}). Wait for one to finish.`;
69
+ if (this.#spent >= budget.budget)
70
+ return `The sub-agent token budget (${budget.budget}) is spent. Do the rest of this work yourself.`;
71
+ return;
72
+ }
73
+ static childOf(parent, kind) {
74
+ const budget = parent.tools.subagent;
75
+ return {
76
+ ...parent,
77
+ name: `${parent.name}:${kind}`,
78
+ tools: {
79
+ ...parent.tools,
80
+ builtin: SubagentPool2.kinds[kind].readOnly ? parent.tools.builtin.filter((tool) => codeAgentReadOnlyBuiltins.includes(tool)) : parent.tools.builtin,
81
+ subagent: budget ? { ...budget, maxDepth: budget.maxDepth } : false
82
+ },
83
+ session: { store: "memory", crossSession: false },
84
+ ui: { canPrompt: false },
85
+ context: { projectFiles: false, skills: parent.context.skills }
86
+ };
87
+ }
88
+ async#run(kind, prompt, signal) {
89
+ const { CodeAgent } = await import("./CodeAgent-zgccwajm.js");
90
+ const budget = this.#options.parent.tools.subagent;
91
+ const child = SubagentPool2.childOf(this.#options.parent, kind);
92
+ const agent = await CodeAgent.create({
93
+ workspace: this.#options.workspace,
94
+ cwd: this.#options.cwd,
95
+ profile: child,
96
+ apps: [],
97
+ depth: this.#options.depth + 1
98
+ });
99
+ const abort = () => void agent.abort();
100
+ signal?.addEventListener("abort", abort, { once: true });
101
+ try {
102
+ let answer = "";
103
+ agent.on((event) => {
104
+ if (event.type === "message" && event.role === "assistant")
105
+ answer = event.text;
106
+ });
107
+ await agent.prompt(prompt);
108
+ await agent.waitForIdle();
109
+ this.#spent += agent.tokensUsed;
110
+ const ceiling = budget ? budget.budget : 0;
111
+ this.#options.onNotice?.(`${kind} sub-agent finished, ${agent.tokensUsed} tokens (${this.#spent} of ${ceiling} spent)`);
112
+ return answer.length > maxResultChars ? `${answer.slice(0, maxResultChars)}
113
+ \u2026(truncated)` : answer || "(no answer)";
114
+ } finally {
115
+ signal?.removeEventListener("abort", abort);
116
+ agent.dispose();
117
+ }
118
+ }
119
+ }
120
+
121
+ export { SubagentPool2 };
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-b3ae16mg.js";
5
+ } from "./index-6na0sd2b.js";
6
6
  import {
7
7
  AGENT_BLOCK_START,
8
8
  AGENT_BLOCK_END,
@@ -13,17 +13,17 @@ import {
13
13
  CLAUDE_COMMENT_RULE,
14
14
  AppExecutor,
15
15
  LibExecutor
16
- } from "./index-5nyznra1.js";
16
+ } from "./index-p4p9t45x.js";
17
17
  import {
18
18
  collectRecipeSources2,
19
19
  scanRecipes2
20
20
  } from "./index-by5gpp8x.js";
21
21
  import {
22
22
  AkanContextAnalyzer
23
- } from "./index-15r9a10e.js";
23
+ } from "./index-v17gj504.js";
24
24
  import {
25
- Prompter
26
- } from "./index-h7yw2z9n.js";
25
+ Prompter2
26
+ } from "./index-twq9p2sp.js";
27
27
 
28
28
  // pkgs/@akanjs/cli/agent/agent.script.ts
29
29
  import { Logger as Logger2 } from "akanjs/common";
@@ -106,10 +106,10 @@ ${scopeIndexPointer}
106
106
  `;
107
107
  };
108
108
  var renderGuides = async (context) => {
109
- const conventions = (await Prompter.getInstruction("conventions")).trim();
109
+ const conventions = (await Prompter2.getInstruction("conventions")).trim();
110
110
  if (context.pkgs.some((pkg) => pkg.name === "akanjs"))
111
111
  return conventions;
112
- const onboarding = (await Prompter.getInstruction("workspaceOnboarding")).trim();
112
+ const onboarding = (await Prompter2.getInstruction("workspaceOnboarding")).trim();
113
113
  const appName = context.apps[0]?.name ?? "app";
114
114
  return `${conventions}
115
115
 
@@ -117,7 +117,7 @@ ${onboarding.replaceAll("<%= appName %>", appName)}`;
117
117
  };
118
118
  var renderManagedBlock = async (workspace) => {
119
119
  const context = await AkanContextAnalyzer.analyze(workspace);
120
- const frameworkGuide = await Prompter.getInstruction("framework");
120
+ const frameworkGuide = await Prompter2.getInstruction("framework");
121
121
  const appNames = context.apps.map((app) => app.name);
122
122
  const sampleCleanup = await renderSampleCleanup(workspace, appNames);
123
123
  const recipeIndex = await renderRecipeIndex(workspace);
@@ -2,24 +2,27 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-b3ae16mg.js";
5
+ } from "./index-6na0sd2b.js";
6
6
  import {
7
7
  WorkspaceExecutor,
8
8
  AppExecutor,
9
9
  LibExecutor,
10
10
  PkgExecutor
11
- } from "./index-5nyznra1.js";
11
+ } from "./index-p4p9t45x.js";
12
12
  import {
13
13
  LibraryScript
14
- } from "./index-1nwxbr2y.js";
14
+ } from "./index-3mg4h788.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-sn7dnzq4.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
 
@@ -2048,9 +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
- var loadBuildRunner = async () => (await import("./applicationBuildRunner-4f1wrba0.js")).ApplicationBuildRunner;
2052
- var loadReleasePackager = async () => (await import("./applicationReleasePackager-jkjmy5ee.js")).ApplicationReleasePackager;
2053
- var loadCapacitorApp = async () => (await import("./capacitorApp-hqvsrec4.js")).CapacitorApp;
1969
+ var loadBuildRunner = async () => (await import("./applicationBuildRunner-x4gbfn7y.js")).ApplicationBuildRunner;
1970
+ var loadReleasePackager = async () => (await import("./applicationReleasePackager-z61ep017.js")).ApplicationReleasePackager;
1971
+ var loadCapacitorApp = async () => (await import("./capacitorApp-shv3ajh5.js")).CapacitorApp;
2054
1972
  var loadPrompts = async () => await import("@inquirer/prompts");
2055
1973
 
2056
1974
  class ApplicationRunner extends runner("application") {
@@ -2664,6 +2582,7 @@ class DevBootConcurrency {
2664
2582
  import { mkdir, rename } from "fs/promises";
2665
2583
  import path6 from "path";
2666
2584
  import dayjs from "dayjs";
2585
+
2667
2586
  class DevSessionLog {
2668
2587
  static fileName = "dev.log";
2669
2588
  static previousFileName = "dev.prev.log";
@@ -2837,6 +2756,7 @@ class DevSupervisor {
2837
2756
  name: app.name,
2838
2757
  port,
2839
2758
  url: `http://localhost:${port}`,
2759
+ shareUrl: this.#options.shares?.get(app.name) ?? null,
2840
2760
  state: "starting",
2841
2761
  detail: "queued",
2842
2762
  exitCode: null
@@ -3253,12 +3173,11 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3253
3173
  first.workspace.log("no sized terminal to draw on; printing prefixed lines instead");
3254
3174
  if (kill)
3255
3175
  await this.reclaimDevPorts(apps);
3256
- if (share)
3257
- await this.#shareOnInterrupt(apps);
3176
+ const shares = share ? await this.#shareOnInterrupt(apps) : null;
3258
3177
  if (mode === "stream" && apps.length === 1)
3259
3178
  return await this.startOne(first, { open, dbup, write, ...DevSupervisor.childHooks() });
3260
3179
  this.#interrupt.ownsExit = false;
3261
- await this.#startMany(apps, { open, dbup, write, mode, concurrency });
3180
+ await this.#startMany(apps, { open, dbup, write, mode, concurrency, shares });
3262
3181
  }
3263
3182
  async startOne(app, { open = false, dbup = true, stdio = "inherit", write = true, onDevEvent } = {}) {
3264
3183
  await app.scanSync({ write });
@@ -3299,14 +3218,15 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3299
3218
  dbup,
3300
3219
  write,
3301
3220
  mode,
3302
- concurrency
3221
+ concurrency,
3222
+ shares
3303
3223
  }) {
3304
3224
  const workspace = apps[0]?.workspace;
3305
3225
  if (!workspace)
3306
3226
  throw new Error("No app selected to start");
3307
3227
  const startedDatabase = dbup ? await this.#prepareSharedDatabase(apps) : false;
3308
- const supervisor = new DevSupervisor({ apps, mode, concurrency, open, write });
3309
- const view = mode === "tui" ? await (await import("./devTuiView-1dj2yq7t.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-y1548wy6.js")).createDevTuiView(supervisor) : new DevStreamView(apps.map((app) => app.name));
3310
3230
  await supervisor.run(view);
3311
3231
  if (startedDatabase)
3312
3232
  await this.#stopDatabase(workspace);
@@ -3424,20 +3344,22 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3424
3344
  }
3425
3345
  spinner.succeed("Local database (/local/docker-compose.yaml) is down");
3426
3346
  }
3427
- #shareOnInterrupt(apps) {
3347
+ async#shareOnInterrupt(apps) {
3428
3348
  const shares = [];
3429
- const open = Promise.all(apps.map(async (app) => {
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) => {
3430
3354
  const { TunnelShare } = await import("./TunnelShare-r5tc2qk5.js");
3431
3355
  const share = await TunnelShare.open(app, { workspace: app.workspace });
3432
3356
  shares.push(share);
3357
+ urls.set(app.name, share.url);
3433
3358
  Logger7.rawLog(`${app.name} is shared at ${share.url}`);
3434
3359
  })).catch((error) => {
3435
3360
  Logger7.rawLog(`Could not open the tunnel: ${error instanceof Error ? error.message : String(error)}`, undefined, "error");
3436
3361
  });
3437
- this.#interrupt.add(async () => {
3438
- await Promise.all(shares.map(async (share) => await share.close()));
3439
- }, "Abandoning the tunnel release; the shares expire on their own.");
3440
- return open;
3362
+ return urls;
3441
3363
  }
3442
3364
  #stopDatabaseOnInterrupt(workspace) {
3443
3365
  this.#interrupt.add(async () => {
@@ -3463,4 +3385,4 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
3463
3385
  }
3464
3386
  }
3465
3387
 
3466
- export { openBrowser, plainTextOf, HOST_SOURCE, DevLogBuffer, ApplicationScript };
3388
+ export { openBrowser, ApplicationScript };