@akanjs/cli 3.0.0-beta.27 → 3.0.0-beta.28
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-h19atbr3.js → CodeAgent-7acv4ah8.js} +2 -2
- package/{CodeTui-46zygq8p.js → CodeTui-9tkh34mj.js} +1 -1
- package/{agent.command-rp505zxa.js → agent.command-q9bmqrag.js} +5 -5
- package/akanCode.js +2 -2
- package/{application.command-1p0cpt6y.js → application.command-xpnkyx4z.js} +70 -8
- package/{applicationBuildRunner-r6b9rkb8.js → applicationBuildRunner-w4917tje.js} +67 -22
- package/buildBatch.proc.js +3 -3
- package/{cloud.command-ps9dabbg.js → cloud.command-7yd624qd.js} +9 -9
- package/cloud.script-25vzkz7b.js +20 -0
- package/{code.command-78qw3q3f.js → code.command-fpx4gzmy.js} +6 -6
- package/commandManifest.json +1 -1
- package/{context.command-x5f7t3gk.js → context.command-snn1k5q3.js} +13 -13
- package/context.runner-nzaf8c98.js +21 -0
- package/{guideline.command-d5qmxx29.js → guideline.command-ene55fkr.js} +2 -2
- package/guidelines/conventions/conventions.instruction.md +27 -7
- package/guidelines/runtimeRule/runtimeRule.instruction.md +107 -1
- package/incrementalBuilder.proc.js +2 -2
- package/{index-118vq9dh.js → index-0ej0sr6m.js} +225 -46
- package/{index-hzy4pe24.js → index-0pqzrbpr.js} +2 -2
- package/{index-6dt6zft6.js → index-20r2g1t3.js} +4 -4
- package/{index-xfgdmm5d.js → index-2ctqegdm.js} +2 -2
- package/{index-d65fzxvd.js → index-2s2e5qnd.js} +1 -1
- package/{index-t02g6dpn.js → index-2z30v4k5.js} +3 -3
- package/{index-vxqe24mp.js → index-52n8xr63.js} +1 -1
- package/{index-tg09x14f.js → index-9j0kykc6.js} +5 -5
- package/{index-58cyna2s.js → index-b68zfsvz.js} +1 -1
- package/{index-2zcm7fjd.js → index-ewbek95g.js} +3 -3
- package/{index-bp9b1g2r.js → index-fy42hyb9.js} +7 -3
- package/{index-zazvn45w.js → index-genegfnt.js} +4 -4
- package/{index-da72pfdv.js → index-h9ed99ax.js} +7 -7
- package/{index-per2kqy9.js → index-k7809wmg.js} +2 -2
- package/{index-j9z8vg2n.js → index-n9704w6y.js} +4 -4
- package/{index-860zjnr1.js → index-nbg9bfnr.js} +1 -1
- package/{index-5mm3g24t.js → index-qtz88kh0.js} +2 -2
- package/{index-0n9q1f23.js → index-r8gp8zk3.js} +231 -98
- package/{index-ggfhz9ab.js → index-rbeahw6j.js} +3 -3
- package/{index-56xwsgyn.js → index-rrt9pnb4.js} +2 -2
- package/{index-v4hnkqz9.js → index-ss828r32.js} +1 -1
- package/index-tfe3711h.js +947 -0
- package/{index-5kjsr2pg.js → index-ttn00pr3.js} +38 -3
- package/{index-w5pet0nq.js → index-vt64c067.js} +11 -9
- package/index.js +21 -21
- package/{library.command-sv6g1h2g.js → library.command-tz7vnwea.js} +3 -3
- package/{localRegistry.command-zppa6w7q.js → localRegistry.command-f39yk7be.js} +8 -8
- package/{module.command-ccdeder9.js → module.command-qhc9ns0s.js} +5 -5
- package/{package.command-xmw605b1.js → package.command-z3epnvas.js} +3 -3
- package/package.json +2 -2
- package/{page.command-ky7vafsn.js → page.command-exd2vakz.js} +3 -3
- package/{primitive.command-bh6j8nfs.js → primitive.command-0w6cha4j.js} +6 -6
- package/{quality.command-rqqrpe98.js → quality.command-je4kc9yv.js} +2 -2
- package/{repair.command-n9nsm9qe.js → repair.command-knvwfgtg.js} +5 -5
- package/{scalar.command-t09gmck8.js → scalar.command-60nxfchc.js} +4 -4
- package/{subspace.command-gx2cjpnv.js → subspace.command-0e53tvxk.js} +4 -4
- package/templates/server.ts +1 -1
- package/{tunnel.command-4g95vhsn.js → tunnel.command-7m2kxtat.js} +2 -2
- package/{workflow.command-b91ph8sx.js → workflow.command-j5tk13ds.js} +10 -10
- package/{workspace.command-1r29qzzk.js → workspace.command-wypqk2zb.js} +20 -20
- package/cloud.script-wrw1kz6k.js +0 -20
- package/context.runner-nfs8ksh3.js +0 -21
- package/index-y736f42m.js +0 -556
|
@@ -37,27 +37,29 @@ import {
|
|
|
37
37
|
import {
|
|
38
38
|
runner,
|
|
39
39
|
script
|
|
40
|
-
} from "./index-
|
|
40
|
+
} from "./index-b68zfsvz.js";
|
|
41
41
|
import {
|
|
42
42
|
WorkspaceExecutor,
|
|
43
43
|
AppExecutor,
|
|
44
44
|
LibExecutor,
|
|
45
45
|
PkgExecutor
|
|
46
|
-
} from "./index-
|
|
46
|
+
} from "./index-r8gp8zk3.js";
|
|
47
47
|
import {
|
|
48
48
|
LibraryScript
|
|
49
|
-
} from "./index-
|
|
49
|
+
} from "./index-qtz88kh0.js";
|
|
50
50
|
import {
|
|
51
|
+
DesktopServerStage,
|
|
51
52
|
resolveMobileTargets,
|
|
53
|
+
resolveAppId,
|
|
52
54
|
NativeApp
|
|
53
|
-
} from "./index-
|
|
55
|
+
} from "./index-tfe3711h.js";
|
|
54
56
|
import {
|
|
55
57
|
stripAnsi
|
|
56
58
|
} from "./index-7md2g9vw.js";
|
|
57
59
|
import {
|
|
58
60
|
SlicePlanner,
|
|
59
61
|
formatSlicePlan
|
|
60
|
-
} from "./index-
|
|
62
|
+
} from "./index-nbg9bfnr.js";
|
|
61
63
|
import {
|
|
62
64
|
openBrowser
|
|
63
65
|
} from "./index-9dp031by.js";
|
|
@@ -725,6 +727,7 @@ class AkanAppHost {
|
|
|
725
727
|
#backendGaveUp = false;
|
|
726
728
|
#backendLifecycleState = "stopped";
|
|
727
729
|
#pendingRestartReason = null;
|
|
730
|
+
#backendRestart = null;
|
|
728
731
|
#pendingRecycle = null;
|
|
729
732
|
#restartFailedAfterApply = null;
|
|
730
733
|
#stopping = false;
|
|
@@ -796,7 +799,9 @@ class AkanAppHost {
|
|
|
796
799
|
this.#cancelIdleSuspend();
|
|
797
800
|
this.#stopIdleWatcher();
|
|
798
801
|
this.#clearRestartTimers();
|
|
802
|
+
this.#pendingRestartReason = null;
|
|
799
803
|
this.#failPendingBuilderMessages("dev server is shutting down");
|
|
804
|
+
await this.#backendRestart;
|
|
800
805
|
await this.#stopBackend();
|
|
801
806
|
this.#stopBuilder();
|
|
802
807
|
return this;
|
|
@@ -817,6 +822,12 @@ class AkanAppHost {
|
|
|
817
822
|
return await createTunnel(type, { app: this.app, environment });
|
|
818
823
|
}
|
|
819
824
|
#startBackend(startStatus = null) {
|
|
825
|
+
if (this.#stopping)
|
|
826
|
+
return;
|
|
827
|
+
if (this.#backend) {
|
|
828
|
+
this.logger.warn(`backend pid=${this.#backend.pid} is still running; not starting a second one`);
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
820
831
|
this.#builderRequests.startGeneration();
|
|
821
832
|
this.#discardPendingBuilderMessages("the backend restarted while the builder was away");
|
|
822
833
|
this.#backendStartStatus = startStatus;
|
|
@@ -997,11 +1008,17 @@ class AkanAppHost {
|
|
|
997
1008
|
clearTimeout(this.#restartTimer);
|
|
998
1009
|
this.#restartTimer = setTimeout(() => {
|
|
999
1010
|
this.#restartTimer = null;
|
|
1011
|
+
this.#backendRestart ??= this.#drainBackendRestarts().finally(() => {
|
|
1012
|
+
this.#backendRestart = null;
|
|
1013
|
+
});
|
|
1014
|
+
}, BACKEND_RESTART_DEBOUNCE_MS);
|
|
1015
|
+
}
|
|
1016
|
+
async#drainBackendRestarts() {
|
|
1017
|
+
while (this.#pendingRestartReason && !this.#restartTimer && !this.#stopping) {
|
|
1000
1018
|
const next = this.#pendingRestartReason;
|
|
1001
1019
|
this.#pendingRestartReason = null;
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
}, BACKEND_RESTART_DEBOUNCE_MS);
|
|
1020
|
+
await this.#restartBackend(next);
|
|
1021
|
+
}
|
|
1005
1022
|
}
|
|
1006
1023
|
async#restartBackend(reason) {
|
|
1007
1024
|
this.logger.verbose(`[backend-reload] restarting backend generation=${reason.generation ?? "(unknown)"} files=${reason.files.length} roles=${reason.roles.join(",") || "(none)"}`);
|
|
@@ -1306,7 +1323,7 @@ ${this.#backendStderrTail.join(`
|
|
|
1306
1323
|
this.logger.info(`[idle-suspend] no build activity for ${Math.round(idleMs / 1000)}s; released the builder \u2014 the next edit or route request brings it back`);
|
|
1307
1324
|
}
|
|
1308
1325
|
get #restartPending() {
|
|
1309
|
-
return !!(this.#pendingRecycle || this.#restartTimer || this.#backendRecoveryTimer || this.#builderRecoveryTimer || this.#rssRecycleReason);
|
|
1326
|
+
return !!(this.#pendingRecycle || this.#restartTimer || this.#backendRestart || this.#backendRecoveryTimer || this.#builderRecoveryTimer || this.#rssRecycleReason);
|
|
1310
1327
|
}
|
|
1311
1328
|
async#startIdleWatcher() {
|
|
1312
1329
|
try {
|
|
@@ -1609,6 +1626,7 @@ ${this.#backendStderrTail.join(`
|
|
|
1609
1626
|
this.#clearRestartTimers();
|
|
1610
1627
|
this.#builderRecoveryAttempts = 0;
|
|
1611
1628
|
this.#pendingRestartReason = null;
|
|
1629
|
+
await this.#backendRestart;
|
|
1612
1630
|
this.#lastGoodFrontend = {};
|
|
1613
1631
|
this.#buildStatusByPhase.clear();
|
|
1614
1632
|
this.#pendingBuildStatusReplay = [];
|
|
@@ -1846,7 +1864,7 @@ ${uniqueCandidates.map((candidate) => ` - ${candidate}`).join(`
|
|
|
1846
1864
|
|
|
1847
1865
|
// pkgs/@akanjs/cli/application/application.runner.ts
|
|
1848
1866
|
import { Logger as Logger3 } from "akanjs/common";
|
|
1849
|
-
var loadBuildRunner = async () => (await import("./applicationBuildRunner-
|
|
1867
|
+
var loadBuildRunner = async () => (await import("./applicationBuildRunner-w4917tje.js")).ApplicationBuildRunner;
|
|
1850
1868
|
var loadPrompts = async () => await import("@inquirer/prompts");
|
|
1851
1869
|
|
|
1852
1870
|
class ApplicationRunner extends runner("application") {
|
|
@@ -2038,59 +2056,137 @@ try {
|
|
|
2038
2056
|
setTimeout(() => openBrowser(`http://localhost:${env.AKAN_PUBLIC_CLIENT_PORT ?? env.PORT ?? "8282"}`), 3000);
|
|
2039
2057
|
return appHost;
|
|
2040
2058
|
}
|
|
2041
|
-
async buildMobile(app, platform, { target, env = "debug", profile = "release" } = {}) {
|
|
2059
|
+
async buildMobile(app, platform, { target, env = "debug", profile = "release", installer = false } = {}) {
|
|
2042
2060
|
const targets = await resolveMobileTargets(app, target);
|
|
2043
|
-
|
|
2061
|
+
if (installer && platform !== "windows")
|
|
2062
|
+
throw new Error(`--installer builds a Windows setup program; this computer builds for ${platform}.`);
|
|
2063
|
+
const carried = await this.#stageMobile(app, platform, targets, env);
|
|
2044
2064
|
await this.#runMobileTargets(targets, async (mobileTarget) => {
|
|
2045
|
-
this.#reportBuild(app, mobileTarget, await new NativeApp(app, mobileTarget).build(platform, {
|
|
2065
|
+
this.#reportBuild(app, mobileTarget, await new NativeApp(app, mobileTarget, env).build(platform, {
|
|
2066
|
+
profile,
|
|
2067
|
+
...carried && ApplicationRunner.carriesServer(mobileTarget, platform) ? { server: carried } : {},
|
|
2068
|
+
...installer ? { installer } : {}
|
|
2069
|
+
}));
|
|
2046
2070
|
});
|
|
2047
2071
|
}
|
|
2048
|
-
async
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
const nativeApp = new NativeApp(app, mobileTarget);
|
|
2072
|
+
async buildDesktop(app, options = {}) {
|
|
2073
|
+
await this.buildMobile(app, NativeApp.desktopPlatform(), options);
|
|
2074
|
+
}
|
|
2075
|
+
async startMobile(app, platform, { target, env = "local", operation = "local", device, teamId, interrupt } = {}) {
|
|
2076
|
+
const mobileTarget = await ApplicationRunner.startTarget(app, platform, target);
|
|
2077
|
+
const nativeApp = new NativeApp(app, mobileTarget, env);
|
|
2054
2078
|
const selection = { ...device ? { device } : {}, ...teamId ? { teamId } : {} };
|
|
2055
2079
|
if (operation === "release") {
|
|
2056
|
-
await this.#
|
|
2057
|
-
const running = await nativeApp.run(platform, {
|
|
2080
|
+
const carried = await this.#stageMobile(app, platform, [mobileTarget], env);
|
|
2081
|
+
const running = await nativeApp.run(platform, {
|
|
2082
|
+
...selection,
|
|
2083
|
+
profile: "release",
|
|
2084
|
+
...carried ? { server: carried } : {}
|
|
2085
|
+
});
|
|
2058
2086
|
await running.exited;
|
|
2059
2087
|
return;
|
|
2060
2088
|
}
|
|
2061
2089
|
const upstream = `http://localhost:${await app.getDevPort()}`;
|
|
2062
|
-
if (!await ApplicationRunner
|
|
2090
|
+
if (!await ApplicationRunner.answers(upstream, app.name))
|
|
2063
2091
|
throw new Error(`No dev server answers on ${upstream}; run \`akan start ${app.name}\` first.`);
|
|
2064
2092
|
const { i18n } = await app.getConfig();
|
|
2065
2093
|
const session = await nativeApp.dev(platform, { upstream, lang: i18n.defaultLocale, ...selection });
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2094
|
+
if (interrupt)
|
|
2095
|
+
interrupt.add(async () => await session.stop(), "Abandoning the app's shutdown; its window may stay open.", 130);
|
|
2096
|
+
else
|
|
2097
|
+
process.once("SIGINT", () => {
|
|
2098
|
+
session.stop().finally(() => process.exit(130));
|
|
2099
|
+
});
|
|
2069
2100
|
await session.exited;
|
|
2070
2101
|
}
|
|
2071
2102
|
async startDesktop(app, options = {}) {
|
|
2072
2103
|
await this.startMobile(app, NativeApp.desktopPlatform(), options);
|
|
2073
2104
|
}
|
|
2074
|
-
static async
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2105
|
+
static async startTarget(app, platform = NativeApp.desktopPlatform(), target) {
|
|
2106
|
+
const targets = await resolveMobileTargets(app, target);
|
|
2107
|
+
const [mobileTarget] = targets;
|
|
2108
|
+
if (!mobileTarget || targets.length > 1)
|
|
2109
|
+
throw new Error(`start-${platform === "ios" || platform === "android" ? platform : "desktop"} runs one mobile target at a time; pass --target <name>.`);
|
|
2110
|
+
return mobileTarget;
|
|
2111
|
+
}
|
|
2112
|
+
static async answers(url, appName) {
|
|
2113
|
+
const signal = AbortSignal.timeout(3000);
|
|
2114
|
+
const health = await fetch(new URL("/_akan/app/health", url), { signal }).catch(() => null);
|
|
2115
|
+
if (!health)
|
|
2079
2116
|
return false;
|
|
2080
|
-
}
|
|
2117
|
+
const info = await fetch(new URL("/_akan/app/info", url), { signal }).then(async (res) => res.ok ? await res.json() : null).catch(() => null);
|
|
2118
|
+
if (info?.appName === appName)
|
|
2119
|
+
return true;
|
|
2120
|
+
const stopIt = `Stop it (\`akan start ${appName} --kill\` takes the port over) or give ${appName} another port with AKAN_DEV_PORT`;
|
|
2121
|
+
if (typeof info?.appName === "string")
|
|
2122
|
+
throw new Error(`${url} is the dev server of ${info.appName}, not ${appName}. ${stopIt}.`);
|
|
2123
|
+
const { pid } = await health.json().catch(() => null) ?? {};
|
|
2124
|
+
throw new Error(typeof pid === "number" ? `${url} is an akan dev server (pid ${pid}) too old to say which app it serves. ${stopIt}.` : `${url} answers, but not as an akan dev server. Stop what holds the port or give ${appName} another port with AKAN_DEV_PORT.`);
|
|
2081
2125
|
}
|
|
2082
2126
|
async releaseIos(app, { target, env = "main", teamId, adHoc = false } = {}) {
|
|
2083
2127
|
const targets = await resolveMobileTargets(app, target);
|
|
2084
2128
|
await this.#buildMobileCsr(app, env);
|
|
2085
2129
|
for (const mobileTarget of targets)
|
|
2086
|
-
this.#reportBuild(app, mobileTarget, await new NativeApp(app, mobileTarget).releaseIos({ teamId, adHoc }));
|
|
2130
|
+
this.#reportBuild(app, mobileTarget, await new NativeApp(app, mobileTarget, env).releaseIos({ teamId, adHoc }));
|
|
2087
2131
|
}
|
|
2088
2132
|
async releaseAndroid(app, format, { target, env = "main" } = {}) {
|
|
2089
2133
|
const targets = await resolveMobileTargets(app, target);
|
|
2090
2134
|
NativeApp.androidSigning();
|
|
2091
2135
|
await this.#buildMobileCsr(app, env);
|
|
2092
2136
|
for (const mobileTarget of targets)
|
|
2093
|
-
this.#reportBuild(app, mobileTarget, await new NativeApp(app, mobileTarget).releaseAndroid({ formats: [format] }));
|
|
2137
|
+
this.#reportBuild(app, mobileTarget, await new NativeApp(app, mobileTarget, env).releaseAndroid({ formats: [format] }));
|
|
2138
|
+
}
|
|
2139
|
+
async packUpdate(app, platform, { target, env = "main", out, against }) {
|
|
2140
|
+
const targets = await resolveMobileTargets(app, target);
|
|
2141
|
+
const [mobileTarget] = targets;
|
|
2142
|
+
if (!mobileTarget || targets.length > 1)
|
|
2143
|
+
throw new Error("pack-update packs one mobile target at a time; pass --target <name>.");
|
|
2144
|
+
await this.#buildMobileCsr(app, env);
|
|
2145
|
+
const packed = await new NativeApp(app, mobileTarget, env).packUpdate(platform, { out });
|
|
2146
|
+
const size = packed.manifest.files.reduce((sum, file) => sum + file.size, 0);
|
|
2147
|
+
app.logger.info(`packed ${mobileTarget.name} ${platform} for channel '${packed.channel}' to ${packed.out}: ${packed.manifest.files.length} files, ${(size / 1024).toFixed(0)} KiB, native API ${packed.manifest.nativeApi}`);
|
|
2148
|
+
if (!against)
|
|
2149
|
+
return;
|
|
2150
|
+
const bundle = path5.join(packed.out, "bundle.json");
|
|
2151
|
+
const compat = await NativeApp.compareBundles(app.cwdPath, against, bundle);
|
|
2152
|
+
await Bun.write(path5.join(packed.out, "compat.json"), `${JSON.stringify({ against, ...compat }, null, 2)}
|
|
2153
|
+
`);
|
|
2154
|
+
if (!compat.compatible)
|
|
2155
|
+
throw new Error(`This bundle needs a new store build; the one ${against} came from provides another native API:
|
|
2156
|
+
- ${compat.problems.join(`
|
|
2157
|
+
- `)}`);
|
|
2158
|
+
app.logger.info(`runs in the store build of ${against}`);
|
|
2159
|
+
}
|
|
2160
|
+
async updateKeygen(app, platform, target) {
|
|
2161
|
+
const nativePlatform = platform === "desktop" ? NativeApp.desktopPlatform() : platform;
|
|
2162
|
+
const seen = new Set;
|
|
2163
|
+
for (const mobileTarget of await resolveMobileTargets(app, target ?? "all")) {
|
|
2164
|
+
const appId = resolveAppId(mobileTarget.config.appId, nativePlatform);
|
|
2165
|
+
if (seen.has(appId))
|
|
2166
|
+
continue;
|
|
2167
|
+
seen.add(appId);
|
|
2168
|
+
const { publicKey, keyPath, created } = await new NativeApp(app, mobileTarget).updateKeygen(nativePlatform);
|
|
2169
|
+
app.log(`${appId}: ${created ? "made" : "read"} ${keyPath}${created ? " (keep it private and backed up: without it, installed apps take no more updates)" : ""}`);
|
|
2170
|
+
app.log(` mobile: { updates: { url: "https://\u2026/${app.name}", publicKey: ${JSON.stringify(publicKey)} } }`);
|
|
2171
|
+
const declared = mobileTarget.config.updates?.publicKey;
|
|
2172
|
+
if (declared && declared !== publicKey)
|
|
2173
|
+
app.logger.warn(`mobile.targets.${mobileTarget.name}.updates.publicKey is another key's; releases would not verify.`);
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2176
|
+
async publishUpdate(app, platform, { target, env = "main", channel } = {}) {
|
|
2177
|
+
const targets = await resolveMobileTargets(app, target);
|
|
2178
|
+
const nativePlatform = platform === "desktop" ? NativeApp.desktopPlatform() : platform;
|
|
2179
|
+
const carried = await this.#stageMobile(app, nativePlatform, targets, env);
|
|
2180
|
+
for (const mobileTarget of targets) {
|
|
2181
|
+
const nativeApp = new NativeApp(app, mobileTarget, env);
|
|
2182
|
+
const published = await nativeApp.publishUpdate(nativePlatform, {
|
|
2183
|
+
...channel ? { channel } : {},
|
|
2184
|
+
...carried && ApplicationRunner.carriesServer(mobileTarget, nativePlatform) ? { server: carried } : {}
|
|
2185
|
+
});
|
|
2186
|
+
this.#reportBuild(app, mobileTarget, published.build);
|
|
2187
|
+
app.log(`${app.name}/${mobileTarget.name} ${published.bundle}: ${published.dir}/${published.channel}.json, ${published.files} files, ${Math.round(published.size / 1024)} KiB`);
|
|
2188
|
+
app.log(`Upload ${nativeApp.updatesDir} to ${mobileTarget.config.updates?.url}, the manifests last.`);
|
|
2189
|
+
}
|
|
2094
2190
|
}
|
|
2095
2191
|
#reportBuild(app, mobileTarget, { artifacts, warnings, signing }) {
|
|
2096
2192
|
for (const warning of warnings)
|
|
@@ -2100,6 +2196,16 @@ try {
|
|
|
2100
2196
|
for (const artifact of artifacts)
|
|
2101
2197
|
app.log(`${app.name}/${mobileTarget.name} ${artifact.kind}: ${artifact.path}`);
|
|
2102
2198
|
}
|
|
2199
|
+
static carriesServer({ config }, platform = NativeApp.desktopPlatform()) {
|
|
2200
|
+
return platform !== "ios" && platform !== "android" && config.native?.desktop?.server === true;
|
|
2201
|
+
}
|
|
2202
|
+
async#stageMobile(app, platform, targets, env) {
|
|
2203
|
+
const carries = targets.some((mobileTarget) => ApplicationRunner.carriesServer(mobileTarget, platform));
|
|
2204
|
+
if (carries)
|
|
2205
|
+
DesktopServerStage.assertCarriable(await app.getConfig());
|
|
2206
|
+
await this.#buildMobileCsr(app, env);
|
|
2207
|
+
return carries ? await new DesktopServerStage(app).prepare(env) : undefined;
|
|
2208
|
+
}
|
|
2103
2209
|
async#buildMobileCsr(app, env) {
|
|
2104
2210
|
const prevEnv = {
|
|
2105
2211
|
AKAN_PUBLIC_ENV: process.env.AKAN_PUBLIC_ENV,
|
|
@@ -2112,7 +2218,7 @@ try {
|
|
|
2112
2218
|
APP_OPERATION_MODE: "release"
|
|
2113
2219
|
});
|
|
2114
2220
|
try {
|
|
2115
|
-
await new (await loadBuildRunner())(app).build({ spinner: true });
|
|
2221
|
+
await new (await loadBuildRunner())(app, { environment: env }).build({ spinner: true });
|
|
2116
2222
|
} finally {
|
|
2117
2223
|
for (const [key, value] of Object.entries(prevEnv)) {
|
|
2118
2224
|
if (value === undefined)
|
|
@@ -2956,6 +3062,7 @@ class InterruptTeardown {
|
|
|
2956
3062
|
#listen;
|
|
2957
3063
|
#report;
|
|
2958
3064
|
#interrupted = false;
|
|
3065
|
+
#chain = Promise.resolve();
|
|
2959
3066
|
ownsExit = true;
|
|
2960
3067
|
constructor({ exit, listen, report } = {}) {
|
|
2961
3068
|
this.#exit = exit ?? ((code) => process.exit(code));
|
|
@@ -2964,36 +3071,48 @@ class InterruptTeardown {
|
|
|
2964
3071
|
});
|
|
2965
3072
|
this.#report = report ?? ((message) => Logger5.rawLog(message, undefined, "error"));
|
|
2966
3073
|
}
|
|
2967
|
-
add(run, abandoned) {
|
|
2968
|
-
this.#teardowns.push({ run, abandoned,
|
|
3074
|
+
add(run, abandoned, exitCode = 0) {
|
|
3075
|
+
this.#teardowns.push({ run, abandoned, exitCode, state: "pending" });
|
|
2969
3076
|
if (this.#teardowns.length === 1)
|
|
2970
3077
|
this.#listen(() => this.#onSignal());
|
|
2971
3078
|
}
|
|
3079
|
+
async runAll() {
|
|
3080
|
+
await this.#runTeardowns();
|
|
3081
|
+
}
|
|
2972
3082
|
#onSignal() {
|
|
2973
3083
|
if (this.#interrupted) {
|
|
2974
3084
|
for (const one of this.#teardowns)
|
|
2975
|
-
if (one.
|
|
3085
|
+
if (one.state !== "done")
|
|
2976
3086
|
this.#report(one.abandoned);
|
|
2977
3087
|
this.#exit(130);
|
|
2978
3088
|
return;
|
|
2979
3089
|
}
|
|
2980
3090
|
this.#interrupted = true;
|
|
2981
|
-
|
|
2982
|
-
one.running = true;
|
|
2983
|
-
await one.run().catch(() => {
|
|
2984
|
-
return;
|
|
2985
|
-
});
|
|
2986
|
-
one.running = false;
|
|
2987
|
-
})).finally(() => {
|
|
3091
|
+
this.#runTeardowns().finally(() => {
|
|
2988
3092
|
if (this.ownsExit)
|
|
2989
|
-
this.#exit(0);
|
|
3093
|
+
this.#exit(Math.max(0, ...this.#teardowns.map((one) => one.exitCode)));
|
|
2990
3094
|
});
|
|
2991
3095
|
}
|
|
3096
|
+
async#runTeardowns() {
|
|
3097
|
+
this.#chain = this.#chain.then(async () => {
|
|
3098
|
+
for (const one of this.#teardowns.toReversed()) {
|
|
3099
|
+
if (one.state !== "pending")
|
|
3100
|
+
continue;
|
|
3101
|
+
one.state = "running";
|
|
3102
|
+
await one.run().catch(() => {
|
|
3103
|
+
return;
|
|
3104
|
+
});
|
|
3105
|
+
one.state = "done";
|
|
3106
|
+
}
|
|
3107
|
+
});
|
|
3108
|
+
await this.#chain;
|
|
3109
|
+
}
|
|
2992
3110
|
}
|
|
2993
3111
|
|
|
2994
3112
|
// pkgs/@akanjs/cli/application/application.script.ts
|
|
2995
3113
|
class ApplicationScript extends script("application", [ApplicationRunner, LibraryScript]) {
|
|
2996
3114
|
static dbShutdownTimeoutMs = 20000;
|
|
3115
|
+
static devServerReadyTimeoutMs = DevSupervisor.bootTimeoutMs;
|
|
2997
3116
|
#interrupt = new InterruptTeardown;
|
|
2998
3117
|
async confirmDatabaseModeDependencyInstall(databaseMode, installSpecs) {
|
|
2999
3118
|
return await confirm({
|
|
@@ -3205,6 +3324,10 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
3205
3324
|
await app.scanSync({ write });
|
|
3206
3325
|
await this.applicationRunner.buildMobile(app, "android", options);
|
|
3207
3326
|
}
|
|
3327
|
+
async buildDesktop(app, { write = true, ...options } = {}) {
|
|
3328
|
+
await app.scanSync({ write });
|
|
3329
|
+
await this.applicationRunner.buildDesktop(app, options);
|
|
3330
|
+
}
|
|
3208
3331
|
async startIos(app, { write = true, ...options } = {}) {
|
|
3209
3332
|
await app.scanSync({ write });
|
|
3210
3333
|
await this.applicationRunner.startMobile(app, "ios", options);
|
|
@@ -3215,7 +3338,42 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
3215
3338
|
}
|
|
3216
3339
|
async startDesktop(app, { write = true, ...options } = {}) {
|
|
3217
3340
|
await app.scanSync({ write });
|
|
3218
|
-
|
|
3341
|
+
if (options.operation === "release")
|
|
3342
|
+
return await this.applicationRunner.startDesktop(app, options);
|
|
3343
|
+
const mobileTarget = await ApplicationRunner.startTarget(app, undefined, options.target);
|
|
3344
|
+
if (!ApplicationRunner.carriesServer(mobileTarget))
|
|
3345
|
+
return await this.applicationRunner.startDesktop(app, options);
|
|
3346
|
+
const upstream = `http://localhost:${await app.getDevPort()}`;
|
|
3347
|
+
if (await ApplicationRunner.answers(upstream, app.name))
|
|
3348
|
+
app.log(`The desktop app follows the dev server on ${upstream}.`);
|
|
3349
|
+
else
|
|
3350
|
+
await this.#startDevServerFor(app, upstream);
|
|
3351
|
+
try {
|
|
3352
|
+
await this.applicationRunner.startDesktop(app, { ...options, interrupt: this.#interrupt });
|
|
3353
|
+
} finally {
|
|
3354
|
+
await this.#interrupt.runAll();
|
|
3355
|
+
}
|
|
3356
|
+
}
|
|
3357
|
+
async#startDevServerFor(app, upstream) {
|
|
3358
|
+
app.log(`No dev server answers on ${upstream}; starting \`akan start ${app.name}\` for the desktop app.`);
|
|
3359
|
+
let settle = () => {};
|
|
3360
|
+
const settled = new Promise((resolve) => settle = resolve);
|
|
3361
|
+
const appHost = await this.startOne(app, {
|
|
3362
|
+
write: false,
|
|
3363
|
+
onDevEvent: (event) => {
|
|
3364
|
+
if ("state" in event && (event.state === "ready" || event.state === "failed"))
|
|
3365
|
+
settle(event.state);
|
|
3366
|
+
}
|
|
3367
|
+
});
|
|
3368
|
+
this.#interrupt.add(async () => {
|
|
3369
|
+
await appHost.stop();
|
|
3370
|
+
}, "Abandoning the dev server shutdown; its processes may still be running.", 130);
|
|
3371
|
+
let state;
|
|
3372
|
+
const timedOut = await DevSupervisor.timesOut(settled.then((settledState) => state = settledState), ApplicationScript.devServerReadyTimeoutMs);
|
|
3373
|
+
if (state === "ready")
|
|
3374
|
+
return;
|
|
3375
|
+
await this.#interrupt.runAll();
|
|
3376
|
+
throw new Error(timedOut ? `akan start ${app.name} did not answer within ${ApplicationScript.devServerReadyTimeoutMs / 1000}s; see its log above.` : `akan start ${app.name} gave up restarting its server; see its log above.`);
|
|
3219
3377
|
}
|
|
3220
3378
|
async releaseIos(app, {
|
|
3221
3379
|
write = true,
|
|
@@ -3235,6 +3393,27 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
3235
3393
|
ApplicationScript.#assertReleaseEnv("releaseAndroid", options.env ?? "main", allowLocalRelease);
|
|
3236
3394
|
await this.applicationRunner.releaseAndroid(app, format, options);
|
|
3237
3395
|
}
|
|
3396
|
+
async packUpdate(app, platform, {
|
|
3397
|
+
write = true,
|
|
3398
|
+
allowLocalRelease = false,
|
|
3399
|
+
...options
|
|
3400
|
+
} = {}) {
|
|
3401
|
+
await app.scanSync({ write });
|
|
3402
|
+
ApplicationScript.#assertReleaseEnv("packUpdate", options.env ?? "main", allowLocalRelease);
|
|
3403
|
+
await this.applicationRunner.packUpdate(app, platform, options);
|
|
3404
|
+
}
|
|
3405
|
+
async updateKeygen(app, platform, { target } = {}) {
|
|
3406
|
+
await this.applicationRunner.updateKeygen(app, platform, target);
|
|
3407
|
+
}
|
|
3408
|
+
async publishUpdate(app, platform, {
|
|
3409
|
+
write = true,
|
|
3410
|
+
allowLocalRelease = false,
|
|
3411
|
+
...options
|
|
3412
|
+
} = {}) {
|
|
3413
|
+
await app.scanSync({ write });
|
|
3414
|
+
ApplicationScript.#assertReleaseEnv("publishUpdate", options.env ?? "main", allowLocalRelease);
|
|
3415
|
+
await this.applicationRunner.publishUpdate(app, platform, options);
|
|
3416
|
+
}
|
|
3238
3417
|
static #assertReleaseEnv(command, env, allowLocalRelease) {
|
|
3239
3418
|
if (env === "local" && !allowLocalRelease)
|
|
3240
3419
|
throw new Error(`${command} --env local is blocked. Pass allowLocalRelease only for explicit local release testing.`);
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
isScannedRootEntry,
|
|
9
9
|
AppExecutor,
|
|
10
10
|
LibExecutor
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-r8gp8zk3.js";
|
|
12
12
|
import {
|
|
13
13
|
FileSys2
|
|
14
14
|
} from "./index-52w0fvh8.js";
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
workflowPathsForPlan,
|
|
22
22
|
workflowRunArtifactPath,
|
|
23
23
|
workflowSyncDir
|
|
24
|
-
} from "./index-
|
|
24
|
+
} from "./index-2s2e5qnd.js";
|
|
25
25
|
|
|
26
26
|
// pkgs/@akanjs/devkit/akanContext.ts
|
|
27
27
|
import { readdir } from "fs/promises";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
script
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-b68zfsvz.js";
|
|
5
5
|
import {
|
|
6
6
|
AppExecutor,
|
|
7
7
|
LibExecutor,
|
|
8
8
|
ModuleExecutor
|
|
9
|
-
} from "./index-
|
|
9
|
+
} from "./index-r8gp8zk3.js";
|
|
10
10
|
import {
|
|
11
11
|
workflowStatus,
|
|
12
12
|
compactDiagnostics,
|
|
@@ -41,10 +41,10 @@ import {
|
|
|
41
41
|
hasSignalFactoryEntry,
|
|
42
42
|
insertSignalFactoryEntry,
|
|
43
43
|
addFieldUiPolicyForType
|
|
44
|
-
} from "./index-
|
|
44
|
+
} from "./index-2s2e5qnd.js";
|
|
45
45
|
import {
|
|
46
46
|
ModuleScript
|
|
47
|
-
} from "./index-
|
|
47
|
+
} from "./index-genegfnt.js";
|
|
48
48
|
|
|
49
49
|
// pkgs/@akanjs/cli/primitive/primitive.script.ts
|
|
50
50
|
import { capitalize, lowerlize } from "akanjs/common";
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import {
|
|
3
3
|
runner,
|
|
4
4
|
script
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-b68zfsvz.js";
|
|
6
6
|
import {
|
|
7
7
|
generatedFilesForSync,
|
|
8
8
|
createPassedPrimitiveReport,
|
|
9
9
|
scalarChangedFiles
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-2s2e5qnd.js";
|
|
11
11
|
import {
|
|
12
12
|
pluralizeName
|
|
13
13
|
} from "./index-nz8prx9g.js";
|
|
@@ -5,13 +5,13 @@ import {
|
|
|
5
5
|
writeGeneratedSyncState,
|
|
6
6
|
createRepairReport,
|
|
7
7
|
renderRepairReport
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-2s2e5qnd.js";
|
|
9
9
|
import {
|
|
10
10
|
AkanContextAnalyzer
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-0pqzrbpr.js";
|
|
12
12
|
import {
|
|
13
13
|
runner
|
|
14
|
-
} from "./index-
|
|
14
|
+
} from "./index-b68zfsvz.js";
|
|
15
15
|
|
|
16
16
|
// pkgs/@akanjs/cli/repair/repair.runner.ts
|
|
17
17
|
var spawnShell = async (workspace, command) => await workspace.spawn("bash", ["-lc", command.startsWith("akan ") ? `bun run ${command}` : command], {
|
|
@@ -116,7 +116,7 @@ class SubagentPool2 {
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
async#run(id, kind, prompt, signal) {
|
|
119
|
-
const { CodeAgent } = await import("./CodeAgent-
|
|
119
|
+
const { CodeAgent } = await import("./CodeAgent-7acv4ah8.js");
|
|
120
120
|
const budget = this.#options.parent.tools.subagent;
|
|
121
121
|
const child = SubagentPool2.childOf(this.#options.parent, kind);
|
|
122
122
|
const agent = await CodeAgent.create({
|
|
@@ -5,19 +5,19 @@ import {
|
|
|
5
5
|
} from "./index-94s080qm.js";
|
|
6
6
|
import {
|
|
7
7
|
script
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-b68zfsvz.js";
|
|
9
9
|
import {
|
|
10
10
|
PkgExecutor
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-r8gp8zk3.js";
|
|
12
12
|
import {
|
|
13
13
|
ApplicationScript
|
|
14
|
-
} from "./index-
|
|
14
|
+
} from "./index-0ej0sr6m.js";
|
|
15
15
|
import {
|
|
16
16
|
PackageScript
|
|
17
|
-
} from "./index-
|
|
17
|
+
} from "./index-k7809wmg.js";
|
|
18
18
|
import {
|
|
19
19
|
CloudRunner
|
|
20
|
-
} from "./index-
|
|
20
|
+
} from "./index-rrt9pnb4.js";
|
|
21
21
|
|
|
22
22
|
// pkgs/@akanjs/cli/cloud/cloud.script.ts
|
|
23
23
|
import { Logger } from "akanjs/common";
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
LibExecutor,
|
|
11
11
|
PkgExecutor,
|
|
12
12
|
ModuleExecutor
|
|
13
|
-
} from "./index-
|
|
13
|
+
} from "./index-r8gp8zk3.js";
|
|
14
14
|
|
|
15
15
|
// pkgs/@akanjs/devkit/commandDecorators/camelToKebabCase.ts
|
|
16
16
|
var camelToKebabCase = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
akanCodePaths2,
|
|
5
5
|
McpServerConfig,
|
|
6
6
|
McpSignIn
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-52n8xr63.js";
|
|
8
8
|
import {
|
|
9
9
|
stripAnsi
|
|
10
10
|
} from "./index-7md2g9vw.js";
|
|
@@ -511,7 +511,7 @@ class AkanToolPack2 {
|
|
|
511
511
|
return { name: "akan-tools", factory: async (pi) => await this.#register(pi) };
|
|
512
512
|
}
|
|
513
513
|
async names() {
|
|
514
|
-
const { ContextRunner } = await import("./context.runner-
|
|
514
|
+
const { ContextRunner } = await import("./context.runner-nzaf8c98.js");
|
|
515
515
|
return [
|
|
516
516
|
...new ContextRunner().listMcpTools(this.#options.mode).map((tool) => tool.name),
|
|
517
517
|
AkanToolPack2.verifyToolName
|
|
@@ -519,7 +519,7 @@ class AkanToolPack2 {
|
|
|
519
519
|
}
|
|
520
520
|
static verifyToolName = "akan_verify";
|
|
521
521
|
async#register(pi) {
|
|
522
|
-
const { ContextRunner } = await import("./context.runner-
|
|
522
|
+
const { ContextRunner } = await import("./context.runner-nzaf8c98.js");
|
|
523
523
|
const runner = new ContextRunner;
|
|
524
524
|
const guidelineNames = await AkanToolPack2.#guidelineNames();
|
|
525
525
|
for (const tool of runner.listMcpTools(this.#options.mode, { guidelineNames })) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
resolveSsrPageEntriesForApp
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-r8gp8zk3.js";
|
|
5
5
|
import {
|
|
6
6
|
computeRouteSeedIndex,
|
|
7
7
|
saveRouteSeedIndex,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
CsrEntryFiles,
|
|
17
17
|
PagesEntrySourceGenerator,
|
|
18
18
|
PagesBundleBuilder
|
|
19
|
-
} from "./index-
|
|
19
|
+
} from "./index-ttn00pr3.js";
|
|
20
20
|
import {
|
|
21
21
|
SOURCE_EXTS
|
|
22
22
|
} from "./index-48k96p55.js";
|
|
@@ -1640,7 +1640,8 @@ class SsrBaseArtifactBuilder {
|
|
|
1640
1640
|
web: SsrBaseArtifactBuilder.servedWeb(this.#command, akanConfig.web),
|
|
1641
1641
|
deepLinkAssociations: Object.values(akanConfig.mobile.targets).filter((target) => (target.deepLinks?.domains?.length ?? 0) > 0).map((target) => ({
|
|
1642
1642
|
targetName: target.name,
|
|
1643
|
-
|
|
1643
|
+
iosAppId: SsrBaseArtifactBuilder.#appIdOn(target.appId, "ios"),
|
|
1644
|
+
androidAppId: SsrBaseArtifactBuilder.#appIdOn(target.appId, "android"),
|
|
1644
1645
|
domains: target.deepLinks?.domains ?? [],
|
|
1645
1646
|
iosTeamId: target.deepLinks?.ios?.teamId,
|
|
1646
1647
|
androidSha256CertFingerprints: target.deepLinks?.android?.sha256CertFingerprints
|
|
@@ -1736,6 +1737,9 @@ ${preparedCssText}`).toString(36);
|
|
|
1736
1737
|
this.#app.verbose(`[base-artifact] wrote ${preparedCssText.length} bytes of CSS for ${basePath} -> ${cssRelPath}`);
|
|
1737
1738
|
return [basePath, { cssUrl, cssRelPath }];
|
|
1738
1739
|
}
|
|
1740
|
+
static #appIdOn(appId, platform) {
|
|
1741
|
+
return typeof appId === "string" ? appId : appId[platform] ?? appId.default ?? null;
|
|
1742
|
+
}
|
|
1739
1743
|
static #warnDroppedImports(app, cssRelPath, css, imported) {
|
|
1740
1744
|
for (const { cssPath, declaredNames } of imported) {
|
|
1741
1745
|
if (declaredNames.length === 0 || declaredNames.some((name) => css.includes(`${name}:`)))
|