@akanjs/cli 3.0.0-beta.17 → 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-gjqnc2mg.js → CodeAgent-6cm97kay.js} +2 -2
- package/{CodeAgentRpcHost-qvwfv0n9.js → CodeAgentRpcHost-p7h6n2hp.js} +1 -1
- package/CodeAgentRpcListener-7p7z5dd7.js +97 -0
- package/{CodeTui-nd9hqvrw.js → CodeTui-za4jsm41.js} +205 -34
- package/{TunnelShare-r5tc2qk5.js → TunnelShare-2j6s511d.js} +2 -2
- package/{agent.command-n664dtcv.js → agent.command-e0wpbbyg.js} +6 -6
- package/akanCode.js +7 -5
- package/{application.command-t5542jte.js → application.command-8wyxqc8q.js} +28 -15
- package/{applicationBuildRunner-x4gbfn7y.js → applicationBuildRunner-n9gzaxd0.js} +35 -10
- package/{applicationReleasePackager-z61ep017.js → applicationReleasePackager-vpggfqgq.js} +1 -1
- package/buildBatch.proc.js +3 -3
- package/{capacitorApp-shv3ajh5.js → capacitorApp-q3z0qht0.js} +2 -2
- package/{cloud.command-dk5tj39k.js → cloud.command-4zwa5dsx.js} +34 -12
- package/cloud.script-fwx3vb34.js +20 -0
- package/{code.command-88sebgnn.js → code.command-468c9d7s.js} +41 -19
- package/commandManifest.json +1 -1
- package/{context.command-pqsm5jrk.js → context.command-dsnw0jby.js} +14 -14
- package/context.runner-rs4rj15d.js +22 -0
- package/{dependencyScanner-shs82ynp.js → dependencyScanner-0z2h2tks.js} +1 -1
- package/{devTui-gy6mendg.js → devTui-ffjsarqa.js} +3 -3
- package/{devTuiView-y1548wy6.js → devTuiView-1q1mdgrv.js} +1 -1
- package/{guideline.command-rpc2emw8.js → guideline.command-vhw13pqr.js} +8 -13
- package/guidelines/agentRule/agentRule.instruction.md +27 -10
- package/guidelines/conventions/conventions.instruction.md +53 -26
- package/guidelines/queryRule/queryRule.instruction.md +17 -7
- package/guidelines/runtimeRule/runtimeRule.instruction.md +74 -0
- package/guidelines/ssrRule/ssrRule.instruction.md +4 -2
- package/guidelines/transportRule/transportRule.instruction.md +10 -8
- package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +4 -3
- package/incrementalBuilder.proc.js +3 -2
- package/{index-4n4821gp.js → index-10dkrrww.js} +4 -4
- package/{index-bzakk0c2.js → index-14zrtgfa.js} +5 -3
- package/{index-v17gj504.js → index-18zybgkc.js} +2 -2
- package/{index-qh7brn20.js → index-22xtgmhn.js} +6 -2
- package/{index-qhtj9y6j.js → index-2446k7b4.js} +74 -21
- package/{index-g9zghs4h.js → index-3jrp517k.js} +12 -12
- package/{index-vpx68e4x.js → index-4m929vvn.js} +2 -2
- package/{index-4cvpzkq6.js → index-53176s7j.js} +3 -3
- package/{index-jwrpsrg3.js → index-667w0yah.js} +1 -1
- package/{index-3mg4h788.js → index-7ep8qtvp.js} +2 -2
- package/{index-w8kmx1b6.js → index-89hy31kf.js} +30 -7
- package/index-9d6nvkz2.js +656 -0
- package/index-9dp031by.js +12 -0
- package/{index-zn8qgeqx.js → index-a1w6934z.js} +3 -3
- package/{index-p0tew3fq.js → index-ab0c38ea.js} +10 -5
- package/index-bc88j1ry.js +1166 -0
- package/{index-ns128c4q.js → index-bftkz6cp.js} +280 -73
- package/{index-kcxmv48c.js → index-bhtmj233.js} +4 -1
- package/{index-kvzjda3v.js → index-bwf965h6.js} +5 -5
- package/{index-p4p9t45x.js → index-crmeqnmf.js} +56 -44
- package/{index-8k16atqy.js → index-d2242ksy.js} +23 -6
- package/{index-2sq06vv0.js → index-e4v6vhxq.js} +417 -105
- package/{index-xjc7gg65.js → index-esk82rvk.js} +23 -33
- package/{index-sn7dnzq4.js → index-kwaq3n9n.js} +1 -1
- package/{index-gm76f0qb.js → index-n3cv0tm4.js} +1 -1
- package/{index-6na0sd2b.js → index-qdgzsnhg.js} +5 -2
- package/{index-twq9p2sp.js → index-s5rhm04y.js} +0 -6
- package/{index-n8kt2wh6.js → index-sq2dzkzm.js} +35 -10
- package/{index-myj01w9r.js → index-srmay5jw.js} +15 -2
- package/{index-2pm1j01n.js → index-txr7dj2g.js} +4 -4
- package/{index-3cymrzsb.js → index-vqx8bdxz.js} +17 -3
- package/{index-te0y1c0m.js → index-zqgj2rt2.js} +12 -7
- package/index.js +21 -21
- package/{library.command-m8p2r1dh.js → library.command-cqr175dy.js} +3 -3
- package/{localRegistry.command-yppdqrxv.js → localRegistry.command-49z55qqz.js} +9 -9
- package/{module.command-mfzvqt0n.js → module.command-9p8mm3b0.js} +5 -5
- package/{package.command-cgp2p2v5.js → package.command-wxyz909t.js} +5 -5
- package/package.json +2 -2
- package/{page.command-taenb02b.js → page.command-gsrsfqqs.js} +3 -3
- package/{primitive.command-7kpncmkk.js → primitive.command-ns1mptje.js} +6 -6
- package/{prompter-9mn3kp36.js → prompter-1f8d9pcc.js} +1 -1
- package/{quality.command-1ar94hrw.js → quality.command-e76k2q9k.js} +18 -17
- package/{repair.command-n08t6j8p.js → repair.command-pkrsm3cw.js} +5 -5
- package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
- package/{scalar.command-mq8qfp4t.js → scalar.command-0cpt3fc8.js} +4 -4
- package/skills/akan-code/SKILL.md +122 -0
- package/skills/akan-module/SKILL.md +2 -2
- package/skills/akan-store/SKILL.md +6 -2
- package/{subspace.command-jqv5n79w.js → subspace.command-fktpwp0g.js} +20 -10
- package/templates/__scalar/__model__/__model__.abstract.md.template +8 -0
- package/templates/appSample/lib/__scalar/workHistory/workHistory.abstract.ts +8 -39
- package/templates/appSample/lib/_noti/noti.abstract.ts +6 -29
- package/templates/appSample/lib/task/task.abstract.ts +12 -32
- package/templates/appSample/lib/task/task.signal.spec.ts +15 -18
- package/templates/appSample/lib/task/task.signal.test.ts +15 -1
- package/templates/appSample/lib/task/task.signal.ts +1 -1
- package/templates/appSample/srvkit/AuthGuard.ts +4 -1
- package/templates/appSample/srvkit/SessionInternalArg.ts +3 -1
- package/templates/crudPages/[__model__Id]/edit/page.tsx +2 -1
- package/templates/crudPages/[__model__Id]/page.tsx +2 -1
- package/templates/crudPages/new/page.tsx +2 -1
- package/templates/crudPages/page.tsx +2 -1
- package/templates/crudSinglePage/page.tsx +2 -1
- package/templates/localDev/docker-compose.yaml.template +3 -14
- package/templates/module/__model__.signal.ts +12 -4
- package/templates/pkgRoot/tsconfig.json.template +2 -7
- package/templates/service/__model__.abstract.md.template +8 -0
- package/{tunnel.command-ht2es78c.js → tunnel.command-d5jy9gk8.js} +4 -4
- package/{workflow.command-tvz4nm9n.js → workflow.command-6tkcysmx.js} +9 -9
- package/{workspace.command-txv1yv5e.js → workspace.command-gv84eh1p.js} +25 -24
- package/cloud.script-ch3xrw3s.js +0 -20
- package/context.runner-bys6ykcp.js +0 -22
- package/guidelines/agentRule/agentRule.generate.json +0 -31
- package/guidelines/componentRule/componentRule.generate.json +0 -31
- package/guidelines/conventions/conventions.generate.json +0 -25
- package/guidelines/cssRule/cssRule.generate.json +0 -31
- package/guidelines/docPageRule/docPageRule.generate.json +0 -31
- package/guidelines/docPageRule/docPageRule.instruction.md +0 -25
- package/guidelines/docSyncRule/docSyncRule.generate.json +0 -31
- package/guidelines/docSyncRule/docSyncRule.instruction.md +0 -25
- package/guidelines/enumConstant/enumConstant.generate.json +0 -31
- package/guidelines/enumConstant/enumConstant.instruction.md +0 -28
- package/guidelines/fieldRule/fieldRule.generate.json +0 -31
- package/guidelines/framework/framework.generate.json +0 -32
- package/guidelines/mcpRule/mcpRule.generate.json +0 -35
- package/guidelines/modelConstant/modelConstant.generate.json +0 -32
- package/guidelines/modelDictionary/modelDictionary.generate.json +0 -32
- package/guidelines/modelDocument/modelDocument.generate.json +0 -31
- package/guidelines/modelService/modelService.generate.json +0 -31
- package/guidelines/modelSignal/modelSignal.generate.json +0 -31
- package/guidelines/modelStore/modelStore.generate.json +0 -31
- package/guidelines/modelTemplate/modelTemplate.generate.json +0 -31
- package/guidelines/modelUnit/modelUnit.generate.json +0 -31
- package/guidelines/modelUtil/modelUtil.generate.json +0 -31
- package/guidelines/modelView/modelView.generate.json +0 -31
- package/guidelines/modelZone/modelZone.generate.json +0 -31
- package/guidelines/moduleCodegen/moduleCodegen.generate.json +0 -31
- package/guidelines/moduleCodegen/moduleCodegen.instruction.md +0 -28
- package/guidelines/moduleOverview/moduleOverview.generate.json +0 -31
- package/guidelines/queryRule/queryRule.generate.json +0 -31
- package/guidelines/recipeRule/recipeRule.generate.json +0 -31
- package/guidelines/runtimeRule/runtimeRule.generate.json +0 -25
- package/guidelines/scalarConstant/scalarConstant.generate.json +0 -32
- package/guidelines/scalarDictionary/scalarDictionary.generate.json +0 -32
- package/guidelines/scalarModule/scalarModule.generate.json +0 -31
- package/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -31
- package/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +0 -25
- package/guidelines/ssrRule/ssrRule.generate.json +0 -31
- package/guidelines/transportRule/transportRule.generate.json +0 -31
- package/guidelines/utilUiUsage/utilUiUsage.generate.json +0 -31
- package/guidelines/utilUiUsage/utilUiUsage.instruction.md +0 -25
- package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +0 -24
- package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +0 -34
- package/index-57p9p179.js +0 -461
- package/index-qt8dqgnf.js +0 -250
- package/templates/__scalar/__model__/__model__.abstract.md +0 -28
- package/templates/module/__model__.abstract.md +0 -28
- package/templates/service/__model__.abstract.md +0 -28
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
import {
|
|
3
3
|
runner,
|
|
4
4
|
script
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-qdgzsnhg.js";
|
|
6
6
|
import {
|
|
7
7
|
WorkspaceExecutor,
|
|
8
8
|
AppExecutor,
|
|
9
9
|
LibExecutor,
|
|
10
10
|
PkgExecutor
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-crmeqnmf.js";
|
|
12
12
|
import {
|
|
13
13
|
LibraryScript
|
|
14
|
-
} from "./index-
|
|
14
|
+
} from "./index-7ep8qtvp.js";
|
|
15
15
|
import {
|
|
16
16
|
HmrWatcher,
|
|
17
17
|
WatchRootResolver
|
|
@@ -22,20 +22,13 @@ import {
|
|
|
22
22
|
import {
|
|
23
23
|
SlicePlanner,
|
|
24
24
|
formatSlicePlan
|
|
25
|
-
} from "./index-
|
|
25
|
+
} from "./index-kwaq3n9n.js";
|
|
26
26
|
import {
|
|
27
27
|
resolveMobileTargets
|
|
28
28
|
} from "./index-47pj3aee.js";
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
function openBrowser(url) {
|
|
33
|
-
const command = process.platform === "darwin" ? ["open", url] : process.platform === "win32" ? ["cmd", "/c", "start", "", url] : ["xdg-open", url];
|
|
34
|
-
const child = spawn(command[0], command.slice(1), { detached: true, stdio: "ignore" });
|
|
35
|
-
child.on("error", () => {});
|
|
36
|
-
child.unref();
|
|
37
|
-
return Promise.resolve();
|
|
38
|
-
}
|
|
29
|
+
import {
|
|
30
|
+
openBrowser
|
|
31
|
+
} from "./index-9dp031by.js";
|
|
39
32
|
|
|
40
33
|
// pkgs/@akanjs/devkit/applicationBuildReporter.ts
|
|
41
34
|
import { Logger } from "akanjs/common";
|
|
@@ -1351,16 +1344,18 @@ ${this.#backendStderrTail.join(`
|
|
|
1351
1344
|
this.#recycleBuilderForRss(settledBytes === null ? reason : `${reason}; still ${asMib(settledBytes)}MiB after settling`);
|
|
1352
1345
|
}
|
|
1353
1346
|
static async readProcessRssBytes(pid) {
|
|
1347
|
+
if (process.platform === "win32")
|
|
1348
|
+
return await AkanAppHost.#readRssKbVia(["tasklist", "/FI", `PID eq ${pid}`, "/FO", "CSV", "/NH"], AkanAppHost.#tasklistRssKb);
|
|
1354
1349
|
const status = await Bun.file(`/proc/${pid}/status`).text().catch(() => null);
|
|
1355
1350
|
const vmRssKb = status === null ? null : /VmRSS:\s+(\d+) kB/.exec(status)?.[1];
|
|
1356
1351
|
if (vmRssKb)
|
|
1357
1352
|
return Number(vmRssKb) * 1024;
|
|
1358
|
-
return await AkanAppHost.#
|
|
1353
|
+
return await AkanAppHost.#readRssKbVia(["ps", "-o", "rss=", "-p", String(pid)], (output) => Number(output.trim()));
|
|
1359
1354
|
}
|
|
1360
|
-
static async#
|
|
1355
|
+
static async#readRssKbVia(command, parseKb, timeoutMs = PS_RSS_TIMEOUT_MS) {
|
|
1361
1356
|
let proc;
|
|
1362
1357
|
try {
|
|
1363
|
-
proc = Bun.spawn(
|
|
1358
|
+
proc = Bun.spawn(command, { stdio: ["ignore", "pipe", "ignore"] });
|
|
1364
1359
|
} catch {
|
|
1365
1360
|
return null;
|
|
1366
1361
|
}
|
|
@@ -1368,7 +1363,7 @@ ${this.#backendStderrTail.join(`
|
|
|
1368
1363
|
try {
|
|
1369
1364
|
const output = await new Response(proc.stdout).text();
|
|
1370
1365
|
await proc.exited;
|
|
1371
|
-
const rssKb =
|
|
1366
|
+
const rssKb = parseKb(output);
|
|
1372
1367
|
return Number.isFinite(rssKb) && rssKb > 0 ? rssKb * 1024 : null;
|
|
1373
1368
|
} catch {
|
|
1374
1369
|
return null;
|
|
@@ -1376,6 +1371,10 @@ ${this.#backendStderrTail.join(`
|
|
|
1376
1371
|
clearTimeout(killer);
|
|
1377
1372
|
}
|
|
1378
1373
|
}
|
|
1374
|
+
static #tasklistRssKb(output) {
|
|
1375
|
+
const memUsage = /"([^"]*)"\s*$/m.exec(output)?.[1];
|
|
1376
|
+
return memUsage ? Number(memUsage.replace(/\D/g, "")) : Number.NaN;
|
|
1377
|
+
}
|
|
1379
1378
|
#cancelRssRecycle() {
|
|
1380
1379
|
this.#rssRecycleReason = null;
|
|
1381
1380
|
this.#rssRecycleOver = null;
|
|
@@ -1966,9 +1965,9 @@ ${uniqueCandidates.map((candidate) => ` - ${candidate}`).join(`
|
|
|
1966
1965
|
|
|
1967
1966
|
// pkgs/@akanjs/cli/application/application.runner.ts
|
|
1968
1967
|
import { Logger as Logger4 } from "akanjs/common";
|
|
1969
|
-
var loadBuildRunner = async () => (await import("./applicationBuildRunner-
|
|
1970
|
-
var loadReleasePackager = async () => (await import("./applicationReleasePackager-
|
|
1971
|
-
var loadCapacitorApp = async () => (await import("./capacitorApp-
|
|
1968
|
+
var loadBuildRunner = async () => (await import("./applicationBuildRunner-n9gzaxd0.js")).ApplicationBuildRunner;
|
|
1969
|
+
var loadReleasePackager = async () => (await import("./applicationReleasePackager-vpggfqgq.js")).ApplicationReleasePackager;
|
|
1970
|
+
var loadCapacitorApp = async () => (await import("./capacitorApp-q3z0qht0.js")).CapacitorApp;
|
|
1972
1971
|
var loadPrompts = async () => await import("@inquirer/prompts");
|
|
1973
1972
|
|
|
1974
1973
|
class ApplicationRunner extends runner("application") {
|
|
@@ -2011,7 +2010,7 @@ class ApplicationRunner extends runner("application") {
|
|
|
2011
2010
|
if (!await app.exists(scriptPath))
|
|
2012
2011
|
throw new Error(`Script file not found: apps/${app.name}/${scriptPath}`);
|
|
2013
2012
|
await app.spawn("bun", [scriptPath], {
|
|
2014
|
-
env: app.getCommandEnv({ AKAN_COMMAND_TYPE: "script" }),
|
|
2013
|
+
env: app.getCommandEnv({ AKAN_COMMAND_TYPE: "script", ...await app.getDatabaseModeEnv() }),
|
|
2015
2014
|
stdio: "inherit"
|
|
2016
2015
|
});
|
|
2017
2016
|
}
|
|
@@ -2083,7 +2082,7 @@ const serverModule = await import(${JSON.stringify(serverPath)});
|
|
|
2083
2082
|
const { assertAkanConsoleAllowed, startAkanConsole } = await import("akanjs/server");
|
|
2084
2083
|
const server = serverModule.server;
|
|
2085
2084
|
if (!server?.start) throw new Error("server.ts must export server with start()");
|
|
2086
|
-
assertAkanConsoleAllowed(
|
|
2085
|
+
assertAkanConsoleAllowed();
|
|
2087
2086
|
await server.start({ listen: false, web: false });
|
|
2088
2087
|
try {
|
|
2089
2088
|
await startAkanConsole(server, {
|
|
@@ -2102,7 +2101,29 @@ try {
|
|
|
2102
2101
|
}
|
|
2103
2102
|
`;
|
|
2104
2103
|
await app.spawn("bun", ["-e", code], {
|
|
2105
|
-
env: app.getCommandEnv({ AKAN_COMMAND_TYPE: "console" }),
|
|
2104
|
+
env: app.getCommandEnv({ AKAN_COMMAND_TYPE: "console", ...await app.getDatabaseModeEnv() }),
|
|
2105
|
+
stdio: "inherit"
|
|
2106
|
+
});
|
|
2107
|
+
}
|
|
2108
|
+
async transferDatabase(app, direction, dir) {
|
|
2109
|
+
const serverPath = `${app.cwdPath}/server.ts`;
|
|
2110
|
+
if (!await app.exists("server.ts"))
|
|
2111
|
+
throw new Error(`Server file not found: apps/${app.name}/server.ts`);
|
|
2112
|
+
const target = path5.resolve(app.workspace.workspaceRoot, dir);
|
|
2113
|
+
const code = `
|
|
2114
|
+
const { server } = await import(${JSON.stringify(serverPath)});
|
|
2115
|
+
const { DatabaseAdaptorRole, DocumentTransfer } = await import("akanjs/service");
|
|
2116
|
+
await server.start({ listen: false, web: false });
|
|
2117
|
+
try {
|
|
2118
|
+
const transfer = new DocumentTransfer(server.get(DatabaseAdaptorRole));
|
|
2119
|
+
const reports = await transfer.${direction === "export" ? "exportTo" : "importFrom"}(${JSON.stringify(target)});
|
|
2120
|
+
for (const { table, rows } of reports) console.info(\`${direction === "export" ? "exported" : "imported"} \${table}: \${rows} rows\`);
|
|
2121
|
+
} finally {
|
|
2122
|
+
await server.stop();
|
|
2123
|
+
}
|
|
2124
|
+
`;
|
|
2125
|
+
await app.spawn("bun", ["-e", code], {
|
|
2126
|
+
env: app.getCommandEnv({ AKAN_COMMAND_TYPE: "script", ...await app.getDatabaseModeEnv() }),
|
|
2106
2127
|
stdio: "inherit"
|
|
2107
2128
|
});
|
|
2108
2129
|
}
|
|
@@ -2262,9 +2283,15 @@ try {
|
|
|
2262
2283
|
if (mode === "single")
|
|
2263
2284
|
return [];
|
|
2264
2285
|
if (mode === "multiple")
|
|
2265
|
-
return ["redis"
|
|
2286
|
+
return ["redis"];
|
|
2266
2287
|
return ["redis", "postgres"];
|
|
2267
2288
|
}
|
|
2289
|
+
async#assertComposeHas(workspace, services) {
|
|
2290
|
+
const compose = Bun.YAML.parse(await Bun.file(`${workspace.workspaceRoot}/local/docker-compose.yaml`).text());
|
|
2291
|
+
const missing = services.filter((service) => !compose?.services?.[service]);
|
|
2292
|
+
if (missing.length)
|
|
2293
|
+
throw new Error(`local/docker-compose.yaml declares no ${missing.join(" or ")} service. Add it, or move the file aside so the next akan dbup writes the current template.`);
|
|
2294
|
+
}
|
|
2268
2295
|
async#isLocalDatabaseUp(workspace, mode) {
|
|
2269
2296
|
const requiredServices = this.#getLocalDatabaseServices(mode);
|
|
2270
2297
|
if (!requiredServices.length)
|
|
@@ -2278,16 +2305,18 @@ try {
|
|
|
2278
2305
|
async dbup(workspace, mode = "multiple") {
|
|
2279
2306
|
if (mode === "single")
|
|
2280
2307
|
return true;
|
|
2308
|
+
const services = this.#getLocalDatabaseServices(mode);
|
|
2309
|
+
await workspace.applyTemplate({
|
|
2310
|
+
basePath: "local",
|
|
2311
|
+
template: "localDev",
|
|
2312
|
+
dict: { repoName: workspace.repoName },
|
|
2313
|
+
overwrite: false
|
|
2314
|
+
});
|
|
2315
|
+
await this.#assertComposeHas(workspace, services);
|
|
2281
2316
|
try {
|
|
2282
|
-
await workspace.applyTemplate({
|
|
2283
|
-
basePath: "local",
|
|
2284
|
-
template: "localDev",
|
|
2285
|
-
dict: { repoName: workspace.repoName },
|
|
2286
|
-
overwrite: false
|
|
2287
|
-
});
|
|
2288
2317
|
const wasAlreadyUp = await this.#isLocalDatabaseUp(workspace, mode);
|
|
2289
2318
|
if (!wasAlreadyUp)
|
|
2290
|
-
await workspace.spawn(`docker`, ["compose", "up", "-d", ...
|
|
2319
|
+
await workspace.spawn(`docker`, ["compose", "up", "-d", ...services], {
|
|
2291
2320
|
cwd: `${workspace.workspaceRoot}/local`
|
|
2292
2321
|
});
|
|
2293
2322
|
return wasAlreadyUp;
|
|
@@ -2348,9 +2377,187 @@ ${detail}`
|
|
|
2348
2377
|
}
|
|
2349
2378
|
}
|
|
2350
2379
|
|
|
2380
|
+
// pkgs/@akanjs/cli/application/hostProcessProbe.ts
|
|
2381
|
+
import { readdirSync, readFileSync, readlinkSync } from "fs";
|
|
2382
|
+
|
|
2383
|
+
class HostProcessProbe {
|
|
2384
|
+
static timeoutMs = 3000;
|
|
2385
|
+
static win32TimeoutMs = 20000;
|
|
2386
|
+
static #procTcpListen = "0A";
|
|
2387
|
+
static #win32ProcessQuery = "[Console]::OutputEncoding=[Text.Encoding]::UTF8; Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId,CommandLine,CreationDate | ConvertTo-Json -Compress";
|
|
2388
|
+
platform;
|
|
2389
|
+
#win32Table = null;
|
|
2390
|
+
constructor(platform = process.platform) {
|
|
2391
|
+
this.platform = platform;
|
|
2392
|
+
}
|
|
2393
|
+
async listenersOn(port) {
|
|
2394
|
+
if (this.platform === "win32")
|
|
2395
|
+
return HostProcessProbe.parseNetstat(await HostProcessProbe.run(["netstat", "-ano"]), port);
|
|
2396
|
+
if (this.platform === "linux")
|
|
2397
|
+
return HostProcessProbe.#procListenersOn(port);
|
|
2398
|
+
const output = await HostProcessProbe.run(["lsof", "-ti", `tcp:${port}`, "-sTCP:LISTEN"]);
|
|
2399
|
+
return [
|
|
2400
|
+
...new Set(output.split(`
|
|
2401
|
+
`).map((line) => Number(line.trim())).filter((pid) => Number.isInteger(pid) && pid > 0))
|
|
2402
|
+
];
|
|
2403
|
+
}
|
|
2404
|
+
async parentOf(pid) {
|
|
2405
|
+
if (this.platform === "win32") {
|
|
2406
|
+
const child = await this.#win32Process(pid);
|
|
2407
|
+
const parent = child ? await this.#win32Process(child.ppid) : null;
|
|
2408
|
+
return child && parent ? HostProcessProbe.parentPidOf(child, parent) : null;
|
|
2409
|
+
}
|
|
2410
|
+
if (this.platform === "linux") {
|
|
2411
|
+
const stat = HostProcessProbe.#readProc(pid, "stat");
|
|
2412
|
+
return stat === null ? null : HostProcessProbe.parseProcStatPpid(stat);
|
|
2413
|
+
}
|
|
2414
|
+
const parsed = Number((await HostProcessProbe.run(["ps", "-p", String(pid), "-o", "ppid="])).trim());
|
|
2415
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : null;
|
|
2416
|
+
}
|
|
2417
|
+
async commandOf(pid) {
|
|
2418
|
+
if (this.platform === "win32")
|
|
2419
|
+
return (await this.#win32Process(pid))?.command ?? null;
|
|
2420
|
+
if (this.platform === "linux") {
|
|
2421
|
+
const cmdline = HostProcessProbe.#readProc(pid, "cmdline");
|
|
2422
|
+
return cmdline?.split("\x00").filter(Boolean).join(" ") || null;
|
|
2423
|
+
}
|
|
2424
|
+
return (await HostProcessProbe.run(["ps", "-ww", "-p", String(pid), "-o", "command="])).trim() || null;
|
|
2425
|
+
}
|
|
2426
|
+
static parentPidOf(child, parent) {
|
|
2427
|
+
if (child.ppid !== parent.pid)
|
|
2428
|
+
return null;
|
|
2429
|
+
if (parent.startedAt !== null && child.startedAt !== null && parent.startedAt > child.startedAt)
|
|
2430
|
+
return null;
|
|
2431
|
+
return parent.pid;
|
|
2432
|
+
}
|
|
2433
|
+
static parseNetstat(output, port) {
|
|
2434
|
+
const pids = new Set;
|
|
2435
|
+
for (const line of output.split(/\r?\n/)) {
|
|
2436
|
+
const fields = line.trim().split(/\s+/);
|
|
2437
|
+
if (fields[0] !== "TCP" || fields.length < 5)
|
|
2438
|
+
continue;
|
|
2439
|
+
const [, local, remote] = fields;
|
|
2440
|
+
if (!local?.endsWith(`:${port}`) || !remote?.endsWith(":0"))
|
|
2441
|
+
continue;
|
|
2442
|
+
const pid = Number(fields.at(-1));
|
|
2443
|
+
if (Number.isInteger(pid) && pid > 0)
|
|
2444
|
+
pids.add(pid);
|
|
2445
|
+
}
|
|
2446
|
+
return [...pids];
|
|
2447
|
+
}
|
|
2448
|
+
static parseProcNetTcp(text, port) {
|
|
2449
|
+
const inodes = [];
|
|
2450
|
+
for (const line of text.split(`
|
|
2451
|
+
`).slice(1)) {
|
|
2452
|
+
const fields = line.trim().split(/\s+/);
|
|
2453
|
+
const [, local, , state, , , , , , inode] = fields;
|
|
2454
|
+
if (!local || !inode || state !== HostProcessProbe.#procTcpListen || inode === "0")
|
|
2455
|
+
continue;
|
|
2456
|
+
if (Number.parseInt(local.slice(local.lastIndexOf(":") + 1), 16) === port)
|
|
2457
|
+
inodes.push(inode);
|
|
2458
|
+
}
|
|
2459
|
+
return inodes;
|
|
2460
|
+
}
|
|
2461
|
+
static parseProcStatPpid(stat) {
|
|
2462
|
+
const ppid = Number(stat.slice(stat.lastIndexOf(")") + 2).split(" ")[1]);
|
|
2463
|
+
return Number.isInteger(ppid) && ppid > 0 ? ppid : null;
|
|
2464
|
+
}
|
|
2465
|
+
static parseWin32Processes(json) {
|
|
2466
|
+
const table = new Map;
|
|
2467
|
+
let parsed;
|
|
2468
|
+
try {
|
|
2469
|
+
parsed = JSON.parse(json.trim() || "[]");
|
|
2470
|
+
} catch {
|
|
2471
|
+
return table;
|
|
2472
|
+
}
|
|
2473
|
+
const rows = Array.isArray(parsed) ? parsed : [parsed];
|
|
2474
|
+
for (const row of rows) {
|
|
2475
|
+
if (typeof row?.ProcessId !== "number")
|
|
2476
|
+
continue;
|
|
2477
|
+
table.set(row.ProcessId, {
|
|
2478
|
+
pid: row.ProcessId,
|
|
2479
|
+
ppid: row.ParentProcessId ?? 0,
|
|
2480
|
+
command: row.CommandLine?.trim() || null,
|
|
2481
|
+
startedAt: HostProcessProbe.#parseCimDate(row.CreationDate)
|
|
2482
|
+
});
|
|
2483
|
+
}
|
|
2484
|
+
return table;
|
|
2485
|
+
}
|
|
2486
|
+
static async run(command, timeoutMs = HostProcessProbe.timeoutMs) {
|
|
2487
|
+
let proc;
|
|
2488
|
+
try {
|
|
2489
|
+
proc = Bun.spawn(command, { stdio: ["ignore", "pipe", "ignore"], windowsHide: true });
|
|
2490
|
+
} catch {
|
|
2491
|
+
return "";
|
|
2492
|
+
}
|
|
2493
|
+
const timer = setTimeout(() => proc.kill("SIGKILL"), timeoutMs);
|
|
2494
|
+
try {
|
|
2495
|
+
return await new Response(proc.stdout).text();
|
|
2496
|
+
} catch {
|
|
2497
|
+
return "";
|
|
2498
|
+
} finally {
|
|
2499
|
+
clearTimeout(timer);
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
async#win32Process(pid) {
|
|
2503
|
+
this.#win32Table ??= await HostProcessProbe.#queryWin32Processes();
|
|
2504
|
+
if (!this.#win32Table.has(pid))
|
|
2505
|
+
this.#win32Table = await HostProcessProbe.#queryWin32Processes();
|
|
2506
|
+
return this.#win32Table.get(pid) ?? null;
|
|
2507
|
+
}
|
|
2508
|
+
static async#queryWin32Processes() {
|
|
2509
|
+
const output = await HostProcessProbe.run(["powershell", "-NoProfile", "-NonInteractive", "-Command", HostProcessProbe.#win32ProcessQuery], HostProcessProbe.win32TimeoutMs);
|
|
2510
|
+
return HostProcessProbe.parseWin32Processes(output);
|
|
2511
|
+
}
|
|
2512
|
+
static #parseCimDate(value) {
|
|
2513
|
+
if (!value)
|
|
2514
|
+
return null;
|
|
2515
|
+
const legacy = /\/Date\((\d+)/.exec(value)?.[1];
|
|
2516
|
+
const ms = legacy ? Number(legacy) : Date.parse(value);
|
|
2517
|
+
return Number.isFinite(ms) ? ms : null;
|
|
2518
|
+
}
|
|
2519
|
+
static #procListenersOn(port) {
|
|
2520
|
+
const inodes = new Set(["tcp", "tcp6"].flatMap((table) => HostProcessProbe.parseProcNetTcp(HostProcessProbe.#readProc("net", table) ?? "", port)));
|
|
2521
|
+
if (!inodes.size)
|
|
2522
|
+
return [];
|
|
2523
|
+
const pids = [];
|
|
2524
|
+
for (const entry of HostProcessProbe.#listDir("/proc")) {
|
|
2525
|
+
if (!/^\d+$/.test(entry))
|
|
2526
|
+
continue;
|
|
2527
|
+
const holds = HostProcessProbe.#listDir(`/proc/${entry}/fd`).some((fd) => {
|
|
2528
|
+
const inode = /^socket:\[(\d+)\]$/.exec(HostProcessProbe.#readLink(`/proc/${entry}/fd/${fd}`))?.[1];
|
|
2529
|
+
return !!inode && inodes.has(inode);
|
|
2530
|
+
});
|
|
2531
|
+
if (holds)
|
|
2532
|
+
pids.push(Number(entry));
|
|
2533
|
+
}
|
|
2534
|
+
return pids;
|
|
2535
|
+
}
|
|
2536
|
+
static #readProc(pid, file) {
|
|
2537
|
+
try {
|
|
2538
|
+
return readFileSync(`/proc/${pid}/${file}`, "utf8");
|
|
2539
|
+
} catch {
|
|
2540
|
+
return null;
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
static #listDir(dir) {
|
|
2544
|
+
try {
|
|
2545
|
+
return readdirSync(dir);
|
|
2546
|
+
} catch {
|
|
2547
|
+
return [];
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
static #readLink(link) {
|
|
2551
|
+
try {
|
|
2552
|
+
return readlinkSync(link);
|
|
2553
|
+
} catch {
|
|
2554
|
+
return "";
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
|
|
2351
2559
|
// pkgs/@akanjs/cli/application/devPortReclaimer.ts
|
|
2352
2560
|
class DevPortReclaimer {
|
|
2353
|
-
static lsofTimeoutMs = 3000;
|
|
2354
2561
|
static releaseTimeoutMs = 8000;
|
|
2355
2562
|
static maxAncestorDepth = 8;
|
|
2356
2563
|
static #releasePollMs = 100;
|
|
@@ -2359,7 +2566,12 @@ class DevPortReclaimer {
|
|
|
2359
2566
|
return [...new Set(ports.flatMap((port) => [port, port + DevPortReclaimer.wsPortOffset]))].sort((left, right) => left - right);
|
|
2360
2567
|
}
|
|
2361
2568
|
static isAkanCommand(command) {
|
|
2362
|
-
|
|
2569
|
+
const normalized = command.replaceAll("\\", "/");
|
|
2570
|
+
return /(^|\/)akan(\.exe)?"?(\s|$)/.test(normalized) || normalized.includes("@akanjs/cli") || normalized.includes("akanjs/server") || /\bapps\/[^/\s]+\/main\.ts\b/.test(normalized) || normalized.includes("incrementalBuilder.proc") || normalized.includes("rscWorker");
|
|
2571
|
+
}
|
|
2572
|
+
#probe;
|
|
2573
|
+
constructor(probe = new HostProcessProbe) {
|
|
2574
|
+
this.#probe = probe;
|
|
2363
2575
|
}
|
|
2364
2576
|
async reclaim(ports) {
|
|
2365
2577
|
const killed = [];
|
|
@@ -2384,10 +2596,10 @@ class DevPortReclaimer {
|
|
|
2384
2596
|
}
|
|
2385
2597
|
async holdersOf(port) {
|
|
2386
2598
|
const holders = [];
|
|
2387
|
-
for (const listenerPid of await this.#
|
|
2599
|
+
for (const listenerPid of await this.#probe.listenersOn(port)) {
|
|
2388
2600
|
if (listenerPid === process.pid || listenerPid === process.ppid)
|
|
2389
2601
|
continue;
|
|
2390
|
-
const command = await this.#commandOf(listenerPid);
|
|
2602
|
+
const command = await this.#probe.commandOf(listenerPid);
|
|
2391
2603
|
if (!command)
|
|
2392
2604
|
continue;
|
|
2393
2605
|
if (!DevPortReclaimer.isAkanCommand(command)) {
|
|
@@ -2402,44 +2614,37 @@ class DevPortReclaimer {
|
|
|
2402
2614
|
async#akanRootOf(pid, command) {
|
|
2403
2615
|
let root = { pid, command };
|
|
2404
2616
|
for (let depth = 0;depth < DevPortReclaimer.maxAncestorDepth; depth += 1) {
|
|
2405
|
-
const parentPid = await this.#
|
|
2617
|
+
const parentPid = await this.#probe.parentOf(root.pid);
|
|
2406
2618
|
if (parentPid === null || parentPid <= 1 || parentPid === process.pid || parentPid === process.ppid)
|
|
2407
2619
|
break;
|
|
2408
|
-
const parentCommand = await this.#commandOf(parentPid);
|
|
2620
|
+
const parentCommand = await this.#probe.commandOf(parentPid);
|
|
2409
2621
|
if (!parentCommand || !DevPortReclaimer.isAkanCommand(parentCommand))
|
|
2410
2622
|
break;
|
|
2411
2623
|
root = { pid: parentPid, command: parentCommand };
|
|
2412
2624
|
}
|
|
2413
2625
|
return root;
|
|
2414
2626
|
}
|
|
2415
|
-
async#ppidOf(pid) {
|
|
2416
|
-
const output = await this.#run(["ps", "-p", String(pid), "-o", "ppid="]);
|
|
2417
|
-
const parsed = Number(output.trim());
|
|
2418
|
-
return Number.isInteger(parsed) && parsed > 0 ? parsed : null;
|
|
2419
|
-
}
|
|
2420
|
-
async#pidsOn(port) {
|
|
2421
|
-
const output = await this.#run(["lsof", "-ti", `tcp:${port}`, "-sTCP:LISTEN"]);
|
|
2422
|
-
return [
|
|
2423
|
-
...new Set(output.split(`
|
|
2424
|
-
`).map((line) => Number(line.trim())).filter((pid) => Number.isInteger(pid) && pid > 0))
|
|
2425
|
-
];
|
|
2426
|
-
}
|
|
2427
|
-
async#commandOf(pid) {
|
|
2428
|
-
const output = await this.#run(["ps", "-p", String(pid), "-o", "command="]);
|
|
2429
|
-
return output.trim() || null;
|
|
2430
|
-
}
|
|
2431
2627
|
async#terminate(pid) {
|
|
2628
|
+
if (this.#probe.platform === "win32") {
|
|
2629
|
+
await HostProcessProbe.run(["taskkill", "/PID", String(pid), "/T", "/F"]);
|
|
2630
|
+
return await this.#released(pid);
|
|
2631
|
+
}
|
|
2432
2632
|
if (!this.#signal(pid, "SIGTERM"))
|
|
2433
2633
|
return !this.#alive(pid);
|
|
2634
|
+
if (await this.#released(pid))
|
|
2635
|
+
return true;
|
|
2636
|
+
this.#signal(pid, "SIGKILL");
|
|
2637
|
+
await Bun.sleep(DevPortReclaimer.#releasePollMs);
|
|
2638
|
+
return !this.#alive(pid);
|
|
2639
|
+
}
|
|
2640
|
+
async#released(pid) {
|
|
2434
2641
|
const deadline = Date.now() + DevPortReclaimer.releaseTimeoutMs;
|
|
2435
2642
|
while (Date.now() < deadline) {
|
|
2436
2643
|
if (!this.#alive(pid))
|
|
2437
2644
|
return true;
|
|
2438
2645
|
await Bun.sleep(DevPortReclaimer.#releasePollMs);
|
|
2439
2646
|
}
|
|
2440
|
-
|
|
2441
|
-
await Bun.sleep(DevPortReclaimer.#releasePollMs);
|
|
2442
|
-
return !this.#alive(pid);
|
|
2647
|
+
return false;
|
|
2443
2648
|
}
|
|
2444
2649
|
#signal(pid, signal) {
|
|
2445
2650
|
try {
|
|
@@ -2457,17 +2662,6 @@ class DevPortReclaimer {
|
|
|
2457
2662
|
return error.code === "EPERM";
|
|
2458
2663
|
}
|
|
2459
2664
|
}
|
|
2460
|
-
async#run(command) {
|
|
2461
|
-
const proc = Bun.spawn(command, { stdio: ["ignore", "pipe", "ignore"] });
|
|
2462
|
-
const timer = setTimeout(() => proc.kill("SIGKILL"), DevPortReclaimer.lsofTimeoutMs);
|
|
2463
|
-
try {
|
|
2464
|
-
return await new Response(proc.stdout).text();
|
|
2465
|
-
} catch {
|
|
2466
|
-
return "";
|
|
2467
|
-
} finally {
|
|
2468
|
-
clearTimeout(timer);
|
|
2469
|
-
}
|
|
2470
|
-
}
|
|
2471
2665
|
}
|
|
2472
2666
|
|
|
2473
2667
|
// pkgs/@akanjs/cli/application/devStreamView.ts
|
|
@@ -3182,7 +3376,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
3182
3376
|
async startOne(app, { open = false, dbup = true, stdio = "inherit", write = true, onDevEvent } = {}) {
|
|
3183
3377
|
await app.scanSync({ write });
|
|
3184
3378
|
const akanConfig = await app.getConfig();
|
|
3185
|
-
const databaseMode =
|
|
3379
|
+
const databaseMode = akanConfig.resolveDatabaseMode();
|
|
3186
3380
|
await this.syncDatabaseModeDependencies(app, akanConfig, databaseMode);
|
|
3187
3381
|
if (app.getEnv() === "local" && dbup && databaseMode !== "single") {
|
|
3188
3382
|
const wasDbAlreadyUp = await this.dbup(app.workspace, databaseMode);
|
|
@@ -3226,7 +3420,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
3226
3420
|
throw new Error("No app selected to start");
|
|
3227
3421
|
const startedDatabase = dbup ? await this.#prepareSharedDatabase(apps) : false;
|
|
3228
3422
|
const supervisor = new DevSupervisor({ apps, mode, concurrency, open, write, shares });
|
|
3229
|
-
const view = mode === "tui" ? await (await import("./devTuiView-
|
|
3423
|
+
const view = mode === "tui" ? await (await import("./devTuiView-1q1mdgrv.js")).createDevTuiView(supervisor) : new DevStreamView(apps.map((app) => app.name));
|
|
3230
3424
|
await supervisor.run(view);
|
|
3231
3425
|
if (startedDatabase)
|
|
3232
3426
|
await this.#stopDatabase(workspace);
|
|
@@ -3240,7 +3434,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
3240
3434
|
if (app.getEnv() !== "local")
|
|
3241
3435
|
continue;
|
|
3242
3436
|
const akanConfig = await app.getConfig();
|
|
3243
|
-
const mode =
|
|
3437
|
+
const mode = akanConfig.resolveDatabaseMode();
|
|
3244
3438
|
await this.syncDatabaseModeDependencies(app, akanConfig, mode);
|
|
3245
3439
|
if (mode !== "single")
|
|
3246
3440
|
modes.add(mode);
|
|
@@ -3328,6 +3522,19 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
3328
3522
|
async codepush(app, os) {
|
|
3329
3523
|
await this.applicationRunner.codepush(app, os);
|
|
3330
3524
|
}
|
|
3525
|
+
async transferDatabase(app, direction, dir) {
|
|
3526
|
+
await this.applicationRunner.transferDatabase(app, direction, dir);
|
|
3527
|
+
}
|
|
3528
|
+
async dbupDeclared(workspace, mode) {
|
|
3529
|
+
const declared = mode ? [mode] : await Promise.all((await workspace.getApps()).map(async (appName) => (await AppExecutor.from(workspace, appName).getConfig()).database.modes)).then((modes) => [...new Set(modes.flat())]);
|
|
3530
|
+
const needing = declared.filter((each) => each !== "single");
|
|
3531
|
+
if (!needing.length) {
|
|
3532
|
+
workspace.log("No app here declares a database mode that runs on local services; single needs none.");
|
|
3533
|
+
return;
|
|
3534
|
+
}
|
|
3535
|
+
for (const each of needing)
|
|
3536
|
+
await this.dbup(workspace, each);
|
|
3537
|
+
}
|
|
3331
3538
|
async dbup(workspace, mode = "multiple") {
|
|
3332
3539
|
const spinner = workspace.spinning(`Starting local database (${mode})...`);
|
|
3333
3540
|
const wasAlreadyUp = await this.applicationRunner.dbup(workspace, mode);
|
|
@@ -3351,7 +3558,7 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
3351
3558
|
await Promise.all(shares.map(async (share) => await share.close()));
|
|
3352
3559
|
}, "Abandoning the tunnel release; the shares expire on their own.");
|
|
3353
3560
|
await Promise.all(apps.map(async (app) => {
|
|
3354
|
-
const { TunnelShare } = await import("./TunnelShare-
|
|
3561
|
+
const { TunnelShare } = await import("./TunnelShare-2j6s511d.js");
|
|
3355
3562
|
const share = await TunnelShare.open(app, { workspace: app.workspace });
|
|
3356
3563
|
shares.push(share);
|
|
3357
3564
|
urls.set(app.name, share.url);
|
|
@@ -3385,4 +3592,4 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
3385
3592
|
}
|
|
3386
3593
|
}
|
|
3387
3594
|
|
|
3388
|
-
export {
|
|
3595
|
+
export { ApplicationScript };
|
|
@@ -10,7 +10,10 @@ import ignore from "ignore";
|
|
|
10
10
|
import ts from "typescript";
|
|
11
11
|
var testFileRegex = /\.(?:test|spec)\.[cm]?[tj]sx?$/;
|
|
12
12
|
var skipDirs = ["node_modules", "dist", "build", ".git", ".next", "public", "ios", "android", "__fixtures__"];
|
|
13
|
-
var isSkippedPath = (filePath) =>
|
|
13
|
+
var isSkippedPath = (filePath) => {
|
|
14
|
+
const posixPath = filePath.split(path.sep).join("/");
|
|
15
|
+
return skipDirs.some((dir) => posixPath.includes(`/${dir}/`) || posixPath.startsWith(`${dir}/`));
|
|
16
|
+
};
|
|
14
17
|
var builtinModuleSet = new Set([...builtinModules, ...builtinModules.map((mod) => `node:${mod}`)]);
|
|
15
18
|
var stripShebang = (source) => source.replace(/^#!.*(?:\r?\n|$)/, "");
|
|
16
19
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
runner,
|
|
4
4
|
script
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-qdgzsnhg.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-crmeqnmf.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-18zybgkc.js";
|
|
24
24
|
import {
|
|
25
25
|
Prompter2
|
|
26
|
-
} from "./index-
|
|
26
|
+
} from "./index-s5rhm04y.js";
|
|
27
27
|
|
|
28
28
|
// pkgs/@akanjs/cli/agent/agent.script.ts
|
|
29
29
|
import { Logger as Logger2 } from "akanjs/common";
|
|
@@ -148,7 +148,7 @@ If generated output is stale or broken, update the owning source file and run \`
|
|
|
148
148
|
${recipeIndex}## MCP Workflow Policy
|
|
149
149
|
|
|
150
150
|
- **Prefer an Akan workflow to a direct source edit.** A direct edit is denied when an allowlisted workflow or repair tool can make the change.
|
|
151
|
-
- Inspect with \`akan mcp --mode plan\` (\`list_workflows\`, \`explain_workflow\`, \`plan_workflow\`); apply with \`akan mcp --mode apply\`, which allowlists \`apply_workflow\`, \`run_validation\`, and the repair tools.
|
|
151
|
+
- Inspect with \`akan mcp --mode plan\` (\`list_workflows\`, \`explain_workflow\`, \`plan_workflow\`); apply with \`akan mcp --mode apply\`, which allowlists \`apply_workflow\`, \`run_validation\`, and three of the five repair tools \u2014 \`repair_generated\`, \`repair_imports\` and \`repair_module_shape\`. \`akan repair format\` and \`akan repair dictionary\` are CLI-only.
|
|
152
152
|
- If \`plan_workflow\` returns \`planPath\` or \`next.tool=apply_workflow\`, call \`apply_workflow({ planPath })\` before editing source. Then run \`run_validation\` with \`validationTarget\` when present, otherwise \`applyReportPath\`.
|
|
153
153
|
- Split a compound request into workflows and apply each \`planPath\` in order, such as \`create-module\` followed by \`add-field\`.
|
|
154
154
|
- When no workflow exists, or apply reports unsupported/no-op/failed diagnostics needing manual action, keep edits scoped to owning source files and never patch generated files directly.
|