@multiplatform.one/cli 6.6.0 → 7.0.0

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.
Files changed (47) hide show
  1. package/README.md +83 -8
  2. package/lib/bin/multiplatformOne.mjs +21 -7
  3. package/lib/commands/adoptApp.mjs +127 -0
  4. package/lib/commands/init.mjs +1 -1
  5. package/lib/commands/initApp.mjs +43 -15
  6. package/lib/commands/updateApp.mjs +84 -15
  7. package/package.json +3 -3
  8. package/scripts/frappe-app-name.py +125 -0
  9. package/scripts/frappe-app-name.spec.ts +191 -0
  10. package/scripts/frappe-bootstrap.sh +8 -30
  11. package/src/bin/multiplatformOne.ts +78 -13
  12. package/src/commands/adoptApp.spec.ts +208 -0
  13. package/src/commands/adoptApp.ts +185 -0
  14. package/src/commands/initApp.spec.ts +152 -12
  15. package/src/commands/initApp.ts +95 -21
  16. package/src/commands/updateApp.spec.ts +314 -2
  17. package/src/commands/updateApp.ts +164 -33
  18. package/templates/app/apps/__NAME__/package.json +3 -2
  19. package/templates/app/features/__NAME__/package.json +2 -2
  20. package/templates/app/packages/config/package.json +1 -1
  21. package/templates/pieces/gnome/universal/README.md.partial +5 -5
  22. package/templates/pieces/gnome/universal/apps/__NAME__/gnome/anchor.tsx +39 -0
  23. package/templates/pieces/gnome/universal/apps/__NAME__/gnome/main.tsx +4 -2
  24. package/templates/pieces/gnome/universal/apps/__NAME__/gnome/shims/components.ts +26 -0
  25. package/templates/pieces/gnome/universal/apps/__NAME__/gnome/shims/forms.ts +26 -0
  26. package/templates/pieces/gnome/universal/apps/__NAME__/gnome/shims/frappe-ui.ts +17 -0
  27. package/templates/pieces/gnome/universal/apps/__NAME__/gnome/shims/one.ts +3 -0
  28. package/templates/pieces/gnome/universal/apps/__NAME__/gnome/shims/theme.ts +21 -0
  29. package/templates/pieces/gnome/universal/apps/__NAME__/gnome/tamagui-barrel.ts +21 -0
  30. package/templates/pieces/gnome/universal/apps/__NAME__/vite.config.gnome.ts +49 -7
  31. package/templates/pieces/keycloak/universal/README.md.partial +13 -0
  32. package/templates/pieces/keycloak/universal/docker/compose.keycloak.yaml +19 -3
  33. package/templates/pieces/keycloak/universal/env.example.partial +4 -1
  34. package/templates/pieces/vscode/universal/apps/__NAME__/package.json.partial +1 -1
  35. package/templates/pieces/webext/universal/apps/__NAME__/package.json.partial +2 -2
  36. package/templates/universal/apps/__NAME__/package.json +4 -3
  37. package/templates/universal/features/__NAME__/package.json +1 -1
  38. package/templates/universal/packages/config/package.json +1 -1
  39. package/templates/universal/packages/i18n/package.json +1 -1
  40. package/templates/universal/packages/themes/package.json +3 -3
  41. package/types/bin/multiplatformOne.d.ts.map +1 -1
  42. package/types/commands/adoptApp.d.ts +25 -0
  43. package/types/commands/adoptApp.d.ts.map +1 -0
  44. package/types/commands/initApp.d.ts +33 -5
  45. package/types/commands/initApp.d.ts.map +1 -1
  46. package/types/commands/updateApp.d.ts +12 -2
  47. package/types/commands/updateApp.d.ts.map +1 -1
@@ -8,15 +8,18 @@
8
8
  // THIS IS NOT A VARIANT OF THE WEB BUILD. The web target is One (file
9
9
  // router, SSR, react-native-web); this one is a plain Vite library build
10
10
  // whose output GJS executes directly, rendering REAL GTK4 widgets through
11
- // react-gnome — no webview, no DOM. That is the whole difference from the
12
- // tauri piece, which ships the web build inside a system webview.
11
+ // react-gnome — no webview, no DOM.
13
12
  //
14
13
  // The generic react-gnome settings (aliases, conditions, define, React
15
14
  // dedupe, .native.* extensions) come from @react-gnome/vite-plugin; the
16
15
  // Tamagui-under-GJS bundle patches come from
17
16
  // @multiplatform.one/vite-plugin-gnome.
18
17
 
19
- import { tamaguiLinkedAliases, tamaguiPlugin } from "@multiplatform.one/vite-plugin-gnome";
18
+ import {
19
+ gnomePlatformExtensions,
20
+ tamaguiLinkedAliases,
21
+ tamaguiPlugin,
22
+ } from "@multiplatform.one/vite-plugin-gnome";
20
23
  import {
21
24
  gnomeConditions,
22
25
  gnomeDedupe,
@@ -25,6 +28,7 @@ import {
25
28
  gnomeLinkedAliases,
26
29
  } from "@react-gnome/vite-plugin";
27
30
  import react from "@vitejs/plugin-react";
31
+ import { existsSync } from "node:fs";
28
32
  import { createRequire } from "node:module";
29
33
  import { dirname, resolve } from "node:path";
30
34
  import type { Plugin } from "vite";
@@ -42,6 +46,23 @@ function pkgDir(id: string): string {
42
46
  return dirname(require.resolve(`${id}/package.json`));
43
47
  }
44
48
 
49
+ /** The installed @react-gnome scope directory. Under pnpm's default
50
+ * isolated linker it sits in THIS app's node_modules; under
51
+ * `node-linker=hoisted` (this scaffold's .npmrc) everything hoists to
52
+ * the workspace root and the app-local dir never exists. Walk upward to
53
+ * whichever node_modules actually holds the scope — require.resolve
54
+ * can't do this lookup because the @react-gnome packages' export maps
55
+ * hide package.json. */
56
+ function reactGnomeScopeDir(): string {
57
+ for (let dir = import.meta.dirname; ; ) {
58
+ const candidate = resolve(dir, "node_modules/@react-gnome");
59
+ if (existsSync(candidate)) return candidate;
60
+ const parent = dirname(dir);
61
+ if (parent === dir) throw new Error("@react-gnome scope not found in any node_modules");
62
+ dir = parent;
63
+ }
64
+ }
65
+
45
66
  /** Stub real-RN Flow internals and the expo surface. A dependency that
46
67
  * deep-imports `react-native/Libraries/...` slips past the package-root
47
68
  * alias, and the bundler cannot parse RN's Flow sources; expo modules
@@ -68,7 +89,20 @@ export default defineConfig({
68
89
  resolve: {
69
90
  conditions: [...gnomeConditions],
70
91
  alias: [
71
- ...gnomeLinkedAliases(resolve(import.meta.dirname, "node_modules/@react-gnome")),
92
+ // gnomeLinkedAliases points the renderer at its SOURCE entry — right
93
+ // for a link:ed react-gnome checkout whose dist is a stale gitignored
94
+ // build, wrong for the registry tarball, which ships dist ONLY
95
+ // (files: ["dist", …]). First alias match wins, so prepend the dist
96
+ // fallback when there is no src to point at.
97
+ ...(existsSync(resolve(reactGnomeScopeDir(), "renderer/src/index.ts"))
98
+ ? []
99
+ : [
100
+ {
101
+ find: /^@react-gnome\/renderer$/,
102
+ replacement: resolve(reactGnomeScopeDir(), "renderer/dist/index.js"),
103
+ },
104
+ ]),
105
+ ...gnomeLinkedAliases(reactGnomeScopeDir()),
72
106
  // `tamagui` meta-package → a lean barrel re-exporting only the
73
107
  // granular @tamagui/* packages this app's graph reaches. The full
74
108
  // meta-barrel drags web-only components into the GJS bundle.
@@ -82,6 +116,10 @@ export default defineConfig({
82
116
  },
83
117
  { find: /^@multiplatform\.one\/theme$/, replacement: resolve(gnomeDir, "shims/theme.ts") },
84
118
  { find: /^@multiplatform\.one\/forms$/, replacement: resolve(gnomeDir, "shims/forms.ts") },
119
+ {
120
+ find: /^@multiplatform\.one\/frappe-ui$/,
121
+ replacement: resolve(gnomeDir, "shims/frappe-ui.ts"),
122
+ },
85
123
  // One's file router never mounts on GJS (react-native-screens is a
86
124
  // native-fabric dead end). The shim backs the router API the
87
125
  // screens consume with the framework's navigator seam.
@@ -98,9 +136,13 @@ export default defineConfig({
98
136
  // and react-reconciler copies; dedupe forces every import (including
99
137
  // react-reconciler's CJS require) to this app's root.
100
138
  dedupe: [...gnomeDedupe],
101
- // Metro-style resolution: prefer `.native.*` so platform-split
102
- // modules pick their native variant under GNOME.
103
- extensions: [...gnomeExtensions],
139
+ // Metro-style platform resolution. `.gnome.*` goes FIRST so a module
140
+ // that ships a real GNOME implementation wins — this registration is
141
+ // what makes @multiplatform.one/platform's `isGnome` true rather than a
142
+ // flag nothing ever sets. `.native.*` stays behind it as the fallback
143
+ // for modules that only split web/native (GTK legitimately reports
144
+ // isNative).
145
+ extensions: [...gnomePlatformExtensions, ...gnomeExtensions],
104
146
  },
105
147
  define: gnomeDefine(nodeEnv),
106
148
  build: {
@@ -17,3 +17,16 @@ First boot imports `docker/keycloak/realm.json`: realm `__NAME__` with the
17
17
  two clients above and a `dev` / `dev` user. The admin console lives at
18
18
  http://localhost:8080/auth (admin / admin) — manage users, clients, and
19
19
  flows there, or edit the realm import stub and recreate the volume.
20
+
21
+ Port 8080 is the most contested port on a dev machine. If something
22
+ already owns it, move the host mapping and keep `.env` in step:
23
+
24
+ ```bash
25
+ KEYCLOAK_HTTP_PORT=8081 docker compose -f docker/compose.keycloak.yaml up -d
26
+ # then set KEYCLOAK_BASE_URL=http://localhost:8081/auth in .env
27
+ ```
28
+
29
+ Do not reach for a yaml `!override` on `ports` in a second compose file
30
+ instead: compose versions without that tag drop the whole ports list
31
+ silently, and the container comes up healthy, realm imported, and
32
+ unreachable from the host.
@@ -5,7 +5,8 @@
5
5
  # start-dev uses the embedded dev database (persisted in the named volume)
6
6
  # and imports docker/keycloak/realm.json on first boot — realm "__NAME__"
7
7
  # with the clients the KEYCLOAK_* env keys reference, plus a dev/dev user.
8
- # Admin console: http://localhost:8080/auth (admin/admin).
8
+ # Admin console: http://localhost:8080/auth (admin/admin) — port movable
9
+ # via KEYCLOAK_HTTP_PORT; keep KEYCLOAK_BASE_URL in .env in step.
9
10
  services:
10
11
  keycloak:
11
12
  image: quay.io/keycloak/keycloak:26.6
@@ -18,10 +19,25 @@ services:
18
19
  # /auth keeps parity with KEYCLOAK_BASE_URL (and reverse-proxy setups).
19
20
  KC_HTTP_RELATIVE_PATH: /auth
20
21
  ports:
21
- - "8080:8080"
22
+ # Host port is parameterized because :8080 is the single most
23
+ # contested port on a dev machine (another Keycloak, another Tomcat,
24
+ # another anything). A yaml !override in a second compose file is NOT
25
+ # a reliable replacement — compose versions that don't support the
26
+ # tag drop the whole ports list silently and the container comes up
27
+ # healthy but unreachable (measured 2026-08-13).
28
+ - "${KEYCLOAK_HTTP_PORT:-8080}:8080"
22
29
  volumes:
23
30
  - ./keycloak/realm.json:/opt/keycloak/data/import/realm.json:ro
24
- - keycloak:/opt/keycloak/data/h2
31
+ # The volume mounts at data/, NOT data/h2: the image ships no h2/
32
+ # subdirectory, so a mount there is created root-owned and Keycloak
33
+ # (uid 1000) dies at boot unable to open its own database — H2 90028,
34
+ # "Could not open file /opt/keycloak/data/h2/keycloakdb.mv.db",
35
+ # measured 2026-08-13 on quay.io/keycloak/keycloak:26.6. It reads
36
+ # like corruption and survives `down -v`, because the wipe recreates
37
+ # the same root-owned mount point. data/ exists in the image with
38
+ # keycloak ownership, so Docker seeds the volume correctly; the realm
39
+ # bind above simply layers inside it.
40
+ - keycloak:/opt/keycloak/data
25
41
 
26
42
  volumes:
27
43
  keycloak: {}
@@ -2,7 +2,10 @@
2
2
  # mounts the KeycloakProvider wired in apps/__NAME__/src/app.ts; the other
3
3
  # keys must match the realm import (docker/keycloak/realm.json).
4
4
  KEYCLOAK_ENABLED=1
5
- # Auth server base URL (docker/compose.keycloak.yaml serves /auth on :8080).
5
+ # Auth server base URL. The dev compose serves /auth on host port 8080 by
6
+ # default; if 8080 is taken, start it with KEYCLOAK_HTTP_PORT=<port> (see
7
+ # docker/compose.keycloak.yaml) and move the port HERE too — nothing
8
+ # checks the two agree.
6
9
  KEYCLOAK_BASE_URL=http://localhost:8080/auth
7
10
  KEYCLOAK_REALM=__NAME__
8
11
  KEYCLOAK_CLIENT_ID=__NAME__
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "devDependencies": {
12
12
  "@multiplatform.one/vite-plugin-vscode": "__MPO_VERSION__",
13
- "@tamagui/vite-plugin": "2.0.0-rc.41",
13
+ "@tamagui/vite-plugin": "2.7.6",
14
14
  "@tomjs/vite-plugin-vscode": "^7.1.1",
15
15
  "@types/node": "^25.6.0",
16
16
  "@types/vscode": "^1.118.0",
@@ -12,8 +12,8 @@
12
12
  "devDependencies": {
13
13
  "@multiplatform.one/utils": "__MPO_VERSION__",
14
14
  "@multiplatform.one/vite-plugin-webext": "__MPO_VERSION__",
15
- "@tamagui/vite-plugin": "2.0.0-rc.41",
16
- "@tamagui/web": "2.0.0-rc.41",
15
+ "@tamagui/vite-plugin": "2.7.6",
16
+ "@tamagui/web": "2.7.6",
17
17
  "@types/chrome": "^0.2.5",
18
18
  "@types/node": "^25.6.0",
19
19
  "dotenv": "^17.4.2",
@@ -7,7 +7,7 @@
7
7
  "dev": "one dev --port 3456",
8
8
  "build": "one build",
9
9
  "serve": "one serve",
10
- "typecheck": "tsc --noEmit",
10
+ "typecheck": "tsgo --noEmit",
11
11
  "prebuild:native": "one prebuild",
12
12
  "prebuild:ios": "one prebuild --platform ios",
13
13
  "prebuild:android": "one prebuild --platform android",
@@ -28,7 +28,7 @@
28
28
  "@package/i18n": "workspace:*",
29
29
  "@package/themes": "workspace:*",
30
30
  "@react-navigation/native": "~7.2.2",
31
- "@tamagui/core": "2.0.0-rc.41",
31
+ "@tamagui/core": "2.7.6",
32
32
  "@tanstack/react-query": "^5.100.7",
33
33
  "@tanstack/react-query-devtools": "^5.100.7",
34
34
  "@tanstack/react-virtual": "^3.13.24",
@@ -47,13 +47,14 @@
47
47
  "react-native-web": "^0.21.2",
48
48
  "react-native-worklets": "~0.7.4",
49
49
  "shiki": "^4.0.2",
50
- "tamagui": "2.0.0-rc.41",
50
+ "tamagui": "2.7.6",
51
51
  "text-encoding-utf-8": "^1.0.2"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@multiplatform.one/config": "__MPO_VERSION__",
55
55
  "@react-native-community/cli": "^20.1.3",
56
56
  "@types/react": "~19.2.14",
57
+ "@typescript/native-preview": "^7.0.0-dev.20260707.2",
57
58
  "@vitejs/plugin-react": "^6.0.2",
58
59
  "typescript": "~5.9.3",
59
60
  "vite": "^8.0.10"
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "scripts": {
12
12
  "test": "vitest run",
13
- "typecheck": "tsc --noEmit"
13
+ "typecheck": "tsgo --noEmit"
14
14
  },
15
15
  "dependencies": {
16
16
  "@multiplatform.one/components": "__MPO_VERSION__",
@@ -9,7 +9,7 @@
9
9
  "./config.json": "./config.json"
10
10
  },
11
11
  "scripts": {
12
- "typecheck": "tsc --noEmit"
12
+ "typecheck": "tsgo --noEmit"
13
13
  },
14
14
  "devDependencies": {
15
15
  "typescript": "~5.9.3"
@@ -9,7 +9,7 @@
9
9
  "./resources": "./resources.ts"
10
10
  },
11
11
  "scripts": {
12
- "typecheck": "tsc --noEmit"
12
+ "typecheck": "tsgo --noEmit"
13
13
  },
14
14
  "dependencies": {
15
15
  "@multiplatform.one/i18n": "__MPO_VERSION__"
@@ -10,12 +10,12 @@
10
10
  "./tamagui.config": "./tamagui.config.ts"
11
11
  },
12
12
  "scripts": {
13
- "typecheck": "tsc --noEmit"
13
+ "typecheck": "tsgo --noEmit"
14
14
  },
15
15
  "dependencies": {
16
16
  "@multiplatform.one/theme": "__MPO_VERSION__",
17
- "@tamagui/font-inter": "2.0.0-rc.41",
18
- "tamagui": "2.0.0-rc.41"
17
+ "@tamagui/font-inter": "2.7.6",
18
+ "tamagui": "2.7.6"
19
19
  },
20
20
  "devDependencies": {
21
21
  "typescript": "~5.9.3"
@@ -1 +1 @@
1
- {"version":3,"file":"multiplatformOne.d.ts","sourceRoot":"","sources":["../../src/bin/multiplatformOne.ts"],"names":[],"mappings":"AA2FA,gHAAgH;AAChH,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,kGAAkG;IAClG,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gGAAgG;IAChG,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,CAAC"}
1
+ {"version":3,"file":"multiplatformOne.d.ts","sourceRoot":"","sources":["../../src/bin/multiplatformOne.ts"],"names":[],"mappings":"AA4FA,gHAAgH;AAChH,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,kGAAkG;IAClG,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gGAAgG;IAChG,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * `mpo adopt` — bring an EXISTING, never-scaffolded project under `mpo
3
+ * update` management. Projects like this hand-copied one or more delivery
4
+ * targets (webext, gnome, …) from the mpo templates and consume
5
+ * @multiplatform.one/* from npm, but have no .mpo.json provenance, so
6
+ * `mpo update` refuses to run.
7
+ *
8
+ * Adoption writes provenance ONLY (template "none" + the chosen pieces +
9
+ * the current CLI version) and seeds .updateignore — it never rewrites a
10
+ * project file. The FIRST `mpo update` afterwards reconciles the piece
11
+ * files against the piece templates from an empty merge base, so real
12
+ * diffs (and conflicts) against hand-copied files are expected there;
13
+ * every later update is an ordinary three-way merge.
14
+ */
15
+ import { type InitAppPiece } from "./initApp";
16
+ export interface AdoptAppOptions {
17
+ /** Pieces the project hand-adopted (at least one is required). */
18
+ pieces?: InitAppPiece[];
19
+ /** Project name (default: package.json name, scope stripped). */
20
+ name?: string;
21
+ /** Non-interactive: never prompt (pieces must come from flags). */
22
+ yes?: boolean;
23
+ }
24
+ export declare function adoptApp(options?: AdoptAppOptions): Promise<void>;
25
+ //# sourceMappingURL=adoptApp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adoptApp.d.ts","sourceRoot":"","sources":["../../src/commands/adoptApp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,EAUL,KAAK,YAAY,EAClB,MAAM,WAAW,CAAC;AAEnB,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IACxB,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAuDD,wBAAsB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0F3E"}
@@ -6,6 +6,14 @@
6
6
  * (apps/<name> + features/<name> + packages/config)
7
7
  */
8
8
  export type InitAppTemplate = "universal" | "app";
9
+ /**
10
+ * The provenance template domain: the scaffold templates plus "none" for
11
+ * ADOPTED projects (`mpo adopt`) — existing repos that were never scaffolded.
12
+ * A "none" scaffold is the selected piece fragments overlaid on an EMPTY
13
+ * tree (no universal/app base), which is exactly the tool-owned surface of
14
+ * an adopted project.
15
+ */
16
+ export type ProvenanceTemplate = InitAppTemplate | "none";
9
17
  /**
10
18
  * Optional composable pieces overlaid onto the base template (additive
11
19
  * fragments under templates/pieces/<piece>/ — the inverse of the old
@@ -21,8 +29,13 @@ export interface InitAppOptions {
21
29
  skipGit?: boolean;
22
30
  /** Pin @multiplatform.one/* to this semver range. Default: ^<cli version>. */
23
31
  version?: string;
24
- /** Project template. When omitted: prompt (interactive) or "universal". */
25
- template?: InitAppTemplate;
32
+ /**
33
+ * Project template. When omitted: prompt (interactive) or "universal".
34
+ * "none" scaffolds ONLY the selected pieces onto an empty tree (the
35
+ * `--pieces-only` flag) — `mpo update` uses it to rebuild the merge
36
+ * baselines of adopted projects.
37
+ */
38
+ template?: ProvenanceTemplate;
26
39
  /** Accept defaults instead of prompting (non-interactive / CI). */
27
40
  yes?: boolean;
28
41
  /**
@@ -31,6 +44,10 @@ export interface InitAppOptions {
31
44
  */
32
45
  pieces?: InitAppPiece[];
33
46
  }
47
+ export declare function validateName(name: string): string;
48
+ /** Root package.json name with any @scope/ prefix stripped (adopt +
49
+ * update-bootstrap provenance name derivation). */
50
+ export declare function packageJsonName(projectDir: string): string | undefined;
34
51
  export declare function cliVersion(): string | undefined;
35
52
  /**
36
53
  * Scaffold provenance (the copier-answers equivalent): which template, which
@@ -39,12 +56,21 @@ export declare function cliVersion(): string | undefined;
39
56
  * three-way template update.
40
57
  */
41
58
  export interface MpoProvenance {
42
- template: InitAppTemplate;
59
+ /** "none" = adopted project (`mpo adopt`): pieces only, no base template. */
60
+ template: ProvenanceTemplate;
43
61
  cliVersion: string;
44
62
  name: string;
45
63
  mpoVersion: string;
46
64
  /** Composable pieces overlaid at init time (sorted). */
47
65
  pieces: InitAppPiece[];
66
+ /**
67
+ * false = adopted but never reconciled: `mpo adopt` wrote provenance
68
+ * without touching any project file, so no tool-owned content exists yet.
69
+ * The first `mpo update` merges the piece baseline from an EMPTY base
70
+ * (surfacing real diffs against hand-copied files) and then clears the
71
+ * flag. Absent/true = the tree carries the recorded scaffold.
72
+ */
73
+ reconciled?: boolean;
48
74
  }
49
75
  export declare const PROVENANCE_FILE = ".mpo.json";
50
76
  export declare function writeProvenance(targetDir: string, provenance: MpoProvenance): void;
@@ -65,9 +91,11 @@ export declare function mergeJsonValues(base: JsonValue, fragment: JsonValue): J
65
91
  * order must be deterministic), and every piece must ship a fragment for the
66
92
  * chosen template.
67
93
  */
68
- export declare function normalizePieces(pieces: string[], template: InitAppTemplate): InitAppPiece[];
94
+ export declare function normalizePieces(pieces: string[], template: ProvenanceTemplate): InitAppPiece[];
69
95
  /** Pieces that can be offered for a template (fragment exists for it). */
70
- export declare function availablePieces(template: InitAppTemplate): InitAppPiece[];
96
+ export declare function availablePieces(template: ProvenanceTemplate): InitAppPiece[];
97
+ /** Human-readable piece summaries (adopt + init prompts). */
98
+ export declare function pieceDescription(piece: InitAppPiece): string;
71
99
  /**
72
100
  * Generate apps/<name>/src/app.ts for the selected backend pieces instead of
73
101
  * storing 2^n template variants: each selected provider adds one createApp
@@ -1 +1 @@
1
- {"version":3,"file":"initApp.d.ts","sourceRoot":"","sources":["../../src/commands/initApp.ts"],"names":[],"mappings":"AAaA;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,KAAK,CAAC;AAElD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,uEAOlB,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAW5D,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,mEAAmE;IACnE,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;CACzB;AA0CD,wBAAgB,UAAU,IAAI,MAAM,GAAG,SAAS,CAQ/C;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,eAAe,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,eAAO,MAAM,eAAe,cAAc,CAAC;AAE3C,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,GAAG,IAAI,CAKlF;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAiB5E;AAiFD,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAM/F;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,GAAG,SAAS,CAoB/E;AAoFD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,eAAe,GAAG,YAAY,EAAE,CAe3F;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe,GAAG,YAAY,EAAE,CAEzE;AA2BD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAyC3D;AAoBD;;;;GAIG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAqJf"}
1
+ {"version":3,"file":"initApp.d.ts","sourceRoot":"","sources":["../../src/commands/initApp.ts"],"names":[],"mappings":"AAaA;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,KAAK,CAAC;AAElD;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,eAAe,GAAG,MAAM,CAAC;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,eAAe,uEAOlB,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAW5D,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,mEAAmE;IACnE,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;CACzB;AAmBD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWjD;AAED;oDACoD;AACpD,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAStE;AAYD,wBAAgB,UAAU,IAAI,MAAM,GAAG,SAAS,CAQ/C;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,6EAA6E;IAC7E,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,eAAe,cAAc,CAAC;AAE3C,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,GAAG,IAAI,CAKlF;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAmB5E;AAoFD,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAM/F;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,GAAG,SAAS,CAoB/E;AAoFD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,kBAAkB,GAAG,YAAY,EAAE,CAe9F;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,QAAQ,EAAE,kBAAkB,GAAG,YAAY,EAAE,CAE5E;AAED,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAE5D;AA2BD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAyC3D;AAoBD;;;;GAIG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAiLf"}
@@ -11,14 +11,24 @@
11
11
  *
12
12
  * `git merge-tree --write-tree --merge-base=<base>` merges template
13
13
  * evolution with your customizations; conflicts land in the worktree with
14
- * normal conflict markers. An `.updateignore` file (one pathspec per line)
15
- * pins matching paths to your HEAD version, exactly like the old script.
14
+ * normal conflict markers. An `.updateignore` file (one exact file or
15
+ * directory prefix per line not globs; `dir/**` is normalized, other
16
+ * glob shapes are refused) pins matching paths to your HEAD version.
16
17
  */
18
+ import { type InitAppTemplate } from "./initApp";
17
19
  export interface UpdateAppOptions {
18
20
  /** Skip pnpm install after the merge. */
19
21
  skipInstall?: boolean;
20
22
  /** Override the semver range written for @multiplatform.one/* deps. */
21
23
  version?: string;
24
+ /**
25
+ * Pre-provenance bootstrap: when .mpo.json is missing, assume the project
26
+ * was scaffolded by this exact CLI version, write provenance first, then
27
+ * proceed with the normal update.
28
+ */
29
+ assumeVersion?: string;
30
+ /** Template recorded by the --assume-version bootstrap (default universal). */
31
+ assumeTemplate?: InitAppTemplate;
22
32
  }
23
33
  /** Structural three-way merge of package.json content. Returns the merged
24
34
  * object, or undefined when a divergence can't be auto-resolved (the file
@@ -1 +1 @@
1
- {"version":3,"file":"updateApp.d.ts","sourceRoot":"","sources":["../../src/commands/updateApp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AASH,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAyPD;;sEAEsE;AACtE,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAerC;AA2DD,wBAAsB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkP7E"}
1
+ {"version":3,"file":"updateApp.d.ts","sourceRoot":"","sources":["../../src/commands/updateApp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAOH,OAAO,EASL,KAAK,eAAe,EAGrB,MAAM,WAAW,CAAC;AAEnB,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,eAAe,CAAC;CAClC;AA2QD;;sEAEsE;AACtE,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAerC;AAyGD,wBAAsB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgS7E"}