@akanjs/cli 3.0.0-beta.18 → 3.0.0-beta.19
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-0035exh3.js → CodeAgent-6cm97kay.js} +2 -2
- package/{CodeAgentRpcHost-qvwfv0n9.js → CodeAgentRpcHost-p7h6n2hp.js} +1 -1
- package/CodeAgentRpcListener-7p7z5dd7.js +97 -0
- package/{CodeTui-eweg1hep.js → CodeTui-za4jsm41.js} +1 -1
- package/{TunnelShare-r5tc2qk5.js → TunnelShare-2j6s511d.js} +2 -2
- package/{agent.command-65zqfkg0.js → agent.command-e0wpbbyg.js} +5 -5
- package/akanCode.js +4 -4
- package/{application.command-2wcj5da3.js → application.command-8wyxqc8q.js} +15 -9
- package/{applicationBuildRunner-m0hhgwsx.js → applicationBuildRunner-n9gzaxd0.js} +31 -7
- package/{applicationReleasePackager-vykfzgx3.js → applicationReleasePackager-vpggfqgq.js} +1 -1
- package/buildBatch.proc.js +3 -3
- package/{capacitorApp-2daqhb5h.js → capacitorApp-q3z0qht0.js} +2 -2
- package/{cloud.command-960bgbf4.js → cloud.command-4zwa5dsx.js} +34 -12
- package/cloud.script-fwx3vb34.js +20 -0
- package/{code.command-4feh3ef7.js → code.command-468c9d7s.js} +41 -19
- package/commandManifest.json +1 -1
- package/{context.command-kzehkx48.js → context.command-dsnw0jby.js} +13 -13
- package/context.runner-rs4rj15d.js +22 -0
- package/{dependencyScanner-shs82ynp.js → dependencyScanner-0z2h2tks.js} +1 -1
- package/{guideline.command-3w2g20x4.js → guideline.command-vhw13pqr.js} +2 -2
- package/guidelines/agentRule/agentRule.instruction.md +27 -10
- package/guidelines/conventions/conventions.instruction.md +16 -4
- package/guidelines/queryRule/queryRule.instruction.md +16 -6
- package/guidelines/runtimeRule/runtimeRule.instruction.md +74 -0
- package/incrementalBuilder.proc.js +3 -2
- package/{index-dw943k93.js → index-10dkrrww.js} +4 -4
- package/{index-rpgxs245.js → index-18zybgkc.js} +2 -2
- package/{index-mt2154s2.js → index-22xtgmhn.js} +1 -1
- package/{index-yw6g3bbv.js → index-2446k7b4.js} +1 -1
- package/{index-cjw1sj1x.js → index-3jrp517k.js} +10 -10
- package/{index-q9c3c0hy.js → index-4m929vvn.js} +2 -2
- package/{index-ef228gzf.js → index-53176s7j.js} +3 -3
- package/{index-jwrpsrg3.js → index-667w0yah.js} +1 -1
- package/{index-6q589y9t.js → index-7ep8qtvp.js} +2 -2
- package/{index-w8kmx1b6.js → index-89hy31kf.js} +30 -7
- package/{index-jd01kj5r.js → index-9d6nvkz2.js} +1 -1
- package/{index-zq0mr3hh.js → index-a1w6934z.js} +3 -3
- package/{index-sbfk9daf.js → index-ab0c38ea.js} +4 -4
- package/index-bc88j1ry.js +1166 -0
- package/{index-h94faz96.js → index-bftkz6cp.js} +274 -60
- package/{index-kcxmv48c.js → index-bhtmj233.js} +4 -1
- package/{index-m41ptvat.js → index-bwf965h6.js} +3 -3
- package/{index-bwxpk2cj.js → index-crmeqnmf.js} +52 -26
- package/{index-8k16atqy.js → index-d2242ksy.js} +23 -6
- package/{index-jwexzh42.js → index-e4v6vhxq.js} +222 -56
- package/{index-pn8mhpps.js → index-esk82rvk.js} +4 -4
- package/{index-4r42ext5.js → index-kwaq3n9n.js} +1 -1
- package/{index-gm76f0qb.js → index-n3cv0tm4.js} +1 -1
- package/{index-ycy302an.js → index-qdgzsnhg.js} +1 -1
- package/{index-wcg582a8.js → index-sq2dzkzm.js} +35 -10
- package/{index-myj01w9r.js → index-srmay5jw.js} +15 -2
- package/{index-zmj143x7.js → index-txr7dj2g.js} +3 -3
- package/{index-erfc1x40.js → index-vqx8bdxz.js} +1 -1
- package/{index-d9fjz06h.js → index-zqgj2rt2.js} +4 -4
- package/index.js +21 -21
- package/{library.command-fp0nhr62.js → library.command-cqr175dy.js} +3 -3
- package/{localRegistry.command-8y0ecxb9.js → localRegistry.command-49z55qqz.js} +9 -9
- package/{module.command-kqkn48t2.js → module.command-9p8mm3b0.js} +5 -5
- package/{package.command-qverjh22.js → package.command-wxyz909t.js} +4 -4
- package/package.json +2 -2
- package/{page.command-94bwhd0g.js → page.command-gsrsfqqs.js} +3 -3
- package/{primitive.command-2ydvtah2.js → primitive.command-ns1mptje.js} +6 -6
- package/{quality.command-fa0gth4p.js → quality.command-e76k2q9k.js} +17 -15
- package/{repair.command-4qng2hpm.js → repair.command-pkrsm3cw.js} +5 -5
- package/{scalar.command-pb2y95sh.js → scalar.command-0cpt3fc8.js} +4 -4
- package/{subspace.command-vkxmwp74.js → subspace.command-fktpwp0g.js} +20 -10
- package/templates/appSample/lib/task/task.signal.test.ts +1 -1
- package/templates/localDev/docker-compose.yaml.template +3 -14
- package/{tunnel.command-02cvp9nf.js → tunnel.command-d5jy9gk8.js} +4 -4
- package/{workflow.command-132txnrh.js → workflow.command-6tkcysmx.js} +9 -9
- package/{workspace.command-d5wkswek.js → workspace.command-gv84eh1p.js} +24 -23
- package/cloud.script-qhcnqt1n.js +0 -20
- package/context.runner-z0rrcz7b.js +0 -22
- package/index-3hpxeys1.js +0 -462
|
@@ -4,20 +4,20 @@ import {
|
|
|
4
4
|
akanCodePaths2,
|
|
5
5
|
McpServerConfig,
|
|
6
6
|
McpSignIn
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-9d6nvkz2.js";
|
|
8
8
|
import {
|
|
9
9
|
stripAnsi
|
|
10
10
|
} from "./index-7md2g9vw.js";
|
|
11
11
|
import {
|
|
12
|
+
akanCodeDefaultModel2,
|
|
12
13
|
akanCodeModel2,
|
|
13
14
|
akanCodeModelSupportsImages2,
|
|
14
15
|
akanCodeModelWarnings2
|
|
15
|
-
} from "./index-
|
|
16
|
+
} from "./index-667w0yah.js";
|
|
16
17
|
|
|
17
18
|
// pkgs/@akanjs/devkit/codeAgent/agent/CodeAgent.ts
|
|
18
19
|
import {
|
|
19
20
|
createAgentSession,
|
|
20
|
-
DEFAULT_COMPACTION_SETTINGS,
|
|
21
21
|
DefaultResourceLoader
|
|
22
22
|
} from "@earendil-works/pi-coding-agent";
|
|
23
23
|
import {
|
|
@@ -514,7 +514,7 @@ class AkanToolPack2 {
|
|
|
514
514
|
return { name: "akan-tools", factory: async (pi) => await this.#register(pi) };
|
|
515
515
|
}
|
|
516
516
|
async names() {
|
|
517
|
-
const { ContextRunner } = await import("./context.runner-
|
|
517
|
+
const { ContextRunner } = await import("./context.runner-rs4rj15d.js");
|
|
518
518
|
return [
|
|
519
519
|
...new ContextRunner().listMcpTools(this.#options.mode).map((tool) => tool.name),
|
|
520
520
|
AkanToolPack2.verifyToolName
|
|
@@ -522,7 +522,7 @@ class AkanToolPack2 {
|
|
|
522
522
|
}
|
|
523
523
|
static verifyToolName = "akan_verify";
|
|
524
524
|
async#register(pi) {
|
|
525
|
-
const { ContextRunner } = await import("./context.runner-
|
|
525
|
+
const { ContextRunner } = await import("./context.runner-rs4rj15d.js");
|
|
526
526
|
const runner = new ContextRunner;
|
|
527
527
|
const guidelineNames = await AkanToolPack2.#guidelineNames();
|
|
528
528
|
for (const tool of runner.listMcpTools(this.#options.mode, { guidelineNames })) {
|
|
@@ -1272,7 +1272,9 @@ class AkanCodePlugins2 {
|
|
|
1272
1272
|
}
|
|
1273
1273
|
|
|
1274
1274
|
// pkgs/@akanjs/devkit/codeAgent/agent/AkanCodeServices.ts
|
|
1275
|
-
import { existsSync as existsSync7, mkdirSync } from "fs";
|
|
1275
|
+
import { existsSync as existsSync7, mkdirSync, mkdtempSync } from "fs";
|
|
1276
|
+
import { tmpdir } from "os";
|
|
1277
|
+
import path7 from "path";
|
|
1276
1278
|
import { ModelRuntime, SessionManager as SessionManager2, SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
1277
1279
|
|
|
1278
1280
|
// pkgs/@akanjs/devkit/codeAgent/tools/AkanEnvKeys.ts
|
|
@@ -1495,11 +1497,20 @@ class AkanCodeServices2 {
|
|
|
1495
1497
|
return SettingsManager.inMemory({
|
|
1496
1498
|
enableInstallTelemetry: false,
|
|
1497
1499
|
enableAnalytics: false,
|
|
1498
|
-
quietStartup: true
|
|
1500
|
+
quietStartup: true,
|
|
1501
|
+
compaction: { reserveTokens: 32768 }
|
|
1499
1502
|
});
|
|
1500
1503
|
}
|
|
1501
|
-
static async runtime(workspaceRoot) {
|
|
1504
|
+
static async runtime(workspaceRoot, proxy = null) {
|
|
1502
1505
|
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
|
+
}
|
|
1503
1514
|
const runtime = await ModelRuntime.create({
|
|
1504
1515
|
authPath: akanCodePaths2.authFile(),
|
|
1505
1516
|
modelsPath: akanCodePaths2.modelsFile()
|
|
@@ -1508,7 +1519,7 @@ class AkanCodeServices2 {
|
|
|
1508
1519
|
return runtime;
|
|
1509
1520
|
}
|
|
1510
1521
|
static sessions(workspaceRoot, cwd, profile, resume) {
|
|
1511
|
-
if (profile.session.store
|
|
1522
|
+
if (profile.session.store === "memory")
|
|
1512
1523
|
return SessionManager2.inMemory(cwd);
|
|
1513
1524
|
const dir = akanCodePaths2.sessionsDir(workspaceRoot);
|
|
1514
1525
|
mkdirSync(dir, { recursive: true });
|
|
@@ -1555,6 +1566,7 @@ class CodeAgentAsks2 {
|
|
|
1555
1566
|
#question;
|
|
1556
1567
|
#approvals = new Map;
|
|
1557
1568
|
#nextId = 0;
|
|
1569
|
+
#epoch = Date.now().toString(36);
|
|
1558
1570
|
get pendingQuestionId() {
|
|
1559
1571
|
return this.#question?.question.questionId;
|
|
1560
1572
|
}
|
|
@@ -1566,7 +1578,7 @@ class CodeAgentAsks2 {
|
|
|
1566
1578
|
}
|
|
1567
1579
|
nextId(prefix) {
|
|
1568
1580
|
this.#nextId += 1;
|
|
1569
|
-
return `${prefix}${this.#nextId}`;
|
|
1581
|
+
return `${prefix}${this.#epoch}.${this.#nextId}`;
|
|
1570
1582
|
}
|
|
1571
1583
|
openQuestion(question) {
|
|
1572
1584
|
this.#question?.deferred.resolve("");
|
|
@@ -1675,7 +1687,15 @@ class CodeAgentEventMapper2 {
|
|
|
1675
1687
|
case "compaction_start":
|
|
1676
1688
|
return [{ type: "compaction", phase: "start", reason: event.reason }];
|
|
1677
1689
|
case "compaction_end":
|
|
1678
|
-
return [
|
|
1690
|
+
return [
|
|
1691
|
+
{
|
|
1692
|
+
type: "compaction",
|
|
1693
|
+
phase: "end",
|
|
1694
|
+
reason: event.reason,
|
|
1695
|
+
...event.errorMessage ? { error: event.errorMessage } : {},
|
|
1696
|
+
...event.aborted ? { aborted: true } : {}
|
|
1697
|
+
}
|
|
1698
|
+
];
|
|
1679
1699
|
case "auto_retry_start":
|
|
1680
1700
|
return [
|
|
1681
1701
|
{
|
|
@@ -1819,7 +1839,7 @@ class CodeAgentEventMapper2 {
|
|
|
1819
1839
|
}
|
|
1820
1840
|
|
|
1821
1841
|
// pkgs/@akanjs/devkit/codeAgent/agent/CodeAgentGate.ts
|
|
1822
|
-
import
|
|
1842
|
+
import path8 from "path";
|
|
1823
1843
|
var writeTools = new Set(["write", "edit"]);
|
|
1824
1844
|
var commandTools = new Set(["bash"]);
|
|
1825
1845
|
|
|
@@ -1858,9 +1878,9 @@ class CodeAgentGate2 {
|
|
|
1858
1878
|
return `The command names "${hit}", which the profile's deny list covers. Ask the user for the value instead of reading the file.`;
|
|
1859
1879
|
}
|
|
1860
1880
|
#deniedReason(target) {
|
|
1861
|
-
const absolute =
|
|
1862
|
-
const relative =
|
|
1863
|
-
if (relative.startsWith("..") ||
|
|
1881
|
+
const absolute = path8.isAbsolute(target) ? target : path8.resolve(this.#profile.paths.root, target);
|
|
1882
|
+
const relative = path8.relative(this.#profile.paths.root, absolute);
|
|
1883
|
+
if (relative.startsWith("..") || path8.isAbsolute(relative))
|
|
1864
1884
|
return `Path is outside the agent root (${this.#profile.paths.root}).`;
|
|
1865
1885
|
if (this.#deny.some((glob) => glob.match(absolute) || glob.match(relative)))
|
|
1866
1886
|
return "Path is on the profile's deny list (secrets and environment files are never readable).";
|
|
@@ -1907,6 +1927,137 @@ class CodeAgentGate2 {
|
|
|
1907
1927
|
}
|
|
1908
1928
|
}
|
|
1909
1929
|
|
|
1930
|
+
// pkgs/@akanjs/devkit/codeAgent/agent/CodeAgentProxy.ts
|
|
1931
|
+
import { readFile } from "fs/promises";
|
|
1932
|
+
class CodeAgentProxy {
|
|
1933
|
+
static placeholderKey = "akan-code-proxy";
|
|
1934
|
+
baseUrl;
|
|
1935
|
+
providers;
|
|
1936
|
+
#tokenFile;
|
|
1937
|
+
#token;
|
|
1938
|
+
constructor({ baseUrl, providers, tokenFile, token }) {
|
|
1939
|
+
this.baseUrl = baseUrl.replace(/\/+$/, "");
|
|
1940
|
+
this.providers = providers;
|
|
1941
|
+
this.#tokenFile = tokenFile;
|
|
1942
|
+
this.#token = token;
|
|
1943
|
+
if (!tokenFile && !token)
|
|
1944
|
+
throw new Error("AKAN_CODE_PROXY_URL needs AKAN_CODE_PROXY_TOKEN_FILE or AKAN_CODE_PROXY_TOKEN");
|
|
1945
|
+
}
|
|
1946
|
+
static fromEnv(profile) {
|
|
1947
|
+
const baseUrl = process.env.AKAN_CODE_PROXY_URL?.trim() || profile?.network.proxyBaseUrl;
|
|
1948
|
+
if (!baseUrl)
|
|
1949
|
+
return null;
|
|
1950
|
+
const providers = (process.env.AKAN_CODE_PROXY_PROVIDERS ?? akanCodeDefaultModel2.provider).split(",").map((provider) => provider.trim()).filter(Boolean);
|
|
1951
|
+
return new CodeAgentProxy({
|
|
1952
|
+
baseUrl,
|
|
1953
|
+
providers,
|
|
1954
|
+
tokenFile: process.env.AKAN_CODE_PROXY_TOKEN_FILE?.trim() || undefined,
|
|
1955
|
+
token: process.env.AKAN_CODE_PROXY_TOKEN?.trim() || undefined
|
|
1956
|
+
});
|
|
1957
|
+
}
|
|
1958
|
+
baseUrlFor(provider) {
|
|
1959
|
+
return this.baseUrl.replaceAll("{provider}", provider);
|
|
1960
|
+
}
|
|
1961
|
+
async token() {
|
|
1962
|
+
if (!this.#tokenFile)
|
|
1963
|
+
return this.#token ?? "";
|
|
1964
|
+
const token = (await readFile(this.#tokenFile, "utf8")).trim();
|
|
1965
|
+
if (!token)
|
|
1966
|
+
throw new Error(`${this.#tokenFile} is empty`);
|
|
1967
|
+
return token;
|
|
1968
|
+
}
|
|
1969
|
+
async apply(runtime) {
|
|
1970
|
+
const target = runtime;
|
|
1971
|
+
const original = target.prepareRequest?.bind(runtime);
|
|
1972
|
+
if (!original)
|
|
1973
|
+
throw new Error("The model runtime no longer exposes prepareRequest; update CodeAgentProxy");
|
|
1974
|
+
for (const provider of this.providers)
|
|
1975
|
+
await runtime.setRuntimeApiKey(provider, CodeAgentProxy.placeholderKey);
|
|
1976
|
+
target.prepareRequest = async (model, options = {}) => {
|
|
1977
|
+
const apiKey = await this.token();
|
|
1978
|
+
const prepared = await original(model, { ...options, apiKey });
|
|
1979
|
+
return {
|
|
1980
|
+
...prepared,
|
|
1981
|
+
model: { ...prepared.model, baseUrl: this.baseUrlFor(prepared.model.provider) },
|
|
1982
|
+
options: { ...prepared.options, apiKey }
|
|
1983
|
+
};
|
|
1984
|
+
};
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
|
|
1988
|
+
// pkgs/@akanjs/devkit/codeAgent/agent/CodeAgentSuspended.ts
|
|
1989
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync2, readFileSync as readFileSync4, rmSync, writeFileSync } from "fs";
|
|
1990
|
+
import path9 from "path";
|
|
1991
|
+
|
|
1992
|
+
class CodeAgentSuspended {
|
|
1993
|
+
#file;
|
|
1994
|
+
#state;
|
|
1995
|
+
constructor(file) {
|
|
1996
|
+
this.#file = file;
|
|
1997
|
+
this.#state = CodeAgentSuspended.#read(file);
|
|
1998
|
+
}
|
|
1999
|
+
static fileOf(sessionDir, sessionId) {
|
|
2000
|
+
return sessionDir ? path9.join(sessionDir, `${sessionId}.suspended.json`) : null;
|
|
2001
|
+
}
|
|
2002
|
+
get question() {
|
|
2003
|
+
return this.#state.question;
|
|
2004
|
+
}
|
|
2005
|
+
get approvals() {
|
|
2006
|
+
return this.#state.approvals;
|
|
2007
|
+
}
|
|
2008
|
+
setQuestion(question) {
|
|
2009
|
+
this.#state = { ...this.#state, question };
|
|
2010
|
+
this.#save();
|
|
2011
|
+
}
|
|
2012
|
+
addApproval(request) {
|
|
2013
|
+
this.#state = { ...this.#state, approvals: [...this.#state.approvals, request] };
|
|
2014
|
+
this.#save();
|
|
2015
|
+
}
|
|
2016
|
+
takeQuestion(questionId) {
|
|
2017
|
+
const question = this.#state.question;
|
|
2018
|
+
if (question?.questionId !== questionId)
|
|
2019
|
+
return;
|
|
2020
|
+
this.#state = { approvals: this.#state.approvals };
|
|
2021
|
+
this.#save();
|
|
2022
|
+
return question;
|
|
2023
|
+
}
|
|
2024
|
+
takeApproval(approvalId) {
|
|
2025
|
+
const request = this.#state.approvals.find((approval) => approval.approvalId === approvalId);
|
|
2026
|
+
if (!request)
|
|
2027
|
+
return;
|
|
2028
|
+
this.#state = { ...this.#state, approvals: this.#state.approvals.filter((approval) => approval !== request) };
|
|
2029
|
+
this.#save();
|
|
2030
|
+
return request;
|
|
2031
|
+
}
|
|
2032
|
+
clear() {
|
|
2033
|
+
if (!this.#state.question && !this.#state.approvals.length)
|
|
2034
|
+
return;
|
|
2035
|
+
this.#state = { approvals: [] };
|
|
2036
|
+
this.#save();
|
|
2037
|
+
}
|
|
2038
|
+
#save() {
|
|
2039
|
+
if (!this.#file)
|
|
2040
|
+
return;
|
|
2041
|
+
if (!this.#state.question && !this.#state.approvals.length) {
|
|
2042
|
+
rmSync(this.#file, { force: true });
|
|
2043
|
+
return;
|
|
2044
|
+
}
|
|
2045
|
+
mkdirSync2(path9.dirname(this.#file), { recursive: true });
|
|
2046
|
+
writeFileSync(this.#file, `${JSON.stringify(this.#state)}
|
|
2047
|
+
`);
|
|
2048
|
+
}
|
|
2049
|
+
static #read(file) {
|
|
2050
|
+
if (!file || !existsSync8(file))
|
|
2051
|
+
return { approvals: [] };
|
|
2052
|
+
try {
|
|
2053
|
+
const parsed = JSON.parse(readFileSync4(file, "utf8"));
|
|
2054
|
+
return { ...parsed.question ? { question: parsed.question } : {}, approvals: parsed.approvals ?? [] };
|
|
2055
|
+
} catch {
|
|
2056
|
+
return { approvals: [] };
|
|
2057
|
+
}
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
|
|
1910
2061
|
// pkgs/@akanjs/devkit/codeAgent/agent/CodeAgentUi.ts
|
|
1911
2062
|
class CodeAgentUi2 {
|
|
1912
2063
|
#handlers;
|
|
@@ -1950,15 +2101,15 @@ class CodeAgentUi2 {
|
|
|
1950
2101
|
// pkgs/@akanjs/devkit/codeAgent/agent/CodeMailbox.ts
|
|
1951
2102
|
import {
|
|
1952
2103
|
appendFileSync,
|
|
1953
|
-
existsSync as
|
|
1954
|
-
mkdirSync as
|
|
2104
|
+
existsSync as existsSync9,
|
|
2105
|
+
mkdirSync as mkdirSync3,
|
|
1955
2106
|
readdirSync as readdirSync3,
|
|
1956
|
-
readFileSync as
|
|
1957
|
-
rmSync,
|
|
2107
|
+
readFileSync as readFileSync5,
|
|
2108
|
+
rmSync as rmSync2,
|
|
1958
2109
|
statSync as statSync4,
|
|
1959
|
-
writeFileSync
|
|
2110
|
+
writeFileSync as writeFileSync2
|
|
1960
2111
|
} from "fs";
|
|
1961
|
-
import
|
|
2112
|
+
import path10 from "path";
|
|
1962
2113
|
|
|
1963
2114
|
class CodeMailbox2 {
|
|
1964
2115
|
static staleMs = 20000;
|
|
@@ -1978,11 +2129,11 @@ class CodeMailbox2 {
|
|
|
1978
2129
|
this.#name = name;
|
|
1979
2130
|
}
|
|
1980
2131
|
get inbox() {
|
|
1981
|
-
return
|
|
2132
|
+
return path10.join(this.#dir, "inbox", `${this.#id}.jsonl`);
|
|
1982
2133
|
}
|
|
1983
2134
|
open(cwd, onMail) {
|
|
1984
|
-
|
|
1985
|
-
|
|
2135
|
+
mkdirSync3(path10.join(this.#dir, "live"), { recursive: true });
|
|
2136
|
+
mkdirSync3(path10.join(this.#dir, "inbox"), { recursive: true });
|
|
1986
2137
|
this.#read = CodeMailbox2.#lines(this.inbox).length;
|
|
1987
2138
|
this.beat(cwd);
|
|
1988
2139
|
this.#beat = setInterval(() => this.beat(cwd), CodeMailbox2.beatMs);
|
|
@@ -1999,7 +2150,7 @@ class CodeMailbox2 {
|
|
|
1999
2150
|
this.#beat = null;
|
|
2000
2151
|
this.#poll = null;
|
|
2001
2152
|
try {
|
|
2002
|
-
|
|
2153
|
+
rmSync2(path10.join(this.#dir, "live", `${this.#id}.json`), { force: true });
|
|
2003
2154
|
} catch {}
|
|
2004
2155
|
}
|
|
2005
2156
|
rename(name, cwd) {
|
|
@@ -2009,15 +2160,15 @@ class CodeMailbox2 {
|
|
|
2009
2160
|
beat(cwd) {
|
|
2010
2161
|
const peer = { id: this.#id, name: this.#name, cwd, pid: process.pid, at: Date.now() };
|
|
2011
2162
|
try {
|
|
2012
|
-
|
|
2163
|
+
writeFileSync2(path10.join(this.#dir, "live", `${this.#id}.json`), JSON.stringify(peer));
|
|
2013
2164
|
} catch {}
|
|
2014
2165
|
}
|
|
2015
2166
|
peers() {
|
|
2016
|
-
const dir =
|
|
2017
|
-
if (!
|
|
2167
|
+
const dir = path10.join(this.#dir, "live");
|
|
2168
|
+
if (!existsSync9(dir))
|
|
2018
2169
|
return [];
|
|
2019
2170
|
const now = Date.now();
|
|
2020
|
-
return readdirSync3(dir).filter((entry) => entry.endsWith(".json")).map((entry) => CodeMailbox2.#peer(
|
|
2171
|
+
return readdirSync3(dir).filter((entry) => entry.endsWith(".json")).map((entry) => CodeMailbox2.#peer(path10.join(dir, entry))).filter((peer) => !!peer && peer.id !== this.#id && now - peer.at < CodeMailbox2.staleMs).sort((left, right) => right.at - left.at);
|
|
2021
2172
|
}
|
|
2022
2173
|
find(target) {
|
|
2023
2174
|
const needle = target.trim().toLowerCase();
|
|
@@ -2035,8 +2186,8 @@ class CodeMailbox2 {
|
|
|
2035
2186
|
throw new Error(`Too many messages: ${CodeMailbox2.sendsPerMinute} a minute is the ceiling.`);
|
|
2036
2187
|
this.#sent.push(now);
|
|
2037
2188
|
const mail = { at: now, from: this.#id, fromName: this.#name, text };
|
|
2038
|
-
|
|
2039
|
-
appendFileSync(
|
|
2189
|
+
mkdirSync3(path10.join(this.#dir, "inbox"), { recursive: true });
|
|
2190
|
+
appendFileSync(path10.join(this.#dir, "inbox", `${to}.jsonl`), `${JSON.stringify(mail)}
|
|
2040
2191
|
`);
|
|
2041
2192
|
}
|
|
2042
2193
|
#drain() {
|
|
@@ -2049,7 +2200,7 @@ class CodeMailbox2 {
|
|
|
2049
2200
|
}
|
|
2050
2201
|
static #peer(file) {
|
|
2051
2202
|
try {
|
|
2052
|
-
const peer = JSON.parse(
|
|
2203
|
+
const peer = JSON.parse(readFileSync5(file, "utf8"));
|
|
2053
2204
|
return typeof peer.id === "string" ? { ...peer, at: peer.at || statSync4(file).mtimeMs } : undefined;
|
|
2054
2205
|
} catch {
|
|
2055
2206
|
return;
|
|
@@ -2057,7 +2208,7 @@ class CodeMailbox2 {
|
|
|
2057
2208
|
}
|
|
2058
2209
|
static #lines(file) {
|
|
2059
2210
|
try {
|
|
2060
|
-
return
|
|
2211
|
+
return readFileSync5(file, "utf8").split(`
|
|
2061
2212
|
`).filter((line) => !!line.trim());
|
|
2062
2213
|
} catch {
|
|
2063
2214
|
return [];
|
|
@@ -2074,15 +2225,15 @@ class CodeMailbox2 {
|
|
|
2074
2225
|
|
|
2075
2226
|
// pkgs/@akanjs/devkit/codeAgent/agent/CodeSessionFork.ts
|
|
2076
2227
|
import { randomBytes } from "crypto";
|
|
2077
|
-
import { readFileSync as
|
|
2078
|
-
import
|
|
2228
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
|
|
2229
|
+
import path11 from "path";
|
|
2079
2230
|
import { codeAgentSessionName } from "akanjs/common";
|
|
2080
2231
|
class CodeSessionFork2 {
|
|
2081
2232
|
static fork(dir, id, name) {
|
|
2082
2233
|
const source = CodeSessionIndex2.fileOf(dir, id);
|
|
2083
2234
|
if (!source)
|
|
2084
2235
|
throw new Error(`No stored session ${id} in ${dir}`);
|
|
2085
|
-
const lines =
|
|
2236
|
+
const lines = readFileSync6(source, "utf8").split(`
|
|
2086
2237
|
`).filter((line) => !!line.trim());
|
|
2087
2238
|
if (!lines.length)
|
|
2088
2239
|
throw new Error(`Session ${id} has nothing in it to fork`);
|
|
@@ -2095,8 +2246,8 @@ class CodeSessionFork2 {
|
|
|
2095
2246
|
first.id = forked;
|
|
2096
2247
|
first.timestamp = at.toISOString();
|
|
2097
2248
|
records.push(CodeSessionFork2.#named(records, name ?? CodeSessionFork2.#nameOf(records), at));
|
|
2098
|
-
const file =
|
|
2099
|
-
|
|
2249
|
+
const file = path11.join(dir, `${at.toISOString().replace(/[:.]/g, "-")}_${forked}.jsonl`);
|
|
2250
|
+
writeFileSync3(file, `${records.map((record) => JSON.stringify(record)).join(`
|
|
2100
2251
|
`)}
|
|
2101
2252
|
`);
|
|
2102
2253
|
return { id: forked, file };
|
|
@@ -2131,6 +2282,7 @@ class CodeAgent2 {
|
|
|
2131
2282
|
#gate;
|
|
2132
2283
|
#mapper = new CodeAgentEventMapper2;
|
|
2133
2284
|
#asks = new CodeAgentAsks2;
|
|
2285
|
+
#suspended = new CodeAgentSuspended(null);
|
|
2134
2286
|
#listeners = new Set;
|
|
2135
2287
|
#session;
|
|
2136
2288
|
#disposePlugins;
|
|
@@ -2152,9 +2304,9 @@ class CodeAgent2 {
|
|
|
2152
2304
|
const cwd = options.cwd ?? workspaceRoot;
|
|
2153
2305
|
const agent = new CodeAgent2(options.profile);
|
|
2154
2306
|
const settingsManager = AkanCodeServices2.settings();
|
|
2155
|
-
const modelRuntime = await AkanCodeServices2.runtime(workspaceRoot);
|
|
2307
|
+
const modelRuntime = await AkanCodeServices2.runtime(workspaceRoot, CodeAgentProxy.fromEnv(options.profile));
|
|
2156
2308
|
const model = await akanCodeModel2(modelRuntime, options.model);
|
|
2157
|
-
const compaction =
|
|
2309
|
+
const compaction = settingsManager.getCompactionSettings(model);
|
|
2158
2310
|
const modelWarnings = akanCodeModelWarnings2(model, compaction.reserveTokens + compaction.keepRecentTokens);
|
|
2159
2311
|
const akan = await AkanCodePlugins2.build({
|
|
2160
2312
|
workspace: options.workspace,
|
|
@@ -2196,10 +2348,11 @@ class CodeAgent2 {
|
|
|
2196
2348
|
agent.#disposePlugins = akan.dispose;
|
|
2197
2349
|
agent.#mcp = akan.mcp;
|
|
2198
2350
|
agent.#workspaceRoot = workspaceRoot;
|
|
2199
|
-
if (options.profile.session.store
|
|
2351
|
+
if (options.profile.session.store !== "memory")
|
|
2200
2352
|
agent.#sessionDir = akanCodePaths2.sessionsDir(workspaceRoot);
|
|
2201
2353
|
await agent.#attach(session, options.mode ?? "print");
|
|
2202
|
-
|
|
2354
|
+
agent.#suspended = new CodeAgentSuspended(CodeAgentSuspended.fileOf(agent.#sessionDir, agent.sessionId));
|
|
2355
|
+
if (agent.#sessionDir && options.profile.session.store === "file")
|
|
2203
2356
|
agent.#openMail(akanCodePaths2.mailDir(workspaceRoot), cwd);
|
|
2204
2357
|
for (const message of modelWarnings)
|
|
2205
2358
|
agent.#emit({ type: "notice", level: "warning", message });
|
|
@@ -2273,6 +2426,11 @@ ${mail.text}`).catch((error) => this.#emit({ type: "notice", level: "error", mes
|
|
|
2273
2426
|
announce() {
|
|
2274
2427
|
this.#emit({ type: "session", info: this.info });
|
|
2275
2428
|
this.#restore();
|
|
2429
|
+
const { question, approvals } = this.#suspended;
|
|
2430
|
+
if (question)
|
|
2431
|
+
this.#emit({ type: "question", question });
|
|
2432
|
+
for (const request of approvals)
|
|
2433
|
+
this.#emit({ type: "approval", request });
|
|
2276
2434
|
}
|
|
2277
2435
|
#restore() {
|
|
2278
2436
|
const session = this.#session;
|
|
@@ -2330,8 +2488,12 @@ ${mail.text}`).catch((error) => this.#emit({ type: "notice", level: "error", mes
|
|
|
2330
2488
|
}
|
|
2331
2489
|
if (this.#profile.interaction.question !== "suspend")
|
|
2332
2490
|
return false;
|
|
2333
|
-
this.#
|
|
2334
|
-
|
|
2491
|
+
const suspended = this.#suspended.takeQuestion(questionId);
|
|
2492
|
+
if (!suspended)
|
|
2493
|
+
return false;
|
|
2494
|
+
const suspendedRendered = codeAgentRenderAnswer(suspended, answer);
|
|
2495
|
+
this.#emit({ type: "question_resolved", questionId, answer, rendered: suspendedRendered });
|
|
2496
|
+
await this.prompt(`The user answered: ${suspendedRendered}
|
|
2335
2497
|
Continue the task.`);
|
|
2336
2498
|
return true;
|
|
2337
2499
|
}
|
|
@@ -2342,6 +2504,8 @@ Continue the task.`);
|
|
|
2342
2504
|
}
|
|
2343
2505
|
if (this.#profile.interaction.approval !== "suspend")
|
|
2344
2506
|
return false;
|
|
2507
|
+
if (!this.#suspended.takeApproval(approvalId))
|
|
2508
|
+
return false;
|
|
2345
2509
|
this.#emit({ type: "approval_resolved", approvalId, approved });
|
|
2346
2510
|
if (approved)
|
|
2347
2511
|
await this.prompt("The user approved the pending action. Retry it and continue.");
|
|
@@ -2507,28 +2671,30 @@ Continue the task.`);
|
|
|
2507
2671
|
if (!this.#profile.ui.canPrompt)
|
|
2508
2672
|
return true;
|
|
2509
2673
|
const approvalId = this.#asks.nextId("a");
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
}
|
|
2519
|
-
});
|
|
2674
|
+
const request = {
|
|
2675
|
+
approvalId,
|
|
2676
|
+
toolCallId,
|
|
2677
|
+
name,
|
|
2678
|
+
summary: codeAgentClip5(summary, codeAgentLabelChars2),
|
|
2679
|
+
policy: this.#profile.approval
|
|
2680
|
+
};
|
|
2681
|
+
this.#emit({ type: "approval", request });
|
|
2520
2682
|
if (this.#profile.interaction.approval === "suspend") {
|
|
2683
|
+
this.#suspended.addApproval(request);
|
|
2521
2684
|
this.#mapper.noteOutcome("awaiting");
|
|
2522
2685
|
return false;
|
|
2523
2686
|
}
|
|
2524
2687
|
return await this.#asks.openApproval(approvalId);
|
|
2525
2688
|
}
|
|
2526
2689
|
async ask(spec) {
|
|
2527
|
-
if (!this.#profile.ui.canPrompt)
|
|
2528
|
-
return;
|
|
2529
2690
|
const question = { questionId: this.#asks.nextId("q"), ...spec };
|
|
2691
|
+
if (!this.#profile.ui.canPrompt) {
|
|
2692
|
+
this.#emit({ type: "question_skipped", question, reason: "no-host" });
|
|
2693
|
+
return;
|
|
2694
|
+
}
|
|
2530
2695
|
this.#emit({ type: "question", question });
|
|
2531
2696
|
if (this.#profile.interaction.question === "suspend") {
|
|
2697
|
+
this.#suspended.setQuestion(question);
|
|
2532
2698
|
this.#mapper.noteOutcome("awaiting");
|
|
2533
2699
|
return;
|
|
2534
2700
|
}
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
runner,
|
|
4
4
|
script
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-qdgzsnhg.js";
|
|
6
6
|
import {
|
|
7
7
|
ModuleExecutor
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-crmeqnmf.js";
|
|
9
9
|
import {
|
|
10
10
|
sourceFile,
|
|
11
11
|
moduleSourcePaths,
|
|
@@ -13,10 +13,10 @@ import {
|
|
|
13
13
|
createPassedPrimitiveReport,
|
|
14
14
|
bilingualLabelForField,
|
|
15
15
|
bilingualDescriptionForField
|
|
16
|
-
} from "./index-
|
|
16
|
+
} from "./index-2446k7b4.js";
|
|
17
17
|
import {
|
|
18
18
|
PageScript
|
|
19
|
-
} from "./index-
|
|
19
|
+
} from "./index-22xtgmhn.js";
|
|
20
20
|
import {
|
|
21
21
|
pluralizeName
|
|
22
22
|
} from "./index-nz8prx9g.js";
|
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
import {
|
|
3
3
|
GlobalConfig,
|
|
4
4
|
CloudApi
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-srmay5jw.js";
|
|
6
6
|
import {
|
|
7
7
|
script
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-qdgzsnhg.js";
|
|
9
9
|
import {
|
|
10
10
|
PkgExecutor
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-crmeqnmf.js";
|
|
12
12
|
import {
|
|
13
13
|
ApplicationScript
|
|
14
|
-
} from "./index-
|
|
14
|
+
} from "./index-bftkz6cp.js";
|
|
15
15
|
import {
|
|
16
16
|
PackageScript
|
|
17
|
-
} from "./index-
|
|
17
|
+
} from "./index-ab0c38ea.js";
|
|
18
18
|
import {
|
|
19
19
|
CloudRunner
|
|
20
|
-
} from "./index-
|
|
20
|
+
} from "./index-bc88j1ry.js";
|
|
21
21
|
|
|
22
22
|
// pkgs/@akanjs/cli/cloud/cloud.script.ts
|
|
23
23
|
import { Logger } from "akanjs/common";
|
|
@@ -55,18 +55,43 @@ class CloudScript2 extends script("cloud", [CloudRunner, ApplicationScript, Pack
|
|
|
55
55
|
await this.cloudRunner.uploadEnvByScp(workspace, path);
|
|
56
56
|
return { workspaceId: null, files };
|
|
57
57
|
}
|
|
58
|
-
async deployAkan(workspace, {
|
|
58
|
+
async deployAkan(workspace, {
|
|
59
|
+
test = true,
|
|
60
|
+
registryUrl,
|
|
61
|
+
platforms = []
|
|
62
|
+
} = {}) {
|
|
59
63
|
const akanPkgs = await this.cloudRunner.getAkanPkgs(workspace);
|
|
60
64
|
await this.packageScript.updateWorskpaceRootPackageJson(workspace);
|
|
61
65
|
const pkgs = akanPkgs.map((pkgName) => PkgExecutor.from(workspace, pkgName));
|
|
62
|
-
if (test)
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
if (test) {
|
|
67
|
+
const platformRun = platforms.length ? await this.cloudRunner.startPlatformTests(workspace, platforms, akanPkgs) : null;
|
|
68
|
+
let localFailure = null;
|
|
69
|
+
try {
|
|
70
|
+
for (const pkg of pkgs)
|
|
71
|
+
await this.applicationScript.test(pkg);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
localFailure = error;
|
|
74
|
+
}
|
|
75
|
+
if (platformRun)
|
|
76
|
+
await this.cloudRunner.settlePlatformTests(platformRun, {
|
|
77
|
+
interactive: !localFailure,
|
|
78
|
+
recordStreaks: !localFailure,
|
|
79
|
+
checkDrift: true
|
|
80
|
+
});
|
|
81
|
+
if (localFailure)
|
|
82
|
+
throw localFailure;
|
|
83
|
+
}
|
|
65
84
|
for (const pkg of pkgs)
|
|
66
85
|
await this.packageScript.buildPackage(pkg);
|
|
67
86
|
await this.packageScript.verifyAkanPublishPackages(workspace);
|
|
68
87
|
await this.cloudRunner.deployAkan(workspace, akanPkgs, { registryUrl });
|
|
69
88
|
}
|
|
89
|
+
async testPlatforms(workspace, { platforms, pkgs }) {
|
|
90
|
+
if (!platforms.length)
|
|
91
|
+
throw new Error("No platform to test on \u2014 pass --platforms linux,windows");
|
|
92
|
+
const run = await this.cloudRunner.startPlatformTests(workspace, platforms, pkgs ?? await this.cloudRunner.getAkanPkgs(workspace));
|
|
93
|
+
await this.cloudRunner.settlePlatformTests(run, { interactive: false, recordStreaks: false, checkDrift: false });
|
|
94
|
+
}
|
|
70
95
|
async update(workspace, tag = "latest", { registryUrl } = {}) {
|
|
71
96
|
const spinner = workspace.spinning("Updating Akan.js packages and CLI...");
|
|
72
97
|
await this.cloudRunner.update(workspace, tag, { registryUrl });
|
|
@@ -13,7 +13,8 @@ var configPath = `${basePath}/config.json`;
|
|
|
13
13
|
var getDefaultHostConfig = (host = GlobalConfig.akanCloudHost) => ({ host });
|
|
14
14
|
var defaultAkanGlobalConfig = {
|
|
15
15
|
cloudHost: {},
|
|
16
|
-
remoteEnvServers: {}
|
|
16
|
+
remoteEnvServers: {},
|
|
17
|
+
testTargets: {}
|
|
17
18
|
};
|
|
18
19
|
|
|
19
20
|
// pkgs/@akanjs/devkit/cloud/globalConfig.ts
|
|
@@ -26,7 +27,8 @@ class GlobalConfig {
|
|
|
26
27
|
...defaultAkanGlobalConfig,
|
|
27
28
|
...akanConfig,
|
|
28
29
|
cloudHost: akanConfig.cloudHost ?? defaultAkanGlobalConfig.cloudHost,
|
|
29
|
-
remoteEnvServers: akanConfig.remoteEnvServers ?? defaultAkanGlobalConfig.remoteEnvServers
|
|
30
|
+
remoteEnvServers: akanConfig.remoteEnvServers ?? defaultAkanGlobalConfig.remoteEnvServers,
|
|
31
|
+
testTargets: akanConfig.testTargets ?? defaultAkanGlobalConfig.testTargets
|
|
30
32
|
};
|
|
31
33
|
}
|
|
32
34
|
static async#setAkanGlobalConfig(akanConfig) {
|
|
@@ -65,6 +67,17 @@ class GlobalConfig {
|
|
|
65
67
|
remoteEnvServers
|
|
66
68
|
});
|
|
67
69
|
}
|
|
70
|
+
static async getTestTargets() {
|
|
71
|
+
const akanConfig = await GlobalConfig.#getAkanGlobalConfig();
|
|
72
|
+
return akanConfig.testTargets;
|
|
73
|
+
}
|
|
74
|
+
static async setTestTargets(testTargets) {
|
|
75
|
+
const akanConfig = await GlobalConfig.#getAkanGlobalConfig();
|
|
76
|
+
await GlobalConfig.#setAkanGlobalConfig({
|
|
77
|
+
...akanConfig,
|
|
78
|
+
testTargets: { ...akanConfig.testTargets, ...testTargets }
|
|
79
|
+
});
|
|
80
|
+
}
|
|
68
81
|
static needRefreshToken(accessToken) {
|
|
69
82
|
return !!accessToken?.expiresAt?.isBefore(dayjs().add(1, "hour"));
|
|
70
83
|
}
|