@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
@@ -1,10 +1,10 @@
1
1
  // @bun
2
2
  import {
3
- openBrowser,
4
- plainTextOf,
5
- HOST_SOURCE,
6
- DevLogBuffer
7
- } from "./index-sg1bgdhe.js";
3
+ stripAnsi
4
+ } from "./index-7md2g9vw.js";
5
+ import {
6
+ openBrowser
7
+ } from "./index-ns128c4q.js";
8
8
  import {
9
9
  writeClipboard
10
10
  } from "./index-p6pbz9n5.js";
@@ -156,6 +156,8 @@ var DevTuiApp = ({ actions }) => {
156
156
  actions.copyLines();
157
157
  else if (input === "Y")
158
158
  actions.copyPath();
159
+ else if (input === "s")
160
+ actions.copyShareUrl();
159
161
  else if (input === "o")
160
162
  actions.openSelected();
161
163
  else if (input === "r")
@@ -216,12 +218,95 @@ var DevTuiApp = ({ actions }) => {
216
218
  }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV(Text, {
217
219
  dimColor: true,
218
220
  wrap: "truncate",
219
- children: `Tab next \xB7 1-9 app \xB7 \u2191\u2193 scroll (shift page) \xB7 G follow${snapshot.following ? "" : " (paused)"} \xB7 / grep${snapshot.grep ? ` (${snapshot.grep})` : ""} \xB7 e errors${snapshot.errorsOnly ? " on" : ""} \xB7 c clear \xB7 y copy \xB7 Y path \xB7 o open \xB7 r restart \xB7 q quit`
221
+ children: `${snapshot.hasShare ? "s share \xB7 " : ""}Tab next \xB7 1-9 app \xB7 \u2191\u2193 scroll (shift page) \xB7 G follow${snapshot.following ? "" : " (paused)"} \xB7 / grep${snapshot.grep ? ` (${snapshot.grep})` : ""} \xB7 e errors${snapshot.errorsOnly ? " on" : ""} \xB7 c clear \xB7 y copy \xB7 Y path \xB7 o open \xB7 r restart \xB7 q quit`
220
222
  }, undefined, false, undefined, this)
221
223
  ]
222
224
  }, undefined, true, undefined, this);
223
225
  };
224
226
 
227
+ // pkgs/@akanjs/cli/application/devLogBuffer.ts
228
+ var plainTextOf = (lines, { withApp = false } = {}) => {
229
+ const width = withApp ? lines.reduce((max, line) => Math.max(max, line.app.length), 0) : 0;
230
+ return lines.map((line) => `${withApp ? `${line.app.padEnd(width)} \u2502 ` : ""}${stripAnsi(line.text)}`).join(`
231
+ `);
232
+ };
233
+ var HOST_SOURCE = "host";
234
+ var childPrefix = /^\[child:(\d+) ([a-z-]+)\] \[(?:stdout|stderr)\] /;
235
+ var sourceOf = (text) => {
236
+ const match = childPrefix.exec(text);
237
+ return match ? `#${match[1]} ${match[2]}` : HOST_SOURCE;
238
+ };
239
+
240
+ class DevLogBuffer {
241
+ static defaultLimit = 5000;
242
+ #limit;
243
+ #lines = [];
244
+ #partial = new Map;
245
+ #sources = new Map;
246
+ #seq = 0;
247
+ constructor({ limit = DevLogBuffer.defaultLimit } = {}) {
248
+ this.#limit = Math.max(1, limit);
249
+ }
250
+ get size() {
251
+ return this.#lines.length;
252
+ }
253
+ sourcesOf(app) {
254
+ return [...this.#sources.get(app) ?? []];
255
+ }
256
+ push(app, kind, chunk) {
257
+ const key = `${app}:${kind}`;
258
+ const parts = `${this.#partial.get(key) ?? ""}${chunk}`.split(`
259
+ `);
260
+ this.#partial.set(key, parts.pop() ?? "");
261
+ return this.#append(app, kind, parts);
262
+ }
263
+ flushPartials() {
264
+ const flushed = [];
265
+ for (const [key, remainder] of [...this.#partial]) {
266
+ this.#partial.set(key, "");
267
+ if (!remainder)
268
+ continue;
269
+ const split = key.lastIndexOf(":");
270
+ const app = key.slice(0, split);
271
+ const kind = key.slice(split + 1) === "stderr" ? "stderr" : "stdout";
272
+ flushed.push(...this.#append(app, kind, [remainder]));
273
+ }
274
+ return flushed;
275
+ }
276
+ select({ app = null, source = null, grep, errorsOnly = false } = {}) {
277
+ const needle = grep?.trim().toLowerCase();
278
+ return this.#lines.filter((line) => {
279
+ if (app !== null && line.app !== app)
280
+ return false;
281
+ if (source !== null && line.source !== source)
282
+ return false;
283
+ if (errorsOnly && line.kind !== "stderr")
284
+ return false;
285
+ if (needle && !stripAnsi(line.text).toLowerCase().includes(needle))
286
+ return false;
287
+ return true;
288
+ });
289
+ }
290
+ clear(app = null) {
291
+ const kept = app === null ? [] : this.#lines.filter((line) => line.app !== app);
292
+ this.#lines.length = 0;
293
+ this.#lines.push(...kept);
294
+ }
295
+ #append(app, kind, texts) {
296
+ const known = this.#sources.get(app) ?? new Set;
297
+ this.#sources.set(app, known);
298
+ const added = texts.map((text) => {
299
+ const source = sourceOf(text);
300
+ known.add(source);
301
+ return { seq: ++this.#seq, app, source, kind, text };
302
+ });
303
+ this.#lines.push(...added);
304
+ if (this.#lines.length > this.#limit)
305
+ this.#lines.splice(0, this.#lines.length - this.#limit);
306
+ return added;
307
+ }
308
+ }
309
+
225
310
  // pkgs/@akanjs/cli/application/devLogWindow.ts
226
311
  var windowOf = (lines, rows, anchor) => {
227
312
  const height = Math.max(1, Math.trunc(rows));
@@ -293,6 +378,7 @@ class DevTui {
293
378
  clear: this.#clear,
294
379
  copyLines: this.#copyLines,
295
380
  copyPath: this.#copyPath,
381
+ copyShareUrl: this.#copyShareUrl,
296
382
  openSelected: this.#openSelected,
297
383
  restartSelected: this.#restartSelected,
298
384
  quit: this.#quit
@@ -328,7 +414,7 @@ class DevTui {
328
414
  process.stdout.write(`${line.app} \u2502 ${line.text}
329
415
  `);
330
416
  for (const status of this.#statuses)
331
- process.stdout.write(`${status.name} ${status.url} \u2014 ${status.state}
417
+ process.stdout.write(`${status.name} ${status.url}${status.shareUrl ? ` \xB7 ${status.shareUrl}` : ""} \u2014 ${status.state}
332
418
  `);
333
419
  const log = this.#supervisor.sessionLog;
334
420
  for (const name of log.appNames)
@@ -388,7 +474,7 @@ class DevTui {
388
474
  this.#cachedSnapshot = {
389
475
  rows,
390
476
  selected: this.#indexOfTarget(rows),
391
- title: status ? `${status.name}${this.#target.source ? ` \xB7 ${this.#target.source}` : ""} \xB7 ${status.url} \xB7 ${status.state}${status.detail ? ` (${status.detail})` : ""}` : "all apps",
477
+ title: status ? `${status.name}${this.#target.source ? ` \xB7 ${this.#target.source}` : ""}${status.shareUrl ? ` \xB7 \u25C8 ${status.shareUrl}` : ""} \xB7 ${status.url} \xB7 ${status.state}${status.detail ? ` (${status.detail})` : ""}` : this.#mergedTitle(),
392
478
  lines: view.lines,
393
479
  above: view.above,
394
480
  below: view.below,
@@ -399,6 +485,7 @@ class DevTui {
399
485
  errorsOnly: this.#errorsOnly,
400
486
  editingGrep: this.#editingGrep,
401
487
  notice: this.#notice,
488
+ hasShare: this.#statuses.some((candidate) => !!candidate.shareUrl),
402
489
  readyCount: this.#statuses.filter((candidate) => candidate.state === "ready").length,
403
490
  appCount: this.#statuses.length,
404
491
  logRows,
@@ -500,6 +587,25 @@ class DevTui {
500
587
  const app = this.#target.app;
501
588
  return (app ? [app] : log.appNames).map((name) => log.relativePathOf(name));
502
589
  }
590
+ #copyShareUrl = () => {
591
+ const urls = this.#shareUrls();
592
+ if (urls.length === 0) {
593
+ this.#setNotice("no public share \u2014 start with --share");
594
+ return;
595
+ }
596
+ writeClipboard(urls.join(`
597
+ `)).then((copied) => {
598
+ this.#setNotice(copied ? `copied ${urls.join(" \xB7 ")}` : urls.join(" \xB7 "));
599
+ });
600
+ };
601
+ #shareUrls() {
602
+ const app = this.#target.app;
603
+ return this.#statuses.filter((status) => app === null || status.name === app).map((status) => status.shareUrl).filter((url) => !!url);
604
+ }
605
+ #mergedTitle() {
606
+ const urls = this.#shareUrls();
607
+ return urls.length === 0 ? "all apps" : `all apps \xB7 \u25C8 ${urls.join(" \xB7 ")}`;
608
+ }
503
609
  #setNotice(text) {
504
610
  this.#notice = text;
505
611
  if (this.#noticeTimer)
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // pkgs/@akanjs/cli/application/devTuiView.ts
3
3
  var createDevTuiView = async (supervisor) => {
4
- const { DevTui } = await import("./devTui-4ted58a6.js");
4
+ const { DevTui } = await import("./devTui-gy6mendg.js");
5
5
  return new DevTui(supervisor);
6
6
  };
7
7
  export {
@@ -2,13 +2,13 @@
2
2
  import {
3
3
  script,
4
4
  command
5
- } from "./index-b3ae16mg.js";
5
+ } from "./index-6na0sd2b.js";
6
6
  import"./index-q0y2jq9j.js";
7
- import"./index-5nyznra1.js";
7
+ import"./index-p4p9t45x.js";
8
8
  import"./index-6wwzs1bc.js";
9
9
  import {
10
- Prompter
11
- } from "./index-h7yw2z9n.js";
10
+ Prompter2
11
+ } from "./index-twq9p2sp.js";
12
12
 
13
13
  // pkgs/@akanjs/cli/guideline/guideline.script.ts
14
14
  import { Logger } from "akanjs/common";
@@ -16,7 +16,7 @@ import { Logger } from "akanjs/common";
16
16
  class GuidelineScript extends script("guideline") {
17
17
  async guideline(action, name = null, format = "markdown") {
18
18
  if (action === "list") {
19
- const guidelines = await Prompter.listGuidelines();
19
+ const guidelines = await Prompter2.listGuidelines();
20
20
  Logger.rawLog(format === "json" ? JSON.stringify({ guidelines }, null, 2) : guidelines.join(`
21
21
  `));
22
22
  return;
@@ -24,7 +24,7 @@ class GuidelineScript extends script("guideline") {
24
24
  if (action === "show") {
25
25
  if (!name)
26
26
  throw new Error("Guideline name is required. Example: akan guideline show framework");
27
- const [instruction, guideJson] = await Promise.all([Prompter.getInstruction(name), Prompter.getGuideJson(name)]);
27
+ const [instruction, guideJson] = await Promise.all([Prompter2.getInstruction(name), Prompter2.getGuideJson(name)]);
28
28
  Logger.rawLog(format === "json" ? JSON.stringify({ name, instruction, guideJson }, null, 2) : instruction);
29
29
  return;
30
30
  }
@@ -46,7 +46,7 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
46
46
  already titles, and `defaultDraft` opens the composer with text in it without sending it. A panel driven by a
47
47
  controlled `open` with **no** `onOpenChange` draws no close button at all rather than an inert one. Then the
48
48
  slots: `AgentLauncher`, `AgentSteps`, `AgentBubble`, `AgentComposer`, `AgentApproval`,
49
- `AgentQuestion`, `AgentQueued`, `AgentMenu`, `AgentMarkdown` and `AgentCode` each replace one part in `_overrides.tsx`, and
49
+ `AgentQuestion`, `AgentToolCard`, `AgentQueued`, `AgentMenu`, `AgentMarkdown` and `AgentCode` each replace one part in `_overrides.tsx`, and
50
50
  `akanjs/ui` exports every default beside them (`DefaultBubble`, `DefaultComposer`, …) so a skin composes the
51
51
  one it is replacing. **`AgentSteps` is one agent turn** — the messages between the user message that opened it
52
52
  and the next one, with `isRunning` saying whether more are still coming — which is the grain a chat needs to
@@ -216,6 +216,15 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
216
216
  is called from components the composer cannot see; writing the token is the composer's half, and `refer` warns
217
217
  rather than staging silently when no chat is mounted on that session — the case where a card sits outside the
218
218
  `<Agent.Zone>` its chat is inside.
219
+ - **The composer draws a pointer as the name it points at, never as the token.** Where `reference` sources are
220
+ declared the input is a Lexical editor rather than a textarea, and each pointer is one atomic node — a backspace
221
+ takes the whole thing rather than a character of a label that would then name nothing. Nothing above it changes:
222
+ the node's text content *is* the `@[…](mention:…)` token, so the draft string the chat reads, the `@` query, the
223
+ chips, the wire and the server's framing all see what they always saw, and every offset the chat hands over is
224
+ an offset into that string. It is its own chunk behind the chat's, fetched only where a source was declared, and
225
+ `mentions={false}` keeps the plain textarea — for an app that overrides `AgentComposer`, or one that would
226
+ rather see the tokens it is sending. An override that draws its own textarea keeps working: it fills the
227
+ `inputRef` it is handed, and the chat reads the caret off that when no editor filled `handleRef`.
219
228
  - **`attach` and `voice` both carry functions, so a server layout cannot pass either.** A closure does not cross
220
229
  the RSC boundary — `non-scalar-props-restricted` says so on `page/**` — so an app that wants either mounts the
221
230
  chat from a small client component in the app's own `ui/` that calls the hook.
@@ -287,6 +296,14 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
287
296
  `data-akan-action` like a store setter does. A `remove*` name defaults to a confirm gate. Reach a store action
288
297
  from the body — `.exec((id) => st.do.removeX(id))` — which is how an agent gets CRUD; `st.do` on its own
289
298
  reaches nobody.
299
+ - **`.card()` is the other way the chain ends, for an answer that is the user's to give.** Where `.exec()` runs a
300
+ function, `.card(({ submit, cancel }, ...args) => <Form …/>)` parks the call in the chat and renders the app's own
301
+ component there; what `submit` is handed is what the model reads back, and `cancel` is the refusal it reads
302
+ instead. A name and a phone number, a date somebody has to look up, a signature — a model that fills those in
303
+ has answered its own question, and every other shape of "ask the user" is `askUser`. The declared arguments are
304
+ checked **before** the card is parked, so a bad one reaches the model as a refusal rather than throwing inside
305
+ the render; `confirm` is not read at all, because the card in front of the user is already the asking. The frame
306
+ draws its own way out even when the card does not, and the turn is never parked on something with no exit.
290
307
  - **The second argument is how the call behaves, never what it is.** `{ settle, confirm, guard }`:
291
308
  `settle: false` marks a read that returns what is already there and skips the wait; every other tool is waited
292
309
  out before its effect on the screen is reported, because a write may still be landing when `exec` resolves. A
@@ -685,7 +702,10 @@ apps and libs never import it directly (`no-import-external-library`) — everyt
685
702
  is among them. The loop parks on the question exactly as it parks on an approval, a dismissal is the tool's
686
703
  error result rather than a silent empty answer, and the settled exchange renders as question-and-answer instead
687
704
  of a tool row. **Never re-implement it per screen** — a `st.tool("askAboutX")` that opens a modal is the same
688
- thing with a worse transcript — and a hook tool named `askUser` shadows it like any other built-in.
705
+ thing with a worse transcript — and a hook tool named `askUser` shadows it like any other built-in. The line
706
+ between it and a `.card()` tool is what the answer *is*: a sentence or a pick off a list is `askUser` and belongs
707
+ to the conversation, while a shape the model must not invent — fields, a form, a signature — is a card the screen
708
+ declares, because only the screen knows what filling it in looks like.
689
709
 
690
710
  ## What The Page Draws
691
711
  - **The page shows the agent's work, not just the transcript.** A chat panel is closed as often as it is open, and
@@ -946,7 +946,9 @@ when two shapes disagree.
946
946
  selected one's log beside it. `Tab` walks every row and `1`-`9` jump to that app (the rail shows each
947
947
  app's digit), `↑↓` scroll (shift for a page, `G` back to following),
948
948
  `/` greps, `e` shows stderr only, `c` clears, `y` copies, `Y` copies the log path, `o` opens the browser,
949
- `r` restarts that app, `q` quits.
949
+ `r` restarts that app, `q` quits. Under `--share`, `s` copies the public URL — the selected app's, or every
950
+ app's from the merged row — and the header carries it ahead of the local one, because the line `--share`
951
+ printed before the view took the terminal is gone by its first repaint.
950
952
  **`--plain` prints prefixed interleaved lines instead**, and a pipe, a redirect or an unsized terminal
951
953
  downgrades to that on its own.
952
954
  - **A supervised session writes `local/apps/<app>/runtime/dev.log`, and that path is how a log gets handed over.**
@@ -3,7 +3,7 @@ import {
3
3
  CodegenLock,
4
4
  WorkspaceExecutor,
5
5
  AppExecutor
6
- } from "./index-5nyznra1.js";
6
+ } from "./index-p4p9t45x.js";
7
7
  import"./index-q0y2jq9j.js";
8
8
  import"./index-6wwzs1bc.js";
9
9
  import {
@@ -2,13 +2,13 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-b3ae16mg.js";
5
+ } from "./index-6na0sd2b.js";
6
6
  import {
7
7
  FileSys
8
8
  } from "./index-q0y2jq9j.js";
9
9
  import {
10
10
  PkgExecutor
11
- } from "./index-5nyznra1.js";
11
+ } from "./index-p4p9t45x.js";
12
12
  import {
13
13
  TypeScriptDependencyScanner2
14
14
  } from "./index-kcxmv48c.js";
@@ -153,7 +153,12 @@ class PackageRunner extends runner("package") {
153
153
  const scanner = await TypeScriptDependencyScanner2.from(pkg);
154
154
  const { npmDeps, npmDevDeps, missingDeps } = await scanner.getPackageBuildDependencies(pkg.name);
155
155
  const packageRuntimeDependencies = {
156
- "@akanjs/devkit": ["tailwind-scrollbar"]
156
+ "@akanjs/devkit": [
157
+ "tailwind-scrollbar",
158
+ "@earendil-works/pi-agent-core",
159
+ "@earendil-works/pi-ai",
160
+ "@earendil-works/pi-tui"
161
+ ]
157
162
  };
158
163
  const packageRuntimeDevDependencies = { akanjs: ["@biomejs/biome", "@types/bun"] };
159
164
  if (pkg.name === "@akanjs/cli") {
@@ -174,7 +179,11 @@ class PackageRunner extends runner("package") {
174
179
  const optionalPeerDeps = new Set(Object.entries(pkgJson.peerDependenciesMeta ?? {}).filter(([, meta]) => meta.optional).map(([dep]) => dep));
175
180
  const packageRuntimeDeps = [...new Set([...npmDeps, ...forcedRuntimeDeps])].filter((dep) => !optionalPeerDeps.has(dep) && !bundledRuntimeDeps.has(dep));
176
181
  const packageRuntimeDevDeps = [...new Set([...npmDevDeps, ...forcedRuntimeDevDeps])].filter((dep) => !optionalPeerDeps.has(dep) && !bundledRuntimeDeps.has(dep));
177
- const rootDeps = { ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies };
182
+ const rootDeps = {
183
+ ...rootPackageJson.overrides,
184
+ ...rootPackageJson.dependencies,
185
+ ...rootPackageJson.devDependencies
186
+ };
178
187
  const missingForcedDeps = forcedRuntimeDeps.filter((dep) => !rootDeps[dep]);
179
188
  const missingForcedDevDeps = forcedRuntimeDevDeps.filter((dep) => !rootDeps[dep]);
180
189
  const requiredMissingDeps = missingDeps.filter((dep) => !optionalPeerDeps.has(dep));
@@ -20,13 +20,13 @@ import {
20
20
  renderWorkflowApply,
21
21
  renderWorkflowValidation,
22
22
  renderWorkflowRunArtifact
23
- } from "./index-jwjaf9fy.js";
23
+ } from "./index-qhtj9y6j.js";
24
24
  import {
25
25
  AkanContextAnalyzer
26
- } from "./index-15r9a10e.js";
26
+ } from "./index-v17gj504.js";
27
27
  import {
28
28
  runner
29
- } from "./index-b3ae16mg.js";
29
+ } from "./index-6na0sd2b.js";
30
30
 
31
31
  // pkgs/@akanjs/cli/workflow/workflow.runner.ts
32
32
  import { mkdir, readFile, writeFile } from "fs/promises";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  CommandExecutionError
4
- } from "./index-5nyznra1.js";
4
+ } from "./index-p4p9t45x.js";
5
5
  import {
6
6
  resolveMobilePath,
7
7
  targetHtmlFilename
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  runner,
4
4
  script
5
- } from "./index-b3ae16mg.js";
5
+ } from "./index-6na0sd2b.js";
6
6
  import {
7
7
  LibExecutor
8
- } from "./index-5nyznra1.js";
8
+ } from "./index-p4p9t45x.js";
9
9
  import {
10
10
  LibSource,
11
11
  formatLibStatuses
@@ -5,13 +5,13 @@ import {
5
5
  writeGeneratedSyncState,
6
6
  createRepairReport,
7
7
  renderRepairReport
8
- } from "./index-jwjaf9fy.js";
8
+ } from "./index-qhtj9y6j.js";
9
9
  import {
10
10
  AkanContextAnalyzer
11
- } from "./index-15r9a10e.js";
11
+ } from "./index-v17gj504.js";
12
12
  import {
13
13
  runner
14
- } from "./index-b3ae16mg.js";
14
+ } from "./index-6na0sd2b.js";
15
15
 
16
16
  // pkgs/@akanjs/cli/repair/repair.runner.ts
17
17
  var commandForShell = (command) => command.startsWith("akan ") ? `bun run ${command}` : command;
@@ -0,0 +1,69 @@
1
+ // @bun
2
+ import {
3
+ jsonText
4
+ } from "./index-qhtj9y6j.js";
5
+ import {
6
+ akanMcpInstallTargets
7
+ } from "./index-v17gj504.js";
8
+ import {
9
+ script
10
+ } from "./index-6na0sd2b.js";
11
+ import {
12
+ ContextRunner2
13
+ } from "./index-g9zghs4h.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 };