@akanjs/cli 3.0.0-beta.26 → 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-p65jja35.js → CodeAgent-7acv4ah8.js} +2 -2
- package/{CodeTui-5xr8kxx4.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-afajz1m5.js → application.command-xpnkyx4z.js} +70 -8
- package/{applicationBuildRunner-412y0345.js → applicationBuildRunner-w4917tje.js} +67 -22
- package/buildBatch.proc.js +3 -3
- package/{cloud.command-yz0h8a2e.js → cloud.command-7yd624qd.js} +9 -9
- package/cloud.script-25vzkz7b.js +20 -0
- package/{code.command-jhrjttm1.js → code.command-fpx4gzmy.js} +6 -6
- package/commandManifest.json +1 -1
- package/{context.command-xncdvv7n.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-cfj73ck1.js → index-0ej0sr6m.js} +225 -47
- 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-tpdn30ya.js → index-52n8xr63.js} +1 -1
- package/{index-mq74nzf8.js → index-9j0kykc6.js} +5 -5
- package/{index-58cyna2s.js → index-b68zfsvz.js} +1 -1
- package/{index-qm4fppfk.js → index-ewbek95g.js} +3 -3
- package/{index-wvebzf0y.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-50rq2qms.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-cd9qt2t6.js → index-ttn00pr3.js} +223 -33
- package/{index-7yxndzea.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-fm41vdtw.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-y1p56wyv.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-d8he10tv.js → workspace.command-wypqk2zb.js} +20 -20
- package/cloud.script-zez2b8am.js +0 -20
- package/context.runner-pjy89k2s.js +0 -21
- package/index-ys6f0bvh.js +0 -471
|
@@ -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,60 +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
|
-
|
|
2069
|
-
|
|
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
|
+
});
|
|
2070
2100
|
await session.exited;
|
|
2071
2101
|
}
|
|
2072
2102
|
async startDesktop(app, options = {}) {
|
|
2073
2103
|
await this.startMobile(app, NativeApp.desktopPlatform(), options);
|
|
2074
2104
|
}
|
|
2075
|
-
static async
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
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)
|
|
2080
2116
|
return false;
|
|
2081
|
-
}
|
|
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.`);
|
|
2082
2125
|
}
|
|
2083
2126
|
async releaseIos(app, { target, env = "main", teamId, adHoc = false } = {}) {
|
|
2084
2127
|
const targets = await resolveMobileTargets(app, target);
|
|
2085
2128
|
await this.#buildMobileCsr(app, env);
|
|
2086
2129
|
for (const mobileTarget of targets)
|
|
2087
|
-
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 }));
|
|
2088
2131
|
}
|
|
2089
2132
|
async releaseAndroid(app, format, { target, env = "main" } = {}) {
|
|
2090
2133
|
const targets = await resolveMobileTargets(app, target);
|
|
2091
2134
|
NativeApp.androidSigning();
|
|
2092
2135
|
await this.#buildMobileCsr(app, env);
|
|
2093
2136
|
for (const mobileTarget of targets)
|
|
2094
|
-
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
|
+
}
|
|
2095
2190
|
}
|
|
2096
2191
|
#reportBuild(app, mobileTarget, { artifacts, warnings, signing }) {
|
|
2097
2192
|
for (const warning of warnings)
|
|
@@ -2101,6 +2196,16 @@ try {
|
|
|
2101
2196
|
for (const artifact of artifacts)
|
|
2102
2197
|
app.log(`${app.name}/${mobileTarget.name} ${artifact.kind}: ${artifact.path}`);
|
|
2103
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
|
+
}
|
|
2104
2209
|
async#buildMobileCsr(app, env) {
|
|
2105
2210
|
const prevEnv = {
|
|
2106
2211
|
AKAN_PUBLIC_ENV: process.env.AKAN_PUBLIC_ENV,
|
|
@@ -2113,7 +2218,7 @@ try {
|
|
|
2113
2218
|
APP_OPERATION_MODE: "release"
|
|
2114
2219
|
});
|
|
2115
2220
|
try {
|
|
2116
|
-
await new (await loadBuildRunner())(app).build({ spinner: true });
|
|
2221
|
+
await new (await loadBuildRunner())(app, { environment: env }).build({ spinner: true });
|
|
2117
2222
|
} finally {
|
|
2118
2223
|
for (const [key, value] of Object.entries(prevEnv)) {
|
|
2119
2224
|
if (value === undefined)
|
|
@@ -2957,6 +3062,7 @@ class InterruptTeardown {
|
|
|
2957
3062
|
#listen;
|
|
2958
3063
|
#report;
|
|
2959
3064
|
#interrupted = false;
|
|
3065
|
+
#chain = Promise.resolve();
|
|
2960
3066
|
ownsExit = true;
|
|
2961
3067
|
constructor({ exit, listen, report } = {}) {
|
|
2962
3068
|
this.#exit = exit ?? ((code) => process.exit(code));
|
|
@@ -2965,36 +3071,48 @@ class InterruptTeardown {
|
|
|
2965
3071
|
});
|
|
2966
3072
|
this.#report = report ?? ((message) => Logger5.rawLog(message, undefined, "error"));
|
|
2967
3073
|
}
|
|
2968
|
-
add(run, abandoned) {
|
|
2969
|
-
this.#teardowns.push({ run, abandoned,
|
|
3074
|
+
add(run, abandoned, exitCode = 0) {
|
|
3075
|
+
this.#teardowns.push({ run, abandoned, exitCode, state: "pending" });
|
|
2970
3076
|
if (this.#teardowns.length === 1)
|
|
2971
3077
|
this.#listen(() => this.#onSignal());
|
|
2972
3078
|
}
|
|
3079
|
+
async runAll() {
|
|
3080
|
+
await this.#runTeardowns();
|
|
3081
|
+
}
|
|
2973
3082
|
#onSignal() {
|
|
2974
3083
|
if (this.#interrupted) {
|
|
2975
3084
|
for (const one of this.#teardowns)
|
|
2976
|
-
if (one.
|
|
3085
|
+
if (one.state !== "done")
|
|
2977
3086
|
this.#report(one.abandoned);
|
|
2978
3087
|
this.#exit(130);
|
|
2979
3088
|
return;
|
|
2980
3089
|
}
|
|
2981
3090
|
this.#interrupted = true;
|
|
2982
|
-
|
|
2983
|
-
one.running = true;
|
|
2984
|
-
await one.run().catch(() => {
|
|
2985
|
-
return;
|
|
2986
|
-
});
|
|
2987
|
-
one.running = false;
|
|
2988
|
-
})).finally(() => {
|
|
3091
|
+
this.#runTeardowns().finally(() => {
|
|
2989
3092
|
if (this.ownsExit)
|
|
2990
|
-
this.#exit(0);
|
|
3093
|
+
this.#exit(Math.max(0, ...this.#teardowns.map((one) => one.exitCode)));
|
|
2991
3094
|
});
|
|
2992
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
|
+
}
|
|
2993
3110
|
}
|
|
2994
3111
|
|
|
2995
3112
|
// pkgs/@akanjs/cli/application/application.script.ts
|
|
2996
3113
|
class ApplicationScript extends script("application", [ApplicationRunner, LibraryScript]) {
|
|
2997
3114
|
static dbShutdownTimeoutMs = 20000;
|
|
3115
|
+
static devServerReadyTimeoutMs = DevSupervisor.bootTimeoutMs;
|
|
2998
3116
|
#interrupt = new InterruptTeardown;
|
|
2999
3117
|
async confirmDatabaseModeDependencyInstall(databaseMode, installSpecs) {
|
|
3000
3118
|
return await confirm({
|
|
@@ -3206,6 +3324,10 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
3206
3324
|
await app.scanSync({ write });
|
|
3207
3325
|
await this.applicationRunner.buildMobile(app, "android", options);
|
|
3208
3326
|
}
|
|
3327
|
+
async buildDesktop(app, { write = true, ...options } = {}) {
|
|
3328
|
+
await app.scanSync({ write });
|
|
3329
|
+
await this.applicationRunner.buildDesktop(app, options);
|
|
3330
|
+
}
|
|
3209
3331
|
async startIos(app, { write = true, ...options } = {}) {
|
|
3210
3332
|
await app.scanSync({ write });
|
|
3211
3333
|
await this.applicationRunner.startMobile(app, "ios", options);
|
|
@@ -3216,7 +3338,42 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
3216
3338
|
}
|
|
3217
3339
|
async startDesktop(app, { write = true, ...options } = {}) {
|
|
3218
3340
|
await app.scanSync({ write });
|
|
3219
|
-
|
|
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.`);
|
|
3220
3377
|
}
|
|
3221
3378
|
async releaseIos(app, {
|
|
3222
3379
|
write = true,
|
|
@@ -3236,6 +3393,27 @@ class ApplicationScript extends script("application", [ApplicationRunner, Librar
|
|
|
3236
3393
|
ApplicationScript.#assertReleaseEnv("releaseAndroid", options.env ?? "main", allowLocalRelease);
|
|
3237
3394
|
await this.applicationRunner.releaseAndroid(app, format, options);
|
|
3238
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
|
+
}
|
|
3239
3417
|
static #assertReleaseEnv(command, env, allowLocalRelease) {
|
|
3240
3418
|
if (env === "local" && !allowLocalRelease)
|
|
3241
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}:`)))
|