@akanjs/cli 3.0.0-beta.19 → 3.0.0-beta.20
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-6cm97kay.js → CodeAgent-awv258wb.js} +2 -2
- package/{CodeTui-za4jsm41.js → CodeTui-1nqh35ez.js} +20 -22
- package/TunnelShare-scf4e4pd.js +9 -0
- package/{agent.command-e0wpbbyg.js → agent.command-1s9ag7sb.js} +8 -9
- package/akanCode.js +4 -4
- package/{application.command-8wyxqc8q.js → application.command-49hwy6va.js} +25 -56
- package/{applicationBuildRunner-n9gzaxd0.js → applicationBuildRunner-ybyp97pv.js} +33 -59
- package/{applicationReleasePackager-vpggfqgq.js → applicationReleasePackager-esnrphw8.js} +40 -60
- package/buildBatch.proc.js +19 -24
- package/{capacitorApp-q3z0qht0.js → capacitorApp-1synz4en.js} +3 -4
- package/{cloud.command-4zwa5dsx.js → cloud.command-d7rqtzt9.js} +16 -26
- package/cloud.script-bkbpcr96.js +19 -0
- package/{code.command-468c9d7s.js → code.command-nn48xzej.js} +22 -37
- package/context.command-s3mcmvpa.js +48 -0
- package/context.runner-k99nb5pk.js +21 -0
- package/{dependencyScanner-0z2h2tks.js → dependencyScanner-ye2e6pdz.js} +2 -2
- package/{devTui-ffjsarqa.js → devTui-q7k7bakd.js} +5 -9
- package/fileSys-5ngz93ga.js +9 -0
- package/{guideline.command-vhw13pqr.js → guideline.command-sct4qnt5.js} +4 -5
- package/guidelines/conventions/conventions.instruction.md +5 -1
- package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
- package/incrementalBuilder.proc.js +30 -48
- package/{index-s5rhm04y.js → index-0bq14vr1.js} +1 -1
- package/{index-10dkrrww.js → index-13ffe9wp.js} +4 -4
- package/{index-srmay5jw.js → index-22d57v4c.js} +84 -67
- package/{index-53176s7j.js → index-31yr441d.js} +10 -17
- package/index-3hx1z96c.js +87 -0
- package/{index-4m929vvn.js → index-3sq321ak.js} +10 -18
- package/{index-bhtmj233.js → index-3t7g9e4r.js} +41 -78
- package/{index-q0y2jq9j.js → index-5b6tavv3.js} +6 -3
- package/{index-47pj3aee.js → index-5e0n4hqx.js} +11 -12
- package/{index-7ep8qtvp.js → index-5pc1qrbv.js} +5 -8
- package/{index-esk82rvk.js → index-8mna0947.js} +34 -71
- package/{index-sq2dzkzm.js → index-8sf7wmdr.js} +6 -6
- package/{index-crmeqnmf.js → index-9d9bgcx4.js} +283 -722
- package/{index-bwf965h6.js → index-ahemdr5n.js} +6 -6
- package/{index-ab0c38ea.js → index-as7xmyz8.js} +20 -20
- package/{index-bc88j1ry.js → index-axzjaqve.js} +94 -142
- package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
- package/{index-667w0yah.js → index-c6eggbee.js} +2 -5
- package/{index-a1w6934z.js → index-ddxvdd1p.js} +169 -305
- package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
- package/{index-22xtgmhn.js → index-dzf3r49a.js} +1 -1
- package/{index-89hy31kf.js → index-fgq75haa.js} +172 -287
- package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
- package/{index-hwkygn9s.js → index-khpfpcsd.js} +302 -33
- package/{index-vqx8bdxz.js → index-mxav6j3c.js} +78 -231
- package/{index-2446k7b4.js → index-myhc3c1j.js} +512 -588
- package/{index-3jrp517k.js → index-nv5976x3.js} +45 -128
- package/{index-zqgj2rt2.js → index-przybvy5.js} +69 -147
- package/{index-n3cv0tm4.js → index-smme4r47.js} +1 -1
- package/{index-qdgzsnhg.js → index-w2zdcw3k.js} +110 -231
- package/{index-14zrtgfa.js → index-wa5jbxj1.js} +6 -39
- package/{index-bftkz6cp.js → index-ww4z397j.js} +198 -555
- package/{index-kwaq3n9n.js → index-xqjwd384.js} +4 -7
- package/{index-txr7dj2g.js → index-xqpzbab5.js} +106 -240
- package/{index-e4v6vhxq.js → index-xsjh6nzh.js} +178 -165
- package/{index-18zybgkc.js → index-ygn77a5w.js} +47 -99
- package/{index-9d6nvkz2.js → index-ztp3e73t.js} +79 -35
- package/index.js +23 -24
- package/{library.command-cqr175dy.js → library.command-1gx04jgn.js} +4 -5
- package/{localRegistry.command-49z55qqz.js → localRegistry.command-zndxj1q6.js} +21 -42
- package/{module.command-9p8mm3b0.js → module.command-3waddk95.js} +6 -7
- package/{package.command-wxyz909t.js → package.command-zrc7br1y.js} +5 -6
- package/package.json +2 -2
- package/{page.command-gsrsfqqs.js → page.command-vpjgardh.js} +4 -5
- package/{primitive.command-ns1mptje.js → primitive.command-sz84tk4t.js} +9 -20
- package/{prompter-1f8d9pcc.js → prompter-ptaa3nk0.js} +2 -2
- package/{quality.command-e76k2q9k.js → quality.command-g869hafs.js} +129 -363
- package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
- package/{repair.command-pkrsm3cw.js → repair.command-chsnjvvv.js} +11 -35
- package/{scalar.command-0cpt3fc8.js → scalar.command-2v21newx.js} +5 -6
- package/skills/akan-code/SKILL.md +12 -4
- package/{subspace.command-fktpwp0g.js → subspace.command-ckcbwfp1.js} +39 -58
- package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +3 -3
- package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +3 -3
- package/templates/client.ts +7 -30
- package/templates/lib/__lib/lib.dictionary.ts +0 -2
- package/templates/lib/__lib/lib.document.ts +0 -2
- package/templates/lib/sig.ts +8 -30
- package/templates/server.ts +0 -2
- package/{tunnel.command-d5jy9gk8.js → tunnel.command-kd2yr4fx.js} +5 -6
- package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
- package/typecheck.proc.js +1 -1
- package/workflow.command-44252cqv.js +79 -0
- package/{workspace.command-gv84eh1p.js → workspace.command-fqcztt5p.js} +72 -107
- package/TunnelShare-2j6s511d.js +0 -9
- package/cloud.script-fwx3vb34.js +0 -20
- package/context.command-dsnw0jby.js +0 -80
- package/context.runner-rs4rj15d.js +0 -22
- package/devTuiView-1q1mdgrv.js +0 -9
- package/getDirname-dr3jz1xg.js +0 -7
- package/index-6wwzs1bc.js +0 -7
- package/workflow.command-6tkcysmx.js +0 -105
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
akanCodePaths2,
|
|
5
5
|
McpServerConfig,
|
|
6
6
|
McpSignIn
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-ztp3e73t.js";
|
|
8
8
|
import {
|
|
9
9
|
stripAnsi
|
|
10
10
|
} from "./index-7md2g9vw.js";
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
akanCodeModel2,
|
|
14
14
|
akanCodeModelSupportsImages2,
|
|
15
15
|
akanCodeModelWarnings2
|
|
16
|
-
} from "./index-
|
|
16
|
+
} from "./index-c6eggbee.js";
|
|
17
17
|
|
|
18
18
|
// pkgs/@akanjs/devkit/codeAgent/agent/CodeAgent.ts
|
|
19
19
|
import {
|
|
@@ -36,7 +36,7 @@ var empty = { paths: [], apps: [], libs: [], needsSync: false, touchesTsx: false
|
|
|
36
36
|
|
|
37
37
|
class AkanEditScope2 {
|
|
38
38
|
static async since(cwd, baseline) {
|
|
39
|
-
const current = await AkanEditScope2
|
|
39
|
+
const current = await AkanEditScope2.baseline(cwd);
|
|
40
40
|
const changed = [...current].filter((line) => !baseline.has(line));
|
|
41
41
|
if (!changed.length)
|
|
42
42
|
return empty;
|
|
@@ -51,9 +51,6 @@ class AkanEditScope2 {
|
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
static async baseline(cwd) {
|
|
54
|
-
return await AkanEditScope2.#status(cwd);
|
|
55
|
-
}
|
|
56
|
-
static async#status(cwd) {
|
|
57
54
|
const proc = Bun.spawn(["git", "status", "--porcelain=v1", "--untracked-files=all"], {
|
|
58
55
|
cwd,
|
|
59
56
|
stdout: "pipe",
|
|
@@ -514,7 +511,7 @@ class AkanToolPack2 {
|
|
|
514
511
|
return { name: "akan-tools", factory: async (pi) => await this.#register(pi) };
|
|
515
512
|
}
|
|
516
513
|
async names() {
|
|
517
|
-
const { ContextRunner } = await import("./context.runner-
|
|
514
|
+
const { ContextRunner } = await import("./context.runner-k99nb5pk.js");
|
|
518
515
|
return [
|
|
519
516
|
...new ContextRunner().listMcpTools(this.#options.mode).map((tool) => tool.name),
|
|
520
517
|
AkanToolPack2.verifyToolName
|
|
@@ -522,7 +519,7 @@ class AkanToolPack2 {
|
|
|
522
519
|
}
|
|
523
520
|
static verifyToolName = "akan_verify";
|
|
524
521
|
async#register(pi) {
|
|
525
|
-
const { ContextRunner } = await import("./context.runner-
|
|
522
|
+
const { ContextRunner } = await import("./context.runner-k99nb5pk.js");
|
|
526
523
|
const runner = new ContextRunner;
|
|
527
524
|
const guidelineNames = await AkanToolPack2.#guidelineNames();
|
|
528
525
|
for (const tool of runner.listMcpTools(this.#options.mode, { guidelineNames })) {
|
|
@@ -537,7 +534,8 @@ class AkanToolPack2 {
|
|
|
537
534
|
const result = await runner.callMcpTool(this.#options.workspace, tool.name, params ?? {}, {
|
|
538
535
|
mode: this.#options.mode
|
|
539
536
|
});
|
|
540
|
-
|
|
537
|
+
const text = typeof result === "string" ? result : JSON.stringify(result, null, 2);
|
|
538
|
+
return { content: [{ type: "text", text }], details: undefined };
|
|
541
539
|
}
|
|
542
540
|
});
|
|
543
541
|
}
|
|
@@ -564,17 +562,12 @@ class AkanToolPack2 {
|
|
|
564
562
|
}
|
|
565
563
|
static async#guidelineNames() {
|
|
566
564
|
try {
|
|
567
|
-
const { Prompter } = await import("./prompter-
|
|
565
|
+
const { Prompter } = await import("./prompter-ptaa3nk0.js");
|
|
568
566
|
return await Prompter.listGuidelines();
|
|
569
567
|
} catch {
|
|
570
568
|
return [];
|
|
571
569
|
}
|
|
572
570
|
}
|
|
573
|
-
static #render(result) {
|
|
574
|
-
if (typeof result === "string")
|
|
575
|
-
return result;
|
|
576
|
-
return JSON.stringify(result, null, 2);
|
|
577
|
-
}
|
|
578
571
|
}
|
|
579
572
|
|
|
580
573
|
// pkgs/@akanjs/devkit/codeAgent/tools/AskToolPack.ts
|
|
@@ -885,24 +878,27 @@ class McpClient2 {
|
|
|
885
878
|
class McpToolPack2 {
|
|
886
879
|
#clients = [];
|
|
887
880
|
#status = [];
|
|
888
|
-
|
|
881
|
+
#onNotice;
|
|
882
|
+
constructor(onNotice) {
|
|
883
|
+
this.#onNotice = onNotice;
|
|
884
|
+
}
|
|
889
885
|
static async connect(options) {
|
|
890
886
|
const refs = McpToolPack2.#refs(options);
|
|
891
887
|
if (!refs.length)
|
|
892
888
|
return;
|
|
893
|
-
const pack = new McpToolPack2;
|
|
889
|
+
const pack = new McpToolPack2(options.onNotice);
|
|
894
890
|
for (const ref of refs) {
|
|
895
891
|
const base = { name: ref.name, transport: ref.transport, target: McpServerConfig.targetOf(ref) };
|
|
896
892
|
const token = ref.transport === "http" ? await McpSignIn.token(ref, options.onNotice) : undefined;
|
|
897
893
|
try {
|
|
898
|
-
const
|
|
899
|
-
const
|
|
900
|
-
pack.#clients.push({ client, tools });
|
|
901
|
-
pack.#status.push({
|
|
894
|
+
const opened = await McpToolPack2.#openRefreshing(ref, token, options.onNotice);
|
|
895
|
+
const status = {
|
|
902
896
|
...base,
|
|
903
|
-
tools: tools.map((tool) => McpToolPack2.#nameOf(ref.name, tool.name)),
|
|
904
|
-
auth: token ? "authorized" : "none"
|
|
905
|
-
}
|
|
897
|
+
tools: opened.tools.map((tool) => McpToolPack2.#nameOf(ref.name, tool.name)),
|
|
898
|
+
auth: opened.token ? "authorized" : "none"
|
|
899
|
+
};
|
|
900
|
+
pack.#clients.push({ ...opened, status, renewing: undefined, refused: undefined });
|
|
901
|
+
pack.#status.push(status);
|
|
906
902
|
} catch (error) {
|
|
907
903
|
if (error instanceof McpUnauthorized2) {
|
|
908
904
|
options.onNotice?.(`MCP server "${ref.name}" needs signing in \u2014 /mcp login ${ref.name}`);
|
|
@@ -915,6 +911,22 @@ class McpToolPack2 {
|
|
|
915
911
|
}
|
|
916
912
|
return pack;
|
|
917
913
|
}
|
|
914
|
+
static async#openRefreshing(ref, token, onNotice) {
|
|
915
|
+
try {
|
|
916
|
+
return await McpToolPack2.#open(ref, token);
|
|
917
|
+
} catch (error) {
|
|
918
|
+
if (!(error instanceof McpUnauthorized2) || !token)
|
|
919
|
+
throw error;
|
|
920
|
+
const retry = await McpSignIn.retryToken(ref, token, onNotice);
|
|
921
|
+
if (!retry)
|
|
922
|
+
throw error;
|
|
923
|
+
return await McpToolPack2.#open(ref, retry);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
static async#open(ref, token) {
|
|
927
|
+
const client = await new McpClient2(ref, token).connect();
|
|
928
|
+
return { client, tools: await client.listTools(), token };
|
|
929
|
+
}
|
|
918
930
|
get toolNames() {
|
|
919
931
|
return this.#clients.flatMap(({ client, tools }) => tools.map((tool) => McpToolPack2.#nameOf(client.ref.name, tool.name)));
|
|
920
932
|
}
|
|
@@ -929,18 +941,18 @@ class McpToolPack2 {
|
|
|
929
941
|
client.close();
|
|
930
942
|
}
|
|
931
943
|
#register(pi) {
|
|
932
|
-
for (const
|
|
933
|
-
for (const tool of tools) {
|
|
934
|
-
const name = McpToolPack2.#nameOf(client.ref.name, tool.name);
|
|
944
|
+
for (const server of this.#clients)
|
|
945
|
+
for (const tool of server.tools) {
|
|
946
|
+
const name = McpToolPack2.#nameOf(server.client.ref.name, tool.name);
|
|
935
947
|
const description = tool.description ?? tool.name;
|
|
936
948
|
pi.registerTool({
|
|
937
949
|
name,
|
|
938
|
-
label: `${client.ref.name}: ${tool.name}`,
|
|
950
|
+
label: `${server.client.ref.name}: ${tool.name}`,
|
|
939
951
|
description,
|
|
940
952
|
promptSnippet: `${name}: ${description.split(".")[0] ?? description}`,
|
|
941
953
|
parameters: Type4.Unsafe(tool.inputSchema),
|
|
942
954
|
execute: async (_id, params) => {
|
|
943
|
-
const result = await
|
|
955
|
+
const result = await this.#call(server, tool.name, params ?? {});
|
|
944
956
|
return {
|
|
945
957
|
content: [{ type: "text", text: codeAgentClip(result.text, codeAgentOutputChars) }],
|
|
946
958
|
details: undefined,
|
|
@@ -950,6 +962,59 @@ class McpToolPack2 {
|
|
|
950
962
|
});
|
|
951
963
|
}
|
|
952
964
|
}
|
|
965
|
+
async#call(server, tool, args) {
|
|
966
|
+
const client = server.client;
|
|
967
|
+
try {
|
|
968
|
+
return await client.callTool(tool, args);
|
|
969
|
+
} catch (error) {
|
|
970
|
+
if (!(error instanceof McpUnauthorized2))
|
|
971
|
+
throw error;
|
|
972
|
+
}
|
|
973
|
+
const renewed = await this.#renewed(server, client);
|
|
974
|
+
try {
|
|
975
|
+
if (renewed)
|
|
976
|
+
return await renewed.callTool(tool, args);
|
|
977
|
+
} catch (error) {
|
|
978
|
+
if (!(error instanceof McpUnauthorized2))
|
|
979
|
+
throw error;
|
|
980
|
+
McpToolPack2.#refuse(server, renewed);
|
|
981
|
+
}
|
|
982
|
+
throw new Error(`MCP server "${client.ref.name}" needs signing in \u2014 /mcp login ${client.ref.name}`);
|
|
983
|
+
}
|
|
984
|
+
static #refuse(server, client) {
|
|
985
|
+
server.refused = client;
|
|
986
|
+
server.status.auth = "required";
|
|
987
|
+
}
|
|
988
|
+
async#renewed(server, refused) {
|
|
989
|
+
if (server.client === refused && server.refused !== refused)
|
|
990
|
+
server.renewing ??= this.#renew(server, refused).finally(() => {
|
|
991
|
+
server.renewing = undefined;
|
|
992
|
+
});
|
|
993
|
+
if (server.renewing)
|
|
994
|
+
return await server.renewing;
|
|
995
|
+
return server.client === server.refused ? undefined : server.client;
|
|
996
|
+
}
|
|
997
|
+
async#renew(server, refused) {
|
|
998
|
+
const token = server.token ? await McpSignIn.retryToken(refused.ref, server.token, this.#onNotice) : undefined;
|
|
999
|
+
const client = token ? await McpToolPack2.#reopen(refused.ref, token) : undefined;
|
|
1000
|
+
if (!client) {
|
|
1001
|
+
McpToolPack2.#refuse(server, refused);
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
1004
|
+
refused.close();
|
|
1005
|
+
server.client = client;
|
|
1006
|
+
server.token = token;
|
|
1007
|
+
return client;
|
|
1008
|
+
}
|
|
1009
|
+
static async#reopen(ref, token) {
|
|
1010
|
+
try {
|
|
1011
|
+
return await new McpClient2(ref, token).connect();
|
|
1012
|
+
} catch (error) {
|
|
1013
|
+
if (error instanceof McpUnauthorized2)
|
|
1014
|
+
return;
|
|
1015
|
+
throw error;
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
953
1018
|
static #nameOf(server, tool) {
|
|
954
1019
|
return `mcp__${server.replace(/[^a-zA-Z0-9_]/g, "_")}__${tool}`;
|
|
955
1020
|
}
|
|
@@ -1172,32 +1237,27 @@ class AkanCodePlugins2 {
|
|
|
1172
1237
|
const dispose = () => mcp?.close();
|
|
1173
1238
|
const mcpStatus = mcp?.status ?? [];
|
|
1174
1239
|
const web = new WebToolPack2({ profile: options.profile });
|
|
1175
|
-
const webExtension = web.extension();
|
|
1176
1240
|
const sessions = new SessionToolPack2({
|
|
1177
1241
|
workspaceRoot: options.workspace.workspaceRoot,
|
|
1178
1242
|
cwd: options.cwd,
|
|
1179
1243
|
profile: options.profile,
|
|
1180
1244
|
currentSessionId: options.currentSessionId
|
|
1181
1245
|
});
|
|
1182
|
-
const sessionExtension = sessions.extension();
|
|
1183
1246
|
const mail = new MailToolPack2({ profile: options.profile, mailbox: options.mailbox });
|
|
1184
|
-
const mailExtension = mail.extension();
|
|
1185
1247
|
const onAsk = options.onAsk;
|
|
1186
1248
|
const ask = onAsk ? new AskToolPack({ profile: options.profile, ask: onAsk }) : undefined;
|
|
1187
|
-
const
|
|
1249
|
+
const shared = {
|
|
1250
|
+
extensions: [mcp?.extension(), web.extension(), sessions.extension(), mail.extension(), ask?.extension()].filter((entry) => !!entry),
|
|
1251
|
+
toolNames: [
|
|
1252
|
+
...mcp?.toolNames ?? [],
|
|
1253
|
+
...web.names(),
|
|
1254
|
+
...sessions.names(),
|
|
1255
|
+
...mail.names(),
|
|
1256
|
+
...ask?.names() ?? []
|
|
1257
|
+
]
|
|
1258
|
+
};
|
|
1188
1259
|
if (!options.profile.tools.akan)
|
|
1189
|
-
return {
|
|
1190
|
-
extensions: [mcp?.extension(), webExtension, sessionExtension, mailExtension, askExtension].filter((entry) => !!entry),
|
|
1191
|
-
toolNames: [
|
|
1192
|
-
...mcp?.toolNames ?? [],
|
|
1193
|
-
...web.names(),
|
|
1194
|
-
...sessions.names(),
|
|
1195
|
-
...mail.names(),
|
|
1196
|
-
...ask?.names() ?? []
|
|
1197
|
-
],
|
|
1198
|
-
mcp: mcpStatus,
|
|
1199
|
-
dispose
|
|
1200
|
-
};
|
|
1260
|
+
return { ...shared, mcp: mcpStatus, dispose };
|
|
1201
1261
|
const readOnly = !options.profile.tools.builtin.includes("write");
|
|
1202
1262
|
const pack = new AkanToolPack2({
|
|
1203
1263
|
workspace: options.workspace,
|
|
@@ -1210,6 +1270,7 @@ class AkanCodePlugins2 {
|
|
|
1210
1270
|
cwd: options.cwd,
|
|
1211
1271
|
parent: options.profile,
|
|
1212
1272
|
depth: options.depth,
|
|
1273
|
+
...options.subagentSpend ? { spend: options.subagentSpend } : {},
|
|
1213
1274
|
...options.onNotice ? { onNotice: options.onNotice } : {},
|
|
1214
1275
|
...options.onAgents ? { onAgents: options.onAgents } : {}
|
|
1215
1276
|
});
|
|
@@ -1221,27 +1282,9 @@ class AkanCodePlugins2 {
|
|
|
1221
1282
|
budget: options.profile.limits.feedback,
|
|
1222
1283
|
...options.onNotice ? { onNotice: options.onNotice } : {}
|
|
1223
1284
|
}).extension());
|
|
1224
|
-
if (mcp)
|
|
1225
|
-
extensions.push(mcp.extension());
|
|
1226
|
-
if (webExtension)
|
|
1227
|
-
extensions.push(webExtension);
|
|
1228
|
-
if (sessionExtension)
|
|
1229
|
-
extensions.push(sessionExtension);
|
|
1230
|
-
if (mailExtension)
|
|
1231
|
-
extensions.push(mailExtension);
|
|
1232
|
-
if (askExtension)
|
|
1233
|
-
extensions.push(askExtension);
|
|
1234
1285
|
return {
|
|
1235
|
-
extensions,
|
|
1236
|
-
toolNames: [
|
|
1237
|
-
...await pack.names(),
|
|
1238
|
-
...subagent ? [SubagentPool2.toolName] : [],
|
|
1239
|
-
...mcp?.toolNames ?? [],
|
|
1240
|
-
...web.names(),
|
|
1241
|
-
...sessions.names(),
|
|
1242
|
-
...mail.names(),
|
|
1243
|
-
...ask?.names() ?? []
|
|
1244
|
-
],
|
|
1286
|
+
extensions: [...extensions, ...shared.extensions],
|
|
1287
|
+
toolNames: [...await pack.names(), ...subagent ? [SubagentPool2.toolName] : [], ...shared.toolNames],
|
|
1245
1288
|
mcp: mcpStatus,
|
|
1246
1289
|
dispose
|
|
1247
1290
|
};
|
|
@@ -1420,9 +1463,38 @@ var akanSystemPrompt2 = (profile) => {
|
|
|
1420
1463
|
};
|
|
1421
1464
|
|
|
1422
1465
|
// pkgs/@akanjs/devkit/codeAgent/agent/CodeSessionIndex.ts
|
|
1423
|
-
import { existsSync as existsSync6, readdirSync as readdirSync2,
|
|
1466
|
+
import { existsSync as existsSync6, readdirSync as readdirSync2, statSync as statSync4 } from "fs";
|
|
1424
1467
|
import path6 from "path";
|
|
1425
1468
|
|
|
1469
|
+
// pkgs/@akanjs/devkit/codeAgent/agent/jsonLines.ts
|
|
1470
|
+
import { closeSync, openSync, readFileSync as readFileSync3, readSync, statSync as statSync3 } from "fs";
|
|
1471
|
+
var readHead = (file, maxBytes) => {
|
|
1472
|
+
const fd = openSync(file, "r");
|
|
1473
|
+
try {
|
|
1474
|
+
const head = Buffer.alloc(maxBytes);
|
|
1475
|
+
return head.subarray(0, readSync(fd, head, 0, maxBytes, 0)).toString("utf8");
|
|
1476
|
+
} finally {
|
|
1477
|
+
closeSync(fd);
|
|
1478
|
+
}
|
|
1479
|
+
};
|
|
1480
|
+
var readJsonLines = (file, maxBytes) => {
|
|
1481
|
+
try {
|
|
1482
|
+
const text = maxBytes !== undefined && statSync3(file).size > maxBytes ? readHead(file, maxBytes) : readFileSync3(file, "utf8");
|
|
1483
|
+
return text.split(`
|
|
1484
|
+
`).filter((line) => !!line.trim());
|
|
1485
|
+
} catch {
|
|
1486
|
+
return [];
|
|
1487
|
+
}
|
|
1488
|
+
};
|
|
1489
|
+
var parseJsonLine = (line) => {
|
|
1490
|
+
try {
|
|
1491
|
+
return JSON.parse(line);
|
|
1492
|
+
} catch {
|
|
1493
|
+
return;
|
|
1494
|
+
}
|
|
1495
|
+
};
|
|
1496
|
+
|
|
1497
|
+
// pkgs/@akanjs/devkit/codeAgent/agent/CodeSessionIndex.ts
|
|
1426
1498
|
class CodeSessionIndex2 {
|
|
1427
1499
|
static readLimit = 512 * 1024;
|
|
1428
1500
|
static list(dir, limit = 30) {
|
|
@@ -1439,18 +1511,18 @@ class CodeSessionIndex2 {
|
|
|
1439
1511
|
}
|
|
1440
1512
|
static #mtime(file) {
|
|
1441
1513
|
try {
|
|
1442
|
-
return
|
|
1514
|
+
return statSync4(file).mtimeMs;
|
|
1443
1515
|
} catch {
|
|
1444
1516
|
return 0;
|
|
1445
1517
|
}
|
|
1446
1518
|
}
|
|
1447
1519
|
static #read(file, updatedAt) {
|
|
1448
|
-
const lines =
|
|
1520
|
+
const lines = readJsonLines(file, CodeSessionIndex2.readLimit);
|
|
1449
1521
|
if (!lines.length)
|
|
1450
1522
|
return;
|
|
1451
1523
|
const entry = { id: "", file, name: undefined, opening: "", updatedAt, turns: 0 };
|
|
1452
1524
|
for (const line of lines) {
|
|
1453
|
-
const record =
|
|
1525
|
+
const record = parseJsonLine(line);
|
|
1454
1526
|
if (!record)
|
|
1455
1527
|
continue;
|
|
1456
1528
|
if (record.type === "session" && typeof record.id === "string")
|
|
@@ -1468,23 +1540,6 @@ class CodeSessionIndex2 {
|
|
|
1468
1540
|
}
|
|
1469
1541
|
return entry.id ? entry : undefined;
|
|
1470
1542
|
}
|
|
1471
|
-
static #lines(file) {
|
|
1472
|
-
try {
|
|
1473
|
-
if (statSync3(file).size > CodeSessionIndex2.readLimit)
|
|
1474
|
-
return [];
|
|
1475
|
-
return readFileSync3(file, "utf8").split(`
|
|
1476
|
-
`).filter((line) => !!line.trim());
|
|
1477
|
-
} catch {
|
|
1478
|
-
return [];
|
|
1479
|
-
}
|
|
1480
|
-
}
|
|
1481
|
-
static #parse(line) {
|
|
1482
|
-
try {
|
|
1483
|
-
return JSON.parse(line);
|
|
1484
|
-
} catch {
|
|
1485
|
-
return;
|
|
1486
|
-
}
|
|
1487
|
-
}
|
|
1488
1543
|
static #text(content) {
|
|
1489
1544
|
const text = typeof content === "string" ? content : Array.isArray(content) ? content.map((part) => typeof part === "object" && part && ("text" in part) ? String(part.text) : "").join(" ") : "";
|
|
1490
1545
|
return text.replace(/\s+/g, " ").trim();
|
|
@@ -1503,19 +1558,14 @@ class AkanCodeServices2 {
|
|
|
1503
1558
|
}
|
|
1504
1559
|
static async runtime(workspaceRoot, proxy = null) {
|
|
1505
1560
|
mkdirSync(akanCodePaths2.globalDir(), { recursive: true, mode: 448 });
|
|
1506
|
-
if (proxy) {
|
|
1507
|
-
const runtime = await ModelRuntime.create({
|
|
1508
|
-
authPath: path7.join(mkdtempSync(path7.join(tmpdir(), "akan-code-proxy-")), "auth.json"),
|
|
1509
|
-
modelsPath: akanCodePaths2.modelsFile()
|
|
1510
|
-
});
|
|
1511
|
-
await proxy.apply(runtime);
|
|
1512
|
-
return runtime;
|
|
1513
|
-
}
|
|
1514
1561
|
const runtime = await ModelRuntime.create({
|
|
1515
|
-
authPath: akanCodePaths2.authFile(),
|
|
1562
|
+
authPath: proxy ? path7.join(mkdtempSync(path7.join(tmpdir(), "akan-code-proxy-")), "auth.json") : akanCodePaths2.authFile(),
|
|
1516
1563
|
modelsPath: akanCodePaths2.modelsFile()
|
|
1517
1564
|
});
|
|
1518
|
-
|
|
1565
|
+
if (proxy)
|
|
1566
|
+
await proxy.apply(runtime);
|
|
1567
|
+
else
|
|
1568
|
+
await AkanEnvKeys2.apply(runtime, workspaceRoot);
|
|
1519
1569
|
return runtime;
|
|
1520
1570
|
}
|
|
1521
1571
|
static sessions(workspaceRoot, cwd, profile, resume) {
|
|
@@ -1582,7 +1632,7 @@ class CodeAgentAsks2 {
|
|
|
1582
1632
|
}
|
|
1583
1633
|
openQuestion(question) {
|
|
1584
1634
|
this.#question?.deferred.resolve("");
|
|
1585
|
-
const deferred =
|
|
1635
|
+
const deferred = Promise.withResolvers();
|
|
1586
1636
|
this.#question = { question, deferred };
|
|
1587
1637
|
return deferred.promise;
|
|
1588
1638
|
}
|
|
@@ -1595,7 +1645,7 @@ class CodeAgentAsks2 {
|
|
|
1595
1645
|
return true;
|
|
1596
1646
|
}
|
|
1597
1647
|
openApproval(id) {
|
|
1598
|
-
const deferred =
|
|
1648
|
+
const deferred = Promise.withResolvers();
|
|
1599
1649
|
this.#approvals.set(id, deferred);
|
|
1600
1650
|
return deferred.promise;
|
|
1601
1651
|
}
|
|
@@ -1614,13 +1664,6 @@ class CodeAgentAsks2 {
|
|
|
1614
1664
|
deferred.resolve(false);
|
|
1615
1665
|
this.#approvals.clear();
|
|
1616
1666
|
}
|
|
1617
|
-
static #defer() {
|
|
1618
|
-
let resolve = () => {};
|
|
1619
|
-
const promise = new Promise((r) => {
|
|
1620
|
-
resolve = r;
|
|
1621
|
-
});
|
|
1622
|
-
return { resolve, promise };
|
|
1623
|
-
}
|
|
1624
1667
|
}
|
|
1625
1668
|
|
|
1626
1669
|
// pkgs/@akanjs/devkit/codeAgent/agent/CodeAgentEventMapper.ts
|
|
@@ -1629,6 +1672,16 @@ import {
|
|
|
1629
1672
|
codeAgentLabelChars,
|
|
1630
1673
|
codeAgentOutputChars as codeAgentOutputChars4
|
|
1631
1674
|
} from "akanjs/common";
|
|
1675
|
+
|
|
1676
|
+
// pkgs/@akanjs/devkit/codeAgent/agent/stringArg.ts
|
|
1677
|
+
var stringArg = (args, key) => {
|
|
1678
|
+
if (!args || typeof args !== "object")
|
|
1679
|
+
return;
|
|
1680
|
+
const value = args[key];
|
|
1681
|
+
return typeof value === "string" && value ? value : undefined;
|
|
1682
|
+
};
|
|
1683
|
+
|
|
1684
|
+
// pkgs/@akanjs/devkit/codeAgent/agent/CodeAgentEventMapper.ts
|
|
1632
1685
|
var toolOps = {
|
|
1633
1686
|
read: "read",
|
|
1634
1687
|
write: "write",
|
|
@@ -1772,7 +1825,7 @@ class CodeAgentEventMapper2 {
|
|
|
1772
1825
|
return "done";
|
|
1773
1826
|
}
|
|
1774
1827
|
#summary(toolCallId, name, args) {
|
|
1775
|
-
const path =
|
|
1828
|
+
const path = stringArg(args, "path");
|
|
1776
1829
|
return {
|
|
1777
1830
|
toolCallId,
|
|
1778
1831
|
name,
|
|
@@ -1798,12 +1851,6 @@ class CodeAgentEventMapper2 {
|
|
|
1798
1851
|
return [];
|
|
1799
1852
|
return [{ type: "message", turnId: this.#turnId, role: message.role, text }];
|
|
1800
1853
|
}
|
|
1801
|
-
static #pathOf(args) {
|
|
1802
|
-
if (!args || typeof args !== "object")
|
|
1803
|
-
return;
|
|
1804
|
-
const value = args.path;
|
|
1805
|
-
return typeof value === "string" && value ? value : undefined;
|
|
1806
|
-
}
|
|
1807
1854
|
static #renderArgs(args) {
|
|
1808
1855
|
if (!args || typeof args !== "object")
|
|
1809
1856
|
return "";
|
|
@@ -1855,13 +1902,13 @@ class CodeAgentGate2 {
|
|
|
1855
1902
|
this.#deniedFragments = [...new Set((profile.paths.deny ?? []).map(CodeAgentGate2.#fragmentOf).filter(Boolean))];
|
|
1856
1903
|
}
|
|
1857
1904
|
verdict(toolName, args) {
|
|
1858
|
-
const target =
|
|
1905
|
+
const target = stringArg(args, "path");
|
|
1859
1906
|
if (target) {
|
|
1860
1907
|
const denied = this.#deniedReason(target);
|
|
1861
1908
|
if (denied)
|
|
1862
1909
|
return { block: denied };
|
|
1863
1910
|
}
|
|
1864
|
-
const command =
|
|
1911
|
+
const command = stringArg(args, "command");
|
|
1865
1912
|
if (command) {
|
|
1866
1913
|
const denied = this.#deniedCommandReason(command);
|
|
1867
1914
|
if (denied)
|
|
@@ -1906,23 +1953,11 @@ class CodeAgentGate2 {
|
|
|
1906
1953
|
const trimmed = pattern.replace(/^\*\*\//, "").replace(/\/\*\*$/, "/").replace(/^\*+/, "");
|
|
1907
1954
|
return trimmed.includes("*") ? "" : trimmed;
|
|
1908
1955
|
}
|
|
1909
|
-
static #commandOf(args) {
|
|
1910
|
-
if (!args || typeof args !== "object")
|
|
1911
|
-
return;
|
|
1912
|
-
const value = args.command;
|
|
1913
|
-
return typeof value === "string" && value ? value : undefined;
|
|
1914
|
-
}
|
|
1915
|
-
static #pathOf(args) {
|
|
1916
|
-
if (!args || typeof args !== "object")
|
|
1917
|
-
return;
|
|
1918
|
-
const value = args.path;
|
|
1919
|
-
return typeof value === "string" && value ? value : undefined;
|
|
1920
|
-
}
|
|
1921
1956
|
static #summarize(toolName, args) {
|
|
1922
1957
|
const record = args ?? {};
|
|
1923
1958
|
if (toolName === "bash")
|
|
1924
1959
|
return `run: ${String(record.command ?? "").slice(0, 200)}`;
|
|
1925
|
-
const target =
|
|
1960
|
+
const target = stringArg(args, "path");
|
|
1926
1961
|
return target ? `${toolName} ${target}` : toolName;
|
|
1927
1962
|
}
|
|
1928
1963
|
}
|
|
@@ -2106,11 +2141,10 @@ import {
|
|
|
2106
2141
|
readdirSync as readdirSync3,
|
|
2107
2142
|
readFileSync as readFileSync5,
|
|
2108
2143
|
rmSync as rmSync2,
|
|
2109
|
-
statSync as
|
|
2144
|
+
statSync as statSync5,
|
|
2110
2145
|
writeFileSync as writeFileSync2
|
|
2111
2146
|
} from "fs";
|
|
2112
2147
|
import path10 from "path";
|
|
2113
|
-
|
|
2114
2148
|
class CodeMailbox2 {
|
|
2115
2149
|
static staleMs = 20000;
|
|
2116
2150
|
static beatMs = 5000;
|
|
@@ -2134,7 +2168,7 @@ class CodeMailbox2 {
|
|
|
2134
2168
|
open(cwd, onMail) {
|
|
2135
2169
|
mkdirSync3(path10.join(this.#dir, "live"), { recursive: true });
|
|
2136
2170
|
mkdirSync3(path10.join(this.#dir, "inbox"), { recursive: true });
|
|
2137
|
-
this.#read =
|
|
2171
|
+
this.#read = readJsonLines(this.inbox).length;
|
|
2138
2172
|
this.beat(cwd);
|
|
2139
2173
|
this.#beat = setInterval(() => this.beat(cwd), CodeMailbox2.beatMs);
|
|
2140
2174
|
this.#poll = setInterval(() => {
|
|
@@ -2191,32 +2225,17 @@ class CodeMailbox2 {
|
|
|
2191
2225
|
`);
|
|
2192
2226
|
}
|
|
2193
2227
|
#drain() {
|
|
2194
|
-
const lines =
|
|
2228
|
+
const lines = readJsonLines(this.inbox);
|
|
2195
2229
|
if (lines.length <= this.#read)
|
|
2196
2230
|
return [];
|
|
2197
2231
|
const fresh = lines.slice(this.#read);
|
|
2198
2232
|
this.#read = lines.length;
|
|
2199
|
-
return fresh.map((line) =>
|
|
2233
|
+
return fresh.map((line) => parseJsonLine(line)).filter((mail) => !!mail?.text && typeof mail.from === "string");
|
|
2200
2234
|
}
|
|
2201
2235
|
static #peer(file) {
|
|
2202
2236
|
try {
|
|
2203
2237
|
const peer = JSON.parse(readFileSync5(file, "utf8"));
|
|
2204
|
-
return typeof peer.id === "string" ? { ...peer, at: peer.at ||
|
|
2205
|
-
} catch {
|
|
2206
|
-
return;
|
|
2207
|
-
}
|
|
2208
|
-
}
|
|
2209
|
-
static #lines(file) {
|
|
2210
|
-
try {
|
|
2211
|
-
return readFileSync5(file, "utf8").split(`
|
|
2212
|
-
`).filter((line) => !!line.trim());
|
|
2213
|
-
} catch {
|
|
2214
|
-
return [];
|
|
2215
|
-
}
|
|
2216
|
-
}
|
|
2217
|
-
static #parse(line) {
|
|
2218
|
-
try {
|
|
2219
|
-
return JSON.parse(line);
|
|
2238
|
+
return typeof peer.id === "string" ? { ...peer, at: peer.at || statSync5(file).mtimeMs } : undefined;
|
|
2220
2239
|
} catch {
|
|
2221
2240
|
return;
|
|
2222
2241
|
}
|
|
@@ -2239,7 +2258,7 @@ class CodeSessionFork2 {
|
|
|
2239
2258
|
throw new Error(`Session ${id} has nothing in it to fork`);
|
|
2240
2259
|
const at = new Date;
|
|
2241
2260
|
const forked = Bun.randomUUIDv7();
|
|
2242
|
-
const records = lines.map((line) =>
|
|
2261
|
+
const records = lines.map((line) => parseJsonLine(line)).filter((record) => !!record);
|
|
2243
2262
|
const first = records.find((record) => record.type === "session");
|
|
2244
2263
|
if (!first)
|
|
2245
2264
|
throw new Error(`Session ${id} carries no session record`);
|
|
@@ -2267,13 +2286,6 @@ class CodeSessionFork2 {
|
|
|
2267
2286
|
const current = typeof named?.name === "string" ? named.name : "";
|
|
2268
2287
|
return codeAgentSessionName(current ? `${current} fork` : "fork");
|
|
2269
2288
|
}
|
|
2270
|
-
static #parse(line) {
|
|
2271
|
-
try {
|
|
2272
|
-
return JSON.parse(line);
|
|
2273
|
-
} catch {
|
|
2274
|
-
return;
|
|
2275
|
-
}
|
|
2276
|
-
}
|
|
2277
2289
|
}
|
|
2278
2290
|
|
|
2279
2291
|
// pkgs/@akanjs/devkit/codeAgent/agent/CodeAgent.ts
|
|
@@ -2315,6 +2327,7 @@ class CodeAgent2 {
|
|
|
2315
2327
|
apps: options.apps ?? [],
|
|
2316
2328
|
canSeeImages: akanCodeModelSupportsImages2(model),
|
|
2317
2329
|
depth: options.depth ?? 0,
|
|
2330
|
+
...options.subagentSpend ? { subagentSpend: options.subagentSpend } : {},
|
|
2318
2331
|
currentSessionId: () => agent.sessionId,
|
|
2319
2332
|
mailbox: () => agent.#mailbox,
|
|
2320
2333
|
onNotice: (message) => agent.#emit({ type: "notice", level: "warning", message }),
|
|
@@ -2395,7 +2408,7 @@ class CodeAgent2 {
|
|
|
2395
2408
|
this.#mailbox.open(cwd, (mail) => {
|
|
2396
2409
|
const from = `${mail.fromName} (${mail.from.slice(0, 8)})`;
|
|
2397
2410
|
this.#emit({ type: "notice", level: "info", message: `message from ${from}` });
|
|
2398
|
-
this
|
|
2411
|
+
this.#prompt(`Message from another session \u2014 ${from}:
|
|
2399
2412
|
${mail.text}`).catch((error) => this.#emit({ type: "notice", level: "error", message: String(error) }));
|
|
2400
2413
|
});
|
|
2401
2414
|
}
|
|
@@ -2465,6 +2478,10 @@ ${mail.text}`).catch((error) => this.#emit({ type: "notice", level: "error", mes
|
|
|
2465
2478
|
return { ...base, frames: this.#replay.filter((event) => event.seq > sinceSeq) };
|
|
2466
2479
|
}
|
|
2467
2480
|
async prompt(message, images) {
|
|
2481
|
+
this.#suspended.clear();
|
|
2482
|
+
await this.#prompt(message, images);
|
|
2483
|
+
}
|
|
2484
|
+
async#prompt(message, images) {
|
|
2468
2485
|
const session = this.#require();
|
|
2469
2486
|
if (!session.sessionName && message.trim())
|
|
2470
2487
|
this.setName(codeAgentSessionName2(message));
|
|
@@ -2493,7 +2510,7 @@ ${mail.text}`).catch((error) => this.#emit({ type: "notice", level: "error", mes
|
|
|
2493
2510
|
return false;
|
|
2494
2511
|
const suspendedRendered = codeAgentRenderAnswer(suspended, answer);
|
|
2495
2512
|
this.#emit({ type: "question_resolved", questionId, answer, rendered: suspendedRendered });
|
|
2496
|
-
await this
|
|
2513
|
+
await this.#prompt(`The user answered: ${suspendedRendered}
|
|
2497
2514
|
Continue the task.`);
|
|
2498
2515
|
return true;
|
|
2499
2516
|
}
|
|
@@ -2508,7 +2525,7 @@ Continue the task.`);
|
|
|
2508
2525
|
return false;
|
|
2509
2526
|
this.#emit({ type: "approval_resolved", approvalId, approved });
|
|
2510
2527
|
if (approved)
|
|
2511
|
-
await this
|
|
2528
|
+
await this.#prompt("The user approved the pending action. Retry it and continue.");
|
|
2512
2529
|
return true;
|
|
2513
2530
|
}
|
|
2514
2531
|
async compact(instructions) {
|
|
@@ -2583,7 +2600,8 @@ Continue the task.`);
|
|
|
2583
2600
|
session.subscribe((event) => {
|
|
2584
2601
|
for (const body of this.#mapper.map(event))
|
|
2585
2602
|
this.#emit(body);
|
|
2586
|
-
|
|
2603
|
+
if (event.type === "agent_end" || event.type === "compaction_end")
|
|
2604
|
+
this.#emitContextNow();
|
|
2587
2605
|
});
|
|
2588
2606
|
await session.bindExtensions({
|
|
2589
2607
|
mode,
|
|
@@ -2606,11 +2624,6 @@ Continue the task.`);
|
|
|
2606
2624
|
};
|
|
2607
2625
|
}));
|
|
2608
2626
|
}
|
|
2609
|
-
#emitContextUsage(eventType) {
|
|
2610
|
-
if (eventType !== "agent_end" && eventType !== "compaction_end")
|
|
2611
|
-
return;
|
|
2612
|
-
this.#emitContextNow();
|
|
2613
|
-
}
|
|
2614
2627
|
#emitContextNow() {
|
|
2615
2628
|
const usage = this.#session?.getContextUsage();
|
|
2616
2629
|
if (usage?.tokens == null)
|