@coreframe/scripts 0.2.19 → 0.2.21
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/dist/coreframe.d.ts +84 -58
- package/dist/coreframe.js +18 -16
- package/package.json +9 -9
package/dist/coreframe.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
3
3
|
parse(context: import("@alloc/cmd-ts/dist/cjs/argparser").ParseContext): Promise<import("@alloc/cmd-ts/dist/cjs/argparser").ParsingResult<{
|
|
4
4
|
command: "build";
|
|
5
5
|
args: {
|
|
6
|
-
platform: "web" | "ios" | "android" | "macos" | undefined;
|
|
6
|
+
platform: "web" | "ios" | "android" | "macos" | "windows" | "linux" | undefined;
|
|
7
7
|
apiOrigin: string | undefined;
|
|
8
8
|
profile: boolean;
|
|
9
9
|
simulator: boolean;
|
|
@@ -15,10 +15,35 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
15
15
|
args: {
|
|
16
16
|
mode: string | undefined;
|
|
17
17
|
};
|
|
18
|
+
} | {
|
|
19
|
+
command: "dev";
|
|
20
|
+
args: {
|
|
21
|
+
port: number;
|
|
22
|
+
};
|
|
18
23
|
} | {
|
|
19
24
|
command: "typegen";
|
|
20
25
|
args: {};
|
|
21
26
|
};
|
|
27
|
+
} | {
|
|
28
|
+
command: "dev";
|
|
29
|
+
args: {
|
|
30
|
+
debug: "managed-dev-overlay" | undefined;
|
|
31
|
+
flutterDebug: boolean;
|
|
32
|
+
flutterOutput: "filtered" | "full";
|
|
33
|
+
https: boolean;
|
|
34
|
+
fresh: boolean;
|
|
35
|
+
host: string | undefined;
|
|
36
|
+
lan: boolean;
|
|
37
|
+
managed: boolean;
|
|
38
|
+
noManaged: boolean;
|
|
39
|
+
reuseVite: boolean;
|
|
40
|
+
simulator: boolean;
|
|
41
|
+
stop: boolean;
|
|
42
|
+
platform: "web" | "ios" | "android" | "macos" | "windows" | "linux" | "webext" | undefined;
|
|
43
|
+
device: string | undefined;
|
|
44
|
+
port: number | undefined;
|
|
45
|
+
verbose: boolean;
|
|
46
|
+
};
|
|
22
47
|
} | {
|
|
23
48
|
command: "typegen";
|
|
24
49
|
args: {};
|
|
@@ -46,6 +71,11 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
46
71
|
variantWidths: number[] | undefined;
|
|
47
72
|
json: boolean;
|
|
48
73
|
};
|
|
74
|
+
} | {
|
|
75
|
+
command: "backup";
|
|
76
|
+
args: {
|
|
77
|
+
branch: string;
|
|
78
|
+
};
|
|
49
79
|
} | {
|
|
50
80
|
command: "check";
|
|
51
81
|
args: {
|
|
@@ -71,7 +101,7 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
71
101
|
args: {
|
|
72
102
|
command: "check";
|
|
73
103
|
args: {
|
|
74
|
-
platform: "ios" | "android" | "macos";
|
|
104
|
+
platform: "ios" | "android" | "macos" | "windows" | "linux";
|
|
75
105
|
apiOrigin: string;
|
|
76
106
|
};
|
|
77
107
|
} | {
|
|
@@ -87,7 +117,7 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
87
117
|
} | {
|
|
88
118
|
command: "prepare";
|
|
89
119
|
args: {
|
|
90
|
-
platform: "ios" | "android" | "macos";
|
|
120
|
+
platform: "ios" | "android" | "macos" | "windows" | "linux";
|
|
91
121
|
apiOrigin: string;
|
|
92
122
|
};
|
|
93
123
|
};
|
|
@@ -114,10 +144,6 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
114
144
|
runMigrations: boolean;
|
|
115
145
|
skipMigrations: boolean;
|
|
116
146
|
skipPostDeployChecks: boolean;
|
|
117
|
-
tauriLocalPlatforms: ("ios" | "android" | "macos" | "windows" | "linux")[];
|
|
118
|
-
tauriWorkflowName: string | undefined;
|
|
119
|
-
tauriWorkflowPlatforms: ("ios" | "android" | "macos" | "windows" | "linux")[];
|
|
120
|
-
tauriWorkflowRef: string | undefined;
|
|
121
147
|
yes: boolean;
|
|
122
148
|
};
|
|
123
149
|
} | {
|
|
@@ -172,25 +198,6 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
172
198
|
check: boolean;
|
|
173
199
|
};
|
|
174
200
|
};
|
|
175
|
-
} | {
|
|
176
|
-
command: "dev";
|
|
177
|
-
args: {
|
|
178
|
-
debug: "managed-dev-overlay" | undefined;
|
|
179
|
-
flutterDebug: boolean;
|
|
180
|
-
flutterOutput: "filtered" | "full";
|
|
181
|
-
https: boolean;
|
|
182
|
-
fresh: boolean;
|
|
183
|
-
host: string | undefined;
|
|
184
|
-
lan: boolean;
|
|
185
|
-
managed: boolean;
|
|
186
|
-
noManaged: boolean;
|
|
187
|
-
reuseVite: boolean;
|
|
188
|
-
stop: boolean;
|
|
189
|
-
platform: "web" | "ios" | "android" | "macos" | "webext" | "desktop" | undefined;
|
|
190
|
-
device: string | undefined;
|
|
191
|
-
port: number | undefined;
|
|
192
|
-
verbose: boolean;
|
|
193
|
-
};
|
|
194
201
|
} | {
|
|
195
202
|
command: "preview";
|
|
196
203
|
args: {
|
|
@@ -301,7 +308,7 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
301
308
|
} & import("@alloc/cmd-ts/dist/cjs/helpdoc").Named & Partial<import("@alloc/cmd-ts/dist/cjs/helpdoc").Descriptive & import("@alloc/cmd-ts/dist/cjs/helpdoc").Versioned> & import("@alloc/cmd-ts/dist/cjs/helpdoc").PrintHelp & Partial<import("@alloc/cmd-ts/dist/cjs/helpdoc").Versioned> & import("@alloc/cmd-ts/dist/cjs/argparser").Register & import("@alloc/cmd-ts/dist/cjs/runner").Handling<{
|
|
302
309
|
command: "build";
|
|
303
310
|
args: {
|
|
304
|
-
platform: "web" | "ios" | "android" | "macos" | undefined;
|
|
311
|
+
platform: "web" | "ios" | "android" | "macos" | "windows" | "linux" | undefined;
|
|
305
312
|
apiOrigin: string | undefined;
|
|
306
313
|
profile: boolean;
|
|
307
314
|
simulator: boolean;
|
|
@@ -313,10 +320,35 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
313
320
|
args: {
|
|
314
321
|
mode: string | undefined;
|
|
315
322
|
};
|
|
323
|
+
} | {
|
|
324
|
+
command: "dev";
|
|
325
|
+
args: {
|
|
326
|
+
port: number;
|
|
327
|
+
};
|
|
316
328
|
} | {
|
|
317
329
|
command: "typegen";
|
|
318
330
|
args: {};
|
|
319
331
|
};
|
|
332
|
+
} | {
|
|
333
|
+
command: "dev";
|
|
334
|
+
args: {
|
|
335
|
+
debug: "managed-dev-overlay" | undefined;
|
|
336
|
+
flutterDebug: boolean;
|
|
337
|
+
flutterOutput: "filtered" | "full";
|
|
338
|
+
https: boolean;
|
|
339
|
+
fresh: boolean;
|
|
340
|
+
host: string | undefined;
|
|
341
|
+
lan: boolean;
|
|
342
|
+
managed: boolean;
|
|
343
|
+
noManaged: boolean;
|
|
344
|
+
reuseVite: boolean;
|
|
345
|
+
simulator: boolean;
|
|
346
|
+
stop: boolean;
|
|
347
|
+
platform: "web" | "ios" | "android" | "macos" | "windows" | "linux" | "webext" | undefined;
|
|
348
|
+
device: string | undefined;
|
|
349
|
+
port: number | undefined;
|
|
350
|
+
verbose: boolean;
|
|
351
|
+
};
|
|
320
352
|
} | {
|
|
321
353
|
command: "typegen";
|
|
322
354
|
args: {};
|
|
@@ -344,6 +376,11 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
344
376
|
variantWidths: number[] | undefined;
|
|
345
377
|
json: boolean;
|
|
346
378
|
};
|
|
379
|
+
} | {
|
|
380
|
+
command: "backup";
|
|
381
|
+
args: {
|
|
382
|
+
branch: string;
|
|
383
|
+
};
|
|
347
384
|
} | {
|
|
348
385
|
command: "check";
|
|
349
386
|
args: {
|
|
@@ -369,7 +406,7 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
369
406
|
args: {
|
|
370
407
|
command: "check";
|
|
371
408
|
args: {
|
|
372
|
-
platform: "ios" | "android" | "macos";
|
|
409
|
+
platform: "ios" | "android" | "macos" | "windows" | "linux";
|
|
373
410
|
apiOrigin: string;
|
|
374
411
|
};
|
|
375
412
|
} | {
|
|
@@ -385,7 +422,7 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
385
422
|
} | {
|
|
386
423
|
command: "prepare";
|
|
387
424
|
args: {
|
|
388
|
-
platform: "ios" | "android" | "macos";
|
|
425
|
+
platform: "ios" | "android" | "macos" | "windows" | "linux";
|
|
389
426
|
apiOrigin: string;
|
|
390
427
|
};
|
|
391
428
|
};
|
|
@@ -412,10 +449,6 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
412
449
|
runMigrations: boolean;
|
|
413
450
|
skipMigrations: boolean;
|
|
414
451
|
skipPostDeployChecks: boolean;
|
|
415
|
-
tauriLocalPlatforms: ("ios" | "android" | "macos" | "windows" | "linux")[];
|
|
416
|
-
tauriWorkflowName: string | undefined;
|
|
417
|
-
tauriWorkflowPlatforms: ("ios" | "android" | "macos" | "windows" | "linux")[];
|
|
418
|
-
tauriWorkflowRef: string | undefined;
|
|
419
452
|
yes: boolean;
|
|
420
453
|
};
|
|
421
454
|
} | {
|
|
@@ -470,25 +503,6 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
470
503
|
check: boolean;
|
|
471
504
|
};
|
|
472
505
|
};
|
|
473
|
-
} | {
|
|
474
|
-
command: "dev";
|
|
475
|
-
args: {
|
|
476
|
-
debug: "managed-dev-overlay" | undefined;
|
|
477
|
-
flutterDebug: boolean;
|
|
478
|
-
flutterOutput: "filtered" | "full";
|
|
479
|
-
https: boolean;
|
|
480
|
-
fresh: boolean;
|
|
481
|
-
host: string | undefined;
|
|
482
|
-
lan: boolean;
|
|
483
|
-
managed: boolean;
|
|
484
|
-
noManaged: boolean;
|
|
485
|
-
reuseVite: boolean;
|
|
486
|
-
stop: boolean;
|
|
487
|
-
platform: "web" | "ios" | "android" | "macos" | "webext" | "desktop" | undefined;
|
|
488
|
-
device: string | undefined;
|
|
489
|
-
port: number | undefined;
|
|
490
|
-
verbose: boolean;
|
|
491
|
-
};
|
|
492
506
|
} | {
|
|
493
507
|
command: "preview";
|
|
494
508
|
args: {
|
|
@@ -603,10 +617,16 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
603
617
|
value: {
|
|
604
618
|
command: "build";
|
|
605
619
|
value: Promise<void>;
|
|
620
|
+
} | {
|
|
621
|
+
command: "dev";
|
|
622
|
+
value: Promise<void>;
|
|
606
623
|
} | {
|
|
607
624
|
command: "typegen";
|
|
608
625
|
value: Promise<void>;
|
|
609
626
|
};
|
|
627
|
+
} | {
|
|
628
|
+
command: "dev";
|
|
629
|
+
value: Promise<void> | Promise<boolean>;
|
|
610
630
|
} | {
|
|
611
631
|
command: "typegen";
|
|
612
632
|
value: Promise<void>;
|
|
@@ -621,6 +641,9 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
621
641
|
} | {
|
|
622
642
|
command: "add";
|
|
623
643
|
value: Promise<void>;
|
|
644
|
+
} | {
|
|
645
|
+
command: "backup";
|
|
646
|
+
value: Promise<void>;
|
|
624
647
|
} | {
|
|
625
648
|
command: "check";
|
|
626
649
|
value: Promise<void>;
|
|
@@ -694,9 +717,6 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
694
717
|
command: "typegen";
|
|
695
718
|
value: Promise<void>;
|
|
696
719
|
};
|
|
697
|
-
} | {
|
|
698
|
-
command: "dev";
|
|
699
|
-
value: Promise<void> | Promise<boolean>;
|
|
700
720
|
} | {
|
|
701
721
|
command: "preview";
|
|
702
722
|
value: Promise<void>;
|
|
@@ -772,10 +792,16 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
772
792
|
value: {
|
|
773
793
|
command: "build";
|
|
774
794
|
value: Promise<void>;
|
|
795
|
+
} | {
|
|
796
|
+
command: "dev";
|
|
797
|
+
value: Promise<void>;
|
|
775
798
|
} | {
|
|
776
799
|
command: "typegen";
|
|
777
800
|
value: Promise<void>;
|
|
778
801
|
};
|
|
802
|
+
} | {
|
|
803
|
+
command: "dev";
|
|
804
|
+
value: Promise<void> | Promise<boolean>;
|
|
779
805
|
} | {
|
|
780
806
|
command: "typegen";
|
|
781
807
|
value: Promise<void>;
|
|
@@ -790,6 +816,9 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
790
816
|
} | {
|
|
791
817
|
command: "add";
|
|
792
818
|
value: Promise<void>;
|
|
819
|
+
} | {
|
|
820
|
+
command: "backup";
|
|
821
|
+
value: Promise<void>;
|
|
793
822
|
} | {
|
|
794
823
|
command: "check";
|
|
795
824
|
value: Promise<void>;
|
|
@@ -863,9 +892,6 @@ declare const coreframeCli: Partial<import("@alloc/cmd-ts/dist/cjs/argparser").R
|
|
|
863
892
|
command: "typegen";
|
|
864
893
|
value: Promise<void>;
|
|
865
894
|
};
|
|
866
|
-
} | {
|
|
867
|
-
command: "dev";
|
|
868
|
-
value: Promise<void> | Promise<boolean>;
|
|
869
895
|
} | {
|
|
870
896
|
command: "preview";
|
|
871
897
|
value: Promise<void>;
|
package/dist/coreframe.js
CHANGED
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import*as e from"@alloc/cmd-ts";import{
|
|
3
|
-
`)}function
|
|
2
|
+
import*as e from"@alloc/cmd-ts";import{command as t,extendType as n,flag as r,number as i,oneOf as a,option as o,optional as s,positional as c,rest as l,string as u,subcommands as d}from"@alloc/cmd-ts";import{ProjectPostgresAlreadyRunningError as f,checkDeployMigrations as p,checkSchemaPush as m,collectDeployMigrationFiles as h,createProjectPostgresDatabaseAdapter as g,createProjectSqliteDatabaseAdapter as _,ensureLocalDb as v,filterPendingMigrations as y,formatDbErrorMessage as b,formatMigrationList as x,formatMigrationScanFailures as S,migrateHeldMigrations as C,migrateLocalDb as w,readAppliedMigrationNames as T,resetLocalDb as E,runDrizzleKitCommand as D,scanDeployMigrationFiles as ee,seedLocalDb as te,setupLocalDb as ne,startProjectPostgres as re,startProjectTurso as ie,stopProjectPostgres as O}from"@coreframe/db";import{checkFlutterClient as k,ensureFlutterDevAssetDirectories as ae,flutterPlatforms as A,generateFlutterNativeBridge as oe,prepareFlutterClient as j,prepareFlutterDevOutput as se,productionApiOrigin as M,runFlutterAcceptance as N}from"@coreframe/flutter-tools";import P,{dirname as F,isAbsolute as ce,join as I,posix as L,resolve as R,sep as z}from"node:path";import B from"nano-spawn";import*as V from"@clack/prompts";import{addAsset as le,backupAssets as ue,buildAssets as de,checkAssets as fe,printAssetResult as pe,publishAssets as me}from"@coreframe/assets";import{assertAssetCredentialProfile as he,configureAssetCredentials as ge,createB2PrivateObjectStore as _e}from"@coreframe/object-storage";import{access as ve,chmod as ye,copyFile as be,cp as xe,link as Se,mkdir as H,mkdtemp as Ce,readFile as U,readdir as we,realpath as Te,rename as Ee,rm as W,stat as De,unlink as Oe,writeFile as G}from"node:fs/promises";import{homedir as ke,networkInterfaces as Ae,tmpdir as je}from"node:os";import{importProjectDependency as Me,importProjectModule as Ne,normalizeWorkerEnvironment as Pe,readProjectConfig as Fe,wranglerEnvironmentNames as Ie}from"@coreframe/config";import{createHash as Le,randomUUID as K}from"node:crypto";import q from"node:process";import{chmodSync as Re,existsSync as ze,lstatSync as Be,mkdirSync as Ve,mkdtempSync as He,readFileSync as J,readlinkSync as Ue,rmSync as We,symlinkSync as Ge,watch as Ke,writeFileSync as qe}from"node:fs";import{finished as Je}from"node:stream/promises";import{createPrefixStream as Y,supervise as Ye}from"procband";import{createConnection as Xe,createServer as Ze}from"node:net";import{spawnSync as X}from"node:child_process";import{parse as Qe,stringify as $e}from"yaml";import{accessTokenSigningSecretName as et,clearAppliedPendingWorkerSecrets as tt,deployEnvironments as nt,discardPendingWorkerSecret as rt,discoverStagingUrl as it,inspectWorkerEnvironment as at,materializePrimaryWorkerConfig as ot,materializePrimaryWorkerTypeConfig as st,parseDeclaredWorkerSecretEnv as ct,prepareAccessTokenSigningSecret as lt,queueWorkerSecret as ut,queueWorkerSecrets as dt,readDeclaredWorkerSecrets as ft,readPackageJson as pt,readPendingWorkerSecretSnapshot as mt,reassignStagingHostname as ht,releaseName as gt,resolveDeployConfig as _t,resolveReleaseVersion as vt,rotateAccessTokenSigningSecret as yt,runAfterWorkerDeploy as bt,runPostDeployChecks as xt,validateWorkerEnvironmentForDeploy as St,verifyAccessTokenSigningSecret as Ct,writePackageVersion as wt}from"@coreframe/deploy";import{connectDevSupervisor as Tt,createDevStartupTiming as Et,devHttpsCertEnv as Dt,devHttpsKeyEnv as Ot,isManagedDevCheckout as kt,isPrimaryCheckout as At,prepareDevHttps as jt,stopDevSupervisor as Mt}from"@coreframe/dev";import{inspect as Nt,parseEnv as Pt}from"node:util";import{once as Ft}from"node:events";import{codexTaskEnv as It}from"@coreframe/dev-contracts/codex-task";import{managedDevEnv as Lt,managedDevFlutterRestartFileEnv as Rt}from"@coreframe/dev-contracts/managed-dev";import{setTimeout as zt}from"node:timers/promises";import{determineAgent as Bt}from"@vercel/detect-agent";import{runPreview as Vt}from"@coreframe/preview";const Ht=[`web`,...A];function Ut(e=`web`,{apiOrigin:t,cwd:n=process.cwd(),profile:r=!1,simulator:i=!1}={}){if(Xt(e,{profile:r,simulator:i}),e===`web`)return[Qt(`pnpm`,[`build`],n,{COREFRAME_PLATFORM:`web`})];let a=M(t);return[{kind:`prepare`,platform:e},Qt(`flutter`,Wt(e,a,{profile:r,simulator:i}),R(n,`src-flutter`),{COREFRAME_API_ORIGIN:a})]}function Wt(e,t,{noCodesign:n=e===`macos`,profile:r=!1,simulator:i=!1}={}){Xt(e,{profile:r,simulator:i});let a=M(t);return[`build`,e===`android`?`apk`:e,r?`--profile`:`--release`,...i?[`--simulator`]:[],...n?[`--no-codesign`]:[],`--dart-define=COREFRAME_API_ORIGIN=${a}`]}function Gt(e,{profile:t=!1}={}){let n=t?`profile`:`release`,r=R(e,`src-flutter/build/app/outputs/flutter-apk/app-${n}.apk`),i=JSON.stringify(r);return[`Android ${n} build succeeded.`,``,`Install it on a connected Android device:`,` 1. Enable Developer options and USB debugging, connect the device, and accept the authorization prompt.`,` 2. Verify the device is visible:`,` adb devices`,` 3. Install or update the APK:`,` adb install -r ${i}`,``,`If multiple devices are connected, use:`,` adb -s <device-id> install -r ${i}`].join(`
|
|
3
|
+
`)}function Kt(e,{profile:t=!1,simulator:n=!1}={}){let r=t?`profile`:`release`,i=R(e,`src-flutter/build/ios/${n?`iphonesimulator`:`iphoneos`}/Runner.app`),a=JSON.stringify(i);return n?[`iOS Simulator ${r} build succeeded.`,``,`Install it on a booted iOS Simulator:`,` 1. Verify available simulators:`,` xcrun simctl list devices`,` 2. Install the app:`,` xcrun simctl install booted ${a}`,``,"If multiple simulators are available, replace `booted` with the simulator UDID."].join(`
|
|
4
4
|
`):[`iOS ${r} build succeeded.`,``,`Install it on a connected iOS device:`,` 1. Enable Developer Mode, connect the device, and trust this Mac if prompted.`,` 2. Verify the device is visible:`,` xcrun devicectl list devices`,` 3. Install the signed app:`,` xcrun devicectl device install app --device <device-id> ${a}`,``,`If multiple devices are connected, use the device UDID shown by devicectl.`].join(`
|
|
5
|
-
`)}async function nn({apiOrigin:e,cwd:t=process.cwd(),environment:n=process.env,platform:r=`web`,profile:i=!1,simulator:a=!1,prepareClient:o=ae,runCommand:s=an}={}){rn(r,{profile:i,simulator:a});let c={...n};delete c.COREFRAME_FLUTTER_DEVELOPMENT,delete c.COREFRAME_PLATFORM,delete c.TAURI_ENV_PLATFORM;let l=r===`web`?void 0:F(e??n.COREFRAME_API_ORIGIN);for(let e of Qt(r,{apiOrigin:l,cwd:t,profile:i,simulator:a})){if(e.kind===`prepare`){if(!l)throw Error(`A production API origin is required for the Flutter ${e.platform} build.`);await o({apiOrigin:l,cwd:t,environment:c,platform:e.platform});continue}await s(e.command,e.args,{cwd:e.cwd,env:{...c,...e.environment}})}r===`android`?console.log(en(t,{profile:i})):r===`ios`&&console.log(tn(t,{profile:i,simulator:a}))}function rn(e,{profile:t,simulator:n}){if(t&&e===`web`)throw Error(`The --profile flag is only supported for Flutter build targets.`);if(n&&e!==`ios`)throw Error(`The --simulator flag is only supported for the iOS build target.`);if(t&&n)throw Error(`Flutter profile builds are not supported for the iOS simulator.`)}async function an(e,t,{cwd:n,env:r}){await V(e,t,{cwd:n,env:r,stdio:`inherit`})}function on(e,t,n,r){return{kind:`command`,command:e,args:t,cwd:n,...r===void 0?{}:{environment:r}}}const sn=r(f,{displayName:`origin`,description:`Exact production HTTPS API origin embedded in a packaged Flutter client.`,async from(e){return F(e)}}),cn=n({name:`build`,description:`Build the web client or a Flutter app (release by default). Tauri is not built.`,args:{platform:u({type:l(s(Zt)),displayName:`platform`,description:`Build target: web, iOS, Android, or macOS. Defaults to web.`}),apiOrigin:c({long:`api-origin`,type:l(sn),description:`Exact production HTTPS API origin for a Flutter build. Defaults to COREFRAME_API_ORIGIN.`}),profile:i({long:`profile`,description:`Build a Flutter profile app instead of the default release app.`,defaultValue:()=>!1}),simulator:i({long:`simulator`,description:`Build iOS for the simulator instead of a physical device.`,defaultValue:()=>!1})},handler:({apiOrigin:e,platform:t,profile:n,simulator:r})=>nn({apiOrigin:e,platform:t,profile:n,simulator:r})}),ln=/^[a-f0-9]{64}$/,un=/^[a-f0-9]{40}$/,dn=/^[A-Za-z0-9][A-Za-z0-9._-]*$/;function fn(e){if(!ln.test(e))throw Error(`Invalid SHA-256 digest "${e}".`);return e}function pn(e){if(!un.test(e))throw Error(`Invalid full Git revision "${e}".`);return e}function mn(e,t){if(!dn.test(e))throw Error(`${t} must contain only letters, numbers, dots, underscores, or hyphens.`);return e}function hn(e){return`projects/${mn(e,`Project ID`)}/i18n/v1`}function gn(e,t){return fn(t),`${hn(e)}/objects/sha256/${t.slice(0,2)}/${t}`}function _n(e,t){return pn(t),`${hn(e)}/commits/${t}.json`}function vn(e,t){return yn(t),`${hn(e)}/releases/${encodeURIComponent(t)}.json`}function yn(e){if(!e.startsWith(`v`)||e.length<2||e.length>128||/\s/.test(e)||e.includes(`..`))throw Error(`Release tag "${e}" must be a valid v-prefixed tag.`);return e}function Z(e,t){if(!t||t.startsWith(`/`)||t.includes(`\0`))throw Error(`Unsafe i18n artifact path "${t}".`);let n=B(e),r=B(n,t);if(r!==n&&!r.startsWith(`${n}${le}`))throw Error(`Unsafe i18n artifact path "${t}".`);return r}function Q(e,t,n){return`${e.directory}/${t}/${n}.json`}function bn(e,t,n){return`${e.directory}/${t}/${n}.mjs`}async function xn(e){await V(`pnpm`,[`exec`,`lingui`,`extract`],{cwd:e,stdio:`inherit`})}async function Sn({config:e,cwd:t,strict:n,temporaryDirectory:r}){let i=[];try{for(let n of e.locales)for(let a of e.catalogs){let o=Z(t,Q(e,n,a)),s=await Dn(o),c=Object.fromEntries(Object.entries(s).filter(([,e])=>!e.obsolete)),l=R(r,`${n}-${a}.json`);await U(L(l),{recursive:!0}),await be(o,l),i.push({path:o,backup:l}),await On(o,c)}await V(`pnpm`,[`exec`,`lingui`,`compile`,...n?[`--strict`]:[]],{cwd:t,stdio:`inherit`})}finally{try{for(let{path:e,backup:t}of i)await be(t,e)}finally{for(let n of e.locales)for(let r of e.catalogs)await G(Z(t,bn(e,n,r)),{force:!0})}}}async function Cn({config:e,cwd:t}){let n=[];for(let r of e.locales)if(r!==e.sourceLocale)for(let i of e.catalogs){let a=await Dn(Z(t,Q(e,r,i)));for(let[e,t]of Object.entries(a)){if(t.obsolete||t.translation?.trim())continue;let a=t.message;if(typeof a!=`string`||!a)throw Error(`Missing source message metadata for ${r}:${e}.`);n.push({catalog:i,comments:t.comments?.filter(e=>typeof e==`string`)??[],context:t.context,id:e,locale:r,message:a,origins:t.origin?.map(([e,t])=>t?`${e}:${t}`:e)??[],placeholders:Object.keys(t.placeholders??{}).sort()})}}return n.sort((e,t)=>Nn(e).localeCompare(Nn(t)))}async function wn({config:e,cwd:t,messages:n,env:r=process.env}){if(n.length===0)return{translations:[],version:1};if(!e.generator)throw Error(`I18n preparation found ${n.length} missing translations, but no generator is configured.`);let i={messages:n,sourceLocale:e.sourceLocale,version:1};return kn(await An({args:e.generator.args??[],command:e.generator.command,cwd:t,env:r,input:JSON.stringify(i)}))}async function Tn({config:e,cwd:t,missing:n,response:r}){let i=new Map(n.map(e=>[Nn(e),e])),a=new Map;for(let e of r.translations){let t=Nn(e);if(!i.has(t))throw Error(`Translation generator returned unexpected entry ${e.locale}:${e.catalog}:${e.id}.`);if(a.has(t))throw Error(`Translation generator returned duplicate entry ${e.locale}:${e.catalog}:${e.id}.`);if(!e.translation.trim())throw Error(`Translation generator returned an empty entry ${e.locale}:${e.id}.`);a.set(t,e.translation)}let o=[...i.keys()].filter(e=>!a.has(e));if(o.length>0)throw Error(`Translation generator omitted ${o.length} required entries.`);let s=await Me(`@lingui/message-utils/compileMessage`,t);for(let e of n){let t=a.get(Nn(e));jn({compileMessage:s,id:e.id,locale:e.locale,source:e.message,translation:t})}for(let n of e.locales)if(n!==e.sourceLocale)for(let r of e.catalogs){let i=Z(t,Q(e,n,r)),o=await Dn(i),s=!1;for(let[e,t]of Object.entries(o)){let i=a.get(Nn({catalog:r,id:e,locale:n}));if(i!==void 0){if(t.translation?.trim())throw Error(`Refusing to overwrite preserved translation ${n}:${e}.`);t.translation=i,s=!0}}s&&await On(i,o)}}async function En({config:e,cwd:t}){let n=await Cn({config:e,cwd:t});if(n.length>0)throw Error(`I18n catalogs remain incomplete: ${n.length} translations are missing.`);let r=await Me(`@lingui/message-utils/compileMessage`,t);for(let n of e.locales)if(n!==e.sourceLocale)for(let i of e.catalogs){let a=await Dn(Z(t,Q(e,n,i)));for(let[e,t]of Object.entries(a))if(!t.obsolete){if(typeof t.message!=`string`||typeof t.translation!=`string`)throw Error(`Incomplete source metadata for active translation ${n}:${e}.`);jn({compileMessage:r,id:e,locale:n,source:t.message,translation:t.translation})}}}async function Dn(e){let t=JSON.parse(await W(e,`utf8`));if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Lingui rich JSON catalog must be an object: ${e}.`);for(let[n,r]of Object.entries(t)){if(!r||typeof r!=`object`||Array.isArray(r))throw Error(`Invalid Lingui rich JSON message ${n} in ${e}.`);let t=r;if(t.translation!==void 0&&typeof t.translation!=`string`)throw Error(`Invalid translation value for ${n} in ${e}.`);if(t.message!==void 0&&t.message!==null&&typeof t.message!=`string`)throw Error(`Invalid source message value for ${n} in ${e}.`);if(t.context!==void 0&&typeof t.context!=`string`)throw Error(`Invalid context value for ${n} in ${e}.`);if(t.obsolete!==void 0&&typeof t.obsolete!=`boolean`)throw Error(`Invalid obsolete marker for ${n} in ${e}.`);if(t.comments!==void 0&&(!Array.isArray(t.comments)||t.comments.some(e=>typeof e!=`string`)))throw Error(`Invalid comments for ${n} in ${e}.`);if(t.origin!==void 0&&(!Array.isArray(t.origin)||t.origin.some(e=>!Array.isArray(e)||typeof e[0]!=`string`||e[1]!==void 0&&typeof e[1]!=`number`)))throw Error(`Invalid origins for ${n} in ${e}.`);if(t.placeholders!==void 0&&(!t.placeholders||typeof t.placeholders!=`object`||Array.isArray(t.placeholders)))throw Error(`Invalid placeholders for ${n} in ${e}.`)}return t}async function On(e,t){await U(L(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;await K(n,`${JSON.stringify(t,null,2)}\n`),await Ee(n,e)}function kn(e){let t;try{t=JSON.parse(e)}catch{throw Error(`Translation generator returned invalid JSON.`)}if(!t||typeof t!=`object`||t.version!==1||!Array.isArray(t.translations))throw Error(`Translation generator returned an invalid response envelope.`);for(let e of t.translations)if(!e||typeof e!=`object`||typeof e.id!=`string`||typeof e.catalog!=`string`||typeof e.locale!=`string`||typeof e.translation!=`string`)throw Error(`Translation generator returned an invalid translation entry.`);return t}function An({args:e,command:t,cwd:n,env:r,input:i}){return V(t,e,{cwd:n,env:r,stdio:[{string:i},`pipe`,`ignore`]}).then(({stdout:e})=>{if(Buffer.byteLength(e)>10*1024*1024)throw Error(`Translation generator output exceeded 10 MiB.`);return e}).catch(()=>{throw Error(`Translation generator exited unsuccessfully.`)})}function jn({compileMessage:e,id:t,locale:n,source:r,translation:i}){let a,o;try{a=e.compileMessageOrThrow(r),o=e.compileMessageOrThrow(i)}catch{throw Error(`Translation ${n}:${t} is not valid ICU MessageFormat.`)}let s=Mn(a),c=Mn(o);if(s.length!==c.length||s.some((e,t)=>e!==c[t]))throw Error(`Translation ${n}:${t} does not preserve source ICU placeholders.`)}function Mn(e){let t=[];function n(e){for(let r of e){if(typeof r==`string`)continue;let[e,i=`argument`,a]=r;if(t.push(`${e}:${i}`),a&&typeof a==`object`&&!Array.isArray(a))for(let e of Object.values(a))Array.isArray(e)&&n(e)}}return n(e),t.sort()}function Nn(e){return`${e.locale}\0${e.catalog}\0${e.id}`}function Pn(e){return Le(`sha256`).update(e).digest(`hex`)}async function Fn(e){return Pn(await W(e))}function In(e){return Buffer.from(`${JSON.stringify(e,null,2)}\n`)}async function Ln({bucket:e,digest:t,projectId:n,source:r,store:i}){if(fn(t),await Fn(r)!==t)throw Error(`I18n object source does not match declared SHA-256 digest ${t}.`);let a=gn(n,t);await i.has(e,a)||await i.upload(e,a,r,`application/octet-stream`);let o=`${r}.${process.pid}.${Re()}.verify`;try{if(await i.download(e,a,o),await Fn(o)!==t)throw Error(`Existing immutable i18n object ${a} failed integrity verification.`)}finally{await G(o,{force:!0})}}async function Rn({bucket:e,key:t,reference:n,store:r,temporaryDirectory:i}){let a=In(n),o=R(i,`reference-${Re()}.json`);if(await r.has(e,t))try{if(await r.download(e,t,o),!(await W(o)).equals(a))throw Error(`Immutable i18n reference ${t} already resolves to different snapshot data.`);return}finally{await G(o,{force:!0})}await K(o,a,{flag:`wx`});try{await r.upload(e,t,o,`application/json`)}finally{await G(o,{force:!0})}let s=R(i,`reference-${Re()}.verify.json`);try{if(await r.download(e,t,s),!(await W(s)).equals(a))throw Error(`Uploaded immutable i18n reference ${t} failed verification.`)}finally{await G(s,{force:!0})}}async function zn({bucket:e,manifest:t,projectId:n,store:r,temporaryDirectory:i}){let a=In(t),o=Pn(a),s=R(i,`manifest-${o}.json`);await K(s,a,{flag:`wx`});try{await Ln({bucket:e,digest:o,projectId:n,source:s,store:r})}finally{await G(s,{force:!0})}return o}async function Bn({bucket:e,key:t,store:n,temporaryDirectory:r}){if(!await n.has(e,t))return;let i=R(r,`reference-${Re()}.json`);try{await n.download(e,t,i);let r=JSON.parse(await W(i,`utf8`));if(r.version!==1||typeof r.revision!=`string`||typeof r.snapshot!=`string`)throw Error(`Invalid i18n reference at ${t}.`);return pn(r.revision),fn(r.snapshot),r}finally{await G(i,{force:!0})}}async function Vn({bucket:e,projectId:t,revision:n,store:r,temporaryDirectory:i}){let a=await Bn({bucket:e,key:_n(t,n),store:r,temporaryDirectory:i});if(a&&a.revision!==n)throw Error(`I18n commit reference does not match requested revision ${n}.`);return a}async function Hn({bucket:e,projectId:t,reference:n,store:r,tag:i,temporaryDirectory:a}){await Rn({bucket:e,key:_n(t,n.revision),reference:n,store:r,temporaryDirectory:a}),i&&await Rn({bucket:e,key:vn(t,i),reference:n,store:r,temporaryDirectory:a})}async function Un({bucket:e,cacheRoot:t,digest:n,projectId:r,store:i,target:a}){fn(n);let o=R(B(t),`v1`,`sha256`,n.slice(0,2),n);if(await Gn(o,n)===!1){await U(L(o),{recursive:!0});let t=`${o}.${process.pid}.${Re()}.tmp`;try{if(await i.download(e,gn(r,n),t),await Fn(t)!==n)throw Error(`Downloaded i18n object failed SHA-256 verification: ${n}.`);await G(o,{force:!0}),await Ee(t,o)}finally{await G(t,{force:!0})}}await U(L(a),{recursive:!0});let s=`${a}.${process.pid}.${Re()}.tmp`;try{if(await be(o,s),await Fn(s)!==n)throw Error(`Cached i18n object failed SHA-256 verification: ${n}.`);await G(a,{force:!0}),await Ee(s,a)}finally{await G(s,{force:!0})}}async function Wn({bucket:e,cacheRoot:t,digest:n,projectId:r,store:i,temporaryDirectory:a}){let o=R(a,`manifest-${n}.json`);await Un({bucket:e,cacheRoot:t,digest:n,projectId:r,store:i,target:o});let s=JSON.parse(await W(o,`utf8`));if(s.version!==1||s.projectId!==r||typeof s.revision!=`string`||!Array.isArray(s.files)||!Array.isArray(s.catalogs)||s.catalogs.some(e=>typeof e!=`string`)||!Array.isArray(s.locales)||s.locales.some(e=>typeof e!=`string`)||typeof s.sourceLocale!=`string`||typeof s.generator!=`string`||typeof s.linguiVersion!=`string`)throw Error(`Invalid i18n snapshot manifest ${n}.`);pn(s.revision),s.baseline!==void 0&&fn(s.baseline);for(let e of s.files){if(!e||typeof e!=`object`||typeof e.path!=`string`||typeof e.digest!=`string`||typeof e.size!=`number`)throw Error(`Invalid file entry in i18n snapshot manifest ${n}.`);fn(e.digest)}return s}async function Gn(e,t){try{return(await De(e)).isFile()&&await Fn(e)===t}catch{return!1}}async function Kn({cwd:e=process.cwd(),env:t=process.env}={}){if((await Fe({cwd:e})).i18n){if(t.COREFRAME_I18N_RELEASE_REVISION){await Yn({cwd:e,env:t,revision:t.COREFRAME_I18N_RELEASE_REVISION});return}await xn(e)}}async function qn({cwd:e=process.cwd(),projectConfig:t}={}){let n=t??await Fe({cwd:e});if(!n.i18n)return;let r=Xn(n.i18n),i=Z(e,r.directory);try{if(!(await De(i)).isDirectory())throw Error(`I18n catalog path is not a directory: ${i}.`)}catch(t){if(t.code!==`ENOENT`)throw t;await xn(e);return}for(let t of r.locales)for(let n of r.catalogs)try{if(!(await De(Z(e,Q(r,t,n)))).isFile())throw Error(`I18n catalog path is not a file: ${t}/${n}.json.`)}catch(t){if(t.code!==`ENOENT`)throw t;await xn(e);return}}async function Jn({cwd:e=process.cwd(),env:t=process.env,store:n,tag:r}){yn(r);let i=await Zn({cwd:e,env:t,store:n});await ar(e);let a=await ir(e);await or(e,r,a);let o=await Ce(R(je(),`coreframe-i18n-prepare-`));try{let n=await Vn({bucket:i.assets.sourceBucket,projectId:i.assets.projectId,revision:a,store:i.store,temporaryDirectory:o});if(n){let e=await Wn({bucket:i.assets.sourceBucket,cacheRoot:i.cacheRoot,digest:n.snapshot,projectId:i.assets.projectId,store:i.store,temporaryDirectory:o});return rr(i,e,a),await $n(i,e),await Hn({bucket:i.assets.sourceBucket,projectId:i.assets.projectId,reference:n,store:i.store,tag:r,temporaryDirectory:o}),{reused:!0,snapshot:n.snapshot}}return await nr(i,o,async()=>{let n=await Qn(i,a,o);n||await tr(i),await xn(e);let s=await Cn({config:i.config,cwd:e}),c=await wn({config:i.config,cwd:e,env:t,messages:s});await Tn({config:i.config,cwd:e,missing:s,response:c}),await En({config:i.config,cwd:e}),await Sn({config:i.config,cwd:e,strict:!0,temporaryDirectory:o});let l=await er(i),u={...n?{baseline:n}:{},catalogs:i.config.catalogs,files:l,generator:s.length>0?i.config.generator?.id??`unconfigured`:`none`,linguiVersion:await sr(e),locales:i.config.locales,projectId:i.assets.projectId,revision:a,sourceLocale:i.config.sourceLocale,version:1},d=await zn({bucket:i.assets.sourceBucket,manifest:u,projectId:i.assets.projectId,store:i.store,temporaryDirectory:o});return await Hn({bucket:i.assets.sourceBucket,projectId:i.assets.projectId,reference:{revision:a,snapshot:d,version:1},store:i.store,tag:r,temporaryDirectory:o}),{reused:!1,snapshot:d}})}finally{await G(o,{force:!0,recursive:!0})}}async function Yn({cwd:e=process.cwd(),env:t=process.env,revision:n,store:r}={}){let i=await Fe({cwd:e});if(!i.i18n)return;let a=await Zn({cwd:e,env:t,store:r,projectConfig:i}),o=pn(n??await ir(e)),s=await Ce(R(je(),`coreframe-i18n-materialize-`));try{let e=await Vn({bucket:a.assets.sourceBucket,projectId:a.assets.projectId,revision:o,store:a.store,temporaryDirectory:s});if(!e)throw Error(`No prepared i18n snapshot exists for commit ${o}. Push a v* tag for this commit and wait for the translation gate.`);let t=await Wn({bucket:a.assets.sourceBucket,cacheRoot:a.cacheRoot,digest:e.snapshot,projectId:a.assets.projectId,store:a.store,temporaryDirectory:s});return rr(a,t,o),await $n(a,t),{revision:o,snapshot:e.snapshot}}finally{await G(s,{force:!0,recursive:!0})}}function Xn(e){let t=mn(e.sourceLocale,`Source locale`),n=[...new Set(e.locales.map(e=>mn(e,`Locale`)))],r=[...new Set(e.catalogs.map(e=>mn(e,`Catalog`)))];if(n.length===0||!n.includes(t))throw Error(`I18n locales must include the source locale.`);if(r.length===0)throw Error(`I18n configuration requires at least one catalog.`);if(e.generator&&(!e.generator.command.trim()||!e.generator.id.trim()))throw Error(`I18n generator command and ID must be non-empty.`);return{catalogs:r,directory:e.directory??`locales`,generator:e.generator,locales:n,sourceLocale:t}}async function Zn({cwd:e=process.cwd(),env:t=process.env,projectConfig:n,store:r}){let i=n??await Fe({cwd:e});if(!i.i18n)throw Error(`Missing i18n configuration in coreframe.config.ts.`);if(!i.assets)throw Error(`I18n snapshots require the existing private build bucket configured under assets.`);let a=i.assets;return{assets:a,cacheRoot:B(e,`.coreframe`,`i18n`,`cache`),config:Xn(i.i18n),cwd:B(e),env:t,store:r??_e({config:a,env:t})}}async function Qn(e,t,n){let{stdout:r}=await V(`git`,[`rev-list`,`--first-parent`,`--skip=1`,t],{cwd:e.cwd,stdin:`ignore`});for(let t of r.split(/\r?\n/).filter(Boolean)){let r=await Vn({bucket:e.assets.sourceBucket,projectId:e.assets.projectId,revision:pn(t),store:e.store,temporaryDirectory:n});if(!r)continue;let i=await Wn({bucket:e.assets.sourceBucket,cacheRoot:e.cacheRoot,digest:r.snapshot,projectId:e.assets.projectId,store:e.store,temporaryDirectory:n});return rr(e,i,t),await $n(e,i),r.snapshot}}async function $n(e,t){for(let n of t.files)if(await Un({bucket:e.assets.sourceBucket,cacheRoot:e.cacheRoot,digest:n.digest,projectId:e.assets.projectId,store:e.store,target:Z(e.cwd,n.path)}),(await De(Z(e.cwd,n.path))).size!==n.size)throw Error(`Materialized i18n artifact size does not match manifest: ${n.path}.`)}async function er(e){let t=[];for(let n of e.config.locales)for(let r of e.config.catalogs){let i=Q(e.config,n,r),a=Z(e.cwd,i),o=await Fn(a);await Ln({bucket:e.assets.sourceBucket,digest:o,projectId:e.assets.projectId,source:a,store:e.store}),t.push({digest:o,path:i,size:(await De(a)).size})}return t.sort((e,t)=>e.path.localeCompare(t.path))}async function tr(e){let{stdout:t}=await V(`git`,[`rev-parse`,`--show-prefix`],{cwd:e.cwd,stdin:`ignore`}),n=t.trim(),{stdout:r}=await V(`git`,[`log`,`-1`,`--format=%H`,`--diff-filter=AM`,`--`,`:(top)${`${n}${e.config.directory}/${e.config.sourceLocale}/${e.config.catalogs[0]}.po`}`],{cwd:e.cwd,stdin:`ignore`}),i=r.trim();if(!i)return!1;let a=(await Me(`@lingui/format-po`,e.cwd)).formatter({lineNumbers:!1}),o=!1;for(let t of e.config.locales)for(let r of e.config.catalogs){let s=`${n}${`${e.config.directory}/${t}/${r}.po`}`;try{let{stdout:n}=await V(`git`,[`show`,`${i}:${s}`],{cwd:e.cwd,stdin:`ignore`});await On(Z(e.cwd,Q(e.config,t,r)),a.parse(n)),o=!0}catch{}}return o}async function nr(e,t,n){let r=[];for(let n of e.config.locales)for(let i of e.config.catalogs){let a=Q(e.config,n,i),o=Z(e.cwd,a);try{await ve(o)}catch{continue}let s=R(t,`previous-catalogs`,a);await U(L(s),{recursive:!0}),await Ee(o,s),r.push({backup:s,path:o})}try{let e=await n();return await G(R(t,`previous-catalogs`),{force:!0,recursive:!0}),e}catch(t){for(let t of e.config.locales)for(let n of e.config.catalogs)await G(Z(e.cwd,Q(e.config,t,n)),{force:!0});for(let{backup:e,path:t}of r)await U(L(t),{recursive:!0}),await Ee(e,t);throw t}}function rr(e,t,n){if(t.revision!==n||t.projectId!==e.assets.projectId||t.sourceLocale!==e.config.sourceLocale||JSON.stringify(t.locales)!==JSON.stringify(e.config.locales)||JSON.stringify(t.catalogs)!==JSON.stringify(e.config.catalogs))throw Error(`I18n snapshot does not match commit or project configuration.`);let r=e.config.locales.flatMap(t=>e.config.catalogs.map(n=>Q(e.config,t,n))),i=t.files.map(e=>e.path);if(new Set(i).size!==i.length||JSON.stringify(i.sort())!==JSON.stringify(r.sort()))throw Error(`I18n snapshot has an incomplete or unexpected artifact set.`)}async function ir(e){let{stdout:t}=await V(`git`,[`rev-parse`,`HEAD`],{cwd:e,stdin:`ignore`});return pn(t.trim())}async function ar(e){let{stdout:t}=await V(`git`,[`status`,`--porcelain`],{cwd:e,stdin:`ignore`});if(t.trim())throw Error(`Tagged i18n preparation requires a clean Git tree.`)}async function or(e,t,n){let{stdout:r}=await V(`git`,[`rev-parse`,`${t}^{commit}`],{cwd:e,stdin:`ignore`});if(r.trim()!==n)throw Error(`Release tag ${t} does not point to checked-out commit ${n}.`)}async function sr(e){let{stdout:t}=await V(`pnpm`,[`exec`,`lingui`,`--version`],{cwd:e,stdin:`ignore`});return t.trim()}const cr=[`Use a B2 Multi-Bucket Application Key restricted to the configured private build-object and public generated-assets buckets.`,`Required capabilities: listAllBucketNames, readFiles, and writeFiles.`,`Deletion, bucket-management, and key-management capabilities are not needed.`].join(` `),lr=r(f,{displayName:`widths`,description:`Comma-separated responsive variant widths.`,async from(e){let t=e.split(`,`).map(e=>Number(e));if(t.length===0||t.some(e=>!Number.isInteger(e)||e<=0)||t.some((e,n)=>n>0&&e<=t[n-1]))throw Error(`Widths must be positive, unique, strictly ascending integers.`);return t}}),ur=r(f,{displayName:`profile`,async from(e){return he(e)}}),dr=r(f,{displayName:`pack`,description:`Asset pack name, such as training-videos.`,async from(e){if(!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(e))throw Error(`Asset pack names must use lowercase hyphen-separated segments.`);return e}}),fr=r(f,{displayName:`origin`,description:`Exact production HTTPS API origin embedded in the packaged Flutter client.`,async from(e){return F(e)}}),pr=p({name:`assets`,cmds:{configure:n({name:`configure`,description:`Store a Backblaze B2 private build-object key in the operating system credential store. ${cr}`,args:{profile:u({type:ur,displayName:`profile`,description:`Credential profile named by coreframe.config.ts.`})},handler:async({profile:e})=>{H.note(cr,`Required B2 key access`);let t=await H.text({message:`Backblaze B2 application key ID`,validate:e=>e?.trim()?void 0:`The application key ID is required.`});if(H.isCancel(t))throw Error(`Asset credential configuration was cancelled.`);let n=await H.password({message:`Backblaze B2 application key`,validate:e=>e?void 0:`The application key is required.`});if(H.isCancel(n))throw Error(`Asset credential configuration was cancelled.`);await ge({applicationKey:n,applicationKeyId:t.trim(),profile:e}),console.log(`Stored Coreframe asset credential profile "${e}".`)}}),add:n({name:`add`,args:{file:u({type:f,displayName:`file`,description:`Source raster image, SVG, MP3, MP4, or Lottie JSON to add to the asset library.`}),id:c({long:`id`,type:f,description:`Logical asset ID, such as blog/my-post/hero.`}),alt:c({long:`alt`,type:l(f),description:`Required alt text for raster image and SVG assets.`}),pack:c({long:`pack`,type:l(dr),description:`Place the asset in a named, lazily loaded pack.`}),variantWidths:c({long:`widths`,type:l(lr),description:`Generate exactly these raster-image widths instead of the default ladder.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({alt:e,file:t,id:n,json:r,pack:i,variantWidths:a})=>pe(await ue({alt:e,file:t,id:n,pack:i,variantWidths:a}),r)}),build:n({name:`build`,args:{id:c({long:`id`,type:l(f),description:`Build only one logical asset ID.`}),pack:c({long:`pack`,type:l(dr),description:`Build only one named asset pack.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({id:e,json:t,pack:n})=>pe(await de({id:e,pack:n}),t)}),check:n({name:`check`,args:{fix:i({long:`fix`,description:`Migrate asset state and build missing generated output when possible.`,defaultValue:()=>!1}),pack:c({long:`pack`,type:l(dr),description:`Check only one named asset pack.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({fix:e,json:t,pack:n})=>{let r=await fe({fix:e,pack:n});pe(r,t),r.ok||(process.exitCode=1)}}),publish:n({name:`publish`,args:{pack:c({long:`pack`,type:l(dr),description:`Publish only one named asset pack.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await me({pack:t});pe(n,e),n.ok||(process.exitCode=1)}}),status:n({name:`status`,args:{pack:c({long:`pack`,type:l(dr),description:`Report status for only one named asset pack.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await fe({pack:t});pe(n,e),n.ok||(process.exitCode=1)}})}}),mr=p({name:`flutter`,cmds:{acceptance:n({name:`acceptance`,description:`Run the complete packaged Flutter conformance gate on macOS.`,args:{apiOrigin:c({long:`api-origin`,env:`COREFRAME_API_ORIGIN`,type:fr,description:`Defaults to COREFRAME_API_ORIGIN.`})},handler:({apiOrigin:e})=>se({environment:{...process.env,COREFRAME_API_ORIGIN:e}})}),codegen:n({name:`codegen`,description:`Generate Flutter bridge contracts and Panda-backed Mix theme tokens.`,args:{check:i({long:`check`,description:`Fail when generated Flutter artifacts are missing or stale.`,defaultValue:()=>!1})},handler:({check:e})=>P({check:e})}),prepare:n({name:`prepare`,description:`Build and package the React client for one Flutter platform.`,args:{platform:u({type:s(N),displayName:`platform`,description:`Flutter platform whose packaged client should be prepared.`}),apiOrigin:c({long:`api-origin`,env:`COREFRAME_API_ORIGIN`,type:fr,description:`Defaults to COREFRAME_API_ORIGIN.`})},handler:({apiOrigin:e,platform:t})=>ae({apiOrigin:e,platform:t})}),check:n({name:`check`,description:`Reject missing, stale, modified, or incorrectly targeted Flutter assets.`,args:{platform:u({type:s(N),displayName:`platform`,description:`Flutter platform whose packaged client should be checked.`}),apiOrigin:c({long:`api-origin`,env:`COREFRAME_API_ORIGIN`,type:fr,description:`Defaults to COREFRAME_API_ORIGIN.`})},handler:({apiOrigin:e,platform:t})=>M({apiOrigin:e,platform:t})})}}),hr=p({name:`i18n`,cmds:{build:n({name:`build`,description:`Extract source messages or materialize an exact release catalog snapshot.`,args:{},handler:async()=>{await Kn()}}),materialize:n({name:`materialize`,description:`Materialize the immutable i18n snapshot for an exact commit.`,args:{revision:c({long:`revision`,type:l(f),description:`Full commit SHA. Defaults to the checked-out commit.`})},handler:async({revision:e})=>{let t=await Yn({revision:e});t&&console.log(`Materialized i18n snapshot ${t.snapshot}.`)}}),prepare:n({name:`prepare`,description:`Fill missing translations, strictly compile, and publish an immutable tagged snapshot.`,args:{tag:c({long:`tag`,type:f,description:`Pushed v* release tag that points to the checked-out commit.`})},handler:async({tag:e})=>{let t=await Jn({tag:e});console.log(`${t.reused?`Reused`:`Published`} i18n snapshot ${t.snapshot}.`)}})}}),gr=q.platform===`win32`?`react-router.cmd`:`react-router`,_r=q.platform===`win32`?`panda.cmd`:`panda`;async function vr(e=q.cwd()){await xr(e),await br(e,[`typegen`])}async function yr(e=q.cwd(),t=q.env,n){if((t.COREFRAME_PLATFORM??t.TAURI_ENV_PLATFORM??`web`)!==`web`)return;let r=I.resolve(e,`.coreframe/dashboard-build`),i=I.join(r,`client`),a=I.resolve(e,`dist/client/__dashboard`);await G(r,{force:!0,recursive:!0}),await Sr(e,_r,[`build`],t),await br(e,[`build`,...n?[`--mode`,n]:[]],t),await G(a,{force:!0,recursive:!0}),await U(I.dirname(a),{recursive:!0}),await xe(i,a,{recursive:!0})}async function br(e,t,n=q.env){await Sr(e,gr,t,n)}async function xr(e){await G(I.resolve(e,`dashboard/.react-router`),{force:!0,recursive:!0})}async function Sr(e,t,n,r=q.env){await V(t,n,{cwd:I.resolve(e,`dashboard`),env:{...r,PATH:I.resolve(e,`node_modules/.bin`)+I.delimiter+(r.PATH??r.Path??``)},stdio:`inherit`})}const Cr=p({name:`dashboard`,cmds:{build:n({name:`build`,args:{mode:c({long:`mode`,type:l(f),description:`Vite environment mode used for the dashboard build.`})},handler:({mode:e})=>yr(void 0,void 0,e)}),typegen:n({name:`typegen`,args:{},handler:()=>vr()})}}),wr=/^[a-z0-9]+(?:-[a-z0-9]+)*$/u;function Tr(e,t){let n=Dr(e,t);if(!Or(n)||!kr(n,[`description`,`requires`,`routes`,`verifier`])||!jr(n.description)||n.requires!==void 0&&(!Array.isArray(n.requires)||!n.requires.every(jr))||n.verifier!==void 0&&!jr(n.verifier)||!Array.isArray(n.routes))throw Error(`${t} must contain a description string, routes array, and optional requires and verifier fields.`);let r=(n.requires??[]).map(e=>Er(e));if(new Set(r).size!==r.length)throw Error(`${t} contains duplicate recipe requirements.`);let i=n.routes.map((e,n)=>{if(!Or(e)||!Ar(e,[`path`,`router`,`when`])||!jr(e.path)||!jr(e.router)||!jr(e.when))throw Error(`${t} route ${n+1} must contain router, path, and when strings.`);return{path:e.path,router:e.router,when:e.when}}),a=i.map(e=>`${e.router}\0${e.path}`);if(new Set(a).size!==a.length)throw Error(`${t} contains a duplicate router and path pair.`);return{description:n.description,requires:r,routes:i,verifier:n.verifier}}function Er(e){if(!wr.test(e))throw Error(`Recipe names use lowercase letters, numbers, and single hyphens.`);return e}function Dr(e,t){try{return Je(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function Or(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function kr(e,t){return Object.keys(e).every(e=>t.includes(e))}function Ar(e,t){let n=Object.keys(e).sort();return n.length===t.length&&n.every((e,n)=>e===t[n])}function jr(e){return typeof e==`string`&&e.length>0}const Mr=`https://github.com/airlock-labs/coreframe.git`;function Nr(e,t){return J(`git`,e,{cwd:t,encoding:`utf8`})}function Pr(e,t){let n=Nr(e,t);if(n.status!==0){let t=n.stderr.trim()||n.stdout.trim();throw Error(`Git command failed: git ${e.join(` `)}${t?`\n${t}`:``}`)}return n.stdout}function Fr(e,t){let n=Nr([`remote`,`get-url`,e],t);if(n.status===2)return null;if(n.status!==0){let t=n.stderr.trim()||n.stdout.trim();throw Error(`Could not inspect remote ${e}.${t?`\n${t}`:``}`)}return n.stdout.trim()}function Ir({cwd:e=process.cwd(),fetch:t=!0,remote:n=`template`}={}){if(n.length===0)throw Error(`Remote name must not be empty.`);Pr([`rev-parse`,`--show-toplevel`],e);let r=Fr(n,e);if(r===null)Pr([`remote`,`add`,n,Mr],e),console.log(`Added ${n} remote: ${Mr}`);else if(r===Mr)console.log(`${n} remote already points at ${Mr}`);else throw Error(`${n} remote points at ${r}, not ${Mr}.\nChoose the intended template source before continuing, then update or rename the remote manually.`);t&&(Pr([`fetch`,n,`--tags`,`--prune`],e),console.log(`Fetched ${n}.`))}const Lr=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u;function Rr(e){return Lr.test(e)?`v${e}`:e}function zr(e){return`${Rr(e)}:template`}function Br(e,t){return`${zr(e)}/${t}`}function Vr({cwd:e=process.cwd(),fetch:t=!0,remote:n=`template`,target:r}={}){let i=Gr(e),a=Yr(i,[`rev-parse`,`--show-toplevel`]),o=Rr(r??Kr(i));return Ir({cwd:a,fetch:t,remote:n}),{projectRoot:i,ref:o,repositoryRoot:a}}function Hr(e,t,n){return Ur(e,t,n).toString(`utf8`)}function Ur(e,t,n){let r=`${t}:${n}`,i=J(`git`,[`show`,r],{cwd:e,encoding:`buffer`});if(i.status!==0)throw Error(`Could not read ${r}. ${Xr([`show`,r],i)}`);return i.stdout}function Wr(e,t,n){let r=J(`git`,[`ls-tree`,`-r`,`--name-only`,`-z`,t,`--`,n],{cwd:e,encoding:`buffer`});if(r.status!==0)throw Error(Xr([`ls-tree`,t,n],r));return r.stdout.toString(`utf8`).split(`\0`).filter(Boolean)}function Gr(e){let t=B(e);for(;;){let e=R(t,`package.json`),n=Jr(e);if(n!==void 0&&qr(n,e).engines?.coreframe)return t;let r=L(t);if(r===t)throw Error(`Could not find a package.json with engines.coreframe.`);t=r}}function Kr(e){let t=R(e,`package.json`),n=Jr(t);if(n===void 0)throw Error(`Required file package.json does not exist.`);let r=qr(n,t).engines?.coreframe;if(!r)throw Error(`package.json must declare an exact engines.coreframe recipe baseline.`);return r}function qr(e,t){try{return JSON.parse(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function Jr(e){try{return X(e,`utf8`)}catch(e){if(Zr(e)&&e.code===`ENOENT`)return;throw e}}function Yr(e,t){let n=J(`git`,t,{cwd:e,encoding:`utf8`});if(n.status!==0)throw Error(Xr(t,n));return n.stdout.trim()}function Xr(e,t){let n=t.stderr.toString(`utf8`).trim()||t.stdout.toString(`utf8`).trim();return`Git command failed: git ${e.join(` `)}${n?`\n${n}`:``}`}function Zr(e){return e instanceof Error&&`code`in e}const Qr=[{path:`package.json`,requirement:`retain the Coreframe Flutter JavaScript runtime used by src-flutter`,test:e=>e.includes(`"@coreframe/flutter-js"`)},{path:`coreframe.config.ts`,requirement:`enable web and at least one Flutter development platform`,test:ti},{path:`src/api/client/app-origin.ts`,requirement:`allow the Flutter shell to provide its exact API origin`,test:e=>ei(e,[`@coreframe/flutter-js/client`,`resolveAppOrigin`,`browserOrigin: location?.origin`])},{path:`src/api/worker/auth-config.ts`,requirement:`trust the exact Flutter authentication origins`,test:e=>ei(e,[`appendFlutterAuthOrigins`,`appendFlutterAuthOrigins([], development)`])},{path:`src/api/worker/middleware/auth.ts`,requirement:`broker Flutter access tokens and accept Flutter bearer origins`,test:e=>ei(e,[`createFlutterAccessTokenResponse`,`isFlutterAuthOrigin(origin, import.meta.env.DEV)`,`readFlutterBearerToken(request, import.meta.env.DEV, developmentOrigin)`,`native && ctx.request.method !== "GET"`])&&!e.includes(`isNativeOrigin`)},{path:`src/api/worker/middleware/flutter-cors.ts`,requirement:`provide the Flutter packaged-origin CORS boundary`,test:e=>ei(e,[`applyFlutterCors`,`handleFlutterCorsPreflight`,`flutterCorsMiddleware`])},{path:`src/api/worker/middleware/index.ts`,requirement:`apply Flutter CORS to ordinary Worker responses`,test:e=>e.includes(`flutterCorsMiddleware`)},{path:`src/web/app/flutter-shell/application.ts`,requirement:`configure the Flutter shell's app-owned query and session hooks`,test:e=>ei(e,[`configureShellQueryFocus`,`authSessionHint`])},{path:`src/web/entry.client.tsx`,requirement:`load the package-owned Flutter development tools only for non-browser development`,test:e=>ei(e,[`@coreframe/vite/flutter-devtools`,`import.meta.env.PLATFORM !== "web"`])}];function $r(e){let t=[];for(let n of Qr){let r=R(e,n.path);if(!Y(r)){t.push(`${n.path} is missing; it must ${n.requirement}.`);continue}let i=X(r,`utf8`);n.test(i)||t.push(`${n.path} must ${n.requirement}.`)}return t}function ei(e,t){return t.every(t=>e.includes(t))}function ti(e){let t=e.match(/\bplatforms\s*:\s*\[([\s\S]*?)\]/)?.[1];if(!t)return!1;let n=new Set([...t.matchAll(/(["'`])([^"'`]*)\1/g)].map(e=>e[2]));return n.has(`web`)&&[`ios`,`android`,`macos`].some(e=>n.has(e))}const ni=[{path:`package.json`,requirement:`declare the Tauri CLI, plugin-log, and Coreframe Tauri runtime packages`,test:e=>$(e,[`"@tauri-apps/cli"`,`"@tauri-apps/plugin-log"`,`"@coreframe/tauri-js"`,`"@coreframe/tauri-plugin-auth-session"`])},{path:`src-tauri/Cargo.toml`,requirement:`declare Tauri, plugin-log, and Coreframe auth-session Rust dependencies`,test:e=>$(e,[`tauri-build`,`tauri-plugin-log`,`coreframe-tauri-plugin-auth-session`])},{path:`src-tauri/src/main.rs`,requirement:`launch the project-owned Tauri Rust library`,test:e=>e.includes(`::run();`)},{path:`src-tauri/src/lib.rs`,requirement:`register plugin-log and the Coreframe auth-session broker`,test:e=>$(e,[`tauri_plugin_log::Builder`,`coreframe_tauri_plugin_auth_session::init`,`VITE_APP_ORIGIN`])},{path:`src-tauri/build.rs`,requirement:`forward VITE_APP_ORIGIN and TAURI_DEV_HOST into the Rust build`,test:e=>$(e,[`VITE_APP_ORIGIN`,`TAURI_DEV_HOST`])},{path:`src-tauri/capabilities/default.json`,requirement:`grant log and auth-session permissions to the main window`,test:e=>$(e,[`"windows": ["main"]`,`"log:default"`,`"coreframe-tauri-plugin-auth-session:default"`])},{path:`vite.config.ts`,requirement:`define the Tauri runtime and platform environment and fixed native dev server`,test:e=>$(e,[`env.host === "tauri"`,`"import.meta.env.TAURI"`,`"import.meta.env.PLATFORM"`,`TAURI_DEV_HOST`,`strictPort: true`])},{path:`src/vite-env.d.ts`,requirement:`type the Tauri runtime, platform, development origin, and packaged app origin`,test:e=>$(e,[`PLATFORM: import("@coreframe/lib/shell").ShellPlatform`,`TAURI: boolean`,`TAURI_DEV_ORIGIN`,`VITE_APP_ORIGIN`])},{path:`react-router.config.ts`,requirement:`skip service-worker generation for non-browser hosts`,test:e=>$(e,[`resolveCoreframeHost`,`resolveCoreframeHost() === "browser"`])},{path:`src/api/client/app-origin.ts`,requirement:`resolve browser and packaged application origins through the Tauri runtime`,test:e=>$(e,[`@coreframe/tauri-js/client`,`browserOrigin: location?.origin`,`development: import.meta.env.DEV`,`packagedAppOrigin: import.meta.env.VITE_APP_ORIGIN`,`tauri: import.meta.env.TAURI`,`tauriDevelopmentOrigin: import.meta.env.TAURI_DEV_ORIGIN`])&&!e.includes(`resolveAppOrigin(import.meta.env`)},{path:`src/api/client/auth-fetch.ts`,requirement:`call the selected framework authentication composition`,test:e=>$(e,[`createAuthenticatedFetch`,`refreshAccess`,`sessionHint: authSessionHint`])},{path:`src/api/client/auth-session-hint.ts`,requirement:`keep native session hints in memory until the credential broker revalidates`,test:e=>$(e,[`import.meta.env.PLATFORM !== "web"`,`persistence: browserPersistence`,`return false`])},{path:`src/api/client/tauri-auth.ts`,requirement:`compose native API and Better Auth transports behind the virtual auth contract`,test:e=>$(e,[`createAuthenticatedFetch`,`createTauriAuthenticatedFetch`,`authSessionHint: options.sessionHint`,`mintAccessToken`,`createAuthClient`,`createAuthFetch`,`onSessionChange: options.onSessionChange`])},{path:`src/web/auth/client.ts`,requirement:`call the selected framework Better Auth composition`,test:e=>$(e,[`createAuthClient as createCoreframeAuthClient`,`createCoreframeAuthClient`,`authFetch`,`customFetchImpl`])},{path:`src/api/worker/middleware/auth.ts`,requirement:`mint and accept bearer access tokens only across the fixed native origin boundary`,test:e=>$(e,[`appendTauriAppOrigins`,`createTauriAccessTokenResponse`,`isTauriAppOrigin`,`readTauriBearerToken`])},{path:`src/api/worker/fetch.ts`,requirement:`apply native CORS at every Worker response boundary`,test:e=>$(e,[`handleTauriCorsPreflight`,`applyTauriCors`])},{path:`coreframe.config.ts`,requirement:`enable web and desktop development platforms`,test:e=>$(e,[`platforms: ["web", "desktop"]`])&&!e.includes(`"ios"`)&&!e.includes(`"android"`)},{path:`src/web/entry.client.tsx`,requirement:`attach native development logs and skip service-worker registration in Tauri`,test:e=>$(e,[`import "./dev/tauri-log.ts"`,`import.meta.env.TAURI`])},{path:`.env.example`,requirement:`document the packaged VITE_APP_ORIGIN build value`,test:e=>e.includes(`VITE_APP_ORIGIN`)},{path:`.gitignore`,requirement:`ignore the Tauri Cargo target directory`,test:e=>e.includes(`src-tauri/target`)},{path:`.oxfmtrc.json`,requirement:`ignore generated Tauri schemas and target output`,test:e=>$(e,[`src-tauri/gen/schemas`,`src-tauri/target`])},{path:`src-tauri/AGENTS.md`,requirement:`route native work to owner-local rules and documentation`,test:e=>$(e,[`.agents/rules/tauri.md`,`.agents/references/authentication.md`,`.agents/references/deployment.md`,`src-tauri/docs/deployment.md`])},{path:`src-tauri/.agents/rules/tauri.md`,requirement:`install the owner-local durable Tauri native-boundary rule`,test:e=>$(e,[`## Native Boundary`,`## Security`,`## Documentation`])},{path:`.agents/rules/integrations.yaml`,requirement:`route cross-boundary Tauri work to the owner-local native rule`,test:e=>e.includes(`src-tauri/.agents/rules/tauri.md`)},{path:`src-tauri/docs/authentication.md`,requirement:`document the native credential broker and bearer-token boundary`,test:e=>$(e,[`@coreframe/tauri-js`,`@coreframe/tauri-plugin-auth-session`,`VITE_APP_ORIGIN`])},{path:`src-tauri/docs/development.md`,requirement:`document native development asset delivery and Leylines scopes`,test:e=>$(e,[`dev.tauri`,`browser.tauri`,`managed asset`])},{path:`src-tauri/docs/deployment.md`,requirement:`document native release topology, signing, token recovery, and provider setup`,test:e=>$(e,[`VITE_APP_ORIGIN`,`native-auth`,`access-token signing-secret`])},{path:`src-tauri/docs/privacy-security.md`,requirement:`record the shipped Tauri remote API and secure-storage boundary`,test:e=>$(e,[`## Remote API Boundary`,`platform secure storage`])},{path:`.github/workflows/tauri-release-artifacts.yml`,requirement:`provide a desktop-only Tauri release-artifact workflow`,test:e=>$(e,[`Build Tauri Release Artifacts`,`pnpm exec tauri`])&&!e.toLowerCase().includes(`ios`)&&!e.toLowerCase().includes(`android`)}],ri=[`CoreframeTemplateProject7A91C`,`coreframe-template-project-7a91c`,`coreframe_template_project_7a91c`,`com.example.coreframetemplateproject7a91c`];function ii(e){let t=[];for(let n of ni){let r=R(e,n.path);if(!Y(r)){t.push(`${n.path} is missing; it must ${n.requirement}.`);continue}let i=X(r,`utf8`);n.test(i)||t.push(`${n.path} must ${n.requirement}.`)}let n=R(e,`src-tauri/tauri.conf.json`);Y(n)?ai(n,t):t.push(`src-tauri/tauri.conf.json is missing.`);for(let n of[`src-tauri/Cargo.toml`,`src-tauri/src/main.rs`,`src-tauri/tauri.conf.json`]){let r=R(e,n);Y(r)&&ri.some(e=>X(r,`utf8`).includes(e))&&t.push(`${n} must replace the Coreframe template identity sentinel.`)}return t}function ai(e,t){let n;try{n=JSON.parse(X(e,`utf8`))}catch{t.push(`src-tauri/tauri.conf.json must contain valid JSON.`);return}(typeof n.identifier!=`string`||!/^[a-z0-9]+(?:\.[a-z0-9]+){2,}$/.test(n.identifier)||n.identifier.startsWith(`com.example.`))&&t.push(`src-tauri/tauri.conf.json must use an organization-owned reverse-domain identifier.`)}function $(e,t){return t.every(t=>e.includes(t))}function oi({name:e,...t}){let n=Vr(t),r=`recipes/${e}/recipe.yaml`,i=li(Tr(Hr(n.repositoryRoot,n.ref,r),r).verifier,n.projectRoot);if(i.length>0)throw Error(`Recipe ${e} verification failed:\n${i.map(e=>`- ${e}`).join(`
|
|
6
|
-
`)}
|
|
7
|
-
`)}\nApply and verify ${n} before continuing.`)}}function li(e,t){if(!e)throw Error(`Required recipe does not declare a verifier.`);if(e===`tauri`)return ii(t);if(e===`flutter`)return $r(t);throw Error(`Unknown recipe verifier ${JSON.stringify(e)}.`)}function ui({cwd:e=process.cwd(),fetch:t=!0,name:n,remote:r=`template`,target:i}){Er(n);let a=Vr({cwd:e,fetch:t,remote:r,target:i}),{projectRoot:o,ref:s,repositoryRoot:c}=a,l=`recipes/${n}`,u=`${l}/recipe.yaml`,d=Tr(Hr(c,s,u),u);ci(d.requires,a);let f=Hr(c,s,`${l}/RECIPE.md`),p=Wr(c,s,`${l}/files`),m=Wr(c,s,`${l}/patches`),h=Wr(c,s,`${l}/.agents`),g=new Map,_=new Map,v=[],y=[],b=[],x=[],S=[],C=[];for(let e of p){let t=e.slice(`${l}/files/`.length);if(_i(t,`Recipe file ${e}`),t.startsWith(`.agents/`))throw Error(`Recipe file ${e} must be stored in the recipe's .agents directory.`);g.set(t,Ur(c,s,e)),_.set(t,e)}for(let e of h){let t=e.slice(`${l}/`.length);if(mi(t,`Recipe asset ${e}`),g.has(t))throw Error(`Recipe declares ${t} as both a file and an agent asset.`);g.set(t,Ur(c,s,e)),_.set(t,e)}for(let e of m){let t=vi(e,l);if(g.has(t))throw Error(`Recipe declares ${t} as both a file and a patch.`);let n=Ur(c,s,e);yi(n.toString(`utf8`),t,e),gi(o,t),bi(o,n,!1)?(v.push({contents:n,destinationPath:t}),x.push(t)):bi(o,n,!0)?S.push(t):b.push({destination:t,source:e})}let w=new Map;for(let[e,t]of g){let r=Ci(gi(o,e));if(r===void 0)w.set(e,t),y.push(e);else if(r.equals(t))S.push(e);else if(e.startsWith(`.agents/`))throw Error(`Recipe ${n} cannot replace modified ${e}. Reconcile that agent asset manually.`);else b.push({destination:e,source:_.get(e)})}let T=new Map;for(let e of d.routes){if(mi(e.router,`Recipe route router`),hi(e.path,`Recipe route path`),g.has(e.router))throw Error(`Recipe cannot replace its destination router ${e.router}.`);if(!g.has(e.path)&&!Y(gi(o,e.path)))throw Error(`Recipe route target ${e.path} does not exist.`);let t=T.get(e.router)??fi(wi(gi(o,e.router),e.router),e.router);T.set(e.router,t);let r=t.routes.find(t=>t.path===e.path);if(r){if(r.when!==e.when)throw Error(`Recipe ${n} route ${e.path} conflicts with the existing trigger in ${e.router}.`);continue}t.routes.push({path:e.path,when:e.when})}for(let[e,t]of T){t.routes.sort((e,t)=>e.path<t.path?-1:+(e.path>t.path));let n=wi(gi(o,e),e),r=Ye(t,{lineWidth:0});r===n?S.push(e):(w.set(e,r),C.push(e))}for(let{destinationPath:e}of v)if(w.has(e))throw Error(`Recipe cannot both write and patch ${e}.`);for(let[e,t]of w){let n=gi(o,e);Ve(L(n),{recursive:!0}),qe(n,t)}return v.length>0&&xi(o,v.map(({contents:e})=>e)),{created:y.sort(),instructions:f,mergeRequired:b.sort((e,t)=>e.destination.localeCompare(t.destination)),name:n,patched:x.sort(),ref:s,unchanged:[...new Set(S)].sort(),updated:C.sort()}}function di(e){console.log(`Prepared Coreframe recipe ${e.name} from ${e.ref}.`);for(let t of e.created)console.log(`created: ${t}`);for(let t of e.updated)console.log(`updated: ${t}`);for(let t of e.patched)console.log(`patched: ${t}`);for(let t of e.mergeRequired)console.log(`merge-required: ${t.destination} (source: ${e.ref}:${t.source})`);for(let t of e.unchanged)console.log(`unchanged: ${t}`);console.log(`\nContinue by following ${e.ref}:recipes/${e.name}/RECIPE.md:\n`),console.log(e.instructions.trimEnd())}function fi(e,t){let n=pi(e,t);if(!Ti(n)||!Ei(n,[`routes`,`rules`])||!Array.isArray(n.rules)||!n.rules.every(Di)||!Array.isArray(n.routes))throw Error(`${t} must contain only string rules and a routes array.`);let r=n.routes.map((e,n)=>{if(!Ti(e)||!Ei(e,[`path`,`when`])||!Di(e.path)||!Di(e.when))throw Error(`${t} route ${n+1} must contain path and when strings.`);return{path:e.path,when:e.when}}),i=r.map(e=>e.path);if(new Set(i).size!==i.length)throw Error(`${t} contains duplicate route paths.`);return{rules:n.rules,routes:r}}function pi(e,t){try{return Je(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function mi(e,t){if(!e.startsWith(`.agents/`))throw Error(`${t} must be a normalized project-relative path beneath .agents/.`);_i(e,t)}function hi(e,t){if(_i(e,t),!/(?:^|\/)\.agents\/rules\/.+\.md$/u.test(e))throw Error(`${t} must point to a Markdown rule beneath an .agents/rules directory.`)}function gi(e,t){_i(t,`Recipe destination`);let n=R(e,t),r=e;for(let e of t.split(`/`))if(r=R(r,e),Y(r)&&Be(r).isSymbolicLink())throw Error(`Recipe destination ${t} crosses symbolic link ${r}.`);return n}function _i(e,t){if(e.length===0||ce(e)||e===`..`||e.startsWith(`../`)||e.includes(`\\`)||z.normalize(e)!==e)throw Error(`${t} must be a normalized project-relative path.`)}function vi(e,t){let n=e.slice(`${t}/patches/`.length);if(!n.endsWith(`.patch`))throw Error(`Recipe patch ${e} must use a .patch suffix.`);let r=n.slice(0,-6);return _i(r,`Recipe patch ${e}`),r}function yi(e,t,n){let r=e.match(/^diff --git .+$/gmu)??[],i=e.match(/^--- .+$/gmu)??[],a=e.match(/^\+\+\+ .+$/gmu)??[];if(r.length!==1||r[0]!==`diff --git a/${t} b/${t}`||i.length!==1||a.length!==1||i[0]!==`--- a/${t}`||a[0]!==`+++ b/${t}`||/^(?:deleted file mode |GIT binary patch$|new file mode |rename from |rename to )/mu.test(e))throw Error(`Recipe patch ${n} must modify only ${t}.`)}function bi(e,t,n){let r=[`apply`,`--check`,`--whitespace=nowarn`];return n&&r.push(`--reverse`),r.push(`-`),J(`git`,r,{cwd:e,input:t}).status===0}function xi(e,t){let n=J(`git`,[`apply`,`--whitespace=nowarn`,`-`],{cwd:e,input:Buffer.concat(t.flatMap(e=>[e,Buffer.from(e.at(-1)===10?``:`
|
|
8
|
-
`)
|
|
5
|
+
`)}function qt(e){return[`Windows release build succeeded.`,``,`The unpackaged application bundle is at ${JSON.stringify(R(e,`src-flutter/build/windows/x64/runner/Release`))}.`,`Create and sign an installer with the Windows packaging workflow for distribution.`].join(`
|
|
6
|
+
`)}function Jt(e){return[`Linux release build succeeded.`,``,`The application bundle is at ${JSON.stringify(R(e,`src-flutter/build/linux/x64/release/bundle`))}.`,`Package the bundle with the Linux distribution format used by your release process.`].join(`
|
|
7
|
+
`)}async function Yt({apiOrigin:e,cwd:t=process.cwd(),environment:n=process.env,platform:r=`web`,profile:i=!1,simulator:a=!1,prepareClient:o=j,runCommand:s=Zt}={}){Xt(r,{profile:i,simulator:a});let c={...n};delete c.COREFRAME_FLUTTER_DEVELOPMENT,delete c.COREFRAME_PLATFORM,delete c.TAURI_ENV_PLATFORM;let l=r===`web`?void 0:M(e??n.COREFRAME_API_ORIGIN);for(let e of Ut(r,{apiOrigin:l,cwd:t,profile:i,simulator:a})){if(e.kind===`prepare`){if(!l)throw Error(`A production API origin is required for the Flutter ${e.platform} build.`);await o({apiOrigin:l,cwd:t,environment:c,platform:e.platform});continue}await s(e.command,e.args,{cwd:e.cwd,env:{...c,...e.environment}})}r===`android`?console.log(Gt(t,{profile:i})):r===`ios`?console.log(Kt(t,{profile:i,simulator:a})):r===`windows`?console.log(qt(t)):r===`linux`&&console.log(Jt(t))}function Xt(e,{profile:t,simulator:n}){if(t&&e===`web`)throw Error(`The --profile flag is only supported for Flutter build targets.`);if(n&&e!==`ios`)throw Error(`The --simulator flag is only supported for the iOS build target.`);if(t&&n)throw Error(`Flutter profile builds are not supported for the iOS simulator.`)}async function Zt(e,t,{cwd:n,env:r}){await B(e,t,{cwd:n,env:r,stdio:`inherit`})}function Qt(e,t,n,r){return{kind:`command`,command:e,args:t,cwd:n,...r===void 0?{}:{environment:r}}}const $t=n(u,{displayName:`origin`,description:`Exact production HTTPS API origin embedded in a packaged Flutter client.`,async from(e){return M(e)}}),en=t({name:`build`,description:`Build the web client or a Flutter app (release by default). Tauri is not built.`,args:{platform:c({type:s(a(Ht)),displayName:`platform`,description:`Build target: web, iOS, Android, macOS, Windows, or Linux. Defaults to web.`}),apiOrigin:o({long:`api-origin`,type:s($t),description:`Exact production HTTPS API origin for a Flutter build. Defaults to COREFRAME_API_ORIGIN.`}),profile:r({long:`profile`,description:`Build a Flutter profile app instead of the default release app.`,defaultValue:()=>!1}),simulator:r({long:`simulator`,description:`Build iOS for the simulator instead of a physical device.`,defaultValue:()=>!1})},handler:({apiOrigin:e,platform:t,profile:n,simulator:r})=>Yt({apiOrigin:e,platform:t,profile:n,simulator:r})}),tn=/^[a-f0-9]{64}$/,nn=/^[a-f0-9]{40}$/,rn=/^[A-Za-z0-9][A-Za-z0-9._-]*$/;function an(e){if(!tn.test(e))throw Error(`Invalid SHA-256 digest "${e}".`);return e}function on(e){if(!nn.test(e))throw Error(`Invalid full Git revision "${e}".`);return e}function sn(e,t){if(!rn.test(e))throw Error(`${t} must contain only letters, numbers, dots, underscores, or hyphens.`);return e}function cn(e){return`projects/${sn(e,`Project ID`)}/i18n/v1`}function ln(e,t){return an(t),`${cn(e)}/objects/sha256/${t.slice(0,2)}/${t}`}function un(e,t){return on(t),`${cn(e)}/commits/${t}.json`}function dn(e,t){return fn(t),`${cn(e)}/releases/${encodeURIComponent(t)}.json`}function fn(e){if(!e.startsWith(`v`)||e.length<2||e.length>128||/\s/.test(e)||e.includes(`..`))throw Error(`Release tag "${e}" must be a valid v-prefixed tag.`);return e}function Z(e,t){if(!t||t.startsWith(`/`)||t.includes(`\0`))throw Error(`Unsafe i18n artifact path "${t}".`);let n=R(e),r=R(n,t);if(r!==n&&!r.startsWith(`${n}${z}`))throw Error(`Unsafe i18n artifact path "${t}".`);return r}function Q(e,t,n){return`${e.directory}/${t}/${n}.json`}function pn(e,t,n){return`${e.directory}/${t}/${n}.mjs`}async function mn(e){await B(`pnpm`,[`exec`,`lingui`,`extract`],{cwd:e,stdio:`inherit`})}async function hn({config:e,cwd:t,strict:n,temporaryDirectory:r}){let i=[];try{for(let n of e.locales)for(let a of e.catalogs){let o=Z(t,Q(e,n,a)),s=await bn(o),c=Object.fromEntries(Object.entries(s).filter(([,e])=>!e.obsolete)),l=I(r,`${n}-${a}.json`);await H(F(l),{recursive:!0}),await be(o,l),i.push({path:o,backup:l}),await xn(o,c)}await B(`pnpm`,[`exec`,`lingui`,`compile`,...n?[`--strict`]:[]],{cwd:t,stdio:`inherit`})}finally{try{for(let{path:e,backup:t}of i)await be(t,e)}finally{for(let n of e.locales)for(let r of e.catalogs)await W(Z(t,pn(e,n,r)),{force:!0})}}}async function gn({config:e,cwd:t}){let n=[];for(let r of e.locales)if(r!==e.sourceLocale)for(let i of e.catalogs){let a=await bn(Z(t,Q(e,r,i)));for(let[e,t]of Object.entries(a)){if(t.obsolete||t.translation?.trim())continue;let a=t.message;if(typeof a!=`string`||!a)throw Error(`Missing source message metadata for ${r}:${e}.`);n.push({catalog:i,comments:t.comments?.filter(e=>typeof e==`string`)??[],context:t.context,id:e,locale:r,message:a,origins:t.origin?.map(([e,t])=>t?`${e}:${t}`:e)??[],placeholders:Object.keys(t.placeholders??{}).sort()})}}return n.sort((e,t)=>En(e).localeCompare(En(t)))}async function _n({config:e,cwd:t,messages:n,env:r=process.env}){if(n.length===0)return{translations:[],version:1};if(!e.generator)throw Error(`I18n preparation found ${n.length} missing translations, but no generator is configured.`);let i={messages:n,sourceLocale:e.sourceLocale,version:1};return Sn(await Cn({args:e.generator.args??[],command:e.generator.command,cwd:t,env:r,input:JSON.stringify(i)}))}async function vn({config:e,cwd:t,missing:n,response:r}){let i=new Map(n.map(e=>[En(e),e])),a=new Map;for(let e of r.translations){let t=En(e);if(!i.has(t))throw Error(`Translation generator returned unexpected entry ${e.locale}:${e.catalog}:${e.id}.`);if(a.has(t))throw Error(`Translation generator returned duplicate entry ${e.locale}:${e.catalog}:${e.id}.`);if(!e.translation.trim())throw Error(`Translation generator returned an empty entry ${e.locale}:${e.id}.`);a.set(t,e.translation)}let o=[...i.keys()].filter(e=>!a.has(e));if(o.length>0)throw Error(`Translation generator omitted ${o.length} required entries.`);let s=await Me(`@lingui/message-utils/compileMessage`,t);for(let e of n){let t=a.get(En(e));wn({compileMessage:s,id:e.id,locale:e.locale,source:e.message,translation:t})}for(let n of e.locales)if(n!==e.sourceLocale)for(let r of e.catalogs){let i=Z(t,Q(e,n,r)),o=await bn(i),s=!1;for(let[e,t]of Object.entries(o)){let i=a.get(En({catalog:r,id:e,locale:n}));if(i!==void 0){if(t.translation?.trim())throw Error(`Refusing to overwrite preserved translation ${n}:${e}.`);t.translation=i,s=!0}}s&&await xn(i,o)}}async function yn({config:e,cwd:t}){let n=await gn({config:e,cwd:t});if(n.length>0)throw Error(`I18n catalogs remain incomplete: ${n.length} translations are missing.`);let r=await Me(`@lingui/message-utils/compileMessage`,t);for(let n of e.locales)if(n!==e.sourceLocale)for(let i of e.catalogs){let a=await bn(Z(t,Q(e,n,i)));for(let[e,t]of Object.entries(a))if(!t.obsolete){if(typeof t.message!=`string`||typeof t.translation!=`string`)throw Error(`Incomplete source metadata for active translation ${n}:${e}.`);wn({compileMessage:r,id:e,locale:n,source:t.message,translation:t.translation})}}}async function bn(e){let t=JSON.parse(await U(e,`utf8`));if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Lingui rich JSON catalog must be an object: ${e}.`);for(let[n,r]of Object.entries(t)){if(!r||typeof r!=`object`||Array.isArray(r))throw Error(`Invalid Lingui rich JSON message ${n} in ${e}.`);let t=r;if(t.translation!==void 0&&typeof t.translation!=`string`)throw Error(`Invalid translation value for ${n} in ${e}.`);if(t.message!==void 0&&t.message!==null&&typeof t.message!=`string`)throw Error(`Invalid source message value for ${n} in ${e}.`);if(t.context!==void 0&&typeof t.context!=`string`)throw Error(`Invalid context value for ${n} in ${e}.`);if(t.obsolete!==void 0&&typeof t.obsolete!=`boolean`)throw Error(`Invalid obsolete marker for ${n} in ${e}.`);if(t.comments!==void 0&&(!Array.isArray(t.comments)||t.comments.some(e=>typeof e!=`string`)))throw Error(`Invalid comments for ${n} in ${e}.`);if(t.origin!==void 0&&(!Array.isArray(t.origin)||t.origin.some(e=>!Array.isArray(e)||typeof e[0]!=`string`||e[1]!==void 0&&typeof e[1]!=`number`)))throw Error(`Invalid origins for ${n} in ${e}.`);if(t.placeholders!==void 0&&(!t.placeholders||typeof t.placeholders!=`object`||Array.isArray(t.placeholders)))throw Error(`Invalid placeholders for ${n} in ${e}.`)}return t}async function xn(e,t){await H(F(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;await G(n,`${JSON.stringify(t,null,2)}\n`),await Ee(n,e)}function Sn(e){let t;try{t=JSON.parse(e)}catch{throw Error(`Translation generator returned invalid JSON.`)}if(!t||typeof t!=`object`||t.version!==1||!Array.isArray(t.translations))throw Error(`Translation generator returned an invalid response envelope.`);for(let e of t.translations)if(!e||typeof e!=`object`||typeof e.id!=`string`||typeof e.catalog!=`string`||typeof e.locale!=`string`||typeof e.translation!=`string`)throw Error(`Translation generator returned an invalid translation entry.`);return t}function Cn({args:e,command:t,cwd:n,env:r,input:i}){return B(t,e,{cwd:n,env:r,stdio:[{string:i},`pipe`,`ignore`]}).then(({stdout:e})=>{if(Buffer.byteLength(e)>10*1024*1024)throw Error(`Translation generator output exceeded 10 MiB.`);return e}).catch(()=>{throw Error(`Translation generator exited unsuccessfully.`)})}function wn({compileMessage:e,id:t,locale:n,source:r,translation:i}){let a,o;try{a=e.compileMessageOrThrow(r),o=e.compileMessageOrThrow(i)}catch{throw Error(`Translation ${n}:${t} is not valid ICU MessageFormat.`)}let s=Tn(a),c=Tn(o);if(s.length!==c.length||s.some((e,t)=>e!==c[t]))throw Error(`Translation ${n}:${t} does not preserve source ICU placeholders.`)}function Tn(e){let t=[];function n(e){for(let r of e){if(typeof r==`string`)continue;let[e,i=`argument`,a]=r;if(t.push(`${e}:${i}`),a&&typeof a==`object`&&!Array.isArray(a))for(let e of Object.values(a))Array.isArray(e)&&n(e)}}return n(e),t.sort()}function En(e){return`${e.locale}\0${e.catalog}\0${e.id}`}function Dn(e){return Le(`sha256`).update(e).digest(`hex`)}async function On(e){return Dn(await U(e))}function kn(e){return Buffer.from(`${JSON.stringify(e,null,2)}\n`)}async function An({bucket:e,digest:t,projectId:n,source:r,store:i}){if(an(t),await On(r)!==t)throw Error(`I18n object source does not match declared SHA-256 digest ${t}.`);let a=ln(n,t);await i.has(e,a)||await i.upload(e,a,r,`application/octet-stream`);let o=`${r}.${process.pid}.${K()}.verify`;try{if(await i.download(e,a,o),await On(o)!==t)throw Error(`Existing immutable i18n object ${a} failed integrity verification.`)}finally{await W(o,{force:!0})}}async function jn({bucket:e,key:t,reference:n,store:r,temporaryDirectory:i}){let a=kn(n),o=I(i,`reference-${K()}.json`);if(await r.has(e,t))try{if(await r.download(e,t,o),!(await U(o)).equals(a))throw Error(`Immutable i18n reference ${t} already resolves to different snapshot data.`);return}finally{await W(o,{force:!0})}await G(o,a,{flag:`wx`});try{await r.upload(e,t,o,`application/json`)}finally{await W(o,{force:!0})}let s=I(i,`reference-${K()}.verify.json`);try{if(await r.download(e,t,s),!(await U(s)).equals(a))throw Error(`Uploaded immutable i18n reference ${t} failed verification.`)}finally{await W(s,{force:!0})}}async function Mn({bucket:e,manifest:t,projectId:n,store:r,temporaryDirectory:i}){let a=kn(t),o=Dn(a),s=I(i,`manifest-${o}.json`);await G(s,a,{flag:`wx`});try{await An({bucket:e,digest:o,projectId:n,source:s,store:r})}finally{await W(s,{force:!0})}return o}async function Nn({bucket:e,key:t,store:n,temporaryDirectory:r}){if(!await n.has(e,t))return;let i=I(r,`reference-${K()}.json`);try{await n.download(e,t,i);let r=JSON.parse(await U(i,`utf8`));if(r.version!==1||typeof r.revision!=`string`||typeof r.snapshot!=`string`)throw Error(`Invalid i18n reference at ${t}.`);return on(r.revision),an(r.snapshot),r}finally{await W(i,{force:!0})}}async function Pn({bucket:e,projectId:t,revision:n,store:r,temporaryDirectory:i}){let a=await Nn({bucket:e,key:un(t,n),store:r,temporaryDirectory:i});if(a&&a.revision!==n)throw Error(`I18n commit reference does not match requested revision ${n}.`);return a}async function Fn({bucket:e,projectId:t,reference:n,store:r,tag:i,temporaryDirectory:a}){await jn({bucket:e,key:un(t,n.revision),reference:n,store:r,temporaryDirectory:a}),i&&await jn({bucket:e,key:dn(t,i),reference:n,store:r,temporaryDirectory:a})}async function In({bucket:e,cacheRoot:t,digest:n,projectId:r,store:i,target:a}){an(n);let o=I(R(t),`v1`,`sha256`,n.slice(0,2),n);if(await Rn(o,n)===!1){await H(F(o),{recursive:!0});let t=`${o}.${process.pid}.${K()}.tmp`;try{if(await i.download(e,ln(r,n),t),await On(t)!==n)throw Error(`Downloaded i18n object failed SHA-256 verification: ${n}.`);await W(o,{force:!0}),await Ee(t,o)}finally{await W(t,{force:!0})}}await H(F(a),{recursive:!0});let s=`${a}.${process.pid}.${K()}.tmp`;try{if(await be(o,s),await On(s)!==n)throw Error(`Cached i18n object failed SHA-256 verification: ${n}.`);await W(a,{force:!0}),await Ee(s,a)}finally{await W(s,{force:!0})}}async function Ln({bucket:e,cacheRoot:t,digest:n,projectId:r,store:i,temporaryDirectory:a}){let o=I(a,`manifest-${n}.json`);await In({bucket:e,cacheRoot:t,digest:n,projectId:r,store:i,target:o});let s=JSON.parse(await U(o,`utf8`));if(s.version!==1||s.projectId!==r||typeof s.revision!=`string`||!Array.isArray(s.files)||!Array.isArray(s.catalogs)||s.catalogs.some(e=>typeof e!=`string`)||!Array.isArray(s.locales)||s.locales.some(e=>typeof e!=`string`)||typeof s.sourceLocale!=`string`||typeof s.generator!=`string`||typeof s.linguiVersion!=`string`)throw Error(`Invalid i18n snapshot manifest ${n}.`);on(s.revision),s.baseline!==void 0&&an(s.baseline);for(let e of s.files){if(!e||typeof e!=`object`||typeof e.path!=`string`||typeof e.digest!=`string`||typeof e.size!=`number`)throw Error(`Invalid file entry in i18n snapshot manifest ${n}.`);an(e.digest)}return s}async function Rn(e,t){try{return(await De(e)).isFile()&&await On(e)===t}catch{return!1}}async function zn({cwd:e=process.cwd(),env:t=process.env}={}){if((await Fe({cwd:e})).i18n){if(t.COREFRAME_I18N_RELEASE_REVISION){await Hn({cwd:e,env:t,revision:t.COREFRAME_I18N_RELEASE_REVISION});return}await mn(e)}}async function Bn({cwd:e=process.cwd(),projectConfig:t}={}){let n=t??await Fe({cwd:e});if(!n.i18n)return;let r=Un(n.i18n),i=Z(e,r.directory);try{if(!(await De(i)).isDirectory())throw Error(`I18n catalog path is not a directory: ${i}.`)}catch(t){if(t.code!==`ENOENT`)throw t;await mn(e);return}for(let t of r.locales)for(let n of r.catalogs)try{if(!(await De(Z(e,Q(r,t,n)))).isFile())throw Error(`I18n catalog path is not a file: ${t}/${n}.json.`)}catch(t){if(t.code!==`ENOENT`)throw t;await mn(e);return}}async function Vn({cwd:e=process.cwd(),env:t=process.env,store:n,tag:r}){fn(r);let i=await Wn({cwd:e,env:t,store:n});await Qn(e);let a=await Zn(e);await $n(e,r,a);let o=await Ce(I(je(),`coreframe-i18n-prepare-`));try{let n=await Pn({bucket:i.assets.sourceBucket,projectId:i.assets.projectId,revision:a,store:i.store,temporaryDirectory:o});if(n){let e=await Ln({bucket:i.assets.sourceBucket,cacheRoot:i.cacheRoot,digest:n.snapshot,projectId:i.assets.projectId,store:i.store,temporaryDirectory:o});return Xn(i,e,a),await Kn(i,e),await Fn({bucket:i.assets.sourceBucket,projectId:i.assets.projectId,reference:n,store:i.store,tag:r,temporaryDirectory:o}),{reused:!0,snapshot:n.snapshot}}return await Yn(i,o,async()=>{let n=await Gn(i,a,o);n||await Jn(i),await mn(e);let s=await gn({config:i.config,cwd:e}),c=await _n({config:i.config,cwd:e,env:t,messages:s});await vn({config:i.config,cwd:e,missing:s,response:c}),await yn({config:i.config,cwd:e}),await hn({config:i.config,cwd:e,strict:!0,temporaryDirectory:o});let l=await qn(i),u={...n?{baseline:n}:{},catalogs:i.config.catalogs,files:l,generator:s.length>0?i.config.generator?.id??`unconfigured`:`none`,linguiVersion:await er(e),locales:i.config.locales,projectId:i.assets.projectId,revision:a,sourceLocale:i.config.sourceLocale,version:1},d=await Mn({bucket:i.assets.sourceBucket,manifest:u,projectId:i.assets.projectId,store:i.store,temporaryDirectory:o});return await Fn({bucket:i.assets.sourceBucket,projectId:i.assets.projectId,reference:{revision:a,snapshot:d,version:1},store:i.store,tag:r,temporaryDirectory:o}),{reused:!1,snapshot:d}})}finally{await W(o,{force:!0,recursive:!0})}}async function Hn({cwd:e=process.cwd(),env:t=process.env,revision:n,store:r}={}){let i=await Fe({cwd:e});if(!i.i18n)return;let a=await Wn({cwd:e,env:t,store:r,projectConfig:i}),o=on(n??await Zn(e)),s=await Ce(I(je(),`coreframe-i18n-materialize-`));try{let e=await Pn({bucket:a.assets.sourceBucket,projectId:a.assets.projectId,revision:o,store:a.store,temporaryDirectory:s});if(!e)throw Error(`No prepared i18n snapshot exists for commit ${o}. Push a v* tag for this commit and wait for the translation gate.`);let t=await Ln({bucket:a.assets.sourceBucket,cacheRoot:a.cacheRoot,digest:e.snapshot,projectId:a.assets.projectId,store:a.store,temporaryDirectory:s});return Xn(a,t,o),await Kn(a,t),{revision:o,snapshot:e.snapshot}}finally{await W(s,{force:!0,recursive:!0})}}function Un(e){let t=sn(e.sourceLocale,`Source locale`),n=[...new Set(e.locales.map(e=>sn(e,`Locale`)))],r=[...new Set(e.catalogs.map(e=>sn(e,`Catalog`)))];if(n.length===0||!n.includes(t))throw Error(`I18n locales must include the source locale.`);if(r.length===0)throw Error(`I18n configuration requires at least one catalog.`);if(e.generator&&(!e.generator.command.trim()||!e.generator.id.trim()))throw Error(`I18n generator command and ID must be non-empty.`);return{catalogs:r,directory:e.directory??`locales`,generator:e.generator,locales:n,sourceLocale:t}}async function Wn({cwd:e=process.cwd(),env:t=process.env,projectConfig:n,store:r}){let i=n??await Fe({cwd:e});if(!i.i18n)throw Error(`Missing i18n configuration in coreframe.config.ts.`);if(!i.assets)throw Error(`I18n snapshots require the existing private build bucket configured under assets.`);let a=i.assets;return{assets:a,cacheRoot:R(e,`.coreframe`,`i18n`,`cache`),config:Un(i.i18n),cwd:R(e),env:t,store:r??_e({config:a,env:t})}}async function Gn(e,t,n){let{stdout:r}=await B(`git`,[`rev-list`,`--first-parent`,`--skip=1`,t],{cwd:e.cwd,stdin:`ignore`});for(let t of r.split(/\r?\n/).filter(Boolean)){let r=await Pn({bucket:e.assets.sourceBucket,projectId:e.assets.projectId,revision:on(t),store:e.store,temporaryDirectory:n});if(!r)continue;let i=await Ln({bucket:e.assets.sourceBucket,cacheRoot:e.cacheRoot,digest:r.snapshot,projectId:e.assets.projectId,store:e.store,temporaryDirectory:n});return Xn(e,i,t),await Kn(e,i),r.snapshot}}async function Kn(e,t){for(let n of t.files)if(await In({bucket:e.assets.sourceBucket,cacheRoot:e.cacheRoot,digest:n.digest,projectId:e.assets.projectId,store:e.store,target:Z(e.cwd,n.path)}),(await De(Z(e.cwd,n.path))).size!==n.size)throw Error(`Materialized i18n artifact size does not match manifest: ${n.path}.`)}async function qn(e){let t=[];for(let n of e.config.locales)for(let r of e.config.catalogs){let i=Q(e.config,n,r),a=Z(e.cwd,i),o=await On(a);await An({bucket:e.assets.sourceBucket,digest:o,projectId:e.assets.projectId,source:a,store:e.store}),t.push({digest:o,path:i,size:(await De(a)).size})}return t.sort((e,t)=>e.path.localeCompare(t.path))}async function Jn(e){let{stdout:t}=await B(`git`,[`rev-parse`,`--show-prefix`],{cwd:e.cwd,stdin:`ignore`}),n=t.trim(),{stdout:r}=await B(`git`,[`log`,`-1`,`--format=%H`,`--diff-filter=AM`,`--`,`:(top)${`${n}${e.config.directory}/${e.config.sourceLocale}/${e.config.catalogs[0]}.po`}`],{cwd:e.cwd,stdin:`ignore`}),i=r.trim();if(!i)return!1;let a=(await Me(`@lingui/format-po`,e.cwd)).formatter({lineNumbers:!1}),o=!1;for(let t of e.config.locales)for(let r of e.config.catalogs){let s=`${n}${`${e.config.directory}/${t}/${r}.po`}`;try{let{stdout:n}=await B(`git`,[`show`,`${i}:${s}`],{cwd:e.cwd,stdin:`ignore`});await xn(Z(e.cwd,Q(e.config,t,r)),a.parse(n)),o=!0}catch{}}return o}async function Yn(e,t,n){let r=[];for(let n of e.config.locales)for(let i of e.config.catalogs){let a=Q(e.config,n,i),o=Z(e.cwd,a);try{await ve(o)}catch{continue}let s=I(t,`previous-catalogs`,a);await H(F(s),{recursive:!0}),await Ee(o,s),r.push({backup:s,path:o})}try{let e=await n();return await W(I(t,`previous-catalogs`),{force:!0,recursive:!0}),e}catch(t){for(let t of e.config.locales)for(let n of e.config.catalogs)await W(Z(e.cwd,Q(e.config,t,n)),{force:!0});for(let{backup:e,path:t}of r)await H(F(t),{recursive:!0}),await Ee(e,t);throw t}}function Xn(e,t,n){if(t.revision!==n||t.projectId!==e.assets.projectId||t.sourceLocale!==e.config.sourceLocale||JSON.stringify(t.locales)!==JSON.stringify(e.config.locales)||JSON.stringify(t.catalogs)!==JSON.stringify(e.config.catalogs))throw Error(`I18n snapshot does not match commit or project configuration.`);let r=e.config.locales.flatMap(t=>e.config.catalogs.map(n=>Q(e.config,t,n))),i=t.files.map(e=>e.path);if(new Set(i).size!==i.length||JSON.stringify(i.sort())!==JSON.stringify(r.sort()))throw Error(`I18n snapshot has an incomplete or unexpected artifact set.`)}async function Zn(e){let{stdout:t}=await B(`git`,[`rev-parse`,`HEAD`],{cwd:e,stdin:`ignore`});return on(t.trim())}async function Qn(e){let{stdout:t}=await B(`git`,[`status`,`--porcelain`],{cwd:e,stdin:`ignore`});if(t.trim())throw Error(`Tagged i18n preparation requires a clean Git tree.`)}async function $n(e,t,n){let{stdout:r}=await B(`git`,[`rev-parse`,`${t}^{commit}`],{cwd:e,stdin:`ignore`});if(r.trim()!==n)throw Error(`Release tag ${t} does not point to checked-out commit ${n}.`)}async function er(e){let{stdout:t}=await B(`pnpm`,[`exec`,`lingui`,`--version`],{cwd:e,stdin:`ignore`});return t.trim()}const tr=[`Use a B2 Multi-Bucket Application Key restricted to the configured private build-object and public generated-assets buckets.`,`Required capabilities: listAllBucketNames, readFiles, and writeFiles.`,`Deletion, bucket-management, and key-management capabilities are not needed.`].join(` `),nr=n(u,{displayName:`widths`,description:`Comma-separated responsive variant widths.`,async from(e){let t=e.split(`,`).map(e=>Number(e));if(t.length===0||t.some(e=>!Number.isInteger(e)||e<=0)||t.some((e,n)=>n>0&&e<=t[n-1]))throw Error(`Widths must be positive, unique, strictly ascending integers.`);return t}}),rr=n(u,{displayName:`profile`,async from(e){return he(e)}}),ir=n(u,{displayName:`pack`,description:`Asset pack name, such as training-videos.`,async from(e){if(!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(e))throw Error(`Asset pack names must use lowercase hyphen-separated segments.`);return e}}),ar=n(u,{displayName:`origin`,description:`Exact production HTTPS API origin embedded in the packaged Flutter client.`,async from(e){return M(e)}}),or=d({name:`assets`,cmds:{configure:t({name:`configure`,description:`Store a Backblaze B2 private build-object key in the operating system credential store. ${tr}`,args:{profile:c({type:rr,displayName:`profile`,description:`Credential profile named by coreframe.config.ts.`})},handler:async({profile:e})=>{V.note(tr,`Required B2 key access`);let t=await V.text({message:`Backblaze B2 application key ID`,validate:e=>e?.trim()?void 0:`The application key ID is required.`});if(V.isCancel(t))throw Error(`Asset credential configuration was cancelled.`);let n=await V.password({message:`Backblaze B2 application key`,validate:e=>e?void 0:`The application key is required.`});if(V.isCancel(n))throw Error(`Asset credential configuration was cancelled.`);await ge({applicationKey:n,applicationKeyId:t.trim(),profile:e}),console.log(`Stored Coreframe asset credential profile "${e}".`)}}),add:t({name:`add`,args:{file:c({type:u,displayName:`file`,description:`Source raster image, SVG, MP3, MP4, or Lottie JSON to add to the asset library.`}),id:o({long:`id`,type:u,description:`Logical asset ID, such as blog/my-post/hero.`}),alt:o({long:`alt`,type:s(u),description:`Required alt text for raster image and SVG assets.`}),pack:o({long:`pack`,type:s(ir),description:`Place the asset in a named, lazily loaded pack.`}),variantWidths:o({long:`widths`,type:s(nr),description:`Generate exactly these raster-image widths instead of the default ladder.`}),json:r({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({alt:e,file:t,id:n,json:r,pack:i,variantWidths:a})=>pe(await le({alt:e,file:t,id:n,pack:i,variantWidths:a}),r)}),backup:t({name:`backup`,description:`Back up every object in both configured asset buckets to a new Git branch.`,args:{branch:o({long:`branch`,type:u,description:`Name of the new local Git branch that will contain the backup.`})},handler:async({branch:e})=>{let t=await ue({branch:e});console.log(`Backed up ${t.objects} objects (${t.bytes} bytes) to branch "${t.branch}" at ${t.commit}.`)}}),build:t({name:`build`,args:{id:o({long:`id`,type:s(u),description:`Build only one logical asset ID.`}),pack:o({long:`pack`,type:s(ir),description:`Build only one named asset pack.`}),json:r({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({id:e,json:t,pack:n})=>pe(await de({id:e,pack:n}),t)}),check:t({name:`check`,args:{fix:r({long:`fix`,description:`Migrate asset state and build missing generated output when possible.`,defaultValue:()=>!1}),pack:o({long:`pack`,type:s(ir),description:`Check only one named asset pack.`}),json:r({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({fix:e,json:t,pack:n})=>{let r=await fe({fix:e,pack:n});pe(r,t),r.ok||(process.exitCode=1)}}),publish:t({name:`publish`,args:{pack:o({long:`pack`,type:s(ir),description:`Publish only one named asset pack.`}),json:r({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await me({pack:t});pe(n,e),n.ok||(process.exitCode=1)}}),status:t({name:`status`,args:{pack:o({long:`pack`,type:s(ir),description:`Report status for only one named asset pack.`}),json:r({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,pack:t})=>{let n=await fe({pack:t});pe(n,e),n.ok||(process.exitCode=1)}})}}),sr=d({name:`flutter`,cmds:{acceptance:t({name:`acceptance`,description:`Run the complete packaged Flutter conformance gate on macOS.`,args:{apiOrigin:o({long:`api-origin`,env:`COREFRAME_API_ORIGIN`,type:ar,description:`Defaults to COREFRAME_API_ORIGIN.`})},handler:({apiOrigin:e})=>N({environment:{...process.env,COREFRAME_API_ORIGIN:e}})}),codegen:t({name:`codegen`,description:`Generate Flutter bridge contracts and Panda-backed Mix theme tokens.`,args:{check:r({long:`check`,description:`Fail when generated Flutter artifacts are missing or stale.`,defaultValue:()=>!1})},handler:({check:e})=>oe({check:e})}),prepare:t({name:`prepare`,description:`Build and package the React client for one Flutter platform.`,args:{platform:c({type:a(A),displayName:`platform`,description:`Flutter platform whose packaged client should be prepared.`}),apiOrigin:o({long:`api-origin`,env:`COREFRAME_API_ORIGIN`,type:ar,description:`Defaults to COREFRAME_API_ORIGIN.`})},handler:({apiOrigin:e,platform:t})=>j({apiOrigin:e,platform:t})}),check:t({name:`check`,description:`Reject missing, stale, modified, or incorrectly targeted Flutter assets.`,args:{platform:c({type:a(A),displayName:`platform`,description:`Flutter platform whose packaged client should be checked.`}),apiOrigin:o({long:`api-origin`,env:`COREFRAME_API_ORIGIN`,type:ar,description:`Defaults to COREFRAME_API_ORIGIN.`})},handler:({apiOrigin:e,platform:t})=>k({apiOrigin:e,platform:t})})}}),cr=d({name:`i18n`,cmds:{build:t({name:`build`,description:`Extract source messages or materialize an exact release catalog snapshot.`,args:{},handler:async()=>{await zn()}}),materialize:t({name:`materialize`,description:`Materialize the immutable i18n snapshot for an exact commit.`,args:{revision:o({long:`revision`,type:s(u),description:`Full commit SHA. Defaults to the checked-out commit.`})},handler:async({revision:e})=>{let t=await Hn({revision:e});t&&console.log(`Materialized i18n snapshot ${t.snapshot}.`)}}),prepare:t({name:`prepare`,description:`Fill missing translations, strictly compile, and publish an immutable tagged snapshot.`,args:{tag:o({long:`tag`,type:u,description:`Pushed v* release tag that points to the checked-out commit.`})},handler:async({tag:e})=>{let t=await Vn({tag:e});console.log(`${t.reused?`Reused`:`Published`} i18n snapshot ${t.snapshot}.`)}})}}),lr=q.platform===`win32`?`react-router.cmd`:`react-router`,ur=q.platform===`win32`?`panda.cmd`:`panda`;async function dr(e=q.cwd()){await mr(e),await pr(e,[`typegen`])}async function fr(e=q.cwd(),t=q.env,n){if((t.COREFRAME_PLATFORM??`web`)!==`web`)return;let r=P.resolve(e,`.coreframe/dashboard-build`),i=P.join(r,`client`),a=P.resolve(e,`dist/client/__dashboard`);await W(r,{force:!0,recursive:!0}),await hr(e,ur,[`build`],t),await pr(e,[`build`,...n?[`--mode`,n]:[]],t),await W(a,{force:!0,recursive:!0}),await H(P.dirname(a),{recursive:!0}),await xe(i,a,{recursive:!0})}async function pr(e,t,n=q.env){await hr(e,lr,t,n)}async function mr(e){await W(P.resolve(e,`dashboard/.react-router`),{force:!0,recursive:!0})}async function hr(e,t,n,r=q.env){await B(t,n,{cwd:P.resolve(e,`dashboard`),env:{...r,PATH:P.resolve(e,`node_modules/.bin`)+P.delimiter+(r.PATH??r.Path??``)},stdio:`inherit`})}const $={access:ve,chmod:ye,mkdir:H,mkdtemp:Ce,readFile:U,readFileSync:J,rm:W,writeFile:G},gr={getAvailablePort:vr},_r={homedir:ke,kill:q.kill,networkInterfaces:Ae,tmpdir:je};async function vr(){let e=Ze();try{await new Promise((t,n)=>{e.once(`error`,n),e.listen(0,`127.0.0.1`,t)});let t=e.address();if(!t||typeof t==`string`)throw Error(`Could not allocate an available TCP port.`);return t.port}finally{e.listening&&await new Promise((t,n)=>{e.close(e=>e?n(e):t())})}}function yr({host:e=`127.0.0.1`,port:t,start:n}){let r,i=!1,a=!1,o=!1,s,c,l,u,d,f=new Set,p=new Promise((e,t)=>{u=e,d=t}),m=e=>{a||o||(o=!0,d(e))},h=()=>(s||=Promise.resolve().then(n).catch(e=>{throw m(e),e}),s),g=e=>{f.add(e),e.once(`close`,()=>f.delete(e)),e.pause(),_(e).catch(t=>{m(t),e.destroy()})},_=async e=>{let t=await h();if(a||e.destroyed)return;let n=await br(t,()=>a);if(a||e.destroyed){n.destroy();return}f.add(n),n.once(`close`,()=>f.delete(n)),n.on(`error`,()=>e.destroy()),n.once(`close`,()=>e.destroy()),e.on(`error`,()=>n.destroy()),e.once(`close`,()=>n.destroy()),e.pipe(n),n.pipe(e)};return{close:async()=>l||(l=(async()=>{a=!0,o||(o=!0,u());for(let e of f)e.destroy();f.clear(),c&&!i&&await Promise.allSettled([c]),!(!r||!i)&&(await new Promise(e=>{r.close(()=>e())}),i=!1)})(),l),fail:m,listen:async()=>c||(r=Ze(g),c=new Promise((n,a)=>{let o=e=>{if(i){m(e);return}a(e)};r.once(`error`,o),r.once(`listening`,()=>{i=!0,r.off(`error`,o),r.on(`error`,m),n()}),r.listen(t,e)}),c),wait:()=>p}}async function br(e,t){let n=Date.now()+1e4,r;for(;!t();)try{return await xr(e)}catch(e){if(r=e,Date.now()>=n)break;await new Promise(e=>setTimeout(e,50))}throw r instanceof Error?r:Error(`Could not connect to the dashboard.`)}function xr({host:e=`127.0.0.1`,port:t}){return new Promise((n,r)=>{let i=Xe({host:e,port:t}),a=e=>{i.off(`connect`,o),i.destroy(),r(e)},o=()=>{i.off(`error`,a),n(i)};i.once(`error`,a),i.once(`connect`,o)})}const Sr=q.platform===`win32`?`react-router.cmd`:`react-router`;function Cr(e){return ze(P.resolve(e,`dashboard/dashboard.config.ts`))}function wr(e){return[`exec`,`coreframe`,`dashboard`,`dev`,`--port`,String(e)]}function Tr({cwd:e,env:t,port:n}){let r=t.PATH??t.Path??``,i,a,o=!1,s,c,l=[`SIGINT`,`SIGTERM`].map(e=>{let t=()=>{d()};return q.on(e,t),{handler:t,signal:e}}),u=async(e,t)=>{try{await e,o||a?.fail(Error(`The dashboard development server stopped unexpectedly.`))}catch(e){o||a?.fail(e)}finally{await t.outputTasks,t.stdout.end(),t.stderr.end(),await Promise.allSettled([Je(t.stdout),Je(t.stderr)]),i===e&&(i=void 0)}};a=yr({port:n,start:async()=>{if(o)throw Error(`The dashboard development server was stopped before it started.`);let n=await gr.getAvailablePort();if(o)throw Error(`The dashboard development server was stopped before it started.`);let a=Y({label:`dashboard`}),s=Y({color:`red`,label:`dashboard`});a.pipe(q.stdout,{end:!1}),s.pipe(q.stderr,{end:!1});let l=B(Sr,[`dev`,`--host`,`127.0.0.1`,`--port`,String(n)],{cwd:P.resolve(e,`dashboard`),env:{...t,PATH:P.resolve(e,`node_modules/.bin`)+P.delimiter+r},stdin:`inherit`});i=l;let d=Promise.allSettled([Dr(l.stdout,a),Dr(l.stderr,s)]);return c=u(l,{outputTasks:d,stderr:s,stdout:a}),{host:`127.0.0.1`,port:n}}});let d=async()=>s||(s=(async()=>{o=!0,await a?.close(),i?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),await c;for(let{handler:e,signal:t}of l)q.off(t,e)})(),s);return{close:d,listen:()=>a.listen(),wait:()=>a.wait()}}async function Er({cwd:e=q.cwd(),env:t=q.env,port:n}){let r=Tr({cwd:e,env:t,port:n});try{await r.listen(),await r.wait()}finally{await r.close()}}async function Dr(e,t){for await(let n of e)t.write(`${n}\n`)||await new Promise(e=>t.once(`drain`,e))}const Or=d({name:`dashboard`,cmds:{dev:t({name:`dev`,args:{port:o({long:`port`,type:i,description:`Local TCP port for the dashboard proxy.`})},handler:({port:e})=>Er({port:e})}),build:t({name:`build`,args:{mode:o({long:`mode`,type:s(u),description:`Vite environment mode used for the dashboard build.`})},handler:({mode:e})=>fr(void 0,void 0,e)}),typegen:t({name:`typegen`,args:{},handler:()=>dr()})}}),kr=/^[a-z0-9]+(?:-[a-z0-9]+)*$/u;function Ar(e,t){let n=Mr(e,t);if(!Nr(n)||!Pr(n,[`description`,`requires`,`routes`,`verifier`])||!Ir(n.description)||n.requires!==void 0&&(!Array.isArray(n.requires)||!n.requires.every(Ir))||n.verifier!==void 0&&!Ir(n.verifier)||!Array.isArray(n.routes))throw Error(`${t} must contain a description string, routes array, and optional requires and verifier fields.`);let r=(n.requires??[]).map(e=>jr(e));if(new Set(r).size!==r.length)throw Error(`${t} contains duplicate recipe requirements.`);let i=n.routes.map((e,n)=>{if(!Nr(e)||!Fr(e,[`path`,`router`,`when`])||!Ir(e.path)||!Ir(e.router)||!Ir(e.when))throw Error(`${t} route ${n+1} must contain router, path, and when strings.`);return{path:e.path,router:e.router,when:e.when}}),a=i.map(e=>`${e.router}\0${e.path}`);if(new Set(a).size!==a.length)throw Error(`${t} contains a duplicate router and path pair.`);return{description:n.description,requires:r,routes:i,verifier:n.verifier}}function jr(e){if(!kr.test(e))throw Error(`Recipe names use lowercase letters, numbers, and single hyphens.`);return e}function Mr(e,t){try{return Qe(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function Nr(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Pr(e,t){return Object.keys(e).every(e=>t.includes(e))}function Fr(e,t){let n=Object.keys(e).sort();return n.length===t.length&&n.every((e,n)=>e===t[n])}function Ir(e){return typeof e==`string`&&e.length>0}const Lr=`https://github.com/airlock-labs/coreframe.git`;function Rr(e,t){return X(`git`,e,{cwd:t,encoding:`utf8`})}function zr(e,t){let n=Rr(e,t);if(n.status!==0){let t=n.stderr.trim()||n.stdout.trim();throw Error(`Git command failed: git ${e.join(` `)}${t?`\n${t}`:``}`)}return n.stdout}function Br(e,t){let n=Rr([`remote`,`get-url`,e],t);if(n.status===2)return null;if(n.status!==0){let t=n.stderr.trim()||n.stdout.trim();throw Error(`Could not inspect remote ${e}.${t?`\n${t}`:``}`)}return n.stdout.trim()}function Vr({cwd:e=process.cwd(),fetch:t=!0,remote:n=`template`}={}){if(n.length===0)throw Error(`Remote name must not be empty.`);zr([`rev-parse`,`--show-toplevel`],e);let r=Br(n,e);if(r===null)zr([`remote`,`add`,n,Lr],e),console.log(`Added ${n} remote: ${Lr}`);else if(r===Lr)console.log(`${n} remote already points at ${Lr}`);else throw Error(`${n} remote points at ${r}, not ${Lr}.\nChoose the intended template source before continuing, then update or rename the remote manually.`);t&&(zr([`fetch`,n,`--tags`,`--prune`],e),console.log(`Fetched ${n}.`))}const Hr=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u;function Ur(e){return Hr.test(e)?`v${e}`:e}function Wr(e){return`${Ur(e)}:template`}function Gr(e,t){return`${Wr(e)}/${t}`}function Kr({cwd:e=process.cwd(),fetch:t=!0,remote:n=`template`,target:r}={}){let i=Xr(e),a=ei(i,[`rev-parse`,`--show-toplevel`]),o=Ur(r??Zr(i));return Vr({cwd:a,fetch:t,remote:n}),{projectRoot:i,ref:o,repositoryRoot:a}}function qr(e,t,n){return Jr(e,t,n).toString(`utf8`)}function Jr(e,t,n){let r=`${t}:${n}`,i=X(`git`,[`show`,r],{cwd:e,encoding:`buffer`});if(i.status!==0)throw Error(`Could not read ${r}. ${ti([`show`,r],i)}`);return i.stdout}function Yr(e,t,n){let r=X(`git`,[`ls-tree`,`-r`,`--name-only`,`-z`,t,`--`,n],{cwd:e,encoding:`buffer`});if(r.status!==0)throw Error(ti([`ls-tree`,t,n],r));return r.stdout.toString(`utf8`).split(`\0`).filter(Boolean)}function Xr(e){let t=R(e);for(;;){let e=I(t,`package.json`),n=$r(e);if(n!==void 0&&Qr(n,e).engines?.coreframe)return t;let r=F(t);if(r===t)throw Error(`Could not find a package.json with engines.coreframe.`);t=r}}function Zr(e){let t=I(e,`package.json`),n=$r(t);if(n===void 0)throw Error(`Required file package.json does not exist.`);let r=Qr(n,t).engines?.coreframe;if(!r)throw Error(`package.json must declare an exact engines.coreframe recipe baseline.`);return r}function Qr(e,t){try{return JSON.parse(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function $r(e){try{return J(e,`utf8`)}catch(e){if(ni(e)&&e.code===`ENOENT`)return;throw e}}function ei(e,t){let n=X(`git`,t,{cwd:e,encoding:`utf8`});if(n.status!==0)throw Error(ti(t,n));return n.stdout.trim()}function ti(e,t){let n=t.stderr.toString(`utf8`).trim()||t.stdout.toString(`utf8`).trim();return`Git command failed: git ${e.join(` `)}${n?`\n${n}`:``}`}function ni(e){return e instanceof Error&&`code`in e}const ri=[{path:`package.json`,requirement:`retain the Coreframe Flutter JavaScript runtime used by src-flutter`,test:e=>e.includes(`"@coreframe/flutter-js"`)},{path:`coreframe.config.ts`,requirement:`enable web and at least one Flutter development platform`,test:oi},{path:`src/api/client/app-origin.ts`,requirement:`allow the Flutter shell to provide its exact API origin`,test:e=>ai(e,[`@coreframe/flutter-js/client`,`resolveAppOrigin`,`browserOrigin: location?.origin`])},{path:`src/api/worker/auth-config.ts`,requirement:`trust the exact Flutter authentication origins`,test:e=>ai(e,[`appendFlutterAuthOrigins`,`appendFlutterAuthOrigins([], development)`])},{path:`src/api/worker/middleware/auth.ts`,requirement:`broker Flutter access tokens and accept Flutter bearer origins`,test:e=>ai(e,[`createFlutterAccessTokenResponse`,`isFlutterAuthOrigin(origin, import.meta.env.DEV)`,`readFlutterBearerToken(request, import.meta.env.DEV, developmentOrigin)`,`native && ctx.request.method !== "GET"`])&&!e.includes(`isNativeOrigin`)},{path:`src/api/worker/middleware/flutter-cors.ts`,requirement:`provide the Flutter packaged-origin CORS boundary`,test:e=>ai(e,[`applyFlutterCors`,`handleFlutterCorsPreflight`,`flutterCorsMiddleware`])},{path:`src/api/worker/middleware/index.ts`,requirement:`apply Flutter CORS to ordinary Worker responses`,test:e=>e.includes(`flutterCorsMiddleware`)},{path:`src/web/app/flutter-shell/application.ts`,requirement:`configure the Flutter shell's app-owned query and session hooks`,test:e=>ai(e,[`configureShellQueryFocus`,`authSessionHint`])},{path:`src/web/entry.client.tsx`,requirement:`load the package-owned Flutter development tools only for non-browser development`,test:e=>ai(e,[`@coreframe/vite/flutter-devtools`,`import.meta.env.PLATFORM !== "web"`])}];function ii(e){let t=[];for(let n of ri){let r=I(e,n.path);if(!ze(r)){t.push(`${n.path} is missing; it must ${n.requirement}.`);continue}let i=J(r,`utf8`);n.test(i)||t.push(`${n.path} must ${n.requirement}.`)}return t}function ai(e,t){return t.every(t=>e.includes(t))}function oi(e){let t=e.match(/\bplatforms\s*:\s*\[([\s\S]*?)\]/)?.[1];if(!t)return!1;let n=new Set([...t.matchAll(/(["'`])([^"'`]*)\1/g)].map(e=>e[2]));return n.has(`web`)&&[`ios`,`android`,`linux`,`macos`,`windows`].some(e=>n.has(e))}function si({name:e,...t}){let n=Kr(t),r=`recipes/${e}/recipe.yaml`,i=ui(Ar(qr(n.repositoryRoot,n.ref,r),r).verifier,n.projectRoot);if(i.length>0)throw Error(`Recipe ${e} verification failed:\n${i.map(e=>`- ${e}`).join(`
|
|
8
|
+
`)}`);return{name:e,ref:n.ref}}function ci(e){console.log(`Verified Coreframe recipe ${e.name} from ${e.ref}.`)}function li(e,t){for(let n of e){let e=`recipes/${n}/recipe.yaml`,r=ui(Ar(qr(t.repositoryRoot,t.ref,e),e).verifier,t.projectRoot);if(r.length>0)throw Error(`Recipe ${n} is required but is not fully applied:\n${r.map(e=>`- ${e}`).join(`
|
|
9
|
+
`)}\nApply and verify ${n} before continuing.`)}}function ui(e,t){if(!e)throw Error(`Required recipe does not declare a verifier.`);if(e===`flutter`)return ii(t);throw Error(`Unknown recipe verifier ${JSON.stringify(e)}.`)}function di({cwd:e=process.cwd(),fetch:t=!0,name:n,remote:r=`template`,target:i}){jr(n);let a=Kr({cwd:e,fetch:t,remote:r,target:i}),{projectRoot:o,ref:s,repositoryRoot:c}=a,l=`recipes/${n}`,u=`${l}/recipe.yaml`,d=Ar(qr(c,s,u),u);li(d.requires,a);let f=qr(c,s,`${l}/RECIPE.md`),p=Yr(c,s,`${l}/files`),m=Yr(c,s,`${l}/patches`),h=Yr(c,s,`${l}/.agents`),g=new Map,_=new Map,v=[],y=[],b=[],x=[],S=[],C=[];for(let e of p){let t=e.slice(`${l}/files/`.length);if(vi(t,`Recipe file ${e}`),t.startsWith(`.agents/`))throw Error(`Recipe file ${e} must be stored in the recipe's .agents directory.`);g.set(t,Jr(c,s,e)),_.set(t,e)}for(let e of h){let t=e.slice(`${l}/`.length);if(hi(t,`Recipe asset ${e}`),g.has(t))throw Error(`Recipe declares ${t} as both a file and an agent asset.`);g.set(t,Jr(c,s,e)),_.set(t,e)}for(let e of m){let t=yi(e,l);if(g.has(t))throw Error(`Recipe declares ${t} as both a file and a patch.`);let n=Jr(c,s,e);bi(n.toString(`utf8`),t,e),_i(o,t),xi(o,n,!1)?(v.push({contents:n,destinationPath:t}),x.push(t)):xi(o,n,!0)?S.push(t):b.push({destination:t,source:e})}let w=new Map;for(let[e,t]of g){let r=wi(_i(o,e));if(r===void 0)w.set(e,t),y.push(e);else if(r.equals(t))S.push(e);else if(e.startsWith(`.agents/`))throw Error(`Recipe ${n} cannot replace modified ${e}. Reconcile that agent asset manually.`);else b.push({destination:e,source:_.get(e)})}let T=new Map;for(let e of d.routes){if(hi(e.router,`Recipe route router`),gi(e.path,`Recipe route path`),g.has(e.router))throw Error(`Recipe cannot replace its destination router ${e.router}.`);if(!g.has(e.path)&&!ze(_i(o,e.path)))throw Error(`Recipe route target ${e.path} does not exist.`);let t=T.get(e.router)??pi(Ti(_i(o,e.router),e.router),e.router);T.set(e.router,t);let r=t.routes.find(t=>t.path===e.path);if(r){if(r.when!==e.when)throw Error(`Recipe ${n} route ${e.path} conflicts with the existing trigger in ${e.router}.`);continue}t.routes.push({path:e.path,when:e.when})}for(let[e,t]of T){t.routes.sort((e,t)=>e.path<t.path?-1:+(e.path>t.path));let n=Ti(_i(o,e),e),r=$e(t,{lineWidth:0});r===n?S.push(e):(w.set(e,r),C.push(e))}for(let{destinationPath:e}of v)if(w.has(e))throw Error(`Recipe cannot both write and patch ${e}.`);for(let[e,t]of w){let n=_i(o,e);Ve(F(n),{recursive:!0}),qe(n,t)}return v.length>0&&Si(o,v.map(({contents:e})=>e)),{created:y.sort(),instructions:f,mergeRequired:b.sort((e,t)=>e.destination.localeCompare(t.destination)),name:n,patched:x.sort(),ref:s,unchanged:[...new Set(S)].sort(),updated:C.sort()}}function fi(e){console.log(`Prepared Coreframe recipe ${e.name} from ${e.ref}.`);for(let t of e.created)console.log(`created: ${t}`);for(let t of e.updated)console.log(`updated: ${t}`);for(let t of e.patched)console.log(`patched: ${t}`);for(let t of e.mergeRequired)console.log(`merge-required: ${t.destination} (source: ${e.ref}:${t.source})`);for(let t of e.unchanged)console.log(`unchanged: ${t}`);console.log(`\nContinue by following ${e.ref}:recipes/${e.name}/RECIPE.md:\n`),console.log(e.instructions.trimEnd())}function pi(e,t){let n=mi(e,t);if(!Ei(n)||!Di(n,[`routes`,`rules`])||!Array.isArray(n.rules)||!n.rules.every(Oi)||!Array.isArray(n.routes))throw Error(`${t} must contain only string rules and a routes array.`);let r=n.routes.map((e,n)=>{if(!Ei(e)||!Di(e,[`path`,`when`])||!Oi(e.path)||!Oi(e.when))throw Error(`${t} route ${n+1} must contain path and when strings.`);return{path:e.path,when:e.when}}),i=r.map(e=>e.path);if(new Set(i).size!==i.length)throw Error(`${t} contains duplicate route paths.`);return{rules:n.rules,routes:r}}function mi(e,t){try{return Qe(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function hi(e,t){if(!e.startsWith(`.agents/`))throw Error(`${t} must be a normalized project-relative path beneath .agents/.`);vi(e,t)}function gi(e,t){if(vi(e,t),!/(?:^|\/)\.agents\/rules\/.+\.md$/u.test(e))throw Error(`${t} must point to a Markdown rule beneath an .agents/rules directory.`)}function _i(e,t){vi(t,`Recipe destination`);let n=I(e,t),r=e;for(let e of t.split(`/`))if(r=I(r,e),ze(r)&&Be(r).isSymbolicLink())throw Error(`Recipe destination ${t} crosses symbolic link ${r}.`);return n}function vi(e,t){if(e.length===0||ce(e)||e===`..`||e.startsWith(`../`)||e.includes(`\\`)||L.normalize(e)!==e)throw Error(`${t} must be a normalized project-relative path.`)}function yi(e,t){let n=e.slice(`${t}/patches/`.length);if(!n.endsWith(`.patch`))throw Error(`Recipe patch ${e} must use a .patch suffix.`);let r=n.slice(0,-6);return vi(r,`Recipe patch ${e}`),r}function bi(e,t,n){let r=e.match(/^diff --git .+$/gmu)??[],i=e.match(/^--- .+$/gmu)??[],a=e.match(/^\+\+\+ .+$/gmu)??[];if(r.length!==1||r[0]!==`diff --git a/${t} b/${t}`||i.length!==1||a.length!==1||i[0]!==`--- a/${t}`||a[0]!==`+++ b/${t}`||/^(?:deleted file mode |GIT binary patch$|new file mode |rename from |rename to )/mu.test(e))throw Error(`Recipe patch ${n} must modify only ${t}.`)}function xi(e,t,n){let r=[`apply`,`--check`,`--whitespace=nowarn`];return n&&r.push(`--reverse`),r.push(`-`),X(`git`,r,{cwd:e,input:t}).status===0}function Si(e,t){let n=X(`git`,[`apply`,`--whitespace=nowarn`,`-`],{cwd:e,input:Buffer.concat(t.flatMap(e=>[e,Buffer.from(e.at(-1)===10?``:`
|
|
10
|
+
`)])),encoding:`utf8`});if(n.status!==0){let e=n.stderr.trim()||n.stdout.trim();throw Error(`Could not apply recipe patches.${e?`\n${e}`:``}`)}}function Ci(e){return wi(e)?.toString(`utf8`)}function wi(e){try{return J(e)}catch(e){if(ki(e)&&e.code===`ENOENT`)return;throw e}}function Ti(e,t){let n=Ci(e);if(n===void 0)throw Error(`Required file ${t} does not exist.`);return n}function Ei(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Di(e,t){let n=Object.keys(e).sort();return n.length===t.length&&n.every((e,n)=>e===t[n])}function Oi(e){return typeof e==`string`&&e.length>0}function ki(e){return e instanceof Error&&`code`in e}function Ai(e={}){let{ref:t,repositoryRoot:n}=Kr(e),r=Yr(n,t,`recipes`).filter(e=>/^recipes\/[^/]+\/recipe\.yaml$/u.test(e)).map(e=>{let r=e.split(`/`)[1];return jr(r),{description:Ar(qr(n,t,e),e).description,name:r}});return r.sort((e,t)=>e.name.localeCompare(t.name)),{recipes:r,ref:t}}function ji(e){console.log(`Coreframe recipes at ${e.ref}:`);for(let t of e.recipes)console.log(`${t.name} — ${t.description}`)}const Mi=`.agents/skills/coreframe-upgrade/SKILL.md`;function Ni(e,t={}){return X(`git`,e,t)}function Pi(e){return e.stderr.toString(`utf8`).trim()||e.stdout.toString(`utf8`).trim()}function Fi(e,t){let n=Gr(e,t),r=Ni([`show`,n],{encoding:`utf8`});if(r.status!==0){let e=Pi(r);throw Error(`Could not read ${n}.${e?` ${e}`:``}`)}return r.stdout.toString()}function Ii(){let e=Ni([`rev-parse`,`--show-toplevel`],{encoding:`utf8`});if(e.status!==0){let t=Pi(e);throw Error(`Could not find git repository root.${t?` ${t}`:``}`)}return e.stdout.toString().trim()}function Li(e,t){let n=He(I(je(),`coreframe-upgrade-skill-`)),r=I(n,`SKILL.md`);try{qe(r,t);let n=Pi(Ni([`--no-pager`,`diff`,`--no-index`,`--color=never`,`--`,e,r]));n&&console.log(n)}finally{We(n,{force:!0,recursive:!0})}}function Ri({apply:e,target:t}){let n=I(Ii(),Mi),r=Ur(t);if(!ze(n))throw Error(`Local ${Mi} does not exist.`);let i=J(n,`utf8`),a=Fi(t,Mi);return i===a?(console.log(`Coreframe upgrade skill matches ${r}:template/${Mi}.`),0):e?(qe(n,a),console.error(`Updated ${Mi} from ${r}:template. Reread it before continuing the upgrade.`),20):(console.error(`Coreframe upgrade skill differs from ${r}:template/${Mi}.`),console.error(`Run again with --apply to update it, then reread ${Mi} before continuing.`),Li(n,a),20)}const zi=[{matches:e=>e===`drizzle`||e.startsWith(`drizzle/`),reason:`project-owned migration history`},{matches:e=>e===`drizzle-hold`||e.startsWith(`drizzle-hold/`),reason:`project-owned migration history`},{matches:e=>e===`src/web/routes.ts`||e.startsWith(`src/web/app/routes/`),reason:`downstream-owned demonstration routes`},{matches:e=>e===`pnpm-lock.yaml`||e===`src-flutter/pubspec.lock`,reason:`downstream-owned dependency lockfile`}],Bi=[{matches:e=>e===`src-tauri`||e.startsWith(`src-tauri/`),reason:`legacy Tauri shell removed by breaking host migration`}],Vi=new Set([`100644`,`100755`,`120000`]);function Hi(e,t={}){return X(`git`,e,t)}function Ui(e){let t=Hi(e,{encoding:`utf8`});if(t.status!==0){let n=t.stderr.toString().trim()||t.stdout.toString().trim();throw Error(`Git command failed: git ${e.join(` `)}${n?`\n${n}`:``}`)}return t.stdout.toString()}function Wi(e){let t=Hi(e);if(t.status!==0){let n=t.stderr.toString(`utf8`).trim()||t.stdout.toString(`utf8`).trim();throw Error(`Git command failed: git ${e.join(` `)}${n?`\n${n}`:``}`)}return t.stdout}function Gi(){return Ui([`rev-parse`,`--show-toplevel`]).trim()}function Ki(e){let t=I(e,`package.json`);if(!ze(t))throw Error(`Missing --base <git-ref>, and package.json does not exist.`);let n=JSON.parse(J(t,`utf8`)).engines?.coreframe;if(typeof n!=`string`||n.length===0)throw Error(`Missing --base <git-ref>, and package.json engines.coreframe is not set.`);return n}function qi(e){let t=[],n=0;for(let r=0;r<e.length;r+=1)e[r]===0&&(t.push(e.subarray(n,r).toString(`utf8`)),n=r+1);return t.filter(e=>e.length>0)}function Ji(e,t){let n=qi(Wi([`diff`,`--name-status`,`-z`,`--no-renames`,Wr(e),Wr(t),`--`])),r=[];for(let e=0;e<n.length;e+=2){let t=n[e],i=n[e+1];if(!t||!i)throw Error(`Could not parse git diff --name-status output.`);r.push({path:i,status:t})}return r}function Yi(e,t){let n=Wi([`ls-tree`,`-z`,`-r`,Wr(e),`--`,t]);if(n.length===0)return null;let r=qi(n)[0],i=r.indexOf(` `);if(i===-1)throw Error(`Could not parse git ls-tree output for ${e}:${t}.`);let[a,o,s]=r.slice(0,i).split(` `);if(!a||!o||!s)throw Error(`Could not parse git ls-tree metadata for ${e}:${t}.`);return{mode:a,object:s,path:t,type:o}}function Xi(e){return Wi([`cat-file`,`blob`,e.object])}function Zi(e,t){let n=R(e,t),r=e.endsWith(z)?e:`${e}${z}`;if(n!==e&&!n.startsWith(r))throw Error(`Refusing to access path outside repository: ${t}`);return n}function Qi(e){try{return Be(e),!0}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return!1;throw e}}function $i(e){return(e.mode&73)!=0}function ea(e){return e===null||e.type===`blob`&&Vi.has(e.mode)}function ta(e){return zi.find(t=>t.matches(e))?.reason}function na(e){return Bi.find(t=>t.matches(e))?.reason}function ra(e,t,n){let r=Zi(e,t);if(n===null)return{matches:!Qi(r)};if(!ea(n))return{matches:!1,reason:`unsupported template entry mode ${n.mode} ${n.type}`};let i;try{i=Be(r)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return{matches:!1,reason:`path is missing from worktree`};throw e}let a=Xi(n);return n.mode===`120000`?i.isSymbolicLink()?{matches:Buffer.from(Ue(r),`utf8`).equals(a)}:{matches:!1,reason:`worktree path is not a symlink`}:i.isFile()?(n.mode===`100755`?$i(i):!$i(i))?{matches:J(r).equals(a)}:{matches:!1,reason:`worktree executable bit differs from template`}:{matches:!1,reason:`worktree path is not a regular file`}}function ia(e){Qi(e)&&We(e,{force:!0,recursive:!1})}function aa(e,t,n){let r=Zi(e,t);if(n===null){ia(r);return}if(Ve(F(r),{recursive:!0}),n.mode===`120000`){ia(r),Ge(Xi(n).toString(`utf8`),r);return}let i=Qi(r)?Be(r):null;i&&!i.isFile()&&ia(r),qe(r,Xi(n)),Re(r,n.mode===`100755`?493:420)}function oa(e,t){return e===null&&t!==null?`add`:e!==null&&t===null?`delete`:`update`}function sa(e,t){if(t.length!==0){console.log(`${e}:`);for(let e of t){let t=e.reason?` (${e.reason})`:``;console.log(` ${e.action}: ${e.path}${t}`)}console.log(``)}}function ca(e){let t=Gi(),n=Ur(e.base??Ki(t)),r=Ur(e.target),i=Ji(n,r),a=[],o=[],s=[],c=[];for(let e of i){let i=ta(e.path);if(i){o.push({action:`ignored`,path:e.path,reason:i});continue}let l=Yi(n,e.path),u=Yi(r,e.path),d=oa(l,u),f=u===null?na(e.path):void 0;if(f){a.push({action:d,path:e.path,reason:f,targetEntry:u});continue}if(!ea(l)||!ea(u)){s.push({action:d,path:e.path,reason:`unsupported template entry type`});continue}if(ra(t,e.path,u).matches){c.push({action:`unchanged`,path:e.path});continue}let p=ra(t,e.path,l);if(!p.matches){s.push({action:d,path:e.path,reason:p.reason??`downstream differs from base template`});continue}a.push({action:d,path:e.path,targetEntry:u})}if(e.apply)for(let e of a)aa(t,e.path,e.targetEntry??null);console.log(`Coreframe template fast-forward: ${n} -> ${r}`),console.log(``),sa(e.apply?`Applied clean template updates`:`Would apply clean template updates`,a),sa(`Ignored downstream-owned paths`,o),sa(`Skipped for agent review`,s),c.length>0&&console.log(`${c.length} changed template path(s) already matched the target state.`),i.length===0&&console.log(`No template file changes found in the requested range.`),!e.apply&&a.length>0&&(console.log(``),console.log(`Run with --apply to write the ${a.length} clean update(s).`))}const la=[`dependencies`,`devDependencies`];function ua(e){let t=X(`git`,e,{encoding:`utf8`});if(t.status!==0){let n=t.stderr.trim()||t.stdout.trim();throw Error(`Git command failed: git ${e.join(` `)}${n?`\n${n}`:``}`)}return t.stdout}function da(e,t){try{return JSON.parse(e)}catch(e){throw Error(`Could not parse ${t}: ${e instanceof Error?e.message:e}`)}}function fa(e,t){let n=`${Ur(e)}:${t}`;return da(ua([`show`,n]),n)}function pa(e){return e.startsWith(`@coreframe/`)}function ma(e){return e.startsWith(`file:`)||e.startsWith(`link:`)||e.startsWith(`workspace:`)}function ha(e){return e.startsWith(`file:`)||e.startsWith(`link:`)}function ga(e,t){let n=e.indexOf(`:`),r=e.slice(n+1),i=L.normalize(L.join(`template`,r,`package.json`));if(r.length===0||L.isAbsolute(r)||i===`..`||i.startsWith(`../`))throw Error(`Invalid local template dependency for ${t}: ${e}`);return i}function _a(e){let t=fa(e,`template/package.json`),n=[],r=new Set;for(let i of la)for(let[a,o]of Object.entries(t[i]??{})){if(!pa(a)||!ha(o))continue;if(r.has(a))throw Error(`Target template declares ${a} more than once.`);let t=ga(o,a),s=fa(e,t);if(s.name!==a||typeof s.version!=`string`)throw Error(`${Ur(e)}:${t} must declare ${a} with a version.`);n.push({group:i,name:a,spec:`^${s.version}`}),r.add(a)}return n}function va(e,t){for(let n of la){let r=e[n]?.[t];if(r)return{group:n,spec:r}}}function ya(e,t,n){let r=t.match(/\n([\t ]+)"/u)?.[1]??` `,i=t.endsWith(`
|
|
9
11
|
`)?`
|
|
10
|
-
`:``;qe(e,`${JSON.stringify(n,null,r)}${i}`)}function
|
|
11
|
-
`),`Pending Worker secret updates`),d.provisioned&&H.log.info(`Provisioning Coreframe-managed access-token signing material.`),await Ia(n);let C=a.database?.dialect??`postgres`,T;switch(C){case`postgres`:T=await v({env:t});break;case`sqlite`:T=await y({env:t});break;default:throw Error(`Unsupported database dialect "${C}".`)}let E=await ka(T),ee=await te(E);if(ee.length>0)throw Error(`Pending deploy migrations contain unsafe SQL. Move unsafe statements to held migrations.\n${w(ee)}`);let D=await ja(n,E);try{_&&(await Dt(Ca,r,m),x=await Ot(c,m)),H.log.step(`Running pre-deploy build`),await V(`pnpm`,[`build`],{env:Ua(g),stdio:`inherit`});let e=c.enabled?await st({env:Ua(g),plan:c,releaseName:h,version:m}):void 0;H.log.step(`Running release build and uploading PostHog source maps`),b=!0,await V(`pnpm`,[`build`],{env:g,stdio:`inherit`}),D&&(H.log.step(`Running deploy-safe database migrations`),await V(`pnpm`,[`db`,`migrate`],{env:g,stdio:`inherit`})),H.log.step(`Deploying Worker and static assets to Cloudflare`);let t={...u?{DASHBOARD_PASSWORD:u}:{},...d.value?{[Xe]:d.value}:{},...l.values},i=Object.keys(t).length>0?await Ba(t):void 0,f=await nt({coreframeConfig:a,environment:n.environment,contributions:{generatedValues:{DEPLOY_ENV:n.environment,POSTHOG_RELEASE:h}}});try{await V(`pnpm`,[`exec`,`wrangler`,`deploy`,`--config`,f.path,`--env`,n.environment,`--strict`,`--keep-vars`,`--tag`,h,`--message`,`Deploy ${h}`,...i?[`--secrets-file`,i.path]:[]],{env:g,stdio:`inherit`}),await Ze(l),await Et({environment:n.environment})}finally{await f.dispose(),await i?.dispose()}let p={environment:n.environment,releaseName:h,url:s,version:m};o.afterWorkerDeploy&&(H.log.step(`Running required after-Worker deploy hook`),await bt(o,p)),n.skipPostDeployChecks||(H.log.step(`Running post-deploy checks`),await xt(o,p)),e&&(H.log.step(`Uploading Tauri release artifacts to Backblaze B2`),await Ct(c,e)),H.outro(`Deployed ${h} to ${n.environment}`)}catch(e){throw!b&&_&&(await K(Ca,i),await vt(x)),e}}function Ta(e){return{environment:Ea(e[0]),runMigrations:e.includes(`--run-migrations`),skipMigrations:e.includes(`--skip-migrations`),skipPostDeployChecks:e.includes(`--skip-post-deploy-checks`),tauriLocalPlatforms:Da(e,`--tauri-local-platform`).map(e=>at(e)),tauriWorkflowName:Oa(e,`--tauri-workflow-name`),tauriWorkflowPlatforms:Da(e,`--tauri-workflow-platform`).map(e=>at(e)),tauriWorkflowRef:Oa(e,`--tauri-workflow-ref`),yes:e.includes(`--yes`)}}function Ea(e){if(e&&Qe.includes(e))return e;throw Error(`Deploy environment must be one of: ${Qe.join(`, `)}.`)}function Da(e,t){let n=[];for(let r=0;r<e.length;r+=1){let i=e[r];if(i===t){let i=e[r+1];if(!i||i.startsWith(`--`))throw Error(`${t} requires a value.`);n.push(...i.split(`,`).filter(Boolean)),r+=1;continue}i.startsWith(`${t}=`)&&n.push(...i.slice(t.length+1).split(`,`).filter(Boolean))}return n}function Oa(e,t){let n=Da(e,t);if(n.length>1)throw Error(`${t} can only be provided once.`);return n[0]}async function ka(e){try{return await Aa(e)}finally{await e.close?.()}}async function Aa(e){return x(await _(),await ee(e))}async function ja(e,t){if(t.length===0)return H.log.info(`No pending deploy migrations.`),!1;if(H.note(C(t),`Pending deploy migrations`),e.runMigrations)return!0;if(e.skipMigrations)return!1;if(!process.stdout.isTTY)throw Error(`Pending migrations require --run-migrations or --skip-migrations in noninteractive deploys.`);let n=await H.confirm({initialValue:!0,message:`Run these deploy-safe database migrations before Cloudflare deploy?`});if(H.isCancel(n))throw H.cancel(`Deploy cancelled.`),Error(`Deploy cancelled.`);return n}async function Ma(){let{stdout:e}=await V(`git`,[`status`,`--porcelain`],{stdin:`ignore`});if(e.trim().length>0)throw Error(`Deploy requires a clean git tree.`);let{stdout:t}=await V(`git`,[`rev-parse`,`HEAD`],{stdin:`ignore`});return t.trim()}function Na(e){if(e.runMigrations&&e.skipMigrations)throw Error(`Use only one of --run-migrations or --skip-migrations.`)}async function Pa(e,t,n=et){return e.url?Fa(e.url,t):t===`staging`&&e.stagingHostname?Fa(await n(),t):Fa(void 0,t)}function Fa(e,t){if(!e)throw Error(`Missing ${t} deploy URL. Set DEPLOY_URL or deploy.environments.${t}.url in coreframe.config.ts.`);let n;try{n=new URL(e)}catch{throw Error(`Invalid ${t} deploy URL "${e}". Expected an HTTP(S) URL.`)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw Error(`Invalid ${t} deploy URL "${e}". Expected an HTTP(S) URL.`);return n.toString()}async function Ia(e){if(e.environment!==`production`||e.yes)return;if(!process.stdout.isTTY)throw Error(`Production deploys require --yes in noninteractive environments.`);let t=await H.confirm({initialValue:!1,message:`Deploy to production?`});if(H.isCancel(t)||!t)throw H.cancel(`Deploy cancelled.`),Error(`Deploy cancelled.`)}function La(e,t){if(e===`staging`&&t)throw Error(`Tauri releases can only be published from production deploys.`)}function Ra(e,t){let n=t.filter(t=>!e[t]);if(n.length>0)throw Error(`Missing required deploy environment variables: ${n.join(`, `)}`);return Object.fromEntries(t.map(t=>[t,e[t]]))}async function za(e,t){let n=e.DASHBOARD_PASSWORD?.trim();if(n)return n;let r;try{r=Rt(await W(`.env`,`utf8`))}catch(e){throw Va(e)&&e.code===`ENOENT`?Error(`Missing ${t} dashboard password. Set DASHBOARD_PASSWORD in ".env".`):e}let i=r.DASHBOARD_PASSWORD?.trim();if(!i)throw Error(`Missing ${t} dashboard password. Set DASHBOARD_PASSWORD in ".env".`);return i}async function Ba(e){let t=await Ce(R(je(),`coreframe-deploy-secrets-`)),n=R(t,`secrets.json`);return await K(n,JSON.stringify(e),{mode:384}),{path:n,dispose:()=>G(t,{force:!0,recursive:!0})}}function Va(e){return e instanceof Error&&`code`in e}function Ha(e,t,n,r,i){return{...e,CLOUDFLARE_ENV:t,DEPLOY_ENV:t,POSTHOG_RELEASE:n,POSTHOG_RELEASE_NAME:e.POSTHOG_RELEASE_NAME??r,POSTHOG_RELEASE_VERSION:e.POSTHOG_RELEASE_VERSION??i}}function Ua(e){let{POSTHOG_API_KEY:t,POSTHOG_PROJECT_ID:n,...r}=e;return r}const Wa={access:ve,chmod:ye,mkdir:U,mkdtemp:Ce,readFile:W,readFileSync:X,rm:G,writeFile:K},Ga={getAvailablePort:qa},Ka={homedir:ke,kill:q.kill,networkInterfaces:Ae,tmpdir:je};async function qa(){let e=qt();try{await new Promise((t,n)=>{e.once(`error`,n),e.listen(0,`127.0.0.1`,t)});let t=e.address();if(!t||typeof t==`string`)throw Error(`Could not allocate an available TCP port.`);return t.port}finally{e.listening&&await new Promise((t,n)=>{e.close(e=>e?n(e):t())})}}async function Ja(){let e=await Xa();return typeof e.mobileDevHost==`string`?{mobileDevHost:e.mobileDevHost}:{}}async function Ya(e){let t=await Xa(),n=Za();await Wa.mkdir(I.dirname(n),{recursive:!0}),await Wa.writeFile(n,`${JSON.stringify({...t,...e},void 0,2)}\n`)}async function Xa(){try{let e=await Wa.readFile(Za(),`utf8`),t=JSON.parse(e);return Qa(t)?t:{}}catch{return{}}}function Za(){return I.join(Ka.homedir(),`.coreframe`,`preferences.json`)}function Qa(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function $a({env:e=q.env,interactive:t=q.stdin.isTTY===!0,platform:n,target:r}){let i=await oo(n,e).catch(()=>[]),a=r?To(i,r):void 0;if(a)return a;if(!r&&i.length>0)return ao(i,n,t);let o=r?To(await co(e).catch(()=>[]),r):void 0;if(o&&o.platform===n)return lo(o,n,e,t);let s=await so(n,e),c=r?To(s,r):void 0;if(c)return c;if(!r&&s.length>0)return ao(s,n,t);let l=n===`ios`?`iOS`:`Android`;throw Error(r?`Could not find a ${l} device matching "${r}".`:`No connected ${l} devices or available ${l} ${n===`ios`?`simulators`:`emulators`} were detected.`)}async function eo(e){let{device:t,host:n,interactive:r=q.stdin.isTTY===!0}=e;if(!t.physical&&n===void 0)return;if(typeof n==`string`&&n!==`0.0.0.0`&&n!==`::`)return n;let i=Do();if(i.length===0)throw Error(`No external IP address was detected. Pass one explicitly with --host.`);let a=await ro();if(a&&i.includes(a))return a;if(i.length===1)return await io(i[0]),i[0];if(!r)throw Error(`Multiple external IP addresses were detected (${i.join(`, `)}). Pass one explicitly with --host.`);let o=await H.select({message:`Which IP address should the mobile device use to reach the development server?`,options:i.map(e=>({label:e,value:e}))});if(H.isCancel(o))throw Error(`Mobile development IP selection was cancelled.`);return await io(o),o}async function to({device:e,env:t=q.env,host:n,interactive:r,platform:i,port:a}){if(i===`android`&&e.physical&&n===void 0)try{return await vo(e.id,a,t)}catch{H.log.warn(`Could not establish Android ADB port forwarding. Using the LAN development address instead.`)}return{close:async()=>void 0,serverUrl:no(i,await eo({device:e,host:n,interactive:r,platform:i}),a),viteHost:!0}}function no(e,t,n){let r=t??(e===`android`?`10.0.2.2`:`127.0.0.1`);return`http://${r.includes(`:`)&&!r.startsWith(`[`)?`[${r}]`:r}:${n}`}async function ro(){return(await Ja()).mobileDevHost}async function io(e){try{await Ya({mobileDevHost:e})}catch(e){H.log.warn(`Could not remember the mobile development IP address: ${e instanceof Error?e.message:String(e)}`)}}async function ao(e,t,n){if(e.length===1)return e[0];if(!n)throw Error(`Multiple ${t===`ios`?`iOS`:`Android`} devices were detected. Pass a device name explicitly.`);let r=await H.select({message:`Which ${t===`ios`?`iOS`:`Android`} device should Coreframe use?`,options:e.map(e=>({label:e.label,value:e,hint:e.id}))});if(H.isCancel(r))throw Error(`Mobile development device selection was cancelled.`);return r}async function oo(e,t){return e===`android`?fo(t):mo(t)}async function so(e,t){return e===`android`?po(t):ho(t)}async function co(e){let{stdout:t}=await V(`flutter`,[`emulators`],{env:e});return t.split(/\r?\n/).flatMap(e=>{let[t,n,,r]=e.split(/\s*•\s*/).map(e=>e.trim());return t&&n&&(r===`android`||r===`ios`)?[{id:t,label:n,name:n,physical:!1,platform:r}]:[]})}async function lo(e,t,n,r){let i=await uo(t,n).catch(()=>[]),{stdout:a}=await V(`flutter`,[`emulators`,`--launch`,e.id],{env:n});if(/No emulator found|More than one emulator matches/i.test(a))throw Error(a.trim());let o=Date.now()+3e4;do{let a=await uo(t,n).catch(()=>[]),o=To(a,e.id);if(o)return o;let s=a.filter(e=>!i.some(t=>t.id===e.id));if(s.length>0)return ao(s,t,r);if(a.length===1)return a[0];await Jt(250)}while(Date.now()<o);let s=t===`ios`?`iOS simulator`:`Android emulator`;throw Error(`Flutter launched "${e.id}", but no ${s} became available.`)}async function uo(e,t){return e===`ios`?ho(t,`booted`):(await fo(t)).filter(e=>!e.physical)}async function fo(e){let t=await _o(e,`platform-tools`,q.platform===`win32`?`adb.exe`:`adb`),{stdout:n}=await V(t,[`devices`],{env:e}),r=n.split(/\r?\n/).map(e=>e.match(/^(\S+)\s+device(?:\s|$)/)?.[1]).filter(e=>e!==void 0);return(await Promise.all(r.map(async n=>{let r=await bo(t,e,n,`ro.product.model`),i=n.startsWith(`emulator-`),a=i?await So(t,e,n,r):await Co(t,e,n,r);return{id:n,label:a===r?a:`${a} (${r})`,name:a,physical:!i}}))).sort(Oo)}async function po(e){let{stdout:t}=await V(await _o(e,`emulator`,q.platform===`win32`?`emulator.exe`:`emulator`),[`-list-avds`],{env:e});return t.split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0&&!/^(INFO|WARNING|ERROR)\s+\|/.test(e)).map(e=>({id:e,label:e,name:e,physical:!1}))}async function mo(e){let t=await Wa.mkdtemp(I.join(Ka.tmpdir(),`coreframe-ios-devices-`)),n=I.join(t,`devices.json`);try{return await Wa.writeFile(n,``),await V(`xcrun`,[`devicectl`,`list`,`devices`,`--json-output`,n],{env:e}),(JSON.parse(await Wa.readFile(n,`utf8`)).result?.devices??[]).filter(go).map(e=>({id:e.hardwareProperties.udid,label:`${e.deviceProperties.name} (${e.hardwareProperties.productType})`,name:e.deviceProperties.name,physical:!0})).sort(Oo)}finally{await Wa.rm(t,{force:!0,recursive:!0})}}async function ho(e,t=`available`){let{stdout:n}=await V(`xcrun`,[`simctl`,`list`,`--json`,`devices`,t],{env:e}),r=JSON.parse(n);return Object.entries(r.devices??{}).filter(([e])=>e.includes(`iOS-`)).flatMap(([,e])=>e).flatMap(e=>e.name&&e.udid?[{id:e.udid,label:e.name,name:e.name,physical:!1}]:[]).sort(Oo)}function go(e){return e.connectionProperties?.tunnelState!==`unavailable`&&typeof e.hardwareProperties?.platform==`string`&&(e.hardwareProperties.platform.includes(`iOS`)||e.hardwareProperties.platform.includes(`xrOS`))&&typeof e.deviceProperties?.name==`string`&&typeof e.hardwareProperties.productType==`string`&&typeof e.hardwareProperties.udid==`string`}async function _o(e,t,n){let r=e.ANDROID_HOME??e.ANDROID_SDK_ROOT,i=r?[r]:yo(e);for(let e of i){let r=I.join(e,t,n);try{return await Wa.access(r),r}catch{}}return n}async function vo(e,t,n){let r=await _o(n,`platform-tools`,q.platform===`win32`?`adb.exe`:`adb`),{stdout:i}=await V(r,[`-s`,e,`reverse`,`tcp:0`,`tcp:${t}`],{env:n,timeout:3e3}),a=Number(i.trim());if(!Number.isInteger(a)||a<1||a>65535)throw Error(`ADB did not return a valid reverse TCP port.`);let o=`tcp:${a}`,s=!1;return{async close(){s||(s=!0,await V(r,[`-s`,e,`reverse`,`--remove`,o],{env:n,timeout:3e3}).catch(()=>void 0))},serverUrl:`http://127.0.0.1:${a}`,viteHost:`127.0.0.1`}}function yo(e){return q.platform===`darwin`?[I.join(Ka.homedir(),`Library`,`Android`,`sdk`)]:q.platform===`win32`&&e.LOCALAPPDATA?[I.join(e.LOCALAPPDATA,`Android`,`Sdk`)]:[I.join(Ka.homedir(),`Android`,`Sdk`)]}async function bo(e,t,n,r){return(await xo(e,t,[`-s`,n,`shell`,`getprop`,r])).trim()}async function xo(e,t,n){return(await V(e,n,{env:t,timeout:3e3})).stdout}async function So(e,t,n,r){return xo(e,t,[`-s`,n,`emu`,`avd`,`name`]).then(e=>e.split(/\r?\n/)[0]?.trim()||r).catch(()=>r)}async function Co(e,t,n,r){return xo(e,t,[`-s`,n,`shell`,`dumpsys`,`bluetooth_manager`]).then(e=>wo(e)||r).catch(()=>r)}function wo(e){return e.match(/\bname: (.+)/)?.[1]?.trim()}function To(e,t){let n=e.map(e=>({device:e,score:Math.max(Eo(t,e.name),Eo(t,e.id))})).sort((e,t)=>t.score-e.score)[0];return n&&n.score>0?n.device:void 0}function Eo(e,t){let n=e.toLowerCase(),r=t.toLowerCase();if(r===n)return 1e4;let i=r.indexOf(n);if(i>=0)return 5e3-i;let a=0,o=0;for(let e of n){let t=r.indexOf(e,o);if(t<0)return 0;a+=t===o?2:1,o=t+1}return a}function Do(){return[...new Set(Object.values(Ka.networkInterfaces()).flatMap(e=>e??[]).filter(e=>!e.internal&&e.family===`IPv4`).map(e=>e.address))].sort()}function Oo(e,t){return e.label.localeCompare(t.label)}async function ko(e,t){if(!e)return()=>void 0;await U(I.dirname(e),{recursive:!0}),await K(e,``,{flag:`a`});let n=await W(e,`utf8`).catch(()=>void 0),r=0,i=!1,a=Ke(e,{persistent:!1},()=>{if(i)return;let a=++r;W(e,`utf8`).then(e=>{i||a!==r||e===n||(n=e,t())},()=>void 0)});return()=>{i=!0,a.close()}}const Ao=`COREFRAME_FLUTTER_DEVELOPMENT`,jo=[`filtered`,`full`];function Mo({enabled:e,env:t=q.env,input:n=q.stdin,onInterrupt:r,onQuit:i,onRestart:a,output:o=q.stdout}){if(!e)return()=>void 0;let s=n.readableFlowing,c=n.isRaw,l=e=>{for(let t of e.toString())t===``?r():t===`R`?a():t===`q`?i():t===`h`?o.write(`
|
|
12
|
+
`:``;qe(e,`${JSON.stringify(n,null,r)}${i}`)}function ba(e,t){if(t.length!==0){console.log(`${e}:`);for(let e of t)console.log(` ${e}`);console.log(``)}}function xa(e){let t=R(ua([`rev-parse`,`--show-toplevel`]).trim(),`package.json`),n=J(t,`utf8`),r=da(n,t),i=Ur(e.target),a=_a(i),o=new Set(a.map(({name:e})=>e)),s=[],c=[],l=[],u=0;for(let e of a){let t=va(r,e.name);if(!t){c.push(`missing: ${e.name} ${e.spec} (${e.group})`);continue}if(ma(t.spec)){l.push(`linked: ${e.name} ${t.spec}`);continue}if(t.spec===e.spec){u+=1;continue}s.push({...e,currentGroup:t.group,currentSpec:t.spec})}let d=la.flatMap(e=>Object.entries(r[e]??{}).filter(([e])=>pa(e)&&!o.has(e)).map(([t,n])=>`review: ${t} ${n} (${e})`));if(e.apply&&s.length>0){for(let e of s)r[e.currentGroup][e.name]=e.spec;ya(t,n,r)}console.log(`Coreframe package sync: ${i}`),console.log(``),ba(e.apply?`Updated Coreframe packages`:`Would update Coreframe packages`,s.map(({currentSpec:e,name:t,spec:n})=>`update: ${t} ${e} -> ${n}`)),ba(`Missing target Coreframe packages`,c),ba(`Locally linked Coreframe packages`,l),ba(`Downstream-only Coreframe packages`,d),u>0&&console.log(`${u} Coreframe package(s) already match the target versions.`),s.length===0?console.log(`No Coreframe package version updates found.`):e.apply||(console.log(``),console.log(`Run with --apply to write the ${s.length} package update(s).`))}const Sa={...u,displayName:`recipe`,description:`Coreframe recipe name, such as yam-db.`,async from(e){return jr(e)}},Ca=d({name:`upgrade`,cmds:{"ensure-template-remote":t({name:`ensure-template-remote`,args:{remote:o({long:`remote`,type:u,defaultValue:()=>`template`,description:`Remote name to ensure.`}),noFetch:r({long:`no-fetch`,description:`Do not fetch the remote after ensuring it exists.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t})=>Vr({fetch:!e,remote:t})}),"check-skill-current":t({name:`check-skill-current`,args:{target:o({long:`target`,type:u,description:`Target Coreframe template git ref.`}),apply:r({long:`apply`,description:`Replace the local upgrade skill with the target version when it differs.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>{process.exitCode=Ri({apply:e,target:t})}}),"fast-forward-template-files":t({name:`fast-forward-template-files`,args:{target:o({long:`target`,type:u,description:`Target Coreframe template git ref.`}),base:o({long:`base`,type:s(u),description:`Previous Coreframe template git ref. Defaults to package.json engines.coreframe.`}),apply:r({long:`apply`,description:`Write clean fast-forwards to the worktree.`,defaultValue:()=>!1})},handler:({apply:e,base:t,target:n})=>ca({apply:e,base:t,target:n})}),"sync-coreframe-packages":t({name:`sync-coreframe-packages`,args:{target:o({long:`target`,type:u,description:`Target Coreframe template git ref.`}),apply:r({long:`apply`,description:`Update existing published Coreframe dependency specifications.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>xa({apply:e,target:t})})}}),wa=d({name:`recipes`,cmds:{apply:t({name:`apply`,args:{recipe:c({type:Sa,displayName:`recipe`,description:`Recipe to prepare and apply.`}),target:o({long:`target`,type:s(u),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:o({long:`remote`,type:u,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:r({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,recipe:t,remote:n,target:r})=>fi(di({fetch:!e,name:t,remote:n,target:r}))}),list:t({name:`list`,args:{target:o({long:`target`,type:s(u),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:o({long:`remote`,type:u,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:r({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t,target:n})=>ji(Ai({fetch:!e,remote:t,target:n}))}),verify:t({name:`verify`,args:{recipe:c({type:Sa,displayName:`recipe`,description:`Recipe adoption to verify.`}),target:o({long:`target`,type:s(u),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:o({long:`remote`,type:u,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:r({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,recipe:t,remote:n,target:r})=>ci(si({fetch:!e,name:t,remote:n,target:r}))})}}),Ta=d({name:`db`,cmds:{ensure:t({name:`ensure`,args:{},handler:v}),generate:t({name:`generate`,args:{args:l({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit generate.`})},handler:({args:e})=>D(`generate`,e)}),migrate:t({name:`migrate`,args:{args:l({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit migrate.`})},handler:({args:e})=>D(`migrate`,e)}),"migrate-held":t({name:`migrate-held`,args:{local:r({long:`local`,description:`Run held migrations against the Coreframe-managed local PostgreSQL database.`,defaultValue:()=>!1})},handler:({local:e})=>C({target:e?`local`:`deployment`})}),"migrate-local":t({name:`migrate-local`,args:{},handler:w}),"migrations-check":t({name:`migrations-check`,args:{},handler:p}),reset:t({name:`reset`,args:{},handler:E}),seed:t({name:`seed`,args:{},handler:()=>te()}),"schema-check":t({name:`schema-check`,args:{seed:r({long:`seed`,description:`Run the configured project seed against the throwaway database.`,defaultValue:()=>!1})},handler:({seed:e})=>m({seed:e})}),setup:t({name:`setup`,args:{},handler:()=>ne()}),studio:t({name:`studio`,args:{args:l({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit studio.`})},handler:({args:e})=>D(`studio`,e)})}}),Ea=`package.json`;async function Da(e=process.argv.slice(2),t=process.env){let n=Oa(e);Pa(n);let{packageJson:r,source:i}=await pt(Ea),a=await Fe(),o=_t(a.deploy??{},n.environment,t);Ra(t,[`POSTHOG_API_KEY`,`POSTHOG_PROJECT_ID`]);let s=await Fa(o,n.environment,()=>it({env:t})),c=await mt({environment:n.environment}),l=c.values.DASHBOARD_PASSWORD??await za(t,n.environment);St(await at({environment:n.environment}),n.environment,{availableNames:[...Object.keys(c.values),...l?[`DASHBOARD_PASSWORD`]:[]]});let u=await lt({environment:n.environment}),d=await Na();await Hn({env:t,revision:d});let f=d.slice(0,12),p=vt(n.environment,r.version,f),m=gt(r.name,p),h={...Ha(t,n.environment,m,r.name,p),COREFRAME_I18N_RELEASE_REVISION:d},v=n.environment===`production`,y=!1;V.intro(`Deploy ${m} to ${n.environment}`);let b=Object.keys(c.values).sort();b.length>0&&V.note(b.join(`
|
|
13
|
+
`),`Pending Worker secret updates`),u.provisioned&&V.log.info(`Provisioning Coreframe-managed access-token signing material.`),await La(n);let x=a.database?.dialect??`postgres`,C;switch(x){case`postgres`:C=await g({env:t});break;case`sqlite`:C=await _({env:t});break;default:throw Error(`Unsupported database dialect "${x}".`)}let w=await Aa(C),T=await ee(w);if(T.length>0)throw Error(`Pending deploy migrations contain unsafe SQL. Move unsafe statements to held migrations.\n${S(T)}`);let E=await Ma(n,w);try{v&&await wt(Ea,r,p),V.log.step(`Running pre-deploy build`),await B(`pnpm`,[`build`],{env:Ua(h),stdio:`inherit`}),V.log.step(`Running release build and uploading PostHog source maps`),y=!0,await B(`pnpm`,[`build`],{env:h,stdio:`inherit`}),E&&(V.log.step(`Running deploy-safe database migrations`),await B(`pnpm`,[`db`,`migrate`],{env:h,stdio:`inherit`})),V.log.step(`Deploying Worker and static assets to Cloudflare`);let e={...l?{DASHBOARD_PASSWORD:l}:{},...u.value?{[et]:u.value}:{},...c.values},t=Object.keys(e).length>0?await Ba(e):void 0,i=await ot({coreframeConfig:a,environment:n.environment,contributions:{generatedValues:{DEPLOY_ENV:n.environment,POSTHOG_RELEASE:m}}});try{await B(`pnpm`,[`exec`,`wrangler`,`deploy`,`--config`,i.path,`--env`,n.environment,`--strict`,`--keep-vars`,`--tag`,m,`--message`,`Deploy ${m}`,...t?[`--secrets-file`,t.path]:[]],{env:h,stdio:`inherit`}),await tt(c),await Ct({environment:n.environment})}finally{await i.dispose(),await t?.dispose()}let d={environment:n.environment,releaseName:m,url:s,version:p};o.afterWorkerDeploy&&(V.log.step(`Running required after-Worker deploy hook`),await bt(o,d)),n.skipPostDeployChecks||(V.log.step(`Running post-deploy checks`),await xt(o,d)),V.outro(`Deployed ${m} to ${n.environment}`)}catch(e){throw!y&&v&&await G(Ea,i),e}}function Oa(e){return{environment:ka(e[0]),runMigrations:e.includes(`--run-migrations`),skipMigrations:e.includes(`--skip-migrations`),skipPostDeployChecks:e.includes(`--skip-post-deploy-checks`),yes:e.includes(`--yes`)}}function ka(e){if(e&&nt.includes(e))return e;throw Error(`Deploy environment must be one of: ${nt.join(`, `)}.`)}async function Aa(e){try{return await ja(e)}finally{await e.close?.()}}async function ja(e){return y(await h(),await T(e))}async function Ma(e,t){if(t.length===0)return V.log.info(`No pending deploy migrations.`),!1;if(V.note(x(t),`Pending deploy migrations`),e.runMigrations)return!0;if(e.skipMigrations)return!1;if(!process.stdout.isTTY)throw Error(`Pending migrations require --run-migrations or --skip-migrations in noninteractive deploys.`);let n=await V.confirm({initialValue:!0,message:`Run these deploy-safe database migrations before Cloudflare deploy?`});if(V.isCancel(n))throw V.cancel(`Deploy cancelled.`),Error(`Deploy cancelled.`);return n}async function Na(){let{stdout:e}=await B(`git`,[`status`,`--porcelain`],{stdin:`ignore`});if(e.trim().length>0)throw Error(`Deploy requires a clean git tree.`);let{stdout:t}=await B(`git`,[`rev-parse`,`HEAD`],{stdin:`ignore`});return t.trim()}function Pa(e){if(e.runMigrations&&e.skipMigrations)throw Error(`Use only one of --run-migrations or --skip-migrations.`)}async function Fa(e,t,n=it){return e.url?Ia(e.url,t):t===`staging`&&e.stagingHostname?Ia(await n(),t):Ia(void 0,t)}function Ia(e,t){if(!e)throw Error(`Missing ${t} deploy URL. Set DEPLOY_URL or deploy.environments.${t}.url in coreframe.config.ts.`);let n;try{n=new URL(e)}catch{throw Error(`Invalid ${t} deploy URL "${e}". Expected an HTTP(S) URL.`)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw Error(`Invalid ${t} deploy URL "${e}". Expected an HTTP(S) URL.`);return n.toString()}async function La(e){if(e.environment!==`production`||e.yes)return;if(!process.stdout.isTTY)throw Error(`Production deploys require --yes in noninteractive environments.`);let t=await V.confirm({initialValue:!1,message:`Deploy to production?`});if(V.isCancel(t)||!t)throw V.cancel(`Deploy cancelled.`),Error(`Deploy cancelled.`)}function Ra(e,t){let n=t.filter(t=>!e[t]);if(n.length>0)throw Error(`Missing required deploy environment variables: ${n.join(`, `)}`);return Object.fromEntries(t.map(t=>[t,e[t]]))}async function za(e,t){let n=e.DASHBOARD_PASSWORD?.trim();if(n)return n;let r;try{r=Pt(await U(`.env`,`utf8`))}catch(e){throw Va(e)&&e.code===`ENOENT`?Error(`Missing ${t} dashboard password. Set DASHBOARD_PASSWORD in ".env".`):e}let i=r.DASHBOARD_PASSWORD?.trim();if(!i)throw Error(`Missing ${t} dashboard password. Set DASHBOARD_PASSWORD in ".env".`);return i}async function Ba(e){let t=await Ce(I(je(),`coreframe-deploy-secrets-`)),n=I(t,`secrets.json`);return await G(n,JSON.stringify(e),{mode:384}),{path:n,dispose:()=>W(t,{force:!0,recursive:!0})}}function Va(e){return e instanceof Error&&`code`in e}function Ha(e,t,n,r,i){return{...e,CLOUDFLARE_ENV:t,DEPLOY_ENV:t,POSTHOG_RELEASE:n,POSTHOG_RELEASE_NAME:e.POSTHOG_RELEASE_NAME??r,POSTHOG_RELEASE_VERSION:e.POSTHOG_RELEASE_VERSION??i}}function Ua(e){let{POSTHOG_API_KEY:t,POSTHOG_PROJECT_ID:n,...r}=e;return r}async function Wa(){let e=await Ka();return typeof e.mobileDevHost==`string`?{mobileDevHost:e.mobileDevHost}:{}}async function Ga(e){let t=await Ka(),n=qa();await $.mkdir(P.dirname(n),{recursive:!0}),await $.writeFile(n,`${JSON.stringify({...t,...e},void 0,2)}\n`)}async function Ka(){try{let e=await $.readFile(qa(),`utf8`),t=JSON.parse(e);return Ja(t)?t:{}}catch{return{}}}function qa(){return P.join(_r.homedir(),`.coreframe`,`preferences.json`)}function Ja(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function Ya({env:e=q.env,interactive:t=q.stdin.isTTY===!0,platform:n,target:r}){let i=await no(n,e).catch(()=>[]),a=r?xo(i,r):void 0;if(a)return a;if(!r&&i.length>0)return to(i,n,t);let o=r?xo(await io(e).catch(()=>[]),r):void 0;if(o&&o.platform===n)return ao(o,n,e,t);let s=await ro(n,e),c=r?xo(s,r):void 0;if(c)return c;if(!r&&s.length>0)return to(s,n,t);let l=n===`ios`?`iOS`:`Android`;throw Error(r?`Could not find a ${l} device matching "${r}".`:`No connected ${l} devices or available ${l} ${n===`ios`?`simulators`:`emulators`} were detected.`)}async function Xa(e){let{device:t,host:n,interactive:r=q.stdin.isTTY===!0}=e;if(!t.physical&&n===void 0)return;if(typeof n==`string`&&n!==`0.0.0.0`&&n!==`::`)return n;let i=Co();if(i.length===0)throw Error(`No external IP address was detected. Pass one explicitly with --host.`);let a=await $a();if(a&&i.includes(a))return a;if(i.length===1)return await eo(i[0]),i[0];if(!r)throw Error(`Multiple external IP addresses were detected (${i.join(`, `)}). Pass one explicitly with --host.`);let o=await V.select({message:`Which IP address should the mobile device use to reach the development server?`,options:i.map(e=>({label:e,value:e}))});if(V.isCancel(o))throw Error(`Mobile development IP selection was cancelled.`);return await eo(o),o}async function Za({device:e,env:t=q.env,host:n,interactive:r,platform:i,port:a}){if(i===`android`&&e.physical&&n===void 0)try{return await mo(e.id,a,t)}catch{V.log.warn(`Could not establish Android ADB port forwarding. Using the LAN development address instead.`)}return{close:async()=>void 0,serverUrl:Qa(i,await Xa({device:e,host:n,interactive:r,platform:i}),a),viteHost:!0}}function Qa(e,t,n){let r=t??(e===`android`?`10.0.2.2`:`127.0.0.1`);return`http://${r.includes(`:`)&&!r.startsWith(`[`)?`[${r}]`:r}:${n}`}async function $a(){return(await Wa()).mobileDevHost}async function eo(e){try{await Ga({mobileDevHost:e})}catch(e){V.log.warn(`Could not remember the mobile development IP address: ${e instanceof Error?e.message:String(e)}`)}}async function to(e,t,n){if(e.length===1)return e[0];if(!n)throw Error(`Multiple ${t===`ios`?`iOS`:`Android`} devices were detected. Pass a device name explicitly.`);let r=await V.select({message:`Which ${t===`ios`?`iOS`:`Android`} device should Coreframe use?`,options:e.map(e=>({label:e.label,value:e,hint:e.id}))});if(V.isCancel(r))throw Error(`Mobile development device selection was cancelled.`);return r}async function no(e,t){return e===`android`?so(t):lo(t)}async function ro(e,t){return e===`android`?co(t):uo(t)}async function io(e){let{stdout:t}=await B(`flutter`,[`emulators`],{env:e});return t.split(/\r?\n/).flatMap(e=>{let[t,n,,r]=e.split(/\s*•\s*/).map(e=>e.trim());return t&&n&&(r===`android`||r===`ios`)?[{id:t,label:n,name:n,physical:!1,platform:r}]:[]})}async function ao(e,t,n,r){let i=await oo(t,n).catch(()=>[]),{stdout:a}=await B(`flutter`,[`emulators`,`--launch`,e.id],{env:n});if(/No emulator found|More than one emulator matches/i.test(a))throw Error(a.trim());let o=Date.now()+3e4;do{let a=await oo(t,n).catch(()=>[]),o=xo(a,e.id);if(o)return o;let s=a.filter(e=>!i.some(t=>t.id===e.id));if(s.length>0)return to(s,t,r);if(a.length===1)return a[0];await zt(250)}while(Date.now()<o);let s=t===`ios`?`iOS simulator`:`Android emulator`;throw Error(`Flutter launched "${e.id}", but no ${s} became available.`)}async function oo(e,t){return e===`ios`?uo(t,`booted`):(await so(t)).filter(e=>!e.physical)}async function so(e){let t=await po(e,`platform-tools`,q.platform===`win32`?`adb.exe`:`adb`),{stdout:n}=await B(t,[`devices`],{env:e}),r=n.split(/\r?\n/).map(e=>e.match(/^(\S+)\s+device(?:\s|$)/)?.[1]).filter(e=>e!==void 0);return(await Promise.all(r.map(async n=>{let r=await go(t,e,n,`ro.product.model`),i=n.startsWith(`emulator-`),a=i?await vo(t,e,n,r):await yo(t,e,n,r);return{id:n,label:a===r?a:`${a} (${r})`,name:a,physical:!i}}))).sort(wo)}async function co(e){let{stdout:t}=await B(await po(e,`emulator`,q.platform===`win32`?`emulator.exe`:`emulator`),[`-list-avds`],{env:e});return t.split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0&&!/^(INFO|WARNING|ERROR)\s+\|/.test(e)).map(e=>({id:e,label:e,name:e,physical:!1}))}async function lo(e){let t=await $.mkdtemp(P.join(_r.tmpdir(),`coreframe-ios-devices-`)),n=P.join(t,`devices.json`);try{return await $.writeFile(n,``),await B(`xcrun`,[`devicectl`,`list`,`devices`,`--json-output`,n],{env:e}),(JSON.parse(await $.readFile(n,`utf8`)).result?.devices??[]).filter(fo).map(e=>({id:e.hardwareProperties.udid,label:`${e.deviceProperties.name} (${e.hardwareProperties.productType})`,name:e.deviceProperties.name,physical:!0})).sort(wo)}finally{await $.rm(t,{force:!0,recursive:!0})}}async function uo(e,t=`available`){let{stdout:n}=await B(`xcrun`,[`simctl`,`list`,`--json`,`devices`,t],{env:e}),r=JSON.parse(n);return Object.entries(r.devices??{}).filter(([e])=>e.includes(`iOS-`)).flatMap(([,e])=>e).flatMap(e=>e.name&&e.udid?[{id:e.udid,label:e.name,name:e.name,physical:!1}]:[]).sort(wo)}function fo(e){return e.connectionProperties?.tunnelState!==`unavailable`&&typeof e.hardwareProperties?.platform==`string`&&(e.hardwareProperties.platform.includes(`iOS`)||e.hardwareProperties.platform.includes(`xrOS`))&&typeof e.deviceProperties?.name==`string`&&typeof e.hardwareProperties.productType==`string`&&typeof e.hardwareProperties.udid==`string`}async function po(e,t,n){let r=e.ANDROID_HOME??e.ANDROID_SDK_ROOT,i=r?[r]:ho(e);for(let e of i){let r=P.join(e,t,n);try{return await $.access(r),r}catch{}}return n}async function mo(e,t,n){let r=await po(n,`platform-tools`,q.platform===`win32`?`adb.exe`:`adb`),{stdout:i}=await B(r,[`-s`,e,`reverse`,`tcp:0`,`tcp:${t}`],{env:n,timeout:3e3}),a=Number(i.trim());if(!Number.isInteger(a)||a<1||a>65535)throw Error(`ADB did not return a valid reverse TCP port.`);let o=`tcp:${a}`,s=!1;return{async close(){s||(s=!0,await B(r,[`-s`,e,`reverse`,`--remove`,o],{env:n,timeout:3e3}).catch(()=>void 0))},serverUrl:`http://127.0.0.1:${a}`,viteHost:`127.0.0.1`}}function ho(e){return q.platform===`darwin`?[P.join(_r.homedir(),`Library`,`Android`,`sdk`)]:q.platform===`win32`&&e.LOCALAPPDATA?[P.join(e.LOCALAPPDATA,`Android`,`Sdk`)]:[P.join(_r.homedir(),`Android`,`Sdk`)]}async function go(e,t,n,r){return(await _o(e,t,[`-s`,n,`shell`,`getprop`,r])).trim()}async function _o(e,t,n){return(await B(e,n,{env:t,timeout:3e3})).stdout}async function vo(e,t,n,r){return _o(e,t,[`-s`,n,`emu`,`avd`,`name`]).then(e=>e.split(/\r?\n/)[0]?.trim()||r).catch(()=>r)}async function yo(e,t,n,r){return _o(e,t,[`-s`,n,`shell`,`dumpsys`,`bluetooth_manager`]).then(e=>bo(e)||r).catch(()=>r)}function bo(e){return e.match(/\bname: (.+)/)?.[1]?.trim()}function xo(e,t){let n=e.map(e=>({device:e,score:Math.max(So(t,e.name),So(t,e.id))})).sort((e,t)=>t.score-e.score)[0];return n&&n.score>0?n.device:void 0}function So(e,t){let n=e.toLowerCase(),r=t.toLowerCase();if(r===n)return 1e4;let i=r.indexOf(n);if(i>=0)return 5e3-i;let a=0,o=0;for(let e of n){let t=r.indexOf(e,o);if(t<0)return 0;a+=t===o?2:1,o=t+1}return a}function Co(){return[...new Set(Object.values(_r.networkInterfaces()).flatMap(e=>e??[]).filter(e=>!e.internal&&e.family===`IPv4`).map(e=>e.address))].sort()}function wo(e,t){return e.label.localeCompare(t.label)}async function To(e,t){if(!e)return()=>void 0;await H(P.dirname(e),{recursive:!0}),await G(e,``,{flag:`a`});let n=await U(e,`utf8`).catch(()=>void 0),r=0,i=!1,a=Ke(e,{persistent:!1},()=>{if(i)return;let a=++r;U(e,`utf8`).then(e=>{i||a!==r||e===n||(n=e,t())},()=>void 0)});return()=>{i=!0,a.close()}}const Eo=`COREFRAME_FLUTTER_DEVELOPMENT`,Do=[`filtered`,`full`];function Oo({enabled:e,env:t=q.env,input:n=q.stdin,onInterrupt:r,onQuit:i,onRestart:a,output:o=q.stdout}){if(!e)return()=>void 0;let s=n.readableFlowing,c=n.isRaw,l=e=>{for(let t of e.toString())t===``?r():t===`R`?a():t===`q`?i():t===`h`?o.write(`
|
|
12
14
|
Coreframe Flutter commands:
|
|
13
15
|
R Restart the Flutter process.
|
|
14
16
|
h Show this help.
|
|
15
17
|
q Quit.
|
|
16
18
|
`):t===`c`&&o.write(`\x1Bc`)};return n.setRawMode?.(!0),n.resume(),n.on(`data`,l),t.CI!==`true`&&o.write(`
|
|
17
19
|
Coreframe: Press "R" to restart the Flutter process.
|
|
18
|
-
`),()=>{n.off(`data`,l),c||n.setRawMode?.(!1),s!==!0&&n.pause()}}function
|
|
19
|
-
`)?t:`${t}\n`)}async function
|
|
20
|
+
`),()=>{n.off(`data`,l),c||n.setRawMode?.(!1),s!==!0&&n.pause()}}function ko(e=!1){return e?`debug`:`profile`}function Ao({device:e,mode:t,platform:n}){if(t===`profile`&&!e.physical)throw Error(`Flutter profile mode is unavailable on ${n===`ios`?`iOS simulator`:`Android emulator`}s. Re-run with --flutter-debug or select a physical device.`)}function jo({device:e,mode:t,serverUrl:n,verbose:r}){return[`run`,`--${t}`,`-d`,e.id,`--dart-define=COREFRAME_DEV_SERVER_URL=${n}`,...r?[`--verbose`]:[]]}const Mo={command:Jo,isRunning:zo,stop(e){try{q.kill(e,`SIGTERM`)}catch(e){if(!Ho(e))throw e}},waitForExit:Bo};async function No({confirmStop:e=Io,cwd:t=q.cwd(),interactive:n=q.stdin.isTTY===!0,pid:r=q.pid,platform:i=`web`,processes:a=Mo}={}){let o=await Zo(t,i),s=o.file,c={pid:r,platform:i,repository:o.repository,token:K()},l=`${JSON.stringify(c)}\n`,u=`${s}.${c.token}.tmp`,d=await Wo({confirmStop:e,file:P.resolve(t,`.coreframe/dev.lock`),interactive:n,owner:c,processes:a});if(d===void 0)return;let f=d;await H(P.dirname(s),{recursive:!0}),await G(u,l,{flag:`wx`,mode:384});try{for(;;){try{return await Se(u,s),{owner:c,async release(){await Ro(s,l)},takeoverApproved:f}}catch(e){if(!Vo(e))throw e}let t=await Fo({confirmStop:e,file:s,interactive:n,owner:c,processes:a});if(t===void 0)return;f||=t}}finally{await Oe(u).catch(()=>void 0)}}async function Po({cwd:e=q.cwd(),platform:t=`web`}={}){let{file:n}=await Zo(e,t);return(await Lo(n))?.owner}async function Fo({confirmStop:e,file:t,interactive:n,owner:r,processes:i}){let a=await Lo(t);if(!a||!ts(a.owner,r)||!i.isRunning(a.owner.pid))return await Ro(t,a?.source),!1;if(!n)throw Error(`Coreframe dev is already running for this project (PID ${a.owner.pid}). Stop it before starting another.`);if(await e(a.owner.pid))return i.stop(a.owner.pid),await i.waitForExit(a.owner.pid),await Ro(t,a.source),!0}async function Io(e){let t=await V.confirm({initialValue:!1,message:`Coreframe dev is already running for this project (PID ${e}). Stop it and start here?`});return V.isCancel(t)||!t?(V.cancel(`Keeping the existing Coreframe dev process.`),!1):!0}async function Lo(e){try{let t=await U(e,`utf8`),n=JSON.parse(t);return!Number.isSafeInteger(n.pid)||Number(n.pid)<=0||typeof n.platform!=`string`||n.platform.length===0||typeof n.repository!=`string`||n.repository.length===0||typeof n.token!=`string`||n.token.length===0?void 0:{owner:n,source:t}}catch{return}}async function Ro(e,t){let n=await U(e,`utf8`).catch(()=>void 0);(t===void 0||n===t)&&await Oe(e).catch(()=>void 0)}function zo(e){try{return q.kill(e,0),!0}catch(e){return!Ho(e)}}async function Bo(e){let t=Date.now()+1e4;for(;zo(e);){if(Date.now()>=t)throw Error(`Coreframe dev process ${e} did not stop within 10 seconds.`);await new Promise(e=>setTimeout(e,50))}}function Vo(e){return Uo(e)&&e.code===`EEXIST`}function Ho(e){return Uo(e)&&e.code===`ESRCH`}function Uo(e){return e instanceof Error}async function Wo({confirmStop:e,file:t,interactive:n,owner:r,processes:i}){let a=await Go(t);if(!a||!i.isRunning(a.owner.pid))return await Ro(t,a?.source),!1;let o=i.command?.(a.owner.pid);if(!o||!Ko(o,r.platform))return!1;if(!n)throw Error(`Coreframe dev is already running for this project (PID ${a.owner.pid}). Stop it before starting another.`);if(await e(a.owner.pid))return i.stop(a.owner.pid),await i.waitForExit(a.owner.pid),await Ro(t,a.source),!0}async function Go(e){try{let t=await U(e,`utf8`),n=JSON.parse(t);return!Number.isSafeInteger(n.pid)||Number(n.pid)<=0||typeof n.token!=`string`||n.token.length===0?void 0:{owner:n,source:t}}catch{return}}function Ko(e,t){let n=e.trim().split(/\s+/u),r=n.findIndex(e=>{let t=e.split(/[\\/]/u).at(-1);return t===`coreframe`||t===`coreframe.js`||t===`coreframe.ts`});if(r<0)return!1;let i=n.indexOf(`dev`,r+1);return i<0?!1:qo(n.slice(i+1))===t}function qo(e){let t=new Set([`android`,`ios`,`linux`,`macos`,`web`,`windows`]),n=new Set([`--debug`,`--host`,`--port`]),r=!1;for(let i of e){if(r){r=!1;continue}if(n.has(i)){r=!0;continue}if(!i.startsWith(`-`))return t.has(i)?i:`web`}return`web`}function Jo(e){let t=q.platform===`win32`?Xo(e):Yo(e);if(t.status===0)return t.stdout.trim()||void 0}function Yo(e){return X(`ps`,[`-p`,String(e),`-o`,`command=`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]})}function Xo(e){return X(`powershell.exe`,[`-NoProfile`,`-NonInteractive`,`-Command`,`(Get-CimInstance Win32_Process -Filter 'ProcessId = ${e}').CommandLine`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]})}async function Zo(e,t){let n=await Qo(P.resolve(e)),r=n.gitCommonDir?P.join(n.path,`coreframe-dev`):P.join(n.path,`.coreframe`);return{file:P.join(r,`dev.${t}.lock`),repository:n.path}}async function Qo(e){let t=$o(e);return t?{gitCommonDir:!0,path:await es(P.resolve(e,t))}:{gitCommonDir:!1,path:await es(e)}}function $o(e){let t=X(`git`,[`rev-parse`,`--git-common-dir`],{cwd:e,encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]});if(t.status===0)return t.stdout.trim()||void 0}async function es(e){return Te(e).catch(()=>P.resolve(e))}function ts(e,t){return e.platform===t.platform&&e.repository===t.repository}function ns(e,t){let n={...e};return t===`web`||t===`webext`?n.COREFRAME_PLATFORM=`web`:n.COREFRAME_PLATFORM=t,n}const rs=q.platform===`win32`?`portless.cmd`:`portless`,is=RegExp(`\x1B\\[[0-?]*[ -/]*[@-~]`,`g`),as=/^Proxy is already running on port \d+\.$/,os=/^To restart: portless proxy stop(?: (?:-p|--port) \d+)? && portless proxy start(?: (?:-p|--port) \d+)?$/;function ss(e){let t=e.split(/(\r\n|\n)/),n=[];for(let e=0;e<t.length;){let r=t[e],i=t[e+2];if(r!==void 0&&i!==void 0&&as.test(r.replace(is,``).trim())&&os.test(i.replace(is,``).trim())){e+=t[e+3]===void 0?3:4;continue}n.push(t[e]??``),e+=1}return n.join(``)}function cs(e){let t=ss(e);t&&q.stdout.write(t.endsWith(`
|
|
21
|
+
`)?t:`${t}\n`)}async function ls({cwd:e,env:t,platform:n}){return n!==`web`||t.PORTLESS===`0`||(await Bt()).isAgent?!1:At(e)}async function us({cwd:e,env:t,lan:n=!1}){let r=P.join(`node_modules`,`.bin`,rs),i=[`proxy`,`start`,...n?[`--lan`]:[]];try{let{stdout:n}=await B(P.resolve(e,r),i,{cwd:e,env:t,stdin:`inherit`,stdout:`pipe`,stderr:`inherit`});cs(n)}catch(e){throw typeof e==`object`&&e&&`stdout`in e&&typeof e.stdout==`string`&&cs(e.stdout),e}}function ds({host:e,lan:t=!1,port:n}){return[...t?[`--lan`]:[],`run`,...n===void 0?[]:[`--app-port`,String(n)],`react-router`,`dev`,...e===void 0?[]:[`--host`,e===!0?`0.0.0.0`:e]]}async function fs({cwd:e=q.cwd(),platform:t}){let n=await ps({cwd:e});if(!n||!Ss(n.platform)||!Cs(n.platform,t)||!Ts(n.owner.pid))return;let r=await Po({cwd:e,platform:n.platform});if(!(!r||!Es(n.owner,r))&&!(n.postgres?.pid!==void 0&&!Ts(n.postgres.pid)))return n}async function ps({cwd:e=q.cwd()}={}){let t;try{t=JSON.parse(await U(gs(e),`utf8`))}catch{return}return _s(t)&&t.cwd===P.resolve(e)?t:void 0}async function ms({cwd:e=q.cwd(),owner:t,platform:n,postgres:r,vitePort:i}){let a=gs(e),o=P.dirname(a),s=`${a}.${K()}.tmp`,c={cwd:P.resolve(e),owner:t,platform:n,...r?{postgres:r}:void 0,version:1,vite:{port:i}};await H(o,{recursive:!0});try{await G(s,`${JSON.stringify(c)}\n`,{flag:`wx`,mode:384}),await Ee(s,a)}finally{await Oe(s).catch(()=>void 0)}}async function hs({cwd:e=q.cwd(),owner:t}){let n=gs(e),r=await ps({cwd:e});!r||!Es(r.owner,t)||await Oe(n).catch(()=>void 0)}function gs(e){return P.resolve(e,`.coreframe/dev.session.json`)}function _s(e){if(!e||typeof e!=`object`)return!1;let t=e;return t.version===1&&typeof t.cwd==`string`&&vs(t.owner)&&bs(t.platform)&&ws(t.vite?.port)&&(t.postgres===void 0||ys(t.postgres))}function vs(e){if(!e||typeof e!=`object`)return!1;let t=e,n=t.pid;return typeof n==`number`&&Number.isSafeInteger(n)&&n>0&&typeof t.token==`string`}function ys(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.dataDir==`string`&&(t.pid===void 0||Number.isSafeInteger(t.pid)&&t.pid>0)}function bs(e){return e===`android`||e===`ios`||e===`linux`||e===`macos`||e===`web`||e===`windows`}function xs(e){return e===`android`||e===`ios`||e===`linux`||e===`macos`||e===`windows`}function Ss(e){return e===`web`||xs(e)}function Cs(e,t){return t===void 0?xs(e):e===t}function ws(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>0&&e<=65535}function Ts(e){try{return q.kill(e,0),!0}catch(e){return e instanceof Error&&e.code===`EPERM`}}function Es(e,t){return e.pid===t.pid&&e.token===t.token}const Ds=q.platform===`win32`?`pnpm.cmd`:`pnpm`,Os=q.platform===`win32`?`portless.cmd`:`portless`,ks=q.platform===`win32`?`react-router.cmd`:`react-router`;async function As({cwd:e=q.cwd(),debug:t,device:n,env:r=q.env,flutterDebug:i=!1,flutterOutput:a=`filtered`,host:o,https:s=!1,interactive:c=q.stdin.isTTY===!0,lan:l=!1,managed:u=!1,noManaged:d=!1,platform:f=`web`,portless:p,fresh:m=!1,reuseVite:h=!1,verbose:g=!1,webPort:_,supervisor:v}){let y=Et({env:r}),b=Is(f)?f:void 0,x=ko(i);if(i&&b===void 0)throw Error(`The --flutter-debug option is only supported for Flutter development platforms (iOS, Android, macOS, Windows, and Linux).`);let S=Ls(f),C=f===`ios`||f===`android`?f:void 0,w=C?await Ya({env:r,interactive:c,platform:C,target:n}):void 0;C&&w&&Ao({device:w,mode:x,platform:C});let T=b?!0:o,E=await y.measure(`config`,()=>Fe({cwd:e})),D=await y.measure(`managed`,async()=>t!==`managed-dev-overlay`&&(u||c&&!d)&&await kt(e));await y.measure(`i18n`,()=>Bn({cwd:e,projectConfig:E}));let ee=await y.measure(`routing`,async()=>p??await ls({cwd:e,env:r,platform:f})),te=await y.measure(`https`,async()=>s&&!ee?jt({cwd:e}):void 0),ne=ns(r,f),re=!h&&Cr(e),ie,O={...ne,...y.environment,...D?{[It]:`1`,[Lt]:`1`}:void 0,...t===`managed-dev-overlay`?{VITE_COREFRAME_MANAGED_DEV_OVERLAY_DEBUG:`1`}:void 0,...b?{COREFRAME_PLATFORM:b,[Rt]:P.resolve(e,`.coreframe`,`managed-dev-flutter-restart`)}:void 0,...te?{[Dt]:te.cert,[Ot]:te.key}:void 0},k=!1,A,oe,j,se,M,N,F,ce,I,L=new Promise(e=>{I=e}),R=new Map,z=[`postgres`,`sqlite`,S];for(let e of z){let t=e===`postgres`||e===`sqlite`?e:e.startsWith(`vite:flutter`)?`flutter`:`web`,n=Y({label:t}),r=Y({color:`red`,label:t});n.pipe(q.stdout,{end:!1}),r.pipe(q.stderr,{end:!1}),R.set(e,{stderr:r,stdout:n})}let B=v.onEvent(e=>{e.event===`log`?(R.get(e.resource)?.[e.stream])?.write(e.data):e.event===`service`&&e.resource===S&&(e.state===`failed`||e.state===`stopped`)&&(e.state===`failed`&&(ce=Error(e.error??`${S} development failed.`)),V())}),V=()=>{k||(k=!0,I(),j?.kill(`SIGTERM`),oe?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0))},le=e=>{A??=e,V()},ue=[`SIGINT`,`SIGTERM`].map(e=>{let t=()=>le(e);return q.on(e,t),{handler:t,signal:e}}),de=async e=>{let t=Ye(e);j=t;try{await t.expectSuccess()}catch(e){if(!k)throw e}finally{j===t&&(j=void 0)}};try{if(await v.subscribe(z),Fs(E)){let e=await v.acquirePostgres({config:E,env:O});M=e.leaseId,O={...O,...e.env}}if(E.database?.dialect===`sqlite`){let e=await v.acquireSqlite({config:E,env:O});N=e.leaseId,O={...O,...e.env}}(Fs(E)||E.database?.dialect===`sqlite`)&&await y.measure(`schema`,()=>de({name:`db`,command:Ds,args:[`db`,`ensure`],cwd:e,env:O,prefix:!1}));let t=Ps(_??r.COREFRAME_WEB_PORT),n=await v.status(),i=n.resources?.find(e=>e.resource===S),u=i!==void 0&&!m,d=u&&t===void 0?void 0:t??(h?5173:await gr.getAvailablePort()),p=d??i?.endpoint?.port??5173;if(d!==void 0&&n.resources?.some(e=>e.resource!==S&&e.endpoint?.port===p)){if(t!==void 0)throw Error(`Port ${p} is already used by another Coreframe development shell.`);p=await gr.getAvailablePort()}if(re&&!u&&(ie=await gr.getAvailablePort(),ie===p&&(ie=await gr.getAvailablePort()),O={...O,COREFRAME_DASHBOARD_ORIGIN:`http://127.0.0.1:${ie}`}),C&&w&&(se=await Za({device:w,env:r,host:o,interactive:c,platform:C,port:p}),T=se.viteHost),!h){let t={...O,CLOUDFLARE_ENV:`development`,NODE_OPTIONS:[O.NODE_OPTIONS,`--conditions=development`].filter(Boolean).join(` `),PATH:P.join(e,`node_modules`,`.bin`)+P.delimiter+(O.PATH??``)},n=[{args:ee?ds({host:T,lan:l,port:p}):[`dev`,...T===void 0?[]:[`--host`,T===!0?`0.0.0.0`:T],`--port`,String(p),...f===`web`||b?[`--strictPort`]:[]],command:ee?Os:ks,cwd:e,env:t},{args:[`exec`,`panda`,`dev`,`--no-color`],command:Ds,cwd:e,env:O},...ie?[{args:wr(ie),command:Ds,cwd:e,env:O}]:[]],r=await v.acquireVite({configFingerprint:Ns({cwd:e,host:T,lan:l,https:s,portless:ee,resource:S}),endpoint:{host:T===!0?`0.0.0.0`:T??`127.0.0.1`,port:p},processes:n,resource:S},m);F=r.leaseId,p=r.endpoint.port}if(y.report(),k)return;if(f===`web`?await Promise.race([Ms(v,S,()=>ce),L]):(await ae({cwd:e}),await js({cwd:e,env:ne,interactive:c,platform:f,requestStop:V,selectedDevice:w,serverUrl:se?.serverUrl??Qa(f,void 0,p),mode:x,output:a,flutterRestartFile:O[Rt],handleShutdown:le,isStopping:()=>k,stopRequested:L,setActiveNative:e=>{oe=e},verbose:g})),ce)throw ce}finally{V(),await se?.close(),se=void 0,F&&await v.release(F).catch(()=>void 0),M&&await v.release(M).catch(()=>void 0),N&&await v.release(N).catch(()=>void 0),B();for(let{handler:e,signal:t}of ue)q.off(t,e);for(let e of R.values())e.stdout.end(),e.stderr.end();A&&(q.exitCode??=A===`SIGINT`?130:143),v.close()}}async function js({cwd:e,env:t,interactive:n,platform:r,requestStop:i,selectedDevice:a,serverUrl:o,mode:s,output:c,flutterRestartFile:l,handleShutdown:u,isStopping:d,stopRequested:f,setActiveNative:p,verbose:m}){let h,g=!1,_=()=>{g||d()||!h||(g=!0,t.CI!==`true`&&q.stdout.write(`
|
|
20
22
|
Restarting Flutter process...
|
|
21
|
-
`),
|
|
23
|
+
`),h.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0))},v=To(l,_);try{for(;;){g=!1;let l=r===`android`&&c===`filtered`&&!m?await se():void 0,v=n&&s===`profile`,y=B(`flutter`,jo({device:a??{id:r},mode:s,serverUrl:o,verbose:m}),{cwd:P.join(e,`src-flutter`),env:{...t,[Eo]:`1`},stdio:l?[v?`pipe`:`inherit`,`pipe`,`pipe`]:v?[`pipe`,`inherit`,`inherit`]:`inherit`});p(y),h=y;let b=Oo({enabled:v,env:t,onInterrupt:()=>u(`SIGINT`),onQuit:i,onRestart:_});try{if(await Promise.all([y,l?.capture(y)]),!g||d())return}catch{if(g&&!d())continue;if(d())return;let e=n?await V.confirm({initialValue:!0,message:`Flutter failed. Retry?`}):!1;if(V.isCancel(e)||!e){V.log.warn(`Flutter stopped. Web development is still running.`),await f;return}}finally{b(),p(void 0),h===y&&(h=void 0)}}}finally{(await v)()}}async function Ms(e,t,n){await e.waitForServiceExit(t);let r=n();if(r)throw r}function Ns({cwd:e,host:t,lan:n,https:r,portless:i,resource:a}){return Le(`sha256`).update(JSON.stringify({cwd:P.resolve(e),host:t??null,lan:n,https:r,portless:i,resource:a})).digest(`hex`)}function Ps(e){if(e===void 0)return;let t=Number(e);if(!Number.isInteger(t)||t<=0||t>65535)throw Error(`COREFRAME_WEB_PORT must be a valid TCP port.`);return t}function Fs(e){return(e.database?.dialect??`postgres`)===`postgres`}function Is(e){return e===`android`||e===`ios`||e===`linux`||e===`macos`||e===`windows`}function Ls(e){if(e===`web`)return`vite:web`;if(Is(e))return`vite:flutter:${e}`;throw Error(`Unsupported supervised development platform: ${e}.`)}const Rs=`extension:dev`;function zs(e){if(!ze(I(e,`src-webext/wxt.config.ts`)))throw Error("No WXT configuration found at src-webext/wxt.config.ts. Apply the wxt recipe or add that convention before running `coreframe dev webext`.");let t=I(e,`package.json`),n;try{n=JSON.parse(J(t,`utf8`))}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}if(!n||typeof n!=`object`||!(`scripts`in n)||!n.scripts||typeof n.scripts!=`object`||!(`extension:dev`in n.scripts)||typeof n.scripts[`extension:dev`]!=`string`)throw Error(`package.json must define scripts.${Rs} for \`coreframe dev webext\`. Apply the wxt recipe and add its named extension lifecycle scripts.`)}function Bs({host:e,port:t}){let n=[...e===void 0?[]:[`--host`,e===!0?`0.0.0.0`:e],...t===void 0?[]:[`--port`,String(t)]];return[`run`,Rs,...n.length>0?[`--`,...n]:[]]}const Vs=[`web`,`webext`,`ios`,`android`,`macos`,`windows`,`linux`],Hs=[`managed-dev-overlay`],Us=P.resolve(`node_modules`,`.bin`),Ws=q.platform===`win32`?`pnpm.cmd`:`pnpm`,Gs=q.platform===`win32`?`portless.cmd`:`portless`,Ks=q.platform===`win32`?`react-router.cmd`:`react-router`;async function qs({cwd:e=q.cwd(),debug:t,device:n,env:r=q.env,flutterDebug:i=!1,flutterOutput:a=`filtered`,host:o,https:s=!1,interactive:c=q.stdin.isTTY===!0,lan:l=!1,managed:u=!1,noManaged:d=!1,platform:f=`web`,fresh:p=!1,reuseVite:m=!1,supervisor:h,verbose:g=!1,webPort:_}={}){let v=Et({env:r}),y=r.PATH??r.Path??``,b=tc(f)?f:void 0,x=ko(i),S=f===`web`||b!==void 0;if(p&&m)throw Error(`Cannot use --fresh and --reuse-vite together.`);let C=!p&&(b||f===`web`)?await v.measure(`dev-session`,()=>fs({cwd:e,platform:f})):void 0,w=m||C!==void 0,T=ec(_??r.COREFRAME_WEB_PORT);if(C&&T!==void 0&&T!==C.vite.port)throw Error(`The active development session uses port ${C.vite.port}. Omit --port or use that port when reusing it.`);let E,D,ee,te,ne,re,O,k,A,oe,j=!1,M,N=r,F,ce;if(u&&d)throw Error(`Cannot use --managed and --no-managed together.`);if(t===`managed-dev-overlay`&&u)throw Error(`Cannot use --managed with --debug managed-dev-overlay.`);if(i&&b===void 0)throw Error(`The --flutter-debug option is only supported for Flutter development platforms (iOS, Android, macOS, Windows, and Linux).`);if(a===`full`&&b===void 0)throw Error(`The --flutter-output option is only supported for Flutter development platforms (iOS, Android, macOS, Windows, and Linux).`);if(m&&b===void 0)throw Error(`The --reuse-vite option is only supported for Flutter development platforms (iOS, Android, macOS, Windows, and Linux).`);if(f===`webext`){if(u||d||t!==void 0||g)throw Error(`Managed development, debug features, and verbose native output are only supported for the main web or native development platforms.`);zs(e)}if(s&&f!==`web`)throw Error(`Local HTTPS is only supported for the web development platform.`);if(n!==void 0&&f!==`ios`&&f!==`android`)throw Error(`A device name or ID is only supported for iOS or Android development.`);let I=await v.measure(`routing`,()=>ls({cwd:e,env:r,platform:f}));if(I&&await v.measure(`portless`,()=>us({cwd:e,env:r,lan:l})),S&&r.COREFRAME_DEV_SUPERVISOR!==`0`){let v=h??await Tt({cwd:e,env:r});if(v)return As({cwd:e,debug:t,device:n,env:r,flutterDebug:i,flutterOutput:a,fresh:p,host:o,https:s,interactive:c,lan:l,managed:u,noManaged:d,platform:f,portless:I,reuseVite:m,supervisor:v,verbose:g,webPort:_})}let L=w?void 0:await v.measure(`dev-lock`,()=>No({cwd:e,interactive:c,platform:f}));if(!w&&!L)return;let R=b===void 0?f===`web`||f===`webext`?C?.vite.port??T:void 0:C?.vite.port??T??(m?5173:await gr.getAvailablePort()),z,le=new Promise(e=>{z=e}),ue=()=>{j||(j=!0,z(),D?.kill(`SIGTERM`),re?.kill(`SIGTERM`),O?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),k?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),A?.close().catch(()=>void 0),E?.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0),de().catch(()=>void 0))},de=()=>te?(ne??=te[Symbol.asyncDispose](),ne):Promise.resolve(),fe=e=>{M??=e,ue()},pe=[`SIGINT`,`SIGTERM`].map(e=>{let t=()=>fe(e);return q.on(e,t),{handler:t,signal:e}}),me=async e=>{let t=Ye(e);D=t;try{await t.expectSuccess()}catch(e){if(!j)throw e}finally{D===t&&(D=void 0)}};try{let i=f===`ios`||f===`android`?f:void 0,p=i?await Ya({env:r,interactive:c,platform:i,target:n}):void 0;i&&p&&Ao({device:p,mode:x,platform:i}),oe=i&&p&&R!==void 0?await Za({device:p,env:r,host:o,interactive:c,platform:i,port:R}):void 0;let m=oe?.viteHost??(b?!0:o),h={},_=!1,S;w||([h,_]=await Promise.all([v.measure(`config`,()=>Fe({cwd:e})),v.measure(`managed`,async()=>t!==`managed-dev-overlay`&&(u||c&&!d)&&await kt(e))]),await v.measure(`i18n`,()=>Bn({cwd:e,projectConfig:h})),S=f!==`webext`&&Cr(e)?await gr.getAvailablePort():void 0);let C=w?void 0:await v.measure(`https`,async()=>s&&!I?jt({cwd:e}):void 0),T=ns(r,f);N={...T,...v.environment,..._?{[It]:`1`}:void 0,...t===`managed-dev-overlay`?{VITE_COREFRAME_MANAGED_DEV_OVERLAY_DEBUG:`1`}:void 0,...b&&(_||w)?{COREFRAME_PLATFORM:b,[Rt]:P.resolve(e,`.coreframe`,`managed-dev-flutter-restart`)}:void 0,...C?{[Dt]:C.cert,[Ot]:C.key}:void 0,...S?{COREFRAME_DASHBOARD_ORIGIN:`http://127.0.0.1:${S}`}:void 0};let D=async()=>{if(!S)return;let t=Tr({cwd:e,env:N,port:S});A=t;try{await t.listen(),await t.wait()}finally{await t.close(),A===t&&(A=void 0)}},ne=async()=>{let t=Y({label:`web`}),n=Y({color:`red`,label:`web`});t.pipe(q.stdout,{end:!1}),n.pipe(q.stderr,{end:!1}),O=B(I?Gs:Ks,I?ds({host:m,lan:l,port:R}):$s({host:m,port:R,strictPort:b!==void 0}),{cwd:e,env:{...N,CLOUDFLARE_ENV:`development`,NODE_OPTIONS:[N.NODE_OPTIONS,`--conditions=development`].filter(Boolean).join(` `),PATH:Us+P.delimiter+y},stdin:`inherit`});let r=Promise.allSettled([Js(O.stdout,t),Js(O.stderr,n)]);try{await O;let e=(await r).find(e=>e.status===`rejected`);if(e)throw e.reason}catch(e){if(!j)throw e}finally{await r,t.end(),n.end(),await Promise.allSettled([Je(t),Je(n)]),O=void 0}},M=async()=>{let t=Y({label:`webext`}),n=Y({color:`red`,label:`webext`});t.pipe(q.stdout,{end:!1}),n.pipe(q.stderr,{end:!1}),k=B(Ws,Bs({host:o,port:R}),{cwd:e,env:N,stdin:`inherit`});let r=Promise.allSettled([Js(k.stdout,t),Js(k.stderr,n)]);try{await k;let e=(await r).find(e=>e.status===`rejected`);if(e)throw e.reason}catch(e){if(!j)throw e}finally{await r,t.end(),n.end(),await Promise.allSettled([Je(t),Je(n)]),k=void 0}},z=async t=>{let n,i=!1,o=()=>{i||j||!n||(i=!0,r.CI!==`true`&&q.stdout.write(`
|
|
22
24
|
Restarting Flutter process...
|
|
23
|
-
`),n.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0))},s=
|
|
24
|
-
`)?t:`${t}\n`)}function
|
|
25
|
-
`)}function
|
|
26
|
-
`)}const _c=new Set([`.coreframe`,`.git`,`.react-router`,`.wrangler`,`.wxt`,`build`,`dist`,`node_modules`,`styled-system`,`target`]),vc=[`node_modules/@react-router/dev/package.json`,`node_modules/react-router/package.json`,`package.json`,`pnpm-lock.yaml`,`react-router.config.ts`,`src/web`],yc=[`dashboard`,`node_modules/@coreframe/dashboard/dist/package/app`,`node_modules/@coreframe/dashboard/package.json`,`node_modules/@react-router/dev/package.json`,`node_modules/react-router/package.json`,`package.json`,`pnpm-lock.yaml`],bc=[`coreframe.config.ts`,`node_modules/@coreframe/config/dist`,`node_modules/@coreframe/config/package.json`,`node_modules/@coreframe/deploy/dist`,`node_modules/@coreframe/deploy/package.json`,`node_modules/wrangler/package.json`,`package.json`,`pnpm-lock.yaml`,`src/api`,`wrangler.jsonc`],xc=`.coreframe/typegen.json`,Sc=[`web`,`dashboard`,`worker`];async function Cc({checkWorker:e=!1,cwd:t=q.cwd(),runners:n={}}={}){let r=await Dc(t)??{generators:{},schemaVersion:1},i=[];return i.push(await Tc({cwd:t,inputPaths:vc,name:`web`,outputPath:`.react-router`,run:()=>(n.web??Ec)(t),state:r})),i.push(await Tc({cwd:t,inputPaths:yc,name:`dashboard`,outputPath:`dashboard/.react-router`,run:()=>(n.dashboard??vr)(t),state:r})),i.push(await Tc({cwd:t,inputPaths:bc,name:`worker`,outputPath:`worker-configuration.d.ts`,run:()=>(n.worker??pc)({check:e,cwd:t}),state:r})),i}function wc(e){return`${{dashboard:`Dashboard route types`,web:`Web route types`,worker:`Worker types`}[e.name]} ${e.changed?`generated`:`unchanged`}.`}async function Tc({cwd:e,inputPaths:t,name:n,outputPath:r,run:i,state:a}){let o=await kc(e,t),s=await Ac(e,r),c=a.generators[n];if(s&&c?.inputFingerprint===o&&c.outputFingerprint===s)return{changed:!1,name:n,ran:!1};await i();let l=await Ac(e,r);if(!l)throw Error(`Coreframe ${n} typegen did not produce ${r}.`);return a.generators[n]={inputFingerprint:o,outputFingerprint:l},await Oc(e,a),{changed:s!==l,name:n,ran:!0}}async function Ec(e){let t=q.platform===`win32`?`react-router.cmd`:`react-router`,n=q.env;await V(t,[`typegen`],{cwd:e,env:{...n,PATH:I.resolve(e,`node_modules/.bin`)+I.delimiter+(n.PATH??n.Path??``)},stdio:`inherit`})}async function Dc(e){try{let t=JSON.parse(await W(I.resolve(e,xc),`utf8`));if(!Pc(t)||t.schemaVersion!==1)return;let n={};if(!Pc(t.generators))return;for(let e of Sc){let r=t.generators[e];Pc(r)&&typeof r.inputFingerprint==`string`&&typeof r.outputFingerprint==`string`&&(n[e]={inputFingerprint:r.inputFingerprint,outputFingerprint:r.outputFingerprint})}return{generators:n,schemaVersion:1}}catch{return}}async function Oc(e,t){let n=I.resolve(e,xc);await U(I.dirname(n),{recursive:!0}),await K(n,`${JSON.stringify(t)}\n`,{mode:384})}async function kc(e,t){let n=Le(`sha256`);for(let r of[...t].sort()){let t=I.resolve(e,r),i=await Mc(t);if(!i){n.update(`missing:${r}\0`);continue}if(i.isDirectory()){n.update(`directory:${r}\0`);for(let r of await jc(t)){let i=I.join(t,r),a=I.relative(e,i).split(I.sep).join(`/`);n.update(`${a}\0`),n.update(await W(i))}continue}i.isFile()&&(n.update(`file:${r}\0`),n.update(await W(t)))}return n.digest(`hex`)}async function Ac(e,t){if(await Mc(I.resolve(e,t)))return kc(e,[t])}async function jc(e){let t=[];async function n(e,r){let i=await we(e,{withFileTypes:!0});i.sort((e,t)=>e.name.localeCompare(t.name));for(let a of i)if(a.isDirectory()){if(_c.has(a.name))continue;await n(I.join(e,a.name),I.join(r,a.name))}else a.isFile()&&t.push(I.join(r,a.name))}return await n(e,``),t.sort()}async function Mc(e){try{return await De(e)}catch(e){if(Nc(e))return;throw e}}function Nc(e){return e instanceof Error&&`code`in e&&e.code===`ENOENT`}function Pc(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}const Fc=I.resolve(`node_modules`,`.bin`);q.env.PATH=Fc+I.delimiter+q.env.PATH;const Ic=q.platform===`win32`?`tsc.cmd`:`tsc`,Lc=[{name:`scripts`,path:`scripts/tsconfig.json`},{name:`shared`,path:`src/shared/tsconfig.json`},{name:`api`,path:`src/api/tsconfig.json`},{name:`worker`,path:`src/api/worker/tsconfig.json`},{name:`web`,path:`src/web/tsconfig.json`},{name:`dashboard`,path:`dashboard/tsconfig.json`}];async function Rc(){await Cc({checkWorker:!0});let e=[];for(let t of Lc)try{await ve(t.path),e.push(t)}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e}let t=e.map(e=>Gt({name:e.name,command:Ic,args:[`-p`,e.path]})),n=(await Promise.all(t.map(e=>e.wait()))).filter(e=>e.exitCode!==0);n.length>0&&(q.exitCode=n[0].exitCode)}const zc=r(s(Ys),{displayName:`feature`,from:async e=>e}),Bc=r(s(jo),{displayName:`filtered|full`,from:async e=>e}),Vc=[`Cookies and sessions are origin-scoped.`,`Exact-host passkeys may require re-registration unless a stable eligible parent RP ID was configured in advance.`,`External OAuth callbacks such as Google may need updating.`,`Database data and private backend resources are unchanged.`],Hc=n({name:`deploy`,args:{environment:u({type:s(Qe),displayName:`environment`,description:`Deploy to the staging or production environment.`}),runMigrations:i({long:`run-migrations`,description:`Run pending deploy-safe database migrations before deploying.`,defaultValue:()=>!1}),skipMigrations:i({long:`skip-migrations`,description:`Deploy without running pending deploy-safe database migrations.`,defaultValue:()=>!1}),skipPostDeployChecks:i({long:`skip-post-deploy-checks`,description:`Skip post-deploy checks after Cloudflare deployment.`,defaultValue:()=>!1}),tauriLocalPlatforms:a({long:`tauri-local-platform`,type:t(s(St)),description:`Build one Tauri release platform locally. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowName:c({long:`tauri-workflow-name`,type:l(f),description:`GitHub Actions workflow file or name for remote Tauri release builds.`}),tauriWorkflowPlatforms:a({long:`tauri-workflow-platform`,type:t(s(St)),description:`Build one Tauri release platform with GitHub Actions. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowRef:c({long:`tauri-workflow-ref`,type:l(f),description:`Git ref used when dispatching remote Tauri release builds.`}),yes:i({long:`yes`,short:`y`,description:`Approve the production deployment confirmation.`,defaultValue:()=>!1})},handler:({environment:e,runMigrations:t,skipMigrations:n,skipPostDeployChecks:r,tauriLocalPlatforms:i,tauriWorkflowName:a,tauriWorkflowPlatforms:o,tauriWorkflowRef:s,yes:c})=>wa([e,...t?[`--run-migrations`]:[],...n?[`--skip-migrations`]:[],...r?[`--skip-post-deploy-checks`]:[],...i.flatMap(e=>[`--tauri-local-platform`,e]),...a?[`--tauri-workflow-name`,a]:[],...o.flatMap(e=>[`--tauri-workflow-platform`,e]),...s?[`--tauri-workflow-ref`,s]:[],...c?[`--yes`]:[]])}),Uc=p({name:`staging`,cmds:{reassign:n({name:`reassign`,args:{json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await pt();if(e){console.log(JSON.stringify({...t,notices:Vc}));return}console.log(t.url),console.error(`Staging hostname reassigned. ${Vc.join(` `)}`)}}),url:n({name:`url`,args:{json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await et();console.log(e?JSON.stringify({url:t}):t)}})}}),Wc=p({name:`secrets`,cmds:{"rotate-access-token":n({name:`rotate-access-token`,args:{environment:u({type:s(Qe),displayName:`environment`,description:`Worker environment whose access JWTs should be invalidated.`}),yes:i({long:`yes`,short:`y`,description:`Confirm immediate signing-secret replacement and invalidation of outstanding access JWTs.`,defaultValue:()=>!1})},handler:async({environment:e,yes:t})=>{if(!t)throw Error(`Access-token signing-secret rotation requires --yes because it immediately invalidates outstanding access JWTs.`);await yt({environment:e}),console.log(`Rotated Coreframe access-token signing material for ${e}. Clients must remint outstanding access JWTs.`)}}),status:n({name:`status`,args:{environment:u({type:l(s(Qe)),displayName:`environment`,description:`Inspect staging, production, or both when omitted.`}),json:i({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({environment:e,json:t})=>{let n=await tt({environment:e});console.log(t?JSON.stringify(n):Xc(n))}}),set:n({name:`set`,args:{environment:u({type:s(Qe),displayName:`environment`,description:`Worker environment to update on its next deploy.`}),name:u({type:l(f),displayName:`name`,description:`Declared Worker secret name; omit to configure known secrets.`}),bulk:i({long:`bulk`,description:`Queue known secrets from pasted or piped dotenv-formatted contents.`,defaultValue:()=>!1})},handler:async({environment:e,name:t,bulk:n})=>{if(n&&t)throw Error(`Use either a secret name or --bulk, not both.`);if(t){await ct({environment:e,name:t,value:await Zc(t)}),console.log(`Queued ${t} for ${e}. Run coreframe deploy ${e} to apply.`);return}let r=await ut(),i=n?await $c(r):await Qc(r,e);await lt({environment:e,values:i});let a=Object.keys(i).sort();console.log(a.length>0?`Queued ${a.join(`, `)} for ${e}. Run coreframe deploy ${e} to apply.`:`No ${e} Worker secret updates were queued.`)}}),discard:n({name:`discard`,args:{environment:u({type:s(Qe),displayName:`environment`,description:`Worker environment with a queued secret update.`}),name:u({type:f,displayName:`name`,description:`Declared Worker secret name.`})},handler:async({environment:e,name:t})=>{let n=await $e({environment:e,name:t});console.log(n?`Discarded the queued ${t} update for ${e}.`:`No ${t} update is queued for ${e}.`)}})}}),Gc=n({name:`typecheck`,args:{},handler:Rc}),Kc=p({name:`worker`,cmds:{typegen:n({name:`typegen`,args:{check:i({long:`check`,description:`Fail when the committed primary Worker declarations are stale.`,defaultValue:()=>!1})},handler:async({check:e})=>{let t=await pc({check:e});console.log(e?`${tl(t.path)} is current.`:`${tl(t.path)} ${t.changed?`generated`:`is unchanged`}.`)}})}}),qc=n({name:`dev`,args:{debug:c({long:`debug`,type:l(zc),description:`Launch a development feature in isolated debug mode.`}),flutterDebug:i({long:`flutter-debug`,description:`Run Flutter in debug mode instead of profile mode.`,defaultValue:()=>!1}),flutterOutput:c({long:`flutter-output`,type:Bc,description:`Choose filtered Android diagnostics (default) or full standard Flutter output.`,defaultValue:()=>`filtered`}),https:i({long:`https`,description:`Serve the web app over locally trusted HTTPS.`,defaultValue:()=>!1}),fresh:i({long:`fresh`,description:`Start a new directory-scoped development session instead of attaching to one.`,defaultValue:()=>!1}),host:c({long:`host`,type:l(f),implicitValue:`0.0.0.0`,description:`Host address for the web development server. Pass without an address to use 0.0.0.0.`}),lan:i({long:`lan`,description:`Expose the Portless development proxy to devices on the local network.`,defaultValue:()=>!1}),managed:i({long:`managed`,description:`Run managed checkout synchronization even without an interactive terminal.`,defaultValue:()=>!1}),noManaged:i({long:`no-managed`,description:`Run without managed checkout synchronization for this invocation.`,defaultValue:()=>!1}),reuseVite:i({long:`reuse-vite`,description:`Use an existing Vite development server instead of starting another one for Flutter.`,defaultValue:()=>!1}),stop:i({long:`stop`,description:`Stop the Vite development server for the selected platform.`,defaultValue:()=>!1}),platform:u({type:l(s(Js)),displayName:`platform`,description:`Development target platform. Defaults to web.`}),device:u({type:l(f),displayName:`device`,description:`Device name or ID for iOS or Android development.`}),port:c({long:`port`,type:l(o),description:`Port for the web development server.`}),verbose:i({long:`verbose`,description:`Show the full native development output.`,defaultValue:()=>!1})},handler:({debug:e,device:t,fresh:n,flutterDebug:r,flutterOutput:i,host:a,https:o,lan:s,managed:c,noManaged:l,platform:u,port:d,reuseVite:f,stop:p,verbose:m})=>p?It({cwd:q.cwd(),resource:Jc(u??`web`)}):ec({debug:e,device:t,fresh:n,flutterDebug:r,flutterOutput:i,host:a,https:o,lan:s,managed:c,noManaged:l,platform:u??`web`,reuseVite:f,verbose:m,webPort:d})});function Jc(e){if(e===`web`)return`vite:web`;if(e===`ios`||e===`android`||e===`macos`)return`vite:flutter:${e}`;throw Error(`The --stop option is only supported for web, iOS, Android, and macOS development targets.`)}const Yc=n({name:`preview`,args:{host:c({long:`host`,type:l(f),description:`Host address for the preview server.`}),port:c({long:`port`,type:l(o),description:`Port for the preview server.`})},handler:({host:e,port:t})=>dc({host:e,port:t})});function Xc(e){if(e.entries.length===0)return`No Worker environment values are declared in coreframe.config.ts.`;let t=e.entries.map(e=>[e.name,e.kind,e.local===`override`?`override`:`built-in default`,e.deployed.staging.replaceAll(`_`,` `),e.deployed.production.replaceAll(`_`,` `)]),n=[`Name`,`Kind`,`Local`,`Staging`,`Production`],r=n.map((e,n)=>Math.max(e.length,...t.map(e=>e[n].length))),i=e=>e.map((e,t)=>e.padEnd(r[t])).join(` `).trimEnd();return[i(n),i(r.map(e=>`-`.repeat(e))),...t].join(`
|
|
27
|
-
`)}async function
|
|
25
|
+
`),n.nodeChildProcess.then(e=>e.kill(`SIGTERM`)).catch(()=>void 0))},s=To(N[Rt],o);try{for(;!j;){i=!1;let s=f===`android`&&a===`filtered`&&!g?await se():void 0,l=c&&x===`profile`,u=B(`flutter`,jo({device:p??{id:f},mode:x,serverUrl:oe?.serverUrl??Qa(f,void 0,R),verbose:g}),{cwd:P.join(e,`src-flutter`),env:{...T,[Eo]:`1`},stdio:s?[l?`pipe`:`inherit`,`pipe`,`pipe`]:l?[`pipe`,`inherit`,`inherit`]:`inherit`});E=u,n=u;let d=Oo({enabled:l,env:r,onInterrupt:()=>fe(`SIGINT`),onQuit:ue,onRestart:o});try{if(await Promise.all([u,s?.capture(u)]),!i||j)return}catch{if(i&&!j)continue;if(j)return;let e=c?await V.confirm({initialValue:!0,message:`Flutter failed. Retry?`}):!1;if(V.isCancel(e)||!e){V.log.warn(t?`Flutter stopped. Web development is still running.`:`Flutter stopped.`),await(t??le);return}}finally{d(),E===u&&(E=void 0),n===u&&(n=void 0)}}}finally{(await s)()}},de=async()=>{if(w){if(f===`web`)return;await ae({cwd:e}),await z();return}if(f===`web`){await ne();return}let t=ne().then(()=>{if(!j)throw Error(`The Vite development server stopped while Flutter was still running.`)});await ae({cwd:e});try{await Promise.race([t,z(t)])}finally{ue(),await Promise.allSettled([t,E]),E=void 0}},pe=async()=>{let t=Ye({name:`panda`,command:Ws,args:[`exec`,`panda`,`dev`,`--no-color`],cwd:e,env:N});re=t;try{if(await t.expectSuccess(),!j)throw Error(`The Panda CSS watcher stopped while development was still running.`)}catch(e){if(!j)throw e}finally{re===t&&(re=void 0)}},he=async()=>{if(f===`webext`){await M();return}if(w){await de();return}let e=pe(),t=de(),n=S?D():void 0;try{await Promise.race([e,t,n].filter(e=>e!==void 0)),j&&await t}finally{ue(),await Promise.allSettled([e,t,n].filter(e=>e!==void 0))}},ge=async()=>{w||!L?.owner||R===void 0||(await ms({cwd:e,owner:L.owner,platform:f,postgres:ce,vitePort:R}),F=L.owner)};if(_&&(N={...N,[Lt]:`1`}),j)return;if(f===`webext`){v.report(),await he();return}if(w){v.report(),await he();return}if(h.database?.dialect===`sqlite`&&(await v.measure(`database`,async()=>{let t=await ie({config:h,cwd:e,env:r,tursoOutput:q.stdout,useSupervisorLease:!0});te=t,N={...N,...t.env}}),await v.measure(`schema`,()=>me({name:`db`,command:Ws,args:[`db`,`ensure`],cwd:e,env:N,prefix:!1})),j))return;if(Qs(h)){let t=Y({label:`postgres`});t.pipe(q.stdout,{end:!1});try{let n=await v.measure(`database`,()=>Zs({config:h,cwd:e,env:N,failIfRunning:!0,interactive:c,isStopping:()=>j,postgresOutput:t,takeoverApproved:L?.takeoverApproved??!1,useSupervisorLease:!0}));if(!n)return;ee=n,N=n.env,ce=await Xs(n.env);try{j||await v.measure(`schema`,()=>me({name:`db`,command:Ws,args:[`db`,`ensure`],cwd:e,env:N,prefix:!1})),j||(await ge(),v.report(),await he())}finally{await n[Symbol.asyncDispose](),ee===n&&(ee=void 0)}}finally{t.end()}return}await ge(),v.report(),await he()}finally{ue(),await oe?.close(),oe=void 0,F&&=(await hs({cwd:e,owner:F}),void 0);let t;try{await ee?.[Symbol.asyncDispose]()}catch(e){t=e}finally{await de();for(let{handler:e,signal:t}of pe)q.off(t,e);M&&(q.exitCode??=M===`SIGINT`?130:143)}Ys(t),await L?.release()}}async function Js(e,t){for await(let n of e)t.write(`${n}\n`)||await Ft(t,`drain`)}function Ys(e){if(e)throw e}async function Xs(e){let t=e.PGDATA;if(!t)return;let n=Number((await $.readFile(P.join(t,`postmaster.pid`),`utf8`).catch(()=>``)).split(/\r?\n/,1)[0]);return{dataDir:P.resolve(t),...Number.isSafeInteger(n)&&n>0?{pid:n}:void 0}}async function Zs({interactive:e,isStopping:t,takeoverApproved:n,...r}){try{return await re(r)}catch(i){if(!(i instanceof f)||!e)throw i;if(!n){let e=await V.confirm({initialValue:!1,message:`PostgreSQL is already running for this project (PID ${i.pid}). Stop it and start here?`});if(V.isCancel(e)||!e){V.cancel(`Keeping the existing PostgreSQL process.`);return}}return await O(i),t()?void 0:re(r)}}function Qs(e){return(e.database?.dialect??`postgres`)===`postgres`}function $s({host:e,port:t,strictPort:n=!1}){return[`dev`,...e===void 0?[]:[`--host`,e===!0?`0.0.0.0`:e],...t===void 0?[]:[`--port`,String(t)],...n?[`--strictPort`]:[]]}function ec(e){if(e===void 0)return;let t=Number(e);if(!Number.isInteger(t)||t<=0||t>65535)throw Error(`COREFRAME_WEB_PORT must be a valid TCP port.`);return t}function tc(e){return e===`android`||e===`ios`||e===`linux`||e===`macos`||e===`windows`}async function nc(e={}){let t=e.cwd??q.cwd(),n=`scripts/preview.ts`,r={},i=!0;try{await ve(P.resolve(t,n))}catch(e){if(e.code===`ENOENT`)i=!1;else throw e}if(i){let e=await Ne(n,t);if(!e.default||typeof e.default!=`object`)throw Error(`scripts/preview.ts must default-export preview hooks.`);for(let t of[`beforeBuild`,`afterBuild`])if(e.default[t]!==void 0&&typeof e.default[t]!=`function`)throw Error(`scripts/preview.ts ${t} must be a function.`);r=e.default}return Vt({...e,cwd:t},r)}const rc=`worker-configuration.d.ts`;async function ic({check:e=!1,cwd:t=process.cwd()}={}){let n=await Fe({cwd:t}),r=await st({coreframeConfig:n,cwd:t}),i=R(t,rc),a=R(t,`.coreframe-worker-types-${K()}.d.ts`);try{try{await B(`pnpm`,[`exec`,`wrangler`,`types`,a,`--config`,r.path,`--strict-vars=false`,`--include-runtime=false`],{cwd:t,stdio:[`ignore`,`pipe`,`pipe`]})}catch(e){throw ac(e),e}let o=oc(await U(a,`utf8`)),s=Ie(r.config),c=Pe(n.worker?.environment).filter(e=>!s.has(e.name)),l=`${o.trimEnd()}\n\n${sc(c)}\n`;if(e){if(await U(i,`utf8`).catch(()=>``)!==l)throw Error(`${rc} is stale. Run "coreframe worker typegen" and commit the result.`);return{changed:!1,path:i}}let u=await U(i,`utf8`).catch(()=>``);return u!==l&&await G(i,l),{changed:u!==l,path:i}}finally{await r.dispose(),await W(a,{force:!0})}}function ac(e){if(typeof e!=`object`||!e||!(`output`in e))return;let{output:t}=e;typeof t!=`string`||t===``||process.stderr.write(t.endsWith(`
|
|
26
|
+
`)?t:`${t}\n`)}function oc(e){return e.split(/\r?\n/).filter(e=>!e.startsWith(`// Generated by Wrangler by running `)).join(`
|
|
27
|
+
`)}function sc(e){return[`// Coreframe application string inventory declaration-merges with Wrangler's generated Env.`,`interface Env {`,...e.map(e=>` /** ${e.description.replaceAll(`*/`,`*\\/`)} */\n ${JSON.stringify(e.name)}?: string`),`}`].join(`
|
|
28
|
+
`)}const cc=new Set([`.coreframe`,`.git`,`.react-router`,`.wrangler`,`.wxt`,`build`,`dist`,`node_modules`,`styled-system`,`target`]),lc=[`node_modules/@react-router/dev/package.json`,`node_modules/react-router/package.json`,`package.json`,`pnpm-lock.yaml`,`react-router.config.ts`,`src/web`],uc=[`dashboard`,`node_modules/@coreframe/dashboard/dist/package/app`,`node_modules/@coreframe/dashboard/package.json`,`node_modules/@react-router/dev/package.json`,`node_modules/react-router/package.json`,`package.json`,`pnpm-lock.yaml`],dc=[`coreframe.config.ts`,`node_modules/@coreframe/config/dist`,`node_modules/@coreframe/config/package.json`,`node_modules/@coreframe/deploy/dist`,`node_modules/@coreframe/deploy/package.json`,`node_modules/wrangler/package.json`,`package.json`,`pnpm-lock.yaml`,`src/api`,`wrangler.jsonc`],fc=`.coreframe/typegen.json`,pc=[`web`,`dashboard`,`worker`];async function mc({checkWorker:e=!1,cwd:t=q.cwd(),runners:n={}}={}){let r=await vc(t)??{generators:{},schemaVersion:1},i=[];return i.push(await gc({cwd:t,inputPaths:lc,name:`web`,outputPath:`.react-router`,run:()=>(n.web??_c)(t),state:r})),i.push(await gc({cwd:t,inputPaths:uc,name:`dashboard`,outputPath:`dashboard/.react-router`,run:()=>(n.dashboard??dr)(t),state:r})),i.push(await gc({cwd:t,inputPaths:dc,name:`worker`,outputPath:`worker-configuration.d.ts`,run:()=>(n.worker??ic)({check:e,cwd:t}),state:r})),i}function hc(e){return`${{dashboard:`Dashboard route types`,web:`Web route types`,worker:`Worker types`}[e.name]} ${e.changed?`generated`:`unchanged`}.`}async function gc({cwd:e,inputPaths:t,name:n,outputPath:r,run:i,state:a}){let o=await bc(e,t),s=await xc(e,r),c=a.generators[n];if(s&&c?.inputFingerprint===o&&c.outputFingerprint===s)return{changed:!1,name:n,ran:!1};await i();let l=await xc(e,r);if(!l)throw Error(`Coreframe ${n} typegen did not produce ${r}.`);return a.generators[n]={inputFingerprint:o,outputFingerprint:l},await yc(e,a),{changed:s!==l,name:n,ran:!0}}async function _c(e){let t=q.platform===`win32`?`react-router.cmd`:`react-router`,n=q.env;await B(t,[`typegen`],{cwd:e,env:{...n,PATH:P.resolve(e,`node_modules/.bin`)+P.delimiter+(n.PATH??n.Path??``)},stdio:`inherit`})}async function vc(e){try{let t=JSON.parse(await U(P.resolve(e,fc),`utf8`));if(!Tc(t)||t.schemaVersion!==1)return;let n={};if(!Tc(t.generators))return;for(let e of pc){let r=t.generators[e];Tc(r)&&typeof r.inputFingerprint==`string`&&typeof r.outputFingerprint==`string`&&(n[e]={inputFingerprint:r.inputFingerprint,outputFingerprint:r.outputFingerprint})}return{generators:n,schemaVersion:1}}catch{return}}async function yc(e,t){let n=P.resolve(e,fc);await H(P.dirname(n),{recursive:!0}),await G(n,`${JSON.stringify(t)}\n`,{mode:384})}async function bc(e,t){let n=Le(`sha256`);for(let r of[...t].sort()){let t=P.resolve(e,r),i=await Cc(t);if(!i){n.update(`missing:${r}\0`);continue}if(i.isDirectory()){n.update(`directory:${r}\0`);for(let r of await Sc(t)){let i=P.join(t,r),a=P.relative(e,i).split(P.sep).join(`/`);n.update(`${a}\0`),n.update(await U(i))}continue}i.isFile()&&(n.update(`file:${r}\0`),n.update(await U(t)))}return n.digest(`hex`)}async function xc(e,t){if(await Cc(P.resolve(e,t)))return bc(e,[t])}async function Sc(e){let t=[];async function n(e,r){let i=await we(e,{withFileTypes:!0});i.sort((e,t)=>e.name.localeCompare(t.name));for(let a of i)if(a.isDirectory()){if(cc.has(a.name))continue;await n(P.join(e,a.name),P.join(r,a.name))}else a.isFile()&&t.push(P.join(r,a.name))}return await n(e,``),t.sort()}async function Cc(e){try{return await De(e)}catch(e){if(wc(e))return;throw e}}function wc(e){return e instanceof Error&&`code`in e&&e.code===`ENOENT`}function Tc(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}const Ec=P.resolve(`node_modules`,`.bin`);q.env.PATH=Ec+P.delimiter+q.env.PATH;const Dc=q.platform===`win32`?`tsc.cmd`:`tsc`,Oc=[{name:`scripts`,path:`scripts/tsconfig.json`},{name:`shared`,path:`src/shared/tsconfig.json`},{name:`api`,path:`src/api/tsconfig.json`},{name:`worker`,path:`src/api/worker/tsconfig.json`},{name:`web`,path:`src/web/tsconfig.json`},{name:`dashboard`,path:`dashboard/tsconfig.json`}];async function kc(){await mc({checkWorker:!0});let e=[];for(let t of Oc)try{await ve(t.path),e.push(t)}catch(e){if(!(e instanceof Error&&`code`in e&&e.code===`ENOENT`))throw e}let t=e.map(e=>Ye({name:e.name,command:Dc,args:[`-p`,e.path]})),n=(await Promise.all(t.map(e=>e.wait()))).filter(e=>e.exitCode!==0);n.length>0&&(q.exitCode=n[0].exitCode)}const Ac=n(a(Hs),{displayName:`feature`,from:async e=>e}),jc=n(a(Do),{displayName:`filtered|full`,from:async e=>e}),Mc=[`Cookies and sessions are origin-scoped.`,`Exact-host passkeys may require re-registration unless a stable eligible parent RP ID was configured in advance.`,`External OAuth callbacks such as Google may need updating.`,`Database data and private backend resources are unchanged.`],Nc=t({name:`deploy`,args:{environment:c({type:a(nt),displayName:`environment`,description:`Deploy to the staging or production environment.`}),runMigrations:r({long:`run-migrations`,description:`Run pending deploy-safe database migrations before deploying.`,defaultValue:()=>!1}),skipMigrations:r({long:`skip-migrations`,description:`Deploy without running pending deploy-safe database migrations.`,defaultValue:()=>!1}),skipPostDeployChecks:r({long:`skip-post-deploy-checks`,description:`Skip post-deploy checks after Cloudflare deployment.`,defaultValue:()=>!1}),yes:r({long:`yes`,short:`y`,description:`Approve the production deployment confirmation.`,defaultValue:()=>!1})},handler:({environment:e,runMigrations:t,skipMigrations:n,skipPostDeployChecks:r,yes:i})=>Da([e,...t?[`--run-migrations`]:[],...n?[`--skip-migrations`]:[],...r?[`--skip-post-deploy-checks`]:[],...i?[`--yes`]:[]])}),Pc=d({name:`staging`,cmds:{reassign:t({name:`reassign`,args:{json:r({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await ht();if(e){console.log(JSON.stringify({...t,notices:Mc}));return}console.log(t.url),console.error(`Staging hostname reassigned. ${Mc.join(` `)}`)}}),url:t({name:`url`,args:{json:r({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await it();console.log(e?JSON.stringify({url:t}):t)}})}}),Fc=d({name:`secrets`,cmds:{"rotate-access-token":t({name:`rotate-access-token`,args:{environment:c({type:a(nt),displayName:`environment`,description:`Worker environment whose access JWTs should be invalidated.`}),yes:r({long:`yes`,short:`y`,description:`Confirm immediate signing-secret replacement and invalidation of outstanding access JWTs.`,defaultValue:()=>!1})},handler:async({environment:e,yes:t})=>{if(!t)throw Error(`Access-token signing-secret rotation requires --yes because it immediately invalidates outstanding access JWTs.`);await yt({environment:e}),console.log(`Rotated Coreframe access-token signing material for ${e}. Clients must remint outstanding access JWTs.`)}}),status:t({name:`status`,args:{environment:c({type:s(a(nt)),displayName:`environment`,description:`Inspect staging, production, or both when omitted.`}),json:r({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({environment:e,json:t})=>{let n=await at({environment:e});console.log(t?JSON.stringify(n):Hc(n))}}),set:t({name:`set`,args:{environment:c({type:a(nt),displayName:`environment`,description:`Worker environment to update on its next deploy.`}),name:c({type:s(u),displayName:`name`,description:`Declared Worker secret name; omit to configure known secrets.`}),bulk:r({long:`bulk`,description:`Queue known secrets from pasted or piped dotenv-formatted contents.`,defaultValue:()=>!1})},handler:async({environment:e,name:t,bulk:n})=>{if(n&&t)throw Error(`Use either a secret name or --bulk, not both.`);if(t){await ut({environment:e,name:t,value:await Uc(t)}),console.log(`Queued ${t} for ${e}. Run coreframe deploy ${e} to apply.`);return}let r=await ft(),i=n?await Gc(r):await Wc(r,e);await dt({environment:e,values:i});let a=Object.keys(i).sort();console.log(a.length>0?`Queued ${a.join(`, `)} for ${e}. Run coreframe deploy ${e} to apply.`:`No ${e} Worker secret updates were queued.`)}}),discard:t({name:`discard`,args:{environment:c({type:a(nt),displayName:`environment`,description:`Worker environment with a queued secret update.`}),name:c({type:u,displayName:`name`,description:`Declared Worker secret name.`})},handler:async({environment:e,name:t})=>{let n=await rt({environment:e,name:t});console.log(n?`Discarded the queued ${t} update for ${e}.`:`No ${t} update is queued for ${e}.`)}})}}),Ic=t({name:`typecheck`,args:{},handler:kc}),Lc=d({name:`worker`,cmds:{typegen:t({name:`typegen`,args:{check:r({long:`check`,description:`Fail when the committed primary Worker declarations are stale.`,defaultValue:()=>!1})},handler:async({check:e})=>{let t=await ic({check:e});console.log(e?`${qc(t.path)} is current.`:`${qc(t.path)} ${t.changed?`generated`:`is unchanged`}.`)}})}}),Rc=t({name:`dev`,args:{debug:o({long:`debug`,type:s(Ac),description:`Launch a development feature in isolated debug mode.`}),flutterDebug:r({long:`flutter-debug`,description:`Run Flutter in debug mode instead of profile mode.`,defaultValue:()=>!1}),flutterOutput:o({long:`flutter-output`,type:jc,description:`Choose filtered Android diagnostics (default) or full standard Flutter output.`,defaultValue:()=>`filtered`}),https:r({long:`https`,description:`Serve the web app over locally trusted HTTPS.`,defaultValue:()=>!1}),fresh:r({long:`fresh`,description:`Start a new directory-scoped development session instead of attaching to one.`,defaultValue:()=>!1}),host:o({long:`host`,type:s(u),implicitValue:`0.0.0.0`,description:`Host address for the web development server. Pass without an address to use 0.0.0.0.`}),lan:r({long:`lan`,description:`Expose the Portless development proxy to devices on the local network.`,defaultValue:()=>!1}),managed:r({long:`managed`,description:`Run managed checkout synchronization even without an interactive terminal.`,defaultValue:()=>!1}),noManaged:r({long:`no-managed`,description:`Run without managed checkout synchronization for this invocation.`,defaultValue:()=>!1}),reuseVite:r({long:`reuse-vite`,description:`Use an existing Vite development server instead of starting another one for Flutter.`,defaultValue:()=>!1}),simulator:r({long:`simulator`,description:`Run iOS in Flutter debug mode on the Apple iOS Simulator.`,defaultValue:()=>!1}),stop:r({long:`stop`,description:`Stop the Vite development server for the selected platform.`,defaultValue:()=>!1}),platform:c({type:s(a(Vs)),displayName:`platform`,description:`Development target platform. Defaults to web.`}),device:c({type:s(u),displayName:`device`,description:`Device name or ID for iOS or Android development.`}),port:o({long:`port`,type:s(i),description:`Port for the web development server.`}),verbose:r({long:`verbose`,description:`Show the full native development output.`,defaultValue:()=>!1})},handler:({debug:e,device:t,fresh:n,flutterDebug:r,flutterOutput:i,host:a,https:o,lan:s,managed:c,noManaged:l,platform:u,port:d,reuseVite:f,simulator:p,stop:m,verbose:h})=>{if(m)return Mt({cwd:q.cwd(),resource:Bc(u??`web`)});let g=zc({device:t,flutterDebug:r,platform:u,simulator:p});return qs({debug:e,device:g.device,fresh:n,flutterDebug:g.flutterDebug,flutterOutput:i,host:a,https:o,lan:s,managed:c,noManaged:l,platform:u??`web`,reuseVite:f,verbose:h,webPort:d})}});function zc({device:e,flutterDebug:t,platform:n,simulator:r}){if(!r)return{device:e,flutterDebug:t};if(n!==`ios`)throw Error(`The --simulator flag is only supported for the iOS development target.`);if(e!==void 0)throw Error(`The --simulator flag cannot be combined with an explicit device.`);return{device:`apple_ios_simulator`,flutterDebug:!0}}function Bc(e){if(e===`web`)return`vite:web`;if(e===`ios`||e===`android`||e===`macos`||e===`windows`||e===`linux`)return`vite:flutter:${e}`;throw Error(`The --stop option is only supported for web, iOS, Android, macOS, Windows, and Linux development targets.`)}const Vc=t({name:`preview`,args:{host:o({long:`host`,type:s(u),description:`Host address for the preview server.`}),port:o({long:`port`,type:s(i),description:`Port for the preview server.`})},handler:({host:e,port:t})=>nc({host:e,port:t})});function Hc(e){if(e.entries.length===0)return`No Worker environment values are declared in coreframe.config.ts.`;let t=e.entries.map(e=>[e.name,e.kind,e.local===`override`?`override`:`built-in default`,e.deployed.staging.replaceAll(`_`,` `),e.deployed.production.replaceAll(`_`,` `)]),n=[`Name`,`Kind`,`Local`,`Staging`,`Production`],r=n.map((e,n)=>Math.max(e.length,...t.map(e=>e[n].length))),i=e=>e.map((e,t)=>e.padEnd(r[t])).join(` `).trimEnd();return[i(n),i(r.map(e=>`-`.repeat(e))),...t].join(`
|
|
29
|
+
`)}async function Uc(e){if(!q.stdin.isTTY){let e=``;for await(let t of q.stdin)e+=t.toString();return e.replace(/\r?\n$/,``)}let t=await V.password({message:`Enter the new value for ${e}`});if(V.isCancel(t))throw V.cancel(`Secret update cancelled.`),Error(`Secret update cancelled.`);return t}async function Wc(e,t){if(!q.stdin.isTTY)throw Error(`Interactive secret setup requires a terminal. Provide a secret name or use --bulk with piped dotenv contents.`);if(e.length===0)throw Error(`No Worker secrets are declared in coreframe.config.ts.`);let n={};for(let r of e){let e=r.requiredIn.includes(t),i=await V.password({message:`${r.name}: ${r.description}${e?` (required)`:` (optional; leave blank to skip)`}`,validate:n=>e&&!n?.trim()?`${r.name} is required in ${t}.`:void 0});if(V.isCancel(i))throw V.cancel(`Secret setup cancelled.`),Error(`Secret setup cancelled.`);i.trim()&&(n[r.name]=i)}return n}async function Gc(e){if(e.length===0)throw Error(`No Worker secrets are declared in coreframe.config.ts.`);let t=q.stdin.isTTY?await V.multiline({message:`Paste dotenv-formatted Worker secrets. Press Enter twice to submit.`,validate:e=>e?.trim()?void 0:`Paste at least one dotenv entry.`}):await Kc();if(V.isCancel(t))throw V.cancel(`Secret setup cancelled.`),Error(`Secret setup cancelled.`);let{ignoredNames:n,values:r}=ct(t,e);return n.length>0&&V.log.info(`Ignored non-secret or undeclared names: ${n.join(`, `)}.`),r}async function Kc(){let e=``;for await(let t of q.stdin)e+=t.toString();return e}function qc(e){return e.split(/[\\/]/).at(-1)??e}const Jc=t({name:`typegen`,description:`Generate Coreframe route and Worker type declarations.`,args:{},handler:async()=>{let e=await mc();for(let t of e)console.log(hc(t))}});function Yc(e,{formatMessage:t,temporaryDirectory:n=je(),write:r=e=>console.error(e)}={}){let i=tl(e),a=il(Zc(e,t),i);try{let t=I(He(I(n,`coreframe-error-`)),`error.log`);return qe(t,`${il(Qc(e),i)}\n`,{mode:384}),r(`Error: ${a}\nFull diagnostic: ${t}`),t}catch{r(`Error: ${a}\nThe full diagnostic could not be written to the temporary directory.`);return}}function Xc(t,n={}){let r=typeof t==`function`?t:()=>e.run(e.binary(t),process.argv),i=!1,a=e=>{i||(i=!0,Yc(e,n),process.exit(1))};process.once(`uncaughtException`,a),process.once(`unhandledRejection`,a),Promise.resolve().then(r).catch(a)}function Zc(e,t){try{return t?.(e)||(e instanceof Error?e.message:String(e)).split(/\r?\n/,1)[0]||`Unknown error`}catch{return`Unknown error`}}function Qc(e){try{let t=$c(e);if(!(e instanceof Error)||!el(t))return Nt(t,{customInspect:!1,depth:10});let n=typeof t.stack==`string`?t.stack:`${e.name}: ${e.message}`;return delete t.name,delete t.message,delete t.stack,`${n}${Reflect.ownKeys(t).length?`\n${Nt(t,{customInspect:!1,depth:10})}`:``}`}catch{return`The thrown value could not be inspected.`}}function $c(e,t=new WeakMap){if((typeof e!=`object`||!e)&&typeof e!=`function`)return e;let n=e,r=t.get(n);if(r)return r;if(typeof e==`function`)return`[Function${e.name?`: ${e.name}`:``}]`;let i=Array.isArray(e)?[]:{};t.set(n,i),e instanceof Error&&(i.name=e.name,i.message=e.message,i.stack=e.stack??`${e.name}: ${e.message}`);for(let r of Reflect.ownKeys(n)){if(typeof r!=`string`||r.toLowerCase()===`env`||Array.isArray(e)&&r===`length`||e instanceof Error&&(r===`name`||r===`message`||r===`stack`))continue;let a=Object.getOwnPropertyDescriptor(n,r);!a||!(`value`in a)||Object.defineProperty(i,r,{configurable:!0,enumerable:!0,value:$c(a.value,t),writable:!0})}return i}function el(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function tl(e,t=new WeakSet){let n=new Set;function r(e){if((typeof e!=`object`||!e)&&typeof e!=`function`)return;let i=e;if(!t.has(i)){t.add(i);for(let e of Reflect.ownKeys(i)){if(typeof e!=`string`)continue;let t=Object.getOwnPropertyDescriptor(i,e);!t||!(`value`in t)||(e.toLowerCase()===`env`?nl(t.value,n):r(t.value))}}}try{r(e)}catch{}return n}function nl(e,t){if(!(typeof e!=`object`||!e))for(let n of Reflect.ownKeys(e)){let r=Object.getOwnPropertyDescriptor(e,n);typeof n==`string`&&rl(n)&&r&&`value`in r&&typeof r.value==`string`&&r.value&&t.add(r.value)}}function rl(e){return/(?:^|_)(?:AUTH|CERT|COOKIE|CREDENTIALS?|DATABASE_URL|DSN|KEY|PASS(?:WORD)?|PRIVATE|SECRET|SESSION|TOKEN)(?:_|$)/i.test(e)}function il(e,t){return[...t].sort((e,t)=>t.length-e.length).reduce((e,t)=>e.replaceAll(t,`[redacted environment value]`),e)}const al=d({name:`coreframe`,cmds:{build:en,dashboard:Or,assets:or,flutter:sr,i18n:cr,deploy:Nc,staging:Pc,secrets:Fc,typegen:Jc,typecheck:Ic,worker:Lc,dev:Rc,preview:Vc,upgrade:Ca,recipes:wa,db:Ta}});import.meta.main&&Xc(al,{formatMessage:process.argv[2]===`db`?b:void 0});export{al as coreframeCli};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coreframe/scripts",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.21",
|
|
4
4
|
"description": "Coreframe project workflow CLI and automation scripts",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
"nano-spawn": "^2.1.0",
|
|
29
29
|
"procband": "^0.3.8",
|
|
30
30
|
"yaml": "^2.9.0",
|
|
31
|
-
"@coreframe/assets": "^0.1.
|
|
32
|
-
"@coreframe/config": "^0.1.
|
|
33
|
-
"@coreframe/db": "^0.1.
|
|
34
|
-
"@coreframe/deploy": "^0.1.
|
|
35
|
-
"@coreframe/dev": "^0.1.
|
|
31
|
+
"@coreframe/assets": "^0.1.11",
|
|
32
|
+
"@coreframe/config": "^0.1.8",
|
|
33
|
+
"@coreframe/db": "^0.1.9",
|
|
34
|
+
"@coreframe/deploy": "^0.1.8",
|
|
35
|
+
"@coreframe/dev": "^0.1.12",
|
|
36
36
|
"@coreframe/dev-contracts": "^0.1.5",
|
|
37
|
-
"@coreframe/flutter-tools": "^0.1.
|
|
38
|
-
"@coreframe/object-storage": "^0.1.
|
|
39
|
-
"@coreframe/preview": "^0.1.
|
|
37
|
+
"@coreframe/flutter-tools": "^0.1.15",
|
|
38
|
+
"@coreframe/object-storage": "^0.1.4",
|
|
39
|
+
"@coreframe/preview": "^0.1.8"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/node": "^26.1.0",
|