@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.
- package/.build-stamp +1 -1
- package/CodeAgent-zgccwajm.js +9 -0
- package/CodeAgentRpcHost-qvwfv0n9.js +7 -0
- package/CodeTui-993tx7gf.js +1103 -0
- package/README.md +3 -0
- package/{agent.command-bhwsc2aj.js → agent.command-n664dtcv.js} +6 -6
- package/akanCode.js +100 -0
- package/{application.command-436y543n.js → application.command-t5542jte.js} +6 -5
- package/{applicationBuildRunner-4f1wrba0.js → applicationBuildRunner-x4gbfn7y.js} +2 -2
- package/{applicationReleasePackager-jkjmy5ee.js → applicationReleasePackager-z61ep017.js} +1 -1
- package/buildBatch.proc.js +2 -2
- package/{capacitorApp-hqvsrec4.js → capacitorApp-shv3ajh5.js} +2 -2
- package/{cloud.command-3xn0xpz8.js → cloud.command-4x35k1z6.js} +9 -8
- package/cloud.script-3k8nbbpn.js +20 -0
- package/code.command-mrfb7a1g.js +147 -0
- package/commandManifest.json +1 -1
- package/consoleToStderr-h5bryj94.js +7 -0
- package/{context.command-hxh96cc3.js → context.command-pqsm5jrk.js} +14 -13
- package/context.runner-bys6ykcp.js +22 -0
- package/{devTui-4ted58a6.js → devTui-gy6mendg.js} +114 -8
- package/{devTuiView-1dj2yq7t.js → devTuiView-y1548wy6.js} +1 -1
- package/{guideline.command-cyw8c0m0.js → guideline.command-rpc2emw8.js} +6 -6
- package/guidelines/agentRule/agentRule.instruction.md +22 -2
- package/guidelines/conventions/conventions.instruction.md +3 -1
- package/incrementalBuilder.proc.js +1 -1
- package/{index-t8gvwcrx.js → index-018dszb3.js} +13 -4
- package/{index-8pkvrcv1.js → index-2pm1j01n.js} +3 -3
- package/{index-7f4dsf9v.js → index-3cymrzsb.js} +1 -1
- package/{index-1nwxbr2y.js → index-3mg4h788.js} +2 -2
- package/{index-em4swemt.js → index-4cvpzkq6.js} +3 -3
- package/index-4n4821gp.js +69 -0
- package/index-5405kc0x.js +2434 -0
- package/{index-tt6kzwj5.js → index-57p9p179.js} +3 -3
- package/{index-b3ae16mg.js → index-6na0sd2b.js} +1 -1
- package/index-7md2g9vw.js +6 -0
- package/index-8k16atqy.js +82 -0
- package/{index-fad0hhty.js → index-g9zghs4h.js} +22 -80
- package/index-jgrnpt6y.js +121 -0
- package/{index-31hmq4ys.js → index-kvzjda3v.js} +8 -8
- package/{index-sg1bgdhe.js → index-ns128c4q.js} +27 -105
- package/{index-5nyznra1.js → index-p4p9t45x.js} +3 -0
- package/{index-sh88vtye.js → index-qh7brn20.js} +1 -1
- package/{index-jwjaf9fy.js → index-qhtj9y6j.js} +44 -44
- package/{index-ys7dvdb3.js → index-sn7dnzq4.js} +1 -1
- package/index-sxg87a8f.js +727 -0
- package/{index-r73ha1rf.js → index-te0y1c0m.js} +4 -4
- package/{index-h7yw2z9n.js → index-twq9p2sp.js} +8 -8
- package/{index-15r9a10e.js → index-v17gj504.js} +2 -2
- package/{index-1mrmve4s.js → index-vpx68e4x.js} +2 -2
- package/index-wfwknnje.js +124 -0
- package/{index-9fbk3dbh.js → index-xjc7gg65.js} +4 -4
- package/{index-8tcj5wk8.js → index-zg0v1zte.js} +5 -5
- package/{index-vrwdx0zx.js → index-zn8qgeqx.js} +1 -1
- package/index.js +21 -20
- package/{library.command-1f9h2ex6.js → library.command-m8p2r1dh.js} +3 -3
- package/{localRegistry.command-4cbgz63s.js → localRegistry.command-tt00nwwg.js} +8 -7
- package/{module.command-ew0484va.js → module.command-mfzvqt0n.js} +5 -5
- package/{package.command-y2rh4np7.js → package.command-8sy6jjwy.js} +3 -3
- package/package.json +12 -2
- package/{page.command-e5h29fyt.js → page.command-taenb02b.js} +3 -3
- package/{primitive.command-50ecfzg4.js → primitive.command-7kpncmkk.js} +6 -6
- package/prompter-9mn3kp36.js +8 -0
- package/{quality.command-a2jytczs.js → quality.command-1ar94hrw.js} +2 -2
- package/{repair.command-c2amvt74.js → repair.command-n08t6j8p.js} +5 -5
- package/{scalar.command-bptz6aj6.js → scalar.command-mq8qfp4t.js} +4 -4
- package/skills/akan-debug/SKILL.md +42 -0
- package/skills/akan-deps/SKILL.md +50 -0
- package/skills/akan-err/SKILL.md +39 -0
- package/skills/akan-module/SKILL.md +45 -0
- package/skills/akan-scaffold/SKILL.md +76 -0
- package/skills/akan-scalar/SKILL.md +52 -0
- package/skills/akan-service/SKILL.md +34 -0
- package/skills/akan-store/SKILL.md +63 -0
- package/skills/akan-ui/SKILL.md +63 -0
- package/skills/akan-validate/SKILL.md +44 -0
- package/{subspace.command-kmemx1vm.js → subspace.command-x9897gj4.js} +4 -4
- package/{tunnel.command-67q8vsg5.js → tunnel.command-ht2es78c.js} +2 -2
- package/{workflow.command-2ze5y2xp.js → workflow.command-tvz4nm9n.js} +9 -9
- package/{workspace.command-2n385jkt.js → workspace.command-ayqa1rgt.js} +22 -20
- 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-
|
|
9
|
+
} from "./index-6na0sd2b.js";
|
|
10
10
|
import {
|
|
11
11
|
WorkspaceExecutor,
|
|
12
12
|
AppExecutor
|
|
13
|
-
} from "./index-
|
|
13
|
+
} from "./index-p4p9t45x.js";
|
|
14
14
|
import {
|
|
15
15
|
openBrowser
|
|
16
|
-
} from "./index-
|
|
16
|
+
} from "./index-ns128c4q.js";
|
|
17
17
|
|
|
18
18
|
// pkgs/@akanjs/cli/cloud/cloud.runner.ts
|
|
19
19
|
import path from "path";
|
|
@@ -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-
|
|
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-
|
|
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-
|
|
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-
|
|
24
|
+
} from "./index-3cymrzsb.js";
|
|
31
25
|
import {
|
|
32
|
-
|
|
33
|
-
|
|
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-
|
|
34
|
+
} from "./index-4cvpzkq6.js";
|
|
37
35
|
import {
|
|
38
36
|
WorkflowRunner
|
|
39
|
-
} from "./index-
|
|
37
|
+
} from "./index-2pm1j01n.js";
|
|
40
38
|
import {
|
|
41
39
|
ModuleScript
|
|
42
|
-
} from "./index-
|
|
40
|
+
} from "./index-xjc7gg65.js";
|
|
43
41
|
import {
|
|
44
42
|
PrimitiveScript
|
|
45
|
-
} from "./index-
|
|
43
|
+
} from "./index-te0y1c0m.js";
|
|
46
44
|
import {
|
|
47
45
|
ScalarScript
|
|
48
|
-
} from "./index-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
23
|
+
} from "./index-v17gj504.js";
|
|
24
24
|
import {
|
|
25
|
-
|
|
26
|
-
} from "./index-
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
5
|
+
} from "./index-6na0sd2b.js";
|
|
6
6
|
import {
|
|
7
7
|
WorkspaceExecutor,
|
|
8
8
|
AppExecutor,
|
|
9
9
|
LibExecutor,
|
|
10
10
|
PkgExecutor
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-p4p9t45x.js";
|
|
12
12
|
import {
|
|
13
13
|
LibraryScript
|
|
14
|
-
} from "./index-
|
|
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-
|
|
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-
|
|
2052
|
-
var loadReleasePackager = async () => (await import("./applicationReleasePackager-
|
|
2053
|
-
var loadCapacitorApp = async () => (await import("./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
|
-
|
|
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-
|
|
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
|
|
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
|
-
|
|
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,
|
|
3388
|
+
export { openBrowser, ApplicationScript };
|