@akanjs/cli 3.0.0-beta.25 → 3.0.0-beta.27

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 (29) hide show
  1. package/.build-stamp +1 -1
  2. package/{CodeAgent-p65jja35.js → CodeAgent-h19atbr3.js} +2 -2
  3. package/{CodeTui-5xr8kxx4.js → CodeTui-46zygq8p.js} +1 -1
  4. package/README.ko.md +72 -0
  5. package/README.md +88 -0
  6. package/akanCode.js +2 -2
  7. package/{application.command-2x9jqy0k.js → application.command-1p0cpt6y.js} +2 -2
  8. package/{applicationBuildRunner-tm0vba5t.js → applicationBuildRunner-r6b9rkb8.js} +2 -2
  9. package/buildBatch.proc.js +2 -2
  10. package/{cloud.command-j6m607bp.js → cloud.command-ps9dabbg.js} +3 -3
  11. package/{cloud.script-r5t7nhee.js → cloud.script-wrw1kz6k.js} +3 -3
  12. package/{code.command-jhrjttm1.js → code.command-78qw3q3f.js} +4 -4
  13. package/{context.command-xncdvv7n.js → context.command-x5f7t3gk.js} +3 -3
  14. package/{context.runner-pjy89k2s.js → context.runner-nfs8ksh3.js} +2 -2
  15. package/incrementalBuilder.proc.js +1 -1
  16. package/{index-pb10njz7.js → index-118vq9dh.js} +25 -8
  17. package/{index-qm4fppfk.js → index-2zcm7fjd.js} +3 -3
  18. package/{index-dt1x62ec.js → index-5kjsr2pg.js} +189 -32
  19. package/{index-4mgbzgb5.js → index-bp9b1g2r.js} +1 -1
  20. package/{index-50rq2qms.js → index-j9z8vg2n.js} +1 -1
  21. package/{index-8k93esfr.js → index-tg09x14f.js} +1 -1
  22. package/{index-tpdn30ya.js → index-vxqe24mp.js} +1 -1
  23. package/{index-7yxndzea.js → index-w5pet0nq.js} +1 -1
  24. package/{index-ys6f0bvh.js → index-y736f42m.js} +98 -13
  25. package/index.js +7 -7
  26. package/{localRegistry.command-4kj56531.js → localRegistry.command-zppa6w7q.js} +2 -2
  27. package/package.json +3 -3
  28. package/{subspace.command-ygfdqpbj.js → subspace.command-gx2cjpnv.js} +1 -1
  29. package/{workspace.command-p44d21qf.js → workspace.command-1r29qzzk.js} +5 -5
package/.build-stamp CHANGED
@@ -1 +1 @@
1
- ebb85e20e2ce0664a89d89b8a4118186e1277010b003f7c8a8222101af0c5263
1
+ 137343070b8b77c5504673de077f386f6ebb2d0432d15afa82b8ce9c822710a2
@@ -1,8 +1,8 @@
1
1
  // @bun
2
2
  import {
3
3
  CodeAgent2
4
- } from "./index-qm4fppfk.js";
5
- import"./index-tpdn30ya.js";
4
+ } from "./index-2zcm7fjd.js";
5
+ import"./index-vxqe24mp.js";
6
6
  import"./index-7md2g9vw.js";
7
7
  export {
8
8
  CodeAgent2 as CodeAgent
@@ -4,7 +4,7 @@ import {
4
4
  McpServerConfig,
5
5
  McpTokenStore,
6
6
  McpSignIn
7
- } from "./index-tpdn30ya.js";
7
+ } from "./index-vxqe24mp.js";
8
8
  import {
9
9
  CodeTuiLines2,
10
10
  CodeTuiAgents2,
package/README.ko.md ADDED
@@ -0,0 +1,72 @@
1
+ # @akanjs/cli
2
+
3
+ [문서](https://akanjs.com/docs) | [npm](https://www.npmjs.com/package/@akanjs/cli) | [런타임](https://www.npmjs.com/package/akanjs)
4
+
5
+ Akan.js 워크스페이스를 위한 command-line tooling입니다.
6
+
7
+ `@akanjs/cli`는 Akan 애플리케이션, 라이브러리, 프레임워크 패키지를 생성, 빌드, 테스트, 린트,
8
+ 릴리즈, 유지보수하는 데 사용하는 `akan` 실행 파일을 제공합니다. Bun-first CLI 패키지이며 Akan
9
+ 개발 tooling을 내부에 번들링하므로, 애플리케이션 런타임은 더 작은 `akanjs` 패키지에만 의존할 수
10
+ 있습니다.
11
+
12
+ ## 설치
13
+
14
+ 새 워크스페이스를 바로 만들 수 있습니다.
15
+
16
+ ```bash
17
+ bunx create-akan-workspace@latest
18
+ ```
19
+
20
+ 또는 CLI를 전역으로 설치할 수 있습니다.
21
+
22
+ ```bash
23
+ bun install -g @akanjs/cli@latest
24
+ akan --help
25
+ ```
26
+
27
+ ## 자주 쓰는 명령
28
+
29
+ ```bash
30
+ akan create-workspace <workspace-name>
31
+ akan start <app-name>
32
+ akan build <app-name>
33
+ akan test <app-or-lib-or-pkg>
34
+ akan lint <app-or-lib-or-pkg>
35
+ akan create-application <app-name>
36
+ akan create-library <lib-name>
37
+ akan create-module <module-name>
38
+ akan create-scalar <scalar-name>
39
+ ```
40
+
41
+ 패키지 유지보수 명령도 같은 실행 파일에서 제공합니다.
42
+
43
+ ```bash
44
+ akan build-package akanjs
45
+ akan build-package @akanjs/cli
46
+ akan build-package @akanjs/devkit
47
+ akan build-package create-akan-workspace
48
+ akan verify-akan-publish-packages
49
+ akan smoke-registry --test=true --tag=rc
50
+ ```
51
+
52
+ Akan framework 패키지는 반드시 `dist/pkgs/*` 산출물 기준으로 publish합니다. `verify-akan-publish-packages`는
53
+ 빌드된 패키지에 `npm pack --dry-run --json`을 실행하고, `deploy-akan` 또는 local registry smoke 전에 필요한
54
+ metadata를 검증합니다.
55
+ 저장소 릴리즈에서는 root `akan` bootstrap script가 CLI dist를 덮어쓰지 않도록
56
+ `bun run release:build-packages && bun run release:verify-packages`를 우선 사용합니다.
57
+
58
+ ## 패키지 경계
59
+
60
+ - 애플리케이션과 런타임 코드는 `akanjs`를 사용합니다.
61
+ - 사용자-facing 실행 패키지는 `@akanjs/cli`입니다.
62
+ - `@akanjs/devkit`은 published CLI 사용을 위해 CLI 안에 번들링됩니다. 일반 CLI 사용자가 별도의
63
+ runtime dependency로 설치할 필요는 없습니다.
64
+
65
+ ## 요구사항
66
+
67
+ - [Bun](https://bun.sh) `>=1.4.0`
68
+ - TypeScript 기반 Akan 워크스페이스
69
+
70
+ ## 라이선스
71
+
72
+ MIT
package/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # @akanjs/cli
2
+
3
+ [Docs](https://akanjs.com/docs) | [npm](https://www.npmjs.com/package/@akanjs/cli) | [Runtime](https://www.npmjs.com/package/akanjs)
4
+
5
+ Command-line tooling for Akan.js workspaces.
6
+
7
+ `@akanjs/cli` provides the `akan` executable used to create, build, test, lint, release, and maintain Akan
8
+ applications, libraries, and framework packages. It is a Bun-first CLI package and bundles Akan development
9
+ tooling internally so application runtimes can depend on the smaller `akanjs` package.
10
+
11
+ ## Install
12
+
13
+ Create a new workspace:
14
+
15
+ ```bash
16
+ bunx create-akan-workspace@latest
17
+ ```
18
+
19
+ Or install the CLI globally:
20
+
21
+ ```bash
22
+ bun install -g @akanjs/cli@latest
23
+ akan --help
24
+ ```
25
+
26
+ ## Common Commands
27
+
28
+ ```bash
29
+ akan create-workspace <workspace-name>
30
+ akan start <app-name>
31
+ akan build <app-name>
32
+ akan test <app-or-lib-or-pkg>
33
+ akan lint <app-or-lib-or-pkg>
34
+ akan create-application <app-name>
35
+ akan create-library <lib-name>
36
+ akan create-module <module-name>
37
+ akan create-scalar <scalar-name>
38
+ ```
39
+
40
+ ## Agent And MCP Commands
41
+
42
+ ```bash
43
+ akan context --format markdown
44
+ akan context --format json --module <module-name>
45
+ akan doctor --format json
46
+ akan guideline list
47
+ akan guideline show framework
48
+ akan agent install cursor
49
+ akan mcp
50
+ ```
51
+
52
+ These commands expose Akan workspace structure, module abstracts, diagnostics, and guideline instructions for
53
+ coding agents. The MCP server is read-only and is intended to provide context rather than edit files directly.
54
+
55
+ Package maintenance commands are also exposed through the same executable:
56
+
57
+ ```bash
58
+ akan build-package akanjs
59
+ akan build-package @akanjs/cli
60
+ akan build-package @akanjs/devkit
61
+ akan build-package create-akan-workspace
62
+ akan verify-akan-publish-packages
63
+ akan smoke-registry --test=true --tag=rc
64
+ ```
65
+
66
+ Publish Akan framework packages from `dist/pkgs/*` only. `verify-akan-publish-packages` runs `npm pack --dry-run --json`
67
+ against the built packages and checks metadata that must be correct before `deploy-akan` or local registry smoke.
68
+ For repository releases, prefer `bun run release:build-packages && bun run release:verify-packages` so the CLI package
69
+ artifact is built last and is not overwritten by the root `akan` bootstrap script.
70
+
71
+ ## Package Boundary
72
+
73
+ - Use `akanjs` from application and runtime code.
74
+ - Use `@akanjs/cli` as the user-facing executable package.
75
+ - `@akanjs/devkit` is bundled into the CLI for published CLI usage; it is not required as a separate
76
+ runtime dependency for ordinary CLI users.
77
+ - The `akan code` agent follows that same split: its engine, tools and skills are a devkit facet
78
+ (`@akanjs/devkit/codeAgent`), and `@akanjs/cli/code` is the terminal host plus the SDK entry that
79
+ re-exports both.
80
+
81
+ ## Requirements
82
+
83
+ - [Bun](https://bun.sh) `>=1.4.0`
84
+ - A TypeScript Akan workspace
85
+
86
+ ## License
87
+
88
+ MIT
package/akanCode.js CHANGED
@@ -28,7 +28,7 @@ import {
28
28
  CodeMailbox2,
29
29
  CodeSessionFork2,
30
30
  CodeAgent2
31
- } from "./index-qm4fppfk.js";
31
+ } from "./index-2zcm7fjd.js";
32
32
  import {
33
33
  akanCodeDefaultModel2,
34
34
  akanCodeModel2,
@@ -39,7 +39,7 @@ import {
39
39
  import {
40
40
  SubagentPool2,
41
41
  akanCodePaths2
42
- } from "./index-tpdn30ya.js";
42
+ } from "./index-vxqe24mp.js";
43
43
  import"./index-7md2g9vw.js";
44
44
  import {
45
45
  CodeAgentRpcHost2
@@ -11,12 +11,12 @@ import"./index-52w0fvh8.js";
11
11
  import"./index-0n9q1f23.js";
12
12
  import {
13
13
  getMobileTargetChoices
14
- } from "./index-ys6f0bvh.js";
14
+ } from "./index-y736f42m.js";
15
15
  import"./index-48k96p55.js";
16
16
  import"./index-5mm3g24t.js";
17
17
  import {
18
18
  ApplicationScript
19
- } from "./index-pb10njz7.js";
19
+ } from "./index-118vq9dh.js";
20
20
  import"./index-7md2g9vw.js";
21
21
  import"./index-860zjnr1.js";
22
22
 
@@ -2,14 +2,14 @@
2
2
  import {
3
3
  Spinner
4
4
  } from "./index-0n9q1f23.js";
5
- import"./index-dt1x62ec.js";
5
+ import"./index-5kjsr2pg.js";
6
6
  import {
7
7
  AllRoutesBuilder,
8
8
  CsrArtifactBuilder,
9
9
  FontPruner,
10
10
  precompressArtifacts,
11
11
  SsrBaseArtifactBuilder
12
- } from "./index-4mgbzgb5.js";
12
+ } from "./index-bp9b1g2r.js";
13
13
  import"./index-52w0fvh8.js";
14
14
  import"./index-n68jx79w.js";
15
15
 
@@ -14,14 +14,14 @@ import {
14
14
  PagesBundleBuilder,
15
15
  CsrDevBundler,
16
16
  SsrDevBundler
17
- } from "./index-dt1x62ec.js";
17
+ } from "./index-5kjsr2pg.js";
18
18
  import"./index-52w0fvh8.js";
19
19
  import {
20
20
  CsrArtifactBuilder,
21
21
  CssCompiler,
22
22
  FontOptimizer,
23
23
  SsrBaseArtifactBuilder
24
- } from "./index-4mgbzgb5.js";
24
+ } from "./index-bp9b1g2r.js";
25
25
  import"./index-n68jx79w.js";
26
26
 
27
27
  // pkgs/@akanjs/devkit/incrementalBuilder/buildBatch.proc.ts
@@ -13,14 +13,14 @@ import {
13
13
  } from "./index-56xwsgyn.js";
14
14
  import"./index-48k96p55.js";
15
15
  import"./index-5mm3g24t.js";
16
- import"./index-pb10njz7.js";
17
- import"./index-ys6f0bvh.js";
16
+ import"./index-118vq9dh.js";
17
+ import"./index-y736f42m.js";
18
18
  import"./index-7md2g9vw.js";
19
19
  import"./index-2ahj896a.js";
20
20
  import"./index-per2kqy9.js";
21
21
  import {
22
22
  CloudScript2
23
- } from "./index-8k93esfr.js";
23
+ } from "./index-tg09x14f.js";
24
24
  import"./index-860zjnr1.js";
25
25
 
26
26
  // pkgs/@akanjs/cli/cloud/cloud.command.ts
@@ -1,13 +1,13 @@
1
1
  // @bun
2
2
  import {
3
3
  CloudScript2
4
- } from "./index-8k93esfr.js";
4
+ } from "./index-tg09x14f.js";
5
5
  import"./index-56xwsgyn.js";
6
6
  import"./index-per2kqy9.js";
7
- import"./index-pb10njz7.js";
7
+ import"./index-118vq9dh.js";
8
8
  import"./index-860zjnr1.js";
9
9
  import"./index-5mm3g24t.js";
10
- import"./index-ys6f0bvh.js";
10
+ import"./index-y736f42m.js";
11
11
  import"./index-94s080qm.js";
12
12
  import"./index-58cyna2s.js";
13
13
  import"./index-7md2g9vw.js";
@@ -19,7 +19,7 @@ class CodeRunner extends runner("code") {
19
19
  async serve(options, listen) {
20
20
  await import("./consoleToStderr-h5bryj94.js");
21
21
  const [{ CodeAgent }, { CodeAgentRpcHost }, { CodeAgentRpcListener }] = await Promise.all([
22
- import("./CodeAgent-p65jja35.js"),
22
+ import("./CodeAgent-h19atbr3.js"),
23
23
  import("./CodeAgentRpcHost-p7h6n2hp.js"),
24
24
  import("./CodeAgentRpcListener-7p7z5dd7.js")
25
25
  ]);
@@ -34,8 +34,8 @@ class CodeRunner extends runner("code") {
34
34
  }
35
35
  async tui(options, seed) {
36
36
  const [{ CodeAgent }, { CodeTui }] = await Promise.all([
37
- import("./CodeAgent-p65jja35.js"),
38
- import("./CodeTui-5xr8kxx4.js")
37
+ import("./CodeAgent-h19atbr3.js"),
38
+ import("./CodeTui-46zygq8p.js")
39
39
  ]);
40
40
  const agentOptions = await CodeRunner.#agentOptions(options, false);
41
41
  let resume = options.resume;
@@ -60,7 +60,7 @@ class CodeRunner extends runner("code") {
60
60
  }
61
61
  }
62
62
  async run(prompt, options) {
63
- const { CodeAgent } = await import("./CodeAgent-p65jja35.js");
63
+ const { CodeAgent } = await import("./CodeAgent-h19atbr3.js");
64
64
  const agent = await CodeAgent.create(await CodeRunner.#agentOptions(options, false));
65
65
  const printer = new CodeAgentStreamPrinter2({ json: options.json, thinking: options.thinking });
66
66
  agent.on((event) => printer.print(event));
@@ -8,8 +8,8 @@ import"./index-0n9q1f23.js";
8
8
  import"./index-hj6w4ka1.js";
9
9
  import"./index-d65fzxvd.js";
10
10
  import"./index-hzy4pe24.js";
11
- import"./index-7yxndzea.js";
12
- import"./index-ys6f0bvh.js";
11
+ import"./index-w5pet0nq.js";
12
+ import"./index-y736f42m.js";
13
13
  import"./index-zzvvc845.js";
14
14
  import"./index-t02g6dpn.js";
15
15
  import"./index-v4hnkqz9.js";
@@ -19,7 +19,7 @@ import"./index-xfgdmm5d.js";
19
19
  import"./index-da72pfdv.js";
20
20
  import {
21
21
  ContextScript
22
- } from "./index-50rq2qms.js";
22
+ } from "./index-j9z8vg2n.js";
23
23
 
24
24
  // pkgs/@akanjs/cli/context/context.command.ts
25
25
  class ContextCommand extends command("context", [ContextScript], ({ public: target }) => ({
@@ -1,14 +1,14 @@
1
1
  // @bun
2
2
  import {
3
3
  ContextRunner2
4
- } from "./index-7yxndzea.js";
4
+ } from "./index-w5pet0nq.js";
5
5
  import"./index-da72pfdv.js";
6
6
  import"./index-xfgdmm5d.js";
7
7
  import"./index-6dt6zft6.js";
8
8
  import"./index-t02g6dpn.js";
9
9
  import"./index-zazvn45w.js";
10
10
  import"./index-v4hnkqz9.js";
11
- import"./index-ys6f0bvh.js";
11
+ import"./index-y736f42m.js";
12
12
  import"./index-hzy4pe24.js";
13
13
  import"./index-d65fzxvd.js";
14
14
  import"./index-zzvvc845.js";
@@ -20,7 +20,7 @@ import {
20
20
  DevChangePlanner,
21
21
  DevGeneratedIndexSync,
22
22
  SsrDevBundler
23
- } from "./index-dt1x62ec.js";
23
+ } from "./index-5kjsr2pg.js";
24
24
  import {
25
25
  prepareDevWatchBatch
26
26
  } from "./index-a5vmm6x4.js";
@@ -50,7 +50,7 @@ import {
50
50
  import {
51
51
  resolveMobileTargets,
52
52
  NativeApp
53
- } from "./index-ys6f0bvh.js";
53
+ } from "./index-y736f42m.js";
54
54
  import {
55
55
  stripAnsi
56
56
  } from "./index-7md2g9vw.js";
@@ -244,17 +244,29 @@ class IncrementalBuilderHost {
244
244
  #manualStop = false;
245
245
  #inFlight = new Map;
246
246
  #startOptions = {};
247
- constructor({ app, entry, env, stdio = "inherit", onMessage, onOutput }) {
247
+ constructor({
248
+ app,
249
+ entry,
250
+ env,
251
+ stdio = "inherit",
252
+ onMessage,
253
+ onOutput,
254
+ patcherOff = false
255
+ }) {
248
256
  this.app = app;
249
257
  this.entry = entry;
250
258
  this.env = env;
251
259
  this.#stdio = stdio;
252
260
  this.#onMessage = onMessage;
253
261
  this.#onOutput = onOutput ?? null;
262
+ this.#patcherOff = patcherOff;
254
263
  }
255
264
  get status() {
256
265
  return this.#status;
257
266
  }
267
+ get patcherOff() {
268
+ return this.#patcherOff;
269
+ }
258
270
  get pid() {
259
271
  return this.#proc?.pid ?? null;
260
272
  }
@@ -452,7 +464,8 @@ class IncrementalBuilderHost {
452
464
  }
453
465
  static async create(app, env, onMessage, {
454
466
  stdio = "inherit",
455
- onOutput
467
+ onOutput,
468
+ patcherOff = false
456
469
  } = {}) {
457
470
  const candidates = [
458
471
  path.join(app.workspace.workspaceRoot, "pkgs/@akanjs/devkit/incrementalBuilder/incrementalBuilder.proc.ts"),
@@ -462,7 +475,7 @@ class IncrementalBuilderHost {
462
475
  ];
463
476
  for (const c of candidates)
464
477
  if (await Bun.file(c).exists())
465
- return new IncrementalBuilderHost({ app, entry: c, env, stdio, onMessage, onOutput });
478
+ return new IncrementalBuilderHost({ app, entry: c, env, stdio, onMessage, onOutput, patcherOff });
466
479
  throw new Error(`[cli] frontend builder entry not found; looked in: ${candidates.join(", ")}`);
467
480
  }
468
481
  }
@@ -703,6 +716,7 @@ class AkanAppHost {
703
716
  #bootLatch = new DevBootLatch(() => this.#onDevEvent?.({ app: this.app.name, booted: true }));
704
717
  #backend = null;
705
718
  #builder = null;
719
+ #patcherOff = false;
706
720
  #backendReady = false;
707
721
  #plannedBackendStops = new WeakSet;
708
722
  #restartTimer = null;
@@ -1600,6 +1614,7 @@ ${this.#backendStderrTail.join(`
1600
1614
  this.#pendingBuildStatusReplay = [];
1601
1615
  await this.#stopBackend();
1602
1616
  this.#stopBuilder();
1617
+ this.#patcherOff = false;
1603
1618
  if (refreshConfig) {
1604
1619
  await this.app.getConfig({ refresh: true });
1605
1620
  const { env } = await this.app.prepareCommand("start");
@@ -1715,7 +1730,8 @@ ${this.#backendStderrTail.join(`
1715
1730
  this.#enqueueBuilderMessage(msg);
1716
1731
  }, {
1717
1732
  stdio: this.stdio,
1718
- onOutput: (kind, text) => void (kind === "stderr" ? process.stderr : process.stdout).write(text)
1733
+ onOutput: (kind, text) => void (kind === "stderr" ? process.stderr : process.stdout).write(text),
1734
+ patcherOff: this.#patcherOff
1719
1735
  });
1720
1736
  try {
1721
1737
  await this.#waitForBuilderReady(attempt, { announceBootState });
@@ -1801,6 +1817,8 @@ ${this.#backendStderrTail.join(`
1801
1817
  this.#cancelRssRecycle();
1802
1818
  if (!this.#builder)
1803
1819
  return;
1820
+ if (this.#builder.patcherOff)
1821
+ this.#patcherOff = true;
1804
1822
  this.#builder.stop();
1805
1823
  this.#builder = null;
1806
1824
  }
@@ -1828,7 +1846,7 @@ ${uniqueCandidates.map((candidate) => ` - ${candidate}`).join(`
1828
1846
 
1829
1847
  // pkgs/@akanjs/cli/application/application.runner.ts
1830
1848
  import { Logger as Logger3 } from "akanjs/common";
1831
- var loadBuildRunner = async () => (await import("./applicationBuildRunner-tm0vba5t.js")).ApplicationBuildRunner;
1849
+ var loadBuildRunner = async () => (await import("./applicationBuildRunner-r6b9rkb8.js")).ApplicationBuildRunner;
1832
1850
  var loadPrompts = async () => await import("@inquirer/prompts");
1833
1851
 
1834
1852
  class ApplicationRunner extends runner("application") {
@@ -2045,7 +2063,6 @@ try {
2045
2063
  throw new Error(`No dev server answers on ${upstream}; run \`akan start ${app.name}\` first.`);
2046
2064
  const { i18n } = await app.getConfig();
2047
2065
  const session = await nativeApp.dev(platform, { upstream, lang: i18n.defaultLocale, ...selection });
2048
- app.log(`${app.name}/${mobileTarget.name} on ${platform} follows ${upstream} through ${session.gateway}.`);
2049
2066
  process.once("SIGINT", () => {
2050
2067
  session.stop().finally(() => process.exit(130));
2051
2068
  });
@@ -2056,7 +2073,7 @@ try {
2056
2073
  }
2057
2074
  static async#answers(url) {
2058
2075
  try {
2059
- await fetch(url, { signal: AbortSignal.timeout(3000) });
2076
+ await fetch(new URL("/_akan/app/health", url), { signal: AbortSignal.timeout(3000) });
2060
2077
  return true;
2061
2078
  } catch {
2062
2079
  return false;
@@ -4,7 +4,7 @@ import {
4
4
  akanCodePaths2,
5
5
  McpServerConfig,
6
6
  McpSignIn
7
- } from "./index-tpdn30ya.js";
7
+ } from "./index-vxqe24mp.js";
8
8
  import {
9
9
  stripAnsi
10
10
  } from "./index-7md2g9vw.js";
@@ -511,7 +511,7 @@ class AkanToolPack2 {
511
511
  return { name: "akan-tools", factory: async (pi) => await this.#register(pi) };
512
512
  }
513
513
  async names() {
514
- const { ContextRunner } = await import("./context.runner-pjy89k2s.js");
514
+ const { ContextRunner } = await import("./context.runner-nfs8ksh3.js");
515
515
  return [
516
516
  ...new ContextRunner().listMcpTools(this.#options.mode).map((tool) => tool.name),
517
517
  AkanToolPack2.verifyToolName
@@ -519,7 +519,7 @@ class AkanToolPack2 {
519
519
  }
520
520
  static verifyToolName = "akan_verify";
521
521
  async#register(pi) {
522
- const { ContextRunner } = await import("./context.runner-pjy89k2s.js");
522
+ const { ContextRunner } = await import("./context.runner-nfs8ksh3.js");
523
523
  const runner = new ContextRunner;
524
524
  const guidelineNames = await AkanToolPack2.#guidelineNames();
525
525
  for (const tool of runner.listMcpTools(this.#options.mode, { guidelineNames })) {
@@ -1110,6 +1110,7 @@ import path7 from "path";
1110
1110
  class CsrDevPaths {
1111
1111
  static modulePrefix = "akan-module:";
1112
1112
  static stubPrefix = "stub:";
1113
+ static emptyStubPrefix = "stub:empty:";
1113
1114
  static vendorPrefix = "vendor:";
1114
1115
  root;
1115
1116
  constructor(workspaceRoot) {
@@ -2457,6 +2458,7 @@ class CsrDevResolver {
2457
2458
  #fallbacks = new Set;
2458
2459
  #runtimeResolved = new Map;
2459
2460
  #browserMaps = new Map;
2461
+ #loaded = new Set;
2460
2462
  #startedAt;
2461
2463
  #prepassDone = false;
2462
2464
  constructor({
@@ -2496,9 +2498,45 @@ class CsrDevResolver {
2496
2498
  optimizeImports: this.#context.optimizeImports,
2497
2499
  plugins: [PagesBundleBuilder.createCssStubPlugin()]
2498
2500
  });
2499
- const { inputs } = result.metafile;
2501
+ this.#record(result.metafile.inputs);
2502
+ this.#prepassDone = true;
2503
+ }
2504
+ async cover(files) {
2505
+ if (!this.#prepassDone)
2506
+ return;
2507
+ const pending = files.filter((file) => CsrDevPaths.isScript(file) && !this.#loaded.has(file));
2508
+ if (pending.length === 0)
2509
+ return;
2510
+ for (const file of pending)
2511
+ this.#loaded.add(file);
2512
+ const entries = new Set(pending);
2513
+ const result = await Bun.build({
2514
+ entrypoints: pending,
2515
+ target: "browser",
2516
+ metafile: true,
2517
+ throw: false,
2518
+ external: [...this.#context.externals ?? []],
2519
+ env: "AKAN_PUBLIC_*",
2520
+ define: this.#context.define,
2521
+ plugins: [
2522
+ {
2523
+ name: "akan-csr-cover",
2524
+ setup: (build) => {
2525
+ build.onLoad({ filter: /.*/ }, (args) => entries.has(CsrDevPaths.realpath(args.path)) ? undefined : { contents: "module.exports = {};", loader: "js" });
2526
+ }
2527
+ }
2528
+ ]
2529
+ });
2530
+ if (result.metafile)
2531
+ this.#record(result.metafile.inputs, entries);
2532
+ }
2533
+ #record(inputs, only) {
2500
2534
  for (const [input, { imports }] of Object.entries(inputs)) {
2501
2535
  const importer = CsrDevPaths.realpath(path14.resolve(input));
2536
+ if (only && !only.has(importer))
2537
+ continue;
2538
+ if (imports.every((record) => record.original))
2539
+ this.#loaded.add(importer);
2502
2540
  for (const record of imports) {
2503
2541
  if (!record.original)
2504
2542
  continue;
@@ -2514,11 +2552,13 @@ class CsrDevResolver {
2514
2552
  this.#runtimeResolved.get(importer)?.delete(record.original);
2515
2553
  }
2516
2554
  }
2517
- this.#prepassDone = true;
2518
2555
  }
2519
2556
  resolve(importer, specifier, kind = "import") {
2520
2557
  if (this.#isInlineSpecifier(specifier))
2521
2558
  return CsrDevResolver.inline;
2559
+ const disabled = this.#disabledInBrowser(importer, specifier, kind);
2560
+ if (disabled)
2561
+ return disabled;
2522
2562
  const known = this.#resolution.get(importer)?.get(specifier);
2523
2563
  const usable = known && this.#stillAnswers(importer, specifier, known, kind) ? known : null;
2524
2564
  const target = usable ?? this.#resolveUnknown(importer, specifier, kind);
@@ -2553,24 +2593,41 @@ class CsrDevResolver {
2553
2593
  return base === packageName || base.startsWith(`${packageName}/`);
2554
2594
  });
2555
2595
  }
2596
+ #disabledInBrowser(importer, specifier, kind) {
2597
+ const map = this.#browserMapOf(path14.dirname(importer));
2598
+ if (!map || map.offFiles.size === 0 && map.offNames.size === 0)
2599
+ return null;
2600
+ if (!specifier.startsWith(".") && !path14.isAbsolute(specifier))
2601
+ return map.offNames.has(specifier) ? `${CsrDevPaths.emptyStubPrefix}${specifier}` : null;
2602
+ const target = CsrDevPaths.resolveRelative(path14.dirname(importer), specifier, kind);
2603
+ return target && map.offFiles.has(CsrDevPaths.realpath(target)) ? `${CsrDevPaths.emptyStubPrefix}${this.#paths.idOf(target)}` : null;
2604
+ }
2556
2605
  #hasBrowserMap(dir) {
2606
+ return this.#browserMapOf(dir) !== null;
2607
+ }
2608
+ #browserMapOf(dir) {
2557
2609
  const cached = this.#browserMaps.get(dir);
2558
2610
  if (cached !== undefined)
2559
2611
  return cached;
2560
2612
  const pkgFile = path14.join(dir, "package.json");
2561
2613
  const parent = path14.dirname(dir);
2562
- let mapped;
2614
+ let map = null;
2563
2615
  if (fs6.existsSync(pkgFile)) {
2564
2616
  try {
2565
2617
  const browser = JSON.parse(fs6.readFileSync(pkgFile, "utf8")).browser;
2566
- mapped = typeof browser === "object" && browser !== null;
2567
- } catch {
2568
- mapped = false;
2569
- }
2570
- } else
2571
- mapped = parent !== dir && this.#hasBrowserMap(parent);
2572
- this.#browserMaps.set(dir, mapped);
2573
- return mapped;
2618
+ if (typeof browser === "object" && browser !== null) {
2619
+ const off = Object.entries(browser).filter(([, target]) => target === false).map(([key]) => key);
2620
+ const files = off.filter((key) => key.startsWith(".")).map((key) => CsrDevPaths.resolveRelative(dir, key)).filter((file) => !!file);
2621
+ map = {
2622
+ offFiles: new Set(files.map((file) => CsrDevPaths.realpath(file))),
2623
+ offNames: new Set(off.filter((key) => !key.startsWith(".")))
2624
+ };
2625
+ }
2626
+ } catch {}
2627
+ } else if (parent !== dir)
2628
+ map = this.#browserMapOf(parent);
2629
+ this.#browserMaps.set(dir, map);
2630
+ return map;
2574
2631
  }
2575
2632
  forget(importer) {
2576
2633
  this.#resolution.delete(importer);
@@ -3161,6 +3218,11 @@ class CsrDevArtifactWriter {
3161
3218
  const stubs = new Set(Object.values(graph.modules).flatMap((module) => module.deps.filter(CsrDevPaths.isStub)));
3162
3219
  const lines = [await this.#helperDefinitions(graph, ids), ...await this.#defineLines(ids)];
3163
3220
  for (const stub of [...stubs].sort()) {
3221
+ if (stub.startsWith(CsrDevPaths.emptyStubPrefix)) {
3222
+ lines.push(`__akan.define(${JSON.stringify(stub)}, function () {});
3223
+ `);
3224
+ continue;
3225
+ }
3164
3226
  const message = `[akan-csr] ${stub.slice(CsrDevPaths.stubPrefix.length)} is a Node built-in the browser does not have`;
3165
3227
  lines.push(`__akan.define(${JSON.stringify(stub)}, function () {
3166
3228
  throw new Error(${JSON.stringify(message)});
@@ -3293,6 +3355,45 @@ class CsrDevArtifactWriter {
3293
3355
 
3294
3356
  // pkgs/@akanjs/devkit/frontendBuild/csrDevModuleCompiler.ts
3295
3357
  import path18 from "path";
3358
+
3359
+ // pkgs/@akanjs/devkit/frontendBuild/csrDevFactoryCheck.ts
3360
+ class CsrDevFactoryCheck {
3361
+ static #parsed = new Set;
3362
+ static problemOf(factory, helperDefinition = "") {
3363
+ const key = Bun.hash(`${helperDefinition}\x00${factory}`);
3364
+ if (CsrDevFactoryCheck.#parsed.has(key))
3365
+ return null;
3366
+ const problem = CsrDevFactoryCheck.#syntaxError(`${helperDefinition}return (${factory});`);
3367
+ if (problem === null) {
3368
+ CsrDevFactoryCheck.#parsed.add(key);
3369
+ return null;
3370
+ }
3371
+ if (problem.includes("import.meta")) {
3372
+ const line = factory.split(`
3373
+ `).findIndex((text) => /(?<![\w$.])import\.meta\b/.test(text));
3374
+ return `import.meta is left in it${line > 0 ? ` (compiled line ${line})` : ""}, which a classic script cannot hold: ${problem}`;
3375
+ }
3376
+ if (CsrDevFactoryCheck.#syntaxError(`${helperDefinition}return (async ${factory});`) === null)
3377
+ return `a top-level await is left in it, which a CommonJS factory cannot wait on: ${problem}`;
3378
+ return problem;
3379
+ }
3380
+ static thrower(id, problem) {
3381
+ const message = `[akan-csr] ${id} was left out of the dev registry: ${problem}`;
3382
+ return `function () {
3383
+ throw new Error(${JSON.stringify(message)});
3384
+ }`;
3385
+ }
3386
+ static #syntaxError(source) {
3387
+ try {
3388
+ new Function(source);
3389
+ return null;
3390
+ } catch (error) {
3391
+ return error instanceof Error ? error.message : String(error);
3392
+ }
3393
+ }
3394
+ }
3395
+
3396
+ // pkgs/@akanjs/devkit/frontendBuild/csrDevModuleCompiler.ts
3296
3397
  class CsrDevModuleCompiler {
3297
3398
  static #storeRoot = /(?:^|\/)lib\/st\.ts$/;
3298
3399
  static #factoryArgument = /(?<![\w$.])(?:require|module|exports|__akanImport|\$RefreshReg\$|\$RefreshSig\$)(?![\w$]|\s*:)/;
@@ -3326,6 +3427,7 @@ class CsrDevModuleCompiler {
3326
3427
  const refusedVendors = refuseNewVendor ? frontier.filter((file) => CsrDevPaths.isVendorFile(file)) : [];
3327
3428
  if (refusedVendors.length > 0)
3328
3429
  return { modules: [...compiled.values()], refusedVendors, unresolved: [] };
3430
+ await this.#resolver.cover(frontier);
3329
3431
  const round = await this.#compileRound(frontier);
3330
3432
  if (round.misses.length > 0 && !this.#resolver.prepassDone && refusePrepass)
3331
3433
  return { modules: [...compiled.values()], refusedVendors: [], unresolved: round.misses };
@@ -3373,21 +3475,28 @@ class CsrDevModuleCompiler {
3373
3475
  const mtimes = new Map(files.map((file) => [CsrDevPaths.realpath(file), CsrDevPaths.mtimeOf(file)]));
3374
3476
  const hashes = new Map(await Promise.all(files.map(async (file) => [CsrDevPaths.realpath(file), vendor ? "" : await CsrDevPaths.hashOf(file)])));
3375
3477
  const misses = [];
3376
- const result = await Bun.build({
3377
- entrypoints: files,
3378
- root: this.#paths.root,
3379
- target: "browser",
3380
- format: "cjs",
3381
- reactFastRefresh: !vendor,
3382
- sourcemap: vendor ? "none" : "external",
3383
- naming: { entry: "[dir]/[name].[ext]", asset: "assets/[name]-[hash].[ext]" },
3384
- publicPath: this.#routePrefix,
3385
- metafile: true,
3386
- env: "AKAN_PUBLIC_*",
3387
- define: this.#context.define,
3388
- optimizeImports: this.#context.optimizeImports,
3389
- plugins: [this.#registryPlugin(vendor, misses)]
3390
- });
3478
+ let result;
3479
+ try {
3480
+ result = await Bun.build({
3481
+ entrypoints: files,
3482
+ root: this.#paths.root,
3483
+ target: "browser",
3484
+ format: "cjs",
3485
+ reactFastRefresh: !vendor,
3486
+ sourcemap: vendor ? "none" : "external",
3487
+ naming: { entry: "[dir]/[name].[ext]", asset: "assets/[name]-[hash].[ext]" },
3488
+ publicPath: this.#routePrefix,
3489
+ metafile: true,
3490
+ env: "AKAN_PUBLIC_*",
3491
+ define: { ...this.#context.define, "import.meta": "__akanMeta" },
3492
+ optimizeImports: this.#context.optimizeImports,
3493
+ plugins: [this.#registryPlugin(vendor, misses)]
3494
+ });
3495
+ } catch (error) {
3496
+ if (vendor && error instanceof AggregateError)
3497
+ return await this.#withoutFailed(files, error);
3498
+ throw error;
3499
+ }
3391
3500
  const { outputs } = result.metafile;
3392
3501
  const sourceMaps = new Map(result.outputs.filter((artifact) => artifact.kind === "sourcemap").map((artifact) => [artifact.path, artifact]));
3393
3502
  const modules = [];
@@ -3412,12 +3521,20 @@ class CsrDevModuleCompiler {
3412
3521
  }
3413
3522
  const code = await artifact.text();
3414
3523
  const id = this.#paths.idOf(file);
3524
+ const built = CsrDevModuleCompiler.#factory(id, code);
3525
+ const problem = CsrDevFactoryCheck.problemOf(built.factory, built.helpers?.definition);
3526
+ if (problem && !vendor)
3527
+ throw new Error(`[csr-dev] ${id}: its factory does not parse as a classic script: ${problem}`);
3528
+ if (problem) {
3529
+ modules.push(this.#leftOut(file, problem));
3530
+ continue;
3531
+ }
3415
3532
  const sourceMap = sourceMaps.get(`${artifact.path}.map`);
3416
3533
  modules.push({
3417
3534
  id,
3418
3535
  file,
3419
3536
  vendor,
3420
- ...CsrDevModuleCompiler.#factory(id, code),
3537
+ ...built,
3421
3538
  sourceMap: sourceMap ? this.#rebaseSourceMap(await sourceMap.text()) : undefined,
3422
3539
  deps: this.#emittedDeps(code),
3423
3540
  mtimeMs: mtimes.get(file) ?? CsrDevPaths.mtimeOf(file),
@@ -3426,6 +3543,43 @@ class CsrDevModuleCompiler {
3426
3543
  }
3427
3544
  return { modules, misses, tangled };
3428
3545
  }
3546
+ async#withoutFailed(files, error) {
3547
+ const reasons = new Map;
3548
+ for (const message of error.errors) {
3549
+ const file = message.position?.file;
3550
+ if (typeof file !== "string" || !path18.isAbsolute(file))
3551
+ continue;
3552
+ const real = CsrDevPaths.realpath(file);
3553
+ const at = message.position?.line ? `:${message.position.line}` : "";
3554
+ reasons.set(real, [...reasons.get(real) ?? [], `${String(message.message)} (${this.#paths.idOf(real)}${at})`]);
3555
+ }
3556
+ const failed = new Set(files.filter((file) => reasons.has(CsrDevPaths.realpath(file))));
3557
+ if (failed.size === 0)
3558
+ throw error;
3559
+ const rest = files.filter((file) => !failed.has(file));
3560
+ const round = rest.length > 0 ? await this.#bunBuild(rest, true) : { modules: [], misses: [], tangled: [] };
3561
+ for (const file of failed) {
3562
+ const text = (reasons.get(CsrDevPaths.realpath(file)) ?? []).join("; ");
3563
+ const awaits = text.includes('"await" can only be used');
3564
+ round.modules.push(this.#leftOut(file, awaits ? `a top-level await, which a CommonJS factory cannot wait on: ${text}` : text));
3565
+ }
3566
+ return round;
3567
+ }
3568
+ #leftOut(file, problem) {
3569
+ const real = CsrDevPaths.realpath(file);
3570
+ const id = this.#paths.idOf(real);
3571
+ this.#app.logger.error(`[csr-dev] ${id} is left out of the dev registry: ${problem}`);
3572
+ return {
3573
+ id,
3574
+ file: real,
3575
+ vendor: true,
3576
+ factory: CsrDevFactoryCheck.thrower(id, problem),
3577
+ helpers: null,
3578
+ deps: [],
3579
+ mtimeMs: CsrDevPaths.mtimeOf(real),
3580
+ hash: ""
3581
+ };
3582
+ }
3429
3583
  #registryPlugin(vendor, misses) {
3430
3584
  return {
3431
3585
  name: "akan-csr-registry",
@@ -3476,20 +3630,23 @@ class CsrDevModuleCompiler {
3476
3630
  }
3477
3631
  static #factory(id, code) {
3478
3632
  const prefix = CsrDevPaths.modulePrefix;
3479
- let patched = code.replaceAll(`import("${prefix}`, `__akanImport("${prefix}`).replace(/^\/\/# debugId=.*$/m, "");
3633
+ let patched = code.replace(/^#!/, "//").replaceAll(`import("${prefix}`, `__akanImport("${prefix}`).replace(/^\/\/# debugId=.*$/m, "");
3634
+ const marker = patched.search(/^\/\/ /m);
3635
+ const body = marker < 0 ? "" : patched.slice(marker);
3480
3636
  for (const [name, params, method] of CsrDevModuleCompiler.#helperPatches) {
3481
3637
  const definition = `var ${name} = ${params} => {`;
3482
3638
  if (patched.includes(definition))
3483
3639
  patched = patched.replace(definition, `var ${name} = __akan.${method}, __bun${name} = ${params} => {`);
3484
- else if (patched.includes(`${name}(`))
3640
+ else if (patched.includes(`${name}(`) && !new RegExp(`\\b(?:var|let|const|function)\\s+${name}\\b`).test(body))
3485
3641
  throw new Error(`[csr-dev] ${id}: Bun's ${name} helper no longer reads "${definition}"; CsrDevModuleCompiler must follow`);
3486
3642
  }
3487
3643
  if (CsrDevModuleCompiler.#storeRoot.test(id))
3488
3644
  patched += `
3489
3645
  module.hot.accept();`;
3490
3646
  const shared = CsrDevModuleCompiler.#shareHelpers(patched);
3647
+ const meta = /(?<![\w$.])__akanMeta(?![\w$])/.test(patched) ? ` var __akanMeta = { url: new URL(${JSON.stringify(id.startsWith("/") ? id : `/${id}`)}, self.location.href).href };` : "";
3491
3648
  return {
3492
- factory: `function (require, module, exports, $RefreshReg$, $RefreshSig$, __akanImport) {
3649
+ factory: `function (require, module, exports, $RefreshReg$, $RefreshSig$, __akanImport) {${meta}
3493
3650
  ${shared?.code ?? patched}
3494
3651
  }`,
3495
3652
  helpers: shared?.helpers ?? null
@@ -3664,7 +3821,7 @@ class DevRegistryBundler {
3664
3821
 
3665
3822
  // pkgs/@akanjs/devkit/frontendBuild/csrDevBundler.ts
3666
3823
  class CsrDevBundler extends DevRegistryBundler {
3667
- static #formatVersion = 3;
3824
+ static #formatVersion = 4;
3668
3825
  reloadsOnEntryChange = true;
3669
3826
  #asyncDefaults = new Map;
3670
3827
  constructor(app) {
@@ -4048,7 +4205,7 @@ import { mkdir as mkdir5 } from "fs/promises";
4048
4205
  import path24 from "path";
4049
4206
  import { SSR_DEV_DIRNAME, SSR_DEV_ROUTE_PREFIX } from "akanjs/server/hmr/csrDevManifest";
4050
4207
  class SsrDevBundler extends DevRegistryBundler {
4051
- static #formatVersion = 1;
4208
+ static #formatVersion = 2;
4052
4209
  static bootstrapKey = "";
4053
4210
  reloadsOnEntryChange = false;
4054
4211
  #discovery = null;
@@ -16,7 +16,7 @@ import {
16
16
  CsrEntryFiles,
17
17
  PagesEntrySourceGenerator,
18
18
  PagesBundleBuilder
19
- } from "./index-dt1x62ec.js";
19
+ } from "./index-5kjsr2pg.js";
20
20
  import {
21
21
  SOURCE_EXTS
22
22
  } from "./index-48k96p55.js";
@@ -10,7 +10,7 @@ import {
10
10
  } from "./index-58cyna2s.js";
11
11
  import {
12
12
  ContextRunner2
13
- } from "./index-7yxndzea.js";
13
+ } from "./index-w5pet0nq.js";
14
14
 
15
15
  // pkgs/@akanjs/cli/context/context.script.ts
16
16
  import { Logger } from "akanjs/common";
@@ -11,7 +11,7 @@ import {
11
11
  } from "./index-0n9q1f23.js";
12
12
  import {
13
13
  ApplicationScript
14
- } from "./index-pb10njz7.js";
14
+ } from "./index-118vq9dh.js";
15
15
  import {
16
16
  PackageScript
17
17
  } from "./index-per2kqy9.js";
@@ -116,7 +116,7 @@ class SubagentPool2 {
116
116
  }
117
117
  }
118
118
  async#run(id, kind, prompt, signal) {
119
- const { CodeAgent } = await import("./CodeAgent-p65jja35.js");
119
+ const { CodeAgent } = await import("./CodeAgent-h19atbr3.js");
120
120
  const budget = this.#options.parent.tools.subagent;
121
121
  const child = SubagentPool2.childOf(this.#options.parent, kind);
122
122
  const agent = await CodeAgent.create({
@@ -25,7 +25,7 @@ import {
25
25
  getMobileTargets,
26
26
  NativeApp,
27
27
  isPlaceholderAppId
28
- } from "./index-ys6f0bvh.js";
28
+ } from "./index-y736f42m.js";
29
29
  import {
30
30
  Prompter2
31
31
  } from "./index-zzvvc845.js";
@@ -1,4 +1,8 @@
1
1
  // @bun
2
+ import {
3
+ Executor
4
+ } from "./index-0n9q1f23.js";
5
+
2
6
  // pkgs/@akanjs/devkit/mobile/mobileTarget.ts
3
7
  var trimSlashes = (value) => value.replace(/^\/+|\/+$/g, "");
4
8
  var getMobileTargets = async (app) => {
@@ -101,6 +105,55 @@ class NativeApi {
101
105
  }
102
106
  }
103
107
 
108
+ // pkgs/@akanjs/devkit/mobile/nativeAppLine.ts
109
+ class NativeAppLine {
110
+ static #page = /^\[page(\+)?(?:#(\d+))? (trace|verbose|debug|log|info|warn|error)\] ?(.*)$/;
111
+ static #logcat = /^([VDIWEFA])\/([^(]+?)\s*\(\s*\d+\):\s?(.*)$/;
112
+ static #named = /^\[([^\]\s]+)\] ([\s\S]*)$/;
113
+ static #logcatLevels = {
114
+ V: "verbose",
115
+ D: "debug",
116
+ I: "info",
117
+ W: "warn",
118
+ E: "error",
119
+ F: "error",
120
+ A: "error"
121
+ };
122
+ static read(line, { verbose = false } = {}) {
123
+ const logcat = NativeAppLine.#logcat.exec(line);
124
+ if (logcat) {
125
+ const [, priority = "I", tag = "", text = ""] = logcat;
126
+ const level = NativeAppLine.#logcatLevels[priority] ?? "info";
127
+ if (tag === "AkanNativeConsole")
128
+ return NativeAppLine.#pageLine(level, text, { continuation: false });
129
+ if (tag === "AkanNative")
130
+ return NativeAppLine.#hostLine(`[akan-native] ${text}`, level);
131
+ return { level, message: `[${tag}] ${text}` };
132
+ }
133
+ const page = NativeAppLine.#page.exec(line);
134
+ if (page) {
135
+ const [, continuation, window, level = "info", text = ""] = page;
136
+ return NativeAppLine.#pageLine(level === "log" ? "info" : level, text, {
137
+ continuation: continuation === "+",
138
+ window
139
+ });
140
+ }
141
+ if (line.startsWith("[akan-native"))
142
+ return NativeAppLine.#hostLine(line, "info");
143
+ return { level: verbose ? "info" : "debug", message: line };
144
+ }
145
+ static #pageLine(level, text, { continuation, window }) {
146
+ if (continuation)
147
+ return { level, message: ` ${text}` };
148
+ const named = NativeAppLine.#named.exec(text);
149
+ const scope = `page${window ? `#${window}` : ""}${named ? `:${named[1]}` : ""}`;
150
+ return { level, message: `[${scope}] ${named ? named[2] : text}` };
151
+ }
152
+ static #hostLine(line, level) {
153
+ return { level: /\bpages from\b/.test(line) ? "debug" : level, message: line };
154
+ }
155
+ }
156
+
104
157
  // pkgs/@akanjs/devkit/mobile/nativeConfig.ts
105
158
  import path2 from "path";
106
159
 
@@ -304,6 +357,7 @@ class NativeApp {
304
357
  target;
305
358
  targetRoot;
306
359
  web;
360
+ #boot = null;
307
361
  constructor(app, target) {
308
362
  this.app = app;
309
363
  this.target = target;
@@ -343,7 +397,11 @@ class NativeApp {
343
397
  return { api, config };
344
398
  }
345
399
  #appLine = (line) => {
346
- this.app.logger.info(`[${this.target.name}] ${line}`);
400
+ const read = NativeAppLine.read(line, { verbose: Executor.verbose });
401
+ if (this.#boot)
402
+ this.#boot.lines.push(read);
403
+ else
404
+ this.app.logger[read.level](read.message);
347
405
  };
348
406
  #task(platform, config) {
349
407
  return {
@@ -358,6 +416,8 @@ class NativeApp {
358
416
  this.app.logger.error(event.message);
359
417
  else if (event.level === "warn")
360
418
  this.app.logger.warn(event.message);
419
+ else if (this.#boot)
420
+ this.#boot.steps.push(event.message);
361
421
  else if (event.level === "tool")
362
422
  this.app.logger.verbose(event.message);
363
423
  else
@@ -382,18 +442,43 @@ class NativeApp {
382
442
  });
383
443
  }
384
444
  async dev(platform, { upstream, lang, device, teamId }) {
385
- await mkdir2(this.web.dir, { recursive: true });
386
- const [{ api, config }, { api: routes }] = await Promise.all([this.prepare(), this.app.getConfig()]);
387
- return await api.dev({
388
- ...this.#task(platform, config),
389
- upstream,
390
- hmrPath: "/_akan/hmr",
391
- wsPaths: [`${routes.prefix}${routes.websocketPrefix}`],
392
- onLine: this.#appLine,
393
- startPath: this.startPath(lang),
394
- ...device ? { device } : {},
395
- ...teamId ? { ios: { signing: { teamId } } } : {}
396
- });
445
+ const startedAt = performance.now();
446
+ const boot = { steps: [], lines: [] };
447
+ this.#boot = boot;
448
+ try {
449
+ await mkdir2(this.web.dir, { recursive: true });
450
+ const [{ api, config }, { api: routes }] = await Promise.all([this.prepare(), this.app.getConfig()]);
451
+ const session = await api.dev({
452
+ ...this.#task(platform, config),
453
+ upstream,
454
+ hmrPath: "/_akan/hmr",
455
+ wsPaths: [`${routes.prefix}${routes.websocketPrefix}`],
456
+ onLine: this.#appLine,
457
+ startPath: this.startPath(lang),
458
+ ...device ? { device } : {},
459
+ ...teamId ? { ios: { signing: { teamId } } } : {}
460
+ });
461
+ this.#boot = null;
462
+ this.app.logger.info(this.readyLine(platform, { upstream, device: session.device, startedAt }));
463
+ for (const step of [...boot.steps, `pages through ${session.gateway}`])
464
+ this.app.logger.debug(step);
465
+ for (const line of boot.lines)
466
+ this.app.logger[line.level](line.message);
467
+ return session;
468
+ } catch (error) {
469
+ this.#boot = null;
470
+ for (const step of boot.steps)
471
+ this.app.logger.info(step);
472
+ for (const line of boot.lines)
473
+ this.app.logger[line.level === "debug" ? "info" : line.level](line.message);
474
+ throw error;
475
+ }
476
+ }
477
+ readyLine(platform, { upstream, device, startedAt }) {
478
+ const label = platform === "ios" || platform === "android" ? platform : "desktop";
479
+ const target = this.target.name === "default" ? "" : `/${this.target.name}`;
480
+ const seconds = ((performance.now() - startedAt) / 1000).toFixed(1);
481
+ return [`${this.app.name}${target} ${label} ready`, ...device ? [device.name] : [], upstream, `${seconds}s`].join(" \xB7 ");
397
482
  }
398
483
  async releaseIos({ teamId, adHoc = false } = {}) {
399
484
  await this.assembleWeb();
package/index.js CHANGED
@@ -13,18 +13,18 @@ import path from "path";
13
13
 
14
14
  // pkgs/@akanjs/cli/commandModules.ts
15
15
  var commandModules = {
16
- workspace: async () => (await import("./workspace.command-p44d21qf.js")).WorkspaceCommand,
16
+ workspace: async () => (await import("./workspace.command-1r29qzzk.js")).WorkspaceCommand,
17
17
  agent: async () => (await import("./agent.command-rp505zxa.js")).AgentCommand,
18
- code: async () => (await import("./code.command-jhrjttm1.js")).CodeCommand,
19
- application: async () => (await import("./application.command-2x9jqy0k.js")).ApplicationCommand,
18
+ code: async () => (await import("./code.command-78qw3q3f.js")).CodeCommand,
19
+ application: async () => (await import("./application.command-1p0cpt6y.js")).ApplicationCommand,
20
20
  library: async () => (await import("./library.command-sv6g1h2g.js")).LibraryCommand,
21
- localRegistry: async () => (await import("./localRegistry.command-4kj56531.js")).LocalRegistryCommand,
21
+ localRegistry: async () => (await import("./localRegistry.command-zppa6w7q.js")).LocalRegistryCommand,
22
22
  package: async () => (await import("./package.command-xmw605b1.js")).PackageCommand,
23
23
  module: async () => (await import("./module.command-ccdeder9.js")).ModuleCommand,
24
24
  page: async () => (await import("./page.command-ky7vafsn.js")).PageCommand,
25
- context: async () => (await import("./context.command-xncdvv7n.js")).ContextCommand,
26
- cloud: async () => (await import("./cloud.command-j6m607bp.js")).CloudCommand,
27
- subspace: async () => (await import("./subspace.command-ygfdqpbj.js")).SubspaceCommand,
25
+ context: async () => (await import("./context.command-x5f7t3gk.js")).ContextCommand,
26
+ cloud: async () => (await import("./cloud.command-ps9dabbg.js")).CloudCommand,
27
+ subspace: async () => (await import("./subspace.command-gx2cjpnv.js")).SubspaceCommand,
28
28
  guideline: async () => (await import("./guideline.command-d5qmxx29.js")).GuidelineCommand,
29
29
  scalar: async () => (await import("./scalar.command-t09gmck8.js")).ScalarCommand,
30
30
  primitive: async () => (await import("./primitive.command-bh6j8nfs.js")).PrimitiveCommand,
@@ -13,8 +13,8 @@ import"./index-48k96p55.js";
13
13
  import"./index-5mm3g24t.js";
14
14
  import {
15
15
  ApplicationScript
16
- } from "./index-pb10njz7.js";
17
- import"./index-ys6f0bvh.js";
16
+ } from "./index-118vq9dh.js";
17
+ import"./index-y736f42m.js";
18
18
  import"./index-7md2g9vw.js";
19
19
  import"./index-94s080qm.js";
20
20
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akanjs/cli",
3
- "version": "3.0.0-beta.25",
3
+ "version": "3.0.0-beta.27",
4
4
  "sourceType": "module",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -39,7 +39,7 @@
39
39
  "@earendil-works/pi-tui": "0.86.1",
40
40
  "@inquirer/prompts": "^8.4.3",
41
41
  "@tailwindcss/node": "^4.3.0",
42
- "akanjs": "3.0.0-beta.25",
42
+ "akanjs": "3.0.0-beta.27",
43
43
  "chalk": "^5.6.2",
44
44
  "commander": "^14.0.3",
45
45
  "dayjs": "^1.11.20",
@@ -62,4 +62,4 @@
62
62
  "bun": {
63
63
  "platform": "bun"
64
64
  }
65
- }
65
+ }
@@ -716,7 +716,7 @@ class SubspaceRunner extends runner("subspace") {
716
716
  if (!asked)
717
717
  return { name: subspace.name, workspaceId, host, apps, libs: [], outcome: "cancelled", files: [] };
718
718
  const { libs } = await subspace.slice();
719
- const { CloudScript } = await import("./cloud.script-r5t7nhee.js");
719
+ const { CloudScript } = await import("./cloud.script-wrw1kz6k.js");
720
720
  const { files } = await CommandContainer.get(CloudScript).uploadEnv(workspace, {
721
721
  host,
722
722
  workspaceId,
@@ -44,8 +44,8 @@ import {
44
44
  } from "./index-5mm3g24t.js";
45
45
  import {
46
46
  ApplicationScript
47
- } from "./index-pb10njz7.js";
48
- import"./index-ys6f0bvh.js";
47
+ } from "./index-118vq9dh.js";
48
+ import"./index-y736f42m.js";
49
49
  import"./index-7md2g9vw.js";
50
50
  import"./index-2ahj896a.js";
51
51
  import {
@@ -57,8 +57,8 @@ import {
57
57
  } from "./index-56xwsgyn.js";
58
58
  import {
59
59
  CloudScript2
60
- } from "./index-8k93esfr.js";
61
- import"./index-7yxndzea.js";
60
+ } from "./index-tg09x14f.js";
61
+ import"./index-w5pet0nq.js";
62
62
  import"./index-t02g6dpn.js";
63
63
  import"./index-v4hnkqz9.js";
64
64
  import"./index-zazvn45w.js";
@@ -67,7 +67,7 @@ import"./index-xfgdmm5d.js";
67
67
  import"./index-da72pfdv.js";
68
68
  import {
69
69
  ContextScript
70
- } from "./index-50rq2qms.js";
70
+ } from "./index-j9z8vg2n.js";
71
71
  import"./index-860zjnr1.js";
72
72
 
73
73
  // pkgs/@akanjs/cli/workspace/workspace.runner.ts