ozmoz 0.1.45 → 0.1.47

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 (3) hide show
  1. package/README.md +59 -163
  2. package/dist/cli.cjs +10 -10
  3. package/package.json +2 -1
package/README.md CHANGED
@@ -1,230 +1,126 @@
1
1
  # OZmoz
2
2
 
3
- ### The Client-Side Data OS for Modern Web Apps & AI Vibe-Coding
3
+ **The Data OS for AI agents.** A ready-to-use backend for any application, and Alex AI to count, calculate and present your data in plain language.
4
4
 
5
- OZmoz manages the complete application data lifecycle: from AI-assisted schema modeling (Alex AI DBA) to deterministic Edge enforcement and seamless client-side execution.
5
+ OZmoz is a deterministic and secure software layer on top of MongoDB. Your AI agent builds the interface; OZmoz gives it a backend that is modeled once, sealed, and enforced.
6
6
 
7
- Like an architect drafting blueprints before construction begins, Alex AI models your business domain and spins up an instant, production-ready backend. OZmoz delivers relational integrity, strict typing, and Edge security to MongoDB Atlas without writing backend boilerplate.
7
+ ## Why OZmoz
8
8
 
9
- ---
10
-
11
- <!-- STREAMING_CHUNK:Documenting core value propositions... -->
12
-
13
- ## Why OZmoz?
14
-
15
- - **100% Frontend Focus**: Zero servers, zero custom REST APIs, and zero SQL migrations. Build full-stack applications purely from the client.
16
- - **AI Agent Accelerator**: Eliminates hallucinations and cuts token usage by 90% via deterministic contracts (`svro.schema.json`, `svro.workflow.json`). Agents (Claude Code, Cursor, Windsurf) focus 100% of their reasoning on UX.
17
- - **Deterministic Edge Gatekeeper**: Sub-millisecond $O(1)$ schema validation at the cloud edge before writes hit the database.
18
- - **Zero-Crash Native Web Components**: 7 built-in, framework-agnostic Custom Elements (`<oz-*>`) preventing white-screen crashes on missing or partial data.
19
- - **Zero-Rewrite Philosophy**: Write the exact same frontend code in trial mode (`OZ_PROTOTYPE=true`) and production (`OZ_PROTOTYPE=false`).
20
-
21
- ---
22
-
23
- <!-- STREAMING_CHUNK:Documenting installation and setup commands... -->
24
-
25
- ## Quick Start
9
+ - **Frontend focus**: no server to run, no REST API to write, no SQL migrations.
10
+ - **Built for AI agents**: your agent spends its effort on the UI and UX instead of backend plumbing. Works with Claude Code, Cursor, Codex, Windsurf, GitHub Copilot, Gemini CLI, Antigravity and more.
11
+ - **A sealed data contract**: Alex AI models your data, you validate it, and the contract is sealed. Reads and writes then follow that contract.
12
+ - **Zero-crash components**: seven native `<oz-*>` web components that handle missing or partial data without breaking the screen.
13
+ - **Zero-rewrite**: write the same code in trial mode and in live mode.
14
+ - **Talk to your data**: ask Alex questions in plain language. No SQL, no BI tool to set up.
26
15
 
27
- ### 1. New Project with an AI Agent
16
+ ## Quick start
28
17
 
29
- Let your terminal AI agent build the project for you:
18
+ ### New project with an AI agent
30
19
 
31
20
  ```bash
32
- npx ozmoz start claude "Your application idea"
21
+ npx -y ozmoz start claude "your app idea"
33
22
  ```
34
23
 
35
- Or configure your environment and MCP server:
24
+ Or connect your agent once, then work as usual:
36
25
 
37
26
  ```bash
38
- npx ozmoz login # Authenticate once in your browser
39
- npx ozmoz mcp # Generates AGENTS.md, CLAUDE.md, GEMINI.md and MCP settings
27
+ npx ozmoz login # approve once in the browser
28
+ npx ozmoz mcp # writes AGENTS.md / CLAUDE.md / GEMINI.md and configures the MCP server
40
29
  ```
41
30
 
42
- ### 2. Integration into an Existing Frontend
43
-
44
- Install the package in your Vite project:
31
+ ### Existing frontend project
45
32
 
46
33
  ```bash
47
34
  npm install ozmoz
48
- npx ozmoz init --keyApp=<APP_KEY> --token=<BOOTSTRAP_TOKEN>
49
- npx ozmoz sync
35
+ npx ozmoz init --keyApp=<KEY> --token=<TOKEN>
36
+ npx ozmoz sync # seals the contract and generates the IDE types
50
37
  ```
51
38
 
52
- ---
53
-
54
- <!-- STREAMING_CHUNK:Documenting execution modes and environment configuration... -->
39
+ Use `npx ozmoz sync --check-only` for an offline check.
55
40
 
56
- ## Execution Modes (`.env`)
41
+ ## Modes
57
42
 
58
- Configure your operational mode in `.env`:
43
+ Set the mode in `.env`:
59
44
 
60
- ```env
61
- # Trial / Sandbox mode: all operations are simulated locally with demo data (oz.seed).
62
- # Test code for authentication is always: 0000
45
+ ```bash
46
+ # Trial mode: everything is simulated locally with demo data (oz.seed).
47
+ # The test code for authentication is always 0000.
63
48
  OZ_PROTOTYPE=true
64
49
 
65
- # Live mode: enforced physical schema, Edge security, and real database persistence.
50
+ # Live mode: the data contract is enforced on your real data.
66
51
  OZ_PROTOTYPE=false
67
52
  ```
68
53
 
69
- ---
70
-
71
- <!-- STREAMING_CHUNK:Documenting CRUD operations and strict governance rules... -->
72
-
73
- ## SDK Usage & Strict Governance
74
-
75
- Every write operation requires literal governance metadata `{ desc, role, guard }` to ensure contract validation.
54
+ ## SDK usage
76
55
 
77
- ### Writing Data
56
+ Every write operation carries governance metadata `{ desc, role, guard }`.
78
57
 
79
- ```javascript
80
- // 1. Insert a document with mandatory governance
81
- const res = await oz.add('orders', {
82
- product: 'Desk Pro',
83
- price: 299
84
- }, {
58
+ ```js
59
+ // Insert a document
60
+ const res = await oz.add('orders', { product: 'Desk Pro', price: 299 }, {
85
61
  desc: 'Create customer order',
86
62
  role: 'AUTHENTICATED',
87
63
  guard: 'price > 0'
88
64
  });
65
+ if (!res.success) console.error('Order creation failed:', res.error);
89
66
 
90
- if (!res.success) {
91
- console.error('Order creation failed:', res.error);
92
- } else {
93
- console.log('Created document ID:', res.documentId);
94
- }
95
-
96
- // 2. Update a document
97
- const updateRes = await oz.update('orders', doc._id, {
98
- price: 249
99
- }, {
67
+ // Update a document
68
+ await oz.update('orders', doc._id, { price: 249 }, {
100
69
  desc: 'Apply discount on order',
101
70
  role: 'MANAGER'
102
71
  });
103
72
 
104
- // 3. Delete a document
105
- const delRes = await oz.delete('orders', doc._id, {
73
+ // Delete a document
74
+ await oz.delete('orders', doc._id, {
106
75
  desc: 'Cancel and delete order',
107
76
  role: 'ADMIN'
108
77
  });
109
- ```
110
-
111
- <!-- STREAMING_CHUNK:Documenting read operations and authentication... -->
112
-
113
- ### Reading Data
114
78
 
115
- ```javascript
116
- // Read all global documents in a collection
117
- const orders = await oz.getDocsG('orders');
118
-
119
- // Read documents owned by the authenticated user
120
- const userOrders = await oz.getDocsU('orders');
121
-
122
- // Read a single document by its _id
79
+ // Read data
80
+ const orders = await oz.getDocsG('orders'); // all documents
81
+ const mine = await oz.getDocsU('orders'); // documents of the signed-in user
123
82
  const order = await oz.getDoc('orders', 'order_123');
124
83
  ```
125
84
 
126
- ### Authentication (Passwordless OTP)
127
-
128
- ```javascript
129
- // Step 1: Send OTP code (In trial mode, code is always 0000)
130
- const otpRes = await oz.sendotpsvro('user@example.com');
85
+ ### Authentication (passwordless code)
131
86
 
132
- // Step 2: Verify OTP code and establish session
133
- const authRes = await oz.verifyotpsvro('user@example.com', '0000');
134
- if (authRes.success) {
135
- console.log('Logged in user:', authRes.user);
136
- }
137
-
138
- // Check session status
139
- const loggedIn = await oz.isAuthenticated();
87
+ ```js
88
+ await oz.sendotpsvro('user@example.com'); // trial mode: code is 0000
89
+ const auth = await oz.verifyotpsvro('user@example.com', '0000');
90
+ const signedIn = await oz.isAuthenticated();
140
91
  ```
141
92
 
142
- ---
143
-
144
- <!-- STREAMING_CHUNK:Documenting defensive UI web components... -->
145
-
146
- ## Zero-Crash UI Components
147
-
148
- Render data safely without risk of runtime null-pointer exceptions:
93
+ ## Zero-crash components
149
94
 
150
95
  ```html
151
- <!-- Text with fallback -->
152
96
  <oz-text value={item.name} fallback="No name" />
153
-
154
- <!-- Currency formatting with strict fallback -->
155
97
  <oz-number value={item.price} currency="EUR" invalid-fallback="0" />
156
-
157
- <!-- Boolean toggle representation -->
158
98
  <oz-toggle value={item.isActive} label-true="Active" label-false="Inactive" />
159
-
160
- <!-- Formatted date display -->
161
99
  <oz-date value={item.createdAt} locale="en-US" invalid-fallback="Invalid date" />
162
-
163
- <!-- Enum status validator -->
164
100
  <oz-enum value={item.status} allowed="PENDING,CONFIRMED,DELIVERED" invalid-fallback="Unknown status" />
165
-
166
- <!-- Relational reference resolution -->
167
101
  <oz-reference table="users" id={item.userId} field="fullName" orphan-fallback="Deleted user" />
168
102
  ```
169
103
 
170
- ---
171
-
172
- ## CLI Reference
104
+ ## CLI reference
173
105
 
174
106
  | Command | Description |
175
- | :--- | :--- |
176
- | `npx ozmoz login` | Authenticate your workstation via browser OAuth. |
177
- | `npx ozmoz mcp` | Configure AI agent directives and register MCP tools. |
178
- | `npx ozmoz init` | Initialize local `.env` and bootstrap configurations. |
179
- | `npx ozmoz sync` | Seal contract on Cloud Edge and compile TypeScript definitions. |
180
- | `npx ozmoz sync --check-only` | Offline contract and type validation (no network requests). |
181
- ```
182
- eof
183
-
184
- ### Résumé des éléments générés
107
+ |---|---|
108
+ | `npx ozmoz login` | Sign in from your workstation, through the browser. |
109
+ | `npx ozmoz mcp` | Configure your AI agent and register the OZmoz tools. |
110
+ | `npx ozmoz start <agent> "idea"` | Sign in, configure and launch your terminal agent. |
111
+ | `npx ozmoz init` | Initialize the local `.env` and project configuration. |
112
+ | `npx ozmoz sync` | Seal the data contract and generate the IDE types. |
113
+ | `npx ozmoz sync --check-only` | Offline check of the contract and types, no network request. |
185
114
 
186
- 1. **`checklist_deploiement.md`** : Fournit le diagnostic complet, les points de vigilance sur les bundles et Cloud Functions, ainsi que les 3 commandes de smoke test à exécuter avant le déploiement.
187
- 2. **`README.md`** : Totalement unifié sous la marque **OZmoz**, avec des exemples d'écriture conformes aux règles d'intégrité (gouvernance `{ desc, role }` et vérification de `res.success`).
115
+ Run `npx ozmoz --help` for all commands.
188
116
 
117
+ ## Links
189
118
 
190
- # ozmoz
191
-
192
- ```bash
193
- npx ozmoz
194
- ```
195
-
196
- OZmoz is the SDK and CLI behind the `oz.*` API and the `<oz-*>` tags.
197
-
198
- ## Quick start
199
-
200
- Let an AI agent build for you (Claude Code, Gemini CLI, Codex CLI):
201
-
202
- ```bash
203
- npx -y ozmoz start claude "your app idea"
204
- ```
119
+ - Website: https://ozmoz.io
120
+ - Support: open a ticket from https://ozmoz.io
205
121
 
206
- Or connect your agent once, then work as usual:
207
-
208
- ```bash
209
- npx ozmoz login # approve once in the browser
210
- npx ozmoz mcp # writes AGENTS.md / CLAUDE.md / GEMINI.md and configures the MCP server
211
- ```
212
-
213
- ## In an existing project
214
-
215
- ```bash
216
- npm install ozmoz
217
- npx ozmoz init --keyApp=<KEY> --token=<TOKEN>
218
- npx ozmoz sync # seals the schema and generates the contract + IDE types
219
- ```
220
-
221
- Use `npx ozmoz sync --check-only` for an offline check.
222
-
223
- ## Modes
224
-
225
- Set in `.env`:
122
+ ---
226
123
 
227
- - `OZ_PROTOTYPE=true`: trial mode, everything is simulated locally (no backend call).
228
- - `OZ_PROTOTYPE=false`: live mode, the data contract is enforced.
124
+ MongoDB is a trademark of MongoDB, Inc. OZmoz is an independent product and is not affiliated with or endorsed by MongoDB, Inc.
229
125
 
230
- Run `npx ozmoz --help` for all commands.
126
+ Copyright OZmoz. All rights reserved.
package/dist/cli.cjs CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- var i=require("fs"),a=require("path"),Y=require("https"),oe=require("http"),A=require("os"),{exec:re,spawnSync:N}=require("child_process"),se=[a.join(__dirname,"..","scripts","setup-lib.cjs"),a.join(__dirname,"..","..","scripts","setup-lib.cjs"),a.join(__dirname,"scripts","setup-lib.cjs")],ie=se.find(i.existsSync)||a.join(__dirname,"..","scripts","setup-lib.cjs"),{runFullSetup:K,handleAuthAndEnv:q,touchTsConfig:ae,attemptViteAutoImportPatch:ce,injectUniversalRuntime:le,writeBrowserConfig:de,patchAllowScripts:ue}=require(ie),me=!!(process.stdout&&process.stdout.isTTY&&typeof process.stdout.hasColors=="function"&&process.stdout.hasColors(16777216)),pe=me?"\x1B[38;2;15;156;140m":"\x1B[36m",fe="\x1B[31m",H="\x1B[0m";function u(e){console.log(e.replace(/OZmoz|\[|\]|→/g,t=>`${pe}${t}${H}`))}function y(e){console.error(`${fe}${e}${H}`)}var x="ozmoz",G=/<!--\s*(?:ozmoz|fleetbo|OZmoz):start[^>]*-->[\s\S]*?<!--\s*(?:ozmoz|fleetbo|OZmoz):end\s*-->/i,he="<!-- OZmoz:end -->",X="# OZMOZ DATA OS \u2014 DIRECTIVES SYST\xC8ME",M={claude:"Claude Code",cursor:"Cursor",windsurf:"Windsurf",devin:"Devin",codex:"Codex CLI",gemini:"Gemini CLI",antigravity:"Antigravity CLI",copilot:"GitHub Copilot"},D={created:"created",updated:"updated",unchanged:"already up to date",appended:"OZmoz block appended (your own content was kept)",migrated:"old file replaced (backup: <file>.ozmoz-legacy.bak)",invalid:"skipped: the file is not valid JSON, fix or delete it first"};function ge(){try{return JSON.parse(i.readFileSync(a.join(__dirname,"..","package.json"),"utf8")).version||"dev"}catch{return"dev"}}var ye=Buffer.from("QUl6YVN5QUM1Uk94STNibklPMUR5TmZsTWhGUnJ0blItNDVwNFJF","base64").toString("utf8");function Oe(e){try{let t=JSON.parse(Buffer.from(e.split(".")[1],"base64url").toString("utf8"));return typeof t.exp=="number"&&t.exp*1e3<Date.now()+6e4}catch{return!1}}async function ze(e,t){let r=await fetch(`https://securetoken.googleapis.com/v1/token?key=${ye}`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:`grant_type=refresh_token&refresh_token=${encodeURIComponent(t)}`});if(!r.ok)return null;let o=await r.json();return o.id_token?(i.writeFileSync(e,JSON.stringify({devToken:o.id_token,refreshToken:o.refresh_token||t,updatedAt:new Date().toISOString()},null,2)),o.id_token):null}async function J(){if(process.env.FLEETBO_DEV_TOKEN)return process.env.FLEETBO_DEV_TOKEN;try{let e=a.join(A.homedir(),".fleetbo","credentials.json");if(i.existsSync(e)){let t=JSON.parse(i.readFileSync(e,"utf8"));if(t.devToken&&!Oe(t.devToken))return t.devToken;if(t.refreshToken)try{let r=await ze(e,t.refreshToken);if(r)return r}catch{}}}catch{}return null}async function Q(){let e=a.join(A.homedir(),".fleetbo","guidelines.json"),t=await J();t||y('[OZmoz] Not logged in: run "npx ozmoz login" first to load the full instructions. Using local cache if available.');try{u("[OZmoz] Fetching instructions from Cloud...");let r=await fetch("https://getagentdirectives-jqycakhlxa-uc.a.run.app",{method:"POST",headers:Object.assign({"Content-Type":"application/json"},t?{Authorization:`Bearer ${t}`}:{}),body:JSON.stringify({data:{}})});if(!r.ok)y("[OZmoz] Cloud error HTTP "+r.status);else{let o=await r.json(),s=o.result?.data||o.result||o.data;if(s&&s.protocol&&s.directives)return u("[OZmoz] Instructions loaded successfully."),i.existsSync(a.dirname(e))||i.mkdirSync(a.dirname(e),{recursive:!0}),i.writeFileSync(e,JSON.stringify(s,null,2),"utf8"),s;y("[OZmoz] Empty Cloud response.")}}catch(r){y("[OZmoz] Network error: "+r.message)}if(i.existsSync(e)){u("[OZmoz] Using local cache (~/.fleetbo/guidelines.json)");try{return JSON.parse(i.readFileSync(e,"utf8"))}catch{}}return{protocol:"",directives:"",version:"1.0.0"}}function V(e,t){return"<!-- ozmoz:start v"+e+` -->
2
+ var i=require("fs"),a=require("path"),Y=require("https"),oe=require("http"),A=require("os"),{exec:re,spawnSync:N}=require("child_process"),se=[a.join(__dirname,"..","scripts","setup-lib.cjs"),a.join(__dirname,"..","..","scripts","setup-lib.cjs"),a.join(__dirname,"scripts","setup-lib.cjs")],ie=se.find(i.existsSync)||a.join(__dirname,"..","scripts","setup-lib.cjs"),{runFullSetup:K,handleAuthAndEnv:q,touchTsConfig:ae,attemptViteAutoImportPatch:ce,injectUniversalRuntime:le,writeBrowserConfig:de,patchAllowScripts:ue}=require(ie),me=!!(process.stdout&&process.stdout.isTTY&&typeof process.stdout.hasColors=="function"&&process.stdout.hasColors(16777216)),pe=me?"\x1B[38;2;15;156;140m":"\x1B[36m",fe="\x1B[31m",H="\x1B[0m";function u(e){console.log(e.replace(/OZmoz|\[|\]|→/g,t=>`${pe}${t}${H}`))}function y(e){console.error(`${fe}${e}${H}`)}var x="ozmoz",G=/<!--\s*(?:ozmoz|fleetbo|OZmoz):start[^>]*-->[\s\S]*?<!--\s*(?:ozmoz|fleetbo|OZmoz):end\s*-->/i,he="<!-- OZmoz:end -->",X="# OZMOZ DATA OS \u2014 DIRECTIVES SYST\xC8ME",Z={claude:"Claude Code",cursor:"Cursor",windsurf:"Windsurf",devin:"Devin",codex:"Codex CLI",gemini:"Gemini CLI",antigravity:"Antigravity CLI",copilot:"GitHub Copilot"},D={created:"created",updated:"updated",unchanged:"already up to date",appended:"OZmoz block appended (your own content was kept)",migrated:"old file replaced (backup: <file>.ozmoz-legacy.bak)",invalid:"skipped: the file is not valid JSON, fix or delete it first"};function ge(){try{return JSON.parse(i.readFileSync(a.join(__dirname,"..","package.json"),"utf8")).version||"dev"}catch{return"dev"}}var ye=Buffer.from("QUl6YVN5QUM1Uk94STNibklPMUR5TmZsTWhGUnJ0blItNDVwNFJF","base64").toString("utf8");function Oe(e){try{let t=JSON.parse(Buffer.from(e.split(".")[1],"base64url").toString("utf8"));return typeof t.exp=="number"&&t.exp*1e3<Date.now()+6e4}catch{return!1}}async function ze(e,t){let r=await fetch(`https://securetoken.googleapis.com/v1/token?key=${ye}`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:`grant_type=refresh_token&refresh_token=${encodeURIComponent(t)}`});if(!r.ok)return null;let o=await r.json();return o.id_token?(i.writeFileSync(e,JSON.stringify({devToken:o.id_token,refreshToken:o.refresh_token||t,updatedAt:new Date().toISOString()},null,2)),o.id_token):null}async function J(){if(process.env.FLEETBO_DEV_TOKEN)return process.env.FLEETBO_DEV_TOKEN;try{let e=a.join(A.homedir(),".fleetbo","credentials.json");if(i.existsSync(e)){let t=JSON.parse(i.readFileSync(e,"utf8"));if(t.devToken&&!Oe(t.devToken))return t.devToken;if(t.refreshToken)try{let r=await ze(e,t.refreshToken);if(r)return r}catch{}}}catch{}return null}async function Q(){let e=a.join(A.homedir(),".fleetbo","guidelines.json"),t=await J();t||y('[OZmoz] Not logged in: run "npx ozmoz login" first to load the full instructions. Using local cache if available.');try{u("[OZmoz] Fetching instructions from Cloud...");let r=await fetch("https://getagentdirectives-jqycakhlxa-uc.a.run.app",{method:"POST",headers:Object.assign({"Content-Type":"application/json"},t?{Authorization:`Bearer ${t}`}:{}),body:JSON.stringify({data:{}})});if(!r.ok)y("[OZmoz] Cloud error HTTP "+r.status);else{let o=await r.json(),s=o.result?.data||o.result||o.data;if(s&&s.protocol&&s.directives)return u("[OZmoz] Instructions loaded successfully."),i.existsSync(a.dirname(e))||i.mkdirSync(a.dirname(e),{recursive:!0}),i.writeFileSync(e,JSON.stringify(s,null,2),"utf8"),s;y("[OZmoz] Empty Cloud response.")}}catch(r){y("[OZmoz] Network error: "+r.message)}if(i.existsSync(e)){u("[OZmoz] Using local cache (~/.fleetbo/guidelines.json)");try{return JSON.parse(i.readFileSync(e,"utf8"))}catch{}}return{protocol:"",directives:"",version:"1.0.0"}}function V(e,t){return"<!-- ozmoz:start v"+e+` -->
3
3
  `+t.trim()+`
4
4
  `+he+`
5
5
  `}function ve(e,t,r){let o=i.existsSync(e)?i.readFileSync(e,"utf8"):null,s,n;return o===null?(s="created",n=t):G.test(o)?(n=o.replace(G,()=>t.trimEnd()),s=n===o?"unchanged":"updated"):o.includes(X)?(s="migrated",n=t):(s="appended",n=o.replace(/\s*$/,`
6
6
 
7
- `)+t),!r&&s!=="unchanged"&&(s==="migrated"&&i.writeFileSync(e+".ozmoz-legacy.bak",o,"utf8"),i.mkdirSync(a.dirname(e),{recursive:!0}),i.writeFileSync(e,n,"utf8")),s}function ee(){return[a.join(__dirname,"ozmoz-mcp.js"),a.join(__dirname,"..","bin","ozmoz-mcp.js"),a.join(__dirname,"bin","ozmoz-mcp.js"),a.join(__dirname,"..","src","bin","ozmoz-mcp.js")].find(t=>i.existsSync(t))||a.resolve(__dirname,"ozmoz-mcp.js")}function Z(e,t,r){let o=Object.assign({command:process.execPath,args:[__filename,"mcp","--run"]},r||{}),s={};if(i.existsSync(e))try{let d=JSON.parse(i.readFileSync(e,"utf8"));if(!d||typeof d!="object"||Array.isArray(d))return"invalid";s=d}catch{return"invalid"}let n=s.mcpServers&&s.mcpServers[x];return n&&JSON.stringify(n)===JSON.stringify(o)?"unchanged":(s.mcpServers=s.mcpServers||{},s.mcpServers[x]=o,t||(i.mkdirSync(a.dirname(e),{recursive:!0}),i.writeFileSync(e,JSON.stringify(s,null,2)+`
7
+ `)+t),!r&&s!=="unchanged"&&(s==="migrated"&&i.writeFileSync(e+".ozmoz-legacy.bak",o,"utf8"),i.mkdirSync(a.dirname(e),{recursive:!0}),i.writeFileSync(e,n,"utf8")),s}function ee(){return[a.join(__dirname,"ozmoz-mcp.js"),a.join(__dirname,"..","bin","ozmoz-mcp.js"),a.join(__dirname,"bin","ozmoz-mcp.js"),a.join(__dirname,"..","src","bin","ozmoz-mcp.js")].find(t=>i.existsSync(t))||a.resolve(__dirname,"ozmoz-mcp.js")}function M(e,t,r){let o=Object.assign({command:process.execPath,args:[__filename,"mcp","--run"]},r||{}),s={};if(i.existsSync(e))try{let d=JSON.parse(i.readFileSync(e,"utf8"));if(!d||typeof d!="object"||Array.isArray(d))return"invalid";s=d}catch{return"invalid"}let n=s.mcpServers&&s.mcpServers[x];return n&&JSON.stringify(n)===JSON.stringify(o)?"unchanged":(s.mcpServers=s.mcpServers||{},s.mcpServers[x]=o,t||(i.mkdirSync(a.dirname(e),{recursive:!0}),i.writeFileSync(e,JSON.stringify(s,null,2)+`
8
8
  `,"utf8")),n?"updated":"created")}function R(e){let t=process.platform==="win32"?"where":"which";return N(t,[e],{stdio:"ignore"}).status===0}function $(e,t,r){let o=N(e,t,{encoding:"utf8",timeout:r||3e4,shell:process.platform==="win32"});return{ok:o.status===0,out:(o.stdout||"")+(o.stderr||"")}}function Se(e,t,r){let o=e==="claude"?["--scope",r||"user"]:[],s=ee(),n=["mcp","add"].concat(o,[x,"--",process.execPath,s]),d=["mcp","remove",x].concat(o),c=e+" "+n.join(" ");if(!R(e))return{status:"manual",detail:c};if(t)return{status:"planned",detail:c};let h=$(e,["mcp","list"],6e4),f=h.ok?h.out.split(`
9
9
  `):[],p=f.find(w=>/^[\s|│┃]*ozmoz(?![\w@-])/.test(w)),m=f.some(w=>/^\s*(?:fleetbo|ozmoz):\s/.test(w));if(p&&p.includes("ozmoz@latest"))return{status:"unchanged",legacy:m};if(p&&!$(e,d).ok)return{status:"manual",detail:e+" "+d.join(" ")+" && "+c,legacy:m};let g=$(e,n);return g.ok?{status:p?"updated":"created",legacy:m}:{status:"failed",detail:c,message:g.out.trim().split(`
10
10
  `).slice(-2).join(" "),legacy:m}}function we(e){let t={user:!1,local:!1,others:[]};try{let r=JSON.parse(i.readFileSync(a.join(A.homedir(),".claude.json"),"utf8")),o=c=>!!c&&typeof c=="object"&&/fleetbo|ozmoz/.test(String(c.command||"")+" "+JSON.stringify(c.args||[])),s=(c,h)=>{!c||typeof c!="object"||Object.keys(c).forEach(f=>{f===x?t[h]=!0:o(c[f])&&t.others.push({name:f,where:h})})};s(r.mcpServers,"user");let n=e;try{n=i.realpathSync(e)}catch{}let d=r.projects||{};Array.from(new Set([e,n])).forEach(c=>s((d[c]||{}).mcpServers,"local"))}catch{}return t}function Ee(e){let t=we(e);t.user&&u(" \u26A0\uFE0F A global (user-scope) '"+x+"' entry from a previous version also exists: the tools appear in every project. To keep them in OZmoz projects only: claude mcp remove "+x+" --scope user"),t.local&&u(" \u26A0\uFE0F A local-scope '"+x+"' entry exists for this folder and takes precedence over .mcp.json. Remove it: claude mcp remove "+x+" --scope local"),t.others.forEach(r=>{u(" \u26A0\uFE0F An old MCP entry named '"+r.name+"' ("+r.where+" scope) points to OZmoz. Remove it: claude mcp remove "+r.name+" --scope "+r.where)})}function Te(e){let t=A.homedir(),r=o=>i.existsSync(o);return{claude:R("claude")||r(a.join(t,".claude")),cursor:r(a.join(e,".cursor"))||r(a.join(t,".cursor"))||R("cursor"),windsurf:r(a.join(t,".codeium","windsurf"))||r(a.join(e,".windsurf")),devin:r(a.join(e,".devin")),codex:R("codex")||r(a.join(t,".codex")),gemini:R("gemini")||r(a.join(t,".gemini")),antigravity:R("agy")||r(a.join(t,".antigravity"))||r(a.join(e,".antigravity")),copilot:R("copilot")||r(a.join(t,".copilot"))}}var be={claude:{bin:"claude",launch:e=>[e]},gemini:{bin:"gemini",launch:e=>["-i",e]},codex:{bin:"codex",launch:e=>[e]},antigravity:{bin:"agy",launch:e=>["-i",e]}};function Ae(e){return String(e||"").replace(/[^\p{L}\p{N} '.,:\-_]/gu," ").replace(/\s+/g," ").trim().slice(0,4e3)}function Ce(e,t,r){let o=Ae(t),s=o?`The user already provided their project description and technical choices: "${o}".
@@ -15,7 +15,7 @@ var i=require("fs"),a=require("path"),Y=require("https"),oe=require("http"),A=re
15
15
  [OZmoz] OZmoz is set up in this folder (instruction file + MCP server).
16
16
  `),process.exit(0)),ke(n.bin)||(y('"'+n.bin+'" is not installed or not in your PATH. Install it, then run: npx ozmoz start '+o),process.exit(1));let h=Ce(n.rules,s,e);u(`
17
17
  [OZmoz] Launching `+n.bin+` in this folder...
18
- `);let f=N(n.bin,n.launch(process.platform==="win32"?'"'+h+'"':h),{stdio:"inherit",cwd:e,shell:process.platform==="win32"});process.exit(f.status===null?1:f.status)}async function te(e,t){let r=t.includes("--dry-run"),o=t.find(l=>l.startsWith("--agent=")),s=o&&o.slice(8).trim()?o.slice(8).split(",").map(l=>l.trim().toLowerCase()).filter(Boolean):null,n=null;if(s){n=s.includes("all")?Object.keys(M):s;let l=n.filter(z=>!M[z]);l.length&&(y("Unknown agent(s): "+l.join(", ")+". Valid values: "+Object.keys(M).join(", ")+", all."),process.exit(1))}let d=t.find(l=>l.startsWith("--scope=")),c=d?d.slice(8).trim().toLowerCase():"project";["project","user","local"].includes(c)||(y("Unknown scope: "+c+". Valid values for Claude Code: project (default), user, local."),process.exit(1));let h=Te(e),f=n||Object.keys(M).filter(l=>h[l]),p=ge();u(`
18
+ `);let f=N(n.bin,n.launch(process.platform==="win32"?'"'+h+'"':h),{stdio:"inherit",cwd:e,shell:process.platform==="win32"});process.exit(f.status===null?1:f.status)}async function te(e,t){let r=t.includes("--dry-run"),o=t.find(l=>l.startsWith("--agent=")),s=o&&o.slice(8).trim()?o.slice(8).split(",").map(l=>l.trim().toLowerCase()).filter(Boolean):null,n=null;if(s){n=s.includes("all")?Object.keys(Z):s;let l=n.filter(z=>!Z[z]);l.length&&(y("Unknown agent(s): "+l.join(", ")+". Valid values: "+Object.keys(Z).join(", ")+", all."),process.exit(1))}let d=t.find(l=>l.startsWith("--scope=")),c=d?d.slice(8).trim().toLowerCase():"project";["project","user","local"].includes(c)||(y("Unknown scope: "+c+". Valid values for Claude Code: project (default), user, local."),process.exit(1));let h=Te(e),f=n||Object.keys(Z).filter(l=>h[l]),p=ge();u(`
19
19
  [OZmoz] Configuring your AI agents`+(r?" (dry run: nothing is written)":"")+"...");let m=await Q(),g=m.version||p,w=`# OZMOZ DATA OS \u2014 DIRECTIVES AGENT
20
20
 
21
21
  `+(m.directives||m.guidelines||"")+`
@@ -23,7 +23,7 @@ var i=require("fs"),a=require("path"),Y=require("https"),oe=require("http"),A=re
23
23
  ## PROTOCOLE DONN\xC9ES : QUI FAIT QUOI (AGENT FRONTEND \u2194 ALEX AI)
24
24
 
25
25
  `+(m.protocol||""),E=V(g,w),b=[["AGENTS.md",E],["GEMINI.md",E],["CLAUDE.md",V(g,`# OZMOZ DATA OS \u2014 DIRECTIVES AGENT
26
- @AGENTS.md`)]],v=a.join(e,".cursorrules");if(i.existsSync(v)){let l=i.readFileSync(v,"utf8");(G.test(l)||l.includes(X))&&b.push([".cursorrules",E])}for(let l of b)u("\u2192 "+l[0]+": "+D[ve(a.join(e,l[0]),l[1],r)]);for(let l of f){let z=M[l];if(l==="cursor")u("\u2192 "+z+" MCP (.cursor/mcp.json): "+D[Z(a.join(e,".cursor","mcp.json"),r)]);else if(l==="windsurf")u("\u2192 "+z+" MCP (~/.codeium/windsurf/mcp_config.json): "+D[Z(a.join(A.homedir(),".codeium","windsurf","mcp_config.json"),r)]);else if(l==="copilot")u("\u2192 "+z+" MCP (~/.copilot/mcp-config.json): "+D[Z(a.join(A.homedir(),".copilot","mcp-config.json"),r,{type:"local",tools:["*"]})]);else if(l==="claude"&&c==="project"){let S=Z(a.join(e,".mcp.json"),r);u("\u2192 "+z+" MCP (.mcp.json, project scope): "+D[S]),(S==="created"||S==="updated")&&u(" Claude Code asks you to approve a project server the first time you launch it. Commit .mcp.json to share it with your team (it contains no token)."),Ee(e)}else if(l==="gemini"){let S=[a.join(A.homedir(),".gemini","settings.json"),a.join(e,".gemini","settings.json"),a.join(e,".mcp.json")],T="unchanged";S.forEach(F=>{let P=Z(F,r);(P==="created"||P==="updated")&&(T=P)}),u("\u2192 "+z+" MCP (settings.json & .mcp.json): "+D[T])}else if(l==="claude"||l==="codex"||l==="antigravity"){let S=l==="antigravity"?"agy":l,T=Se(S,r,c);T.status==="manual"?u("\u2192 "+z+": '"+S+"' not found or not scriptable. Run manually: "+T.detail):T.status==="planned"?u("\u2192 "+z+" MCP: would run: "+T.detail):T.status==="failed"?y("\u2192 "+z+" MCP: registration failed ("+T.message+"). Run manually: "+T.detail):u("\u2192 "+z+" MCP"+(l==="claude"?" ("+c+" scope)":"")+": "+D[T.status]),T.legacy&&u(" \u26A0\uFE0F An old MCP entry named 'fleetbo' exists. Remove it: "+S+" mcp remove fleetbo")}else l==="devin"&&u("\u2192 "+z+": reads AGENTS.md. Devin runs in its own environment: add the OZmoz MCP server from Devin's settings (not automated).")}!n&&f.length===0&&u("\u2192 No agent detected: instruction files were written; re-run with --agent=<name> to register the MCP server.");let I=!!(B(e).FLEETBO_DEV_TOKEN||process.env.FLEETBO_DEV_TOKEN),O=a.join(A.homedir(),".fleetbo","credentials.json");if(i.existsSync(O))try{I=I||!!JSON.parse(i.readFileSync(O,"utf8")).devToken}catch{}I||y('\u26A0\uFE0F No developer token found. Run "npx ozmoz login" once.'),process.env.FLEETBO_START||u(`
26
+ @AGENTS.md`)]],v=a.join(e,".cursorrules");if(i.existsSync(v)){let l=i.readFileSync(v,"utf8");(G.test(l)||l.includes(X))&&b.push([".cursorrules",E])}for(let l of b)u("\u2192 "+l[0]+": "+D[ve(a.join(e,l[0]),l[1],r)]);for(let l of f){let z=Z[l];if(l==="cursor")u("\u2192 "+z+" MCP (.cursor/mcp.json): "+D[M(a.join(e,".cursor","mcp.json"),r)]);else if(l==="windsurf")u("\u2192 "+z+" MCP (~/.codeium/windsurf/mcp_config.json): "+D[M(a.join(A.homedir(),".codeium","windsurf","mcp_config.json"),r)]);else if(l==="copilot")u("\u2192 "+z+" MCP (~/.copilot/mcp-config.json): "+D[M(a.join(A.homedir(),".copilot","mcp-config.json"),r,{type:"local",tools:["*"]})]);else if(l==="claude"&&c==="project"){let S=M(a.join(e,".mcp.json"),r);u("\u2192 "+z+" MCP (.mcp.json, project scope): "+D[S]),(S==="created"||S==="updated")&&u(" Claude Code asks you to approve a project server the first time you launch it. Commit .mcp.json to share it with your team (it contains no token)."),Ee(e)}else if(l==="gemini"){let S=[a.join(A.homedir(),".gemini","settings.json"),a.join(e,".gemini","settings.json"),a.join(e,".mcp.json")],T="unchanged";S.forEach(F=>{let P=M(F,r);(P==="created"||P==="updated")&&(T=P)}),u("\u2192 "+z+" MCP (settings.json & .mcp.json): "+D[T])}else if(l==="claude"||l==="codex"||l==="antigravity"){let S=l==="antigravity"?"agy":l,T=Se(S,r,c);T.status==="manual"?u("\u2192 "+z+": '"+S+"' not found or not scriptable. Run manually: "+T.detail):T.status==="planned"?u("\u2192 "+z+" MCP: would run: "+T.detail):T.status==="failed"?y("\u2192 "+z+" MCP: registration failed ("+T.message+"). Run manually: "+T.detail):u("\u2192 "+z+" MCP"+(l==="claude"?" ("+c+" scope)":"")+": "+D[T.status]),T.legacy&&u(" \u26A0\uFE0F An old MCP entry named 'fleetbo' exists. Remove it: "+S+" mcp remove fleetbo")}else l==="devin"&&u("\u2192 "+z+": reads AGENTS.md. Devin runs in its own environment: add the OZmoz MCP server from Devin's settings (not automated).")}!n&&f.length===0&&u("\u2192 No agent detected: instruction files were written; re-run with --agent=<name> to register the MCP server.");let I=!!(B(e).FLEETBO_DEV_TOKEN||process.env.FLEETBO_DEV_TOKEN),O=a.join(A.homedir(),".fleetbo","credentials.json");if(i.existsSync(O))try{I=I||!!JSON.parse(i.readFileSync(O,"utf8")).devToken}catch{}I||y('\u26A0\uFE0F No developer token found. Run "npx ozmoz login" once.'),process.env.FLEETBO_START||u(`
27
27
  [OZmoz] Done.
28
28
  `)}function Ne(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";re(`${t} "${e}"`)}function _e(e){return new Promise((t,r)=>{let o=oe.createServer((s,n)=>{if(n.setHeader("Access-Control-Allow-Origin","*"),n.setHeader("Access-Control-Allow-Methods","GET, OPTIONS"),n.setHeader("Access-Control-Allow-Headers","Content-Type, Authorization"),n.setHeader("Access-Control-Allow-Private-Network","true"),s.method==="OPTIONS"){n.writeHead(204),n.end();return}let d=new URL(s.url,"http://127.0.0.1");if(d.pathname==="/callback"){let c=d.searchParams.get("token"),h=d.searchParams.get("refresh");if(!c){n.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),n.end("<h3>Error: Missing token.</h3>");return}let f=a.join(A.homedir(),".fleetbo");i.existsSync(f)||i.mkdirSync(f,{recursive:!0}),i.writeFileSync(a.join(f,"credentials.json"),JSON.stringify({devToken:c,refreshToken:h||null,updatedAt:new Date().toISOString()},null,2));let p=a.join(e,".env");if(i.existsSync(p)){let m=i.readFileSync(p,"utf8");m.includes("FLEETBO_DEV_TOKEN=")?m=m.replace(/FLEETBO_DEV_TOKEN=.*/g,`FLEETBO_DEV_TOKEN=${c}`):m+=`
29
29
  FLEETBO_DEV_TOKEN=${c}
@@ -627,7 +627,7 @@ ${JSON.stringify({...e||{},context:void 0},null,2)}
627
627
  \`\`\`json
628
628
  ${JSON.stringify(t||{},null,2)}
629
629
  \`\`\`
630
- `}function Me(e){return String(e).toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/[^a-z0-9]/g,"_").replace(/^_+|_+$/g,"").slice(0,30)||"app"}async function Ze(e,t){let r=B(e),o=i.existsSync(a.join(e,"svro.schema.json"));(r.OZ_DB_KEY||o)&&(y("Cannot create project: an OZmoz project already exists in this folder."),u('\u2192 Use "npx ozmoz sync" or evolve the existing contract instead.'),process.exit(1));let s=(t||"").trim();s||(y('Project name is required. Usage: npx ozmoz create "<name>"'),process.exit(1));let n=a.join(e,".ozmoz.lock");if(i.existsSync(n)){let c=!1;try{let h=Number(i.readFileSync(n,"utf8"));Date.now()-h>6e4&&(c=!0)}catch{c=!0}c||(y("A project creation is already running in this folder."),process.exit(1)),i.unlinkSync(n)}i.writeFileSync(n,String(Date.now()));let d=()=>{if(i.existsSync(n))try{i.unlinkSync(n)}catch{}};try{let c=process.env.FLEETBO_DEV_TOKEN;if(!c){let E=a.join(A.homedir(),".fleetbo","credentials.json");if(i.existsSync(E))try{c=JSON.parse(i.readFileSync(E,"utf8")).devToken}catch{}}c||(d(),y('Missing developer token. Please run "npx ozmoz login" first.'),process.exit(1)),u(`[OZmoz] Creating project "${s}" on Cloud...`);let h=Me(s),f=[h,`${h.slice(0,24)}_${Math.random().toString(36).slice(2,6)}`,`${h.slice(0,24)}_${Math.random().toString(36).slice(2,6)}`],p=null,m=null;for(let E of f)try{let b=await fetch("https://createprojectlight-jqycakhlxa-uc.a.run.app",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${c}`},body:JSON.stringify({data:{name:s,keyApp:E}})}),v=await b.json();if(b.ok&&!v.error){p={keyApp:E,data:v.result?.data||v.data||{}};break}else m=v.error?.message||`HTTP ${b.status}`}catch(b){m=b.message}p||(d(),y(`Failed to create project on Cloud: ${m||"Unknown error"}`),process.exit(1));let g=p.data.bootstrapToken;await q(e,[`--keyApp=${p.keyApp}`,`--token=${g}`]);let w=a.join(e,"package.json");K(e,w),await te(e,[]),u(`
630
+ `}function Ze(e){return String(e).toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/[^a-z0-9]/g,"_").replace(/^_+|_+$/g,"").slice(0,30)||"app"}async function Me(e,t){let r=B(e),o=i.existsSync(a.join(e,"svro.schema.json"));(r.OZ_DB_KEY||o)&&(y("Cannot create project: an OZmoz project already exists in this folder."),u('\u2192 Use "npx ozmoz sync" or evolve the existing contract instead.'),process.exit(1));let s=(t||"").trim();s||(y('Project name is required. Usage: npx ozmoz create "<name>"'),process.exit(1));let n=a.join(e,".ozmoz.lock");if(i.existsSync(n)){let c=!1;try{let h=Number(i.readFileSync(n,"utf8"));Date.now()-h>6e4&&(c=!0)}catch{c=!0}c||(y("A project creation is already running in this folder."),process.exit(1)),i.unlinkSync(n)}i.writeFileSync(n,String(Date.now()));let d=()=>{if(i.existsSync(n))try{i.unlinkSync(n)}catch{}};try{let c=process.env.FLEETBO_DEV_TOKEN;if(!c){let E=a.join(A.homedir(),".fleetbo","credentials.json");if(i.existsSync(E))try{c=JSON.parse(i.readFileSync(E,"utf8")).devToken}catch{}}c||(d(),y('Missing developer token. Please run "npx ozmoz login" first.'),process.exit(1)),u(`[OZmoz] Creating project "${s}" on Cloud...`);let h=Ze(s),f=[h,`${h.slice(0,24)}_${Math.random().toString(36).slice(2,6)}`,`${h.slice(0,24)}_${Math.random().toString(36).slice(2,6)}`],p=null,m=null;for(let E of f)try{let b=await fetch("https://createprojectlight-jqycakhlxa-uc.a.run.app",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${c}`},body:JSON.stringify({data:{name:s,keyApp:E}})}),v=await b.json();if(b.ok&&!v.error){p={keyApp:E,data:v.result?.data||v.data||{}};break}else m=v.error?.message||`HTTP ${b.status}`}catch(b){m=b.message}p||(d(),y(`Failed to create project on Cloud: ${m||"Unknown error"}`),process.exit(1));let g=p.data.bootstrapToken;await q(e,[`--keyApp=${p.keyApp}`,`--token=${g}`]);let w=a.join(e,"package.json");K(e,w),await te(e,[]),u(`
631
631
  [OZmoz] Project "${s}" (${p.keyApp}) created and configured successfully.`),u(`AI AGENTS: do NOT stop here and do NOT ask the user to restart. Continue NOW in the same turn: scaffold the frontend if missing, run "npx ozmoz sync", read ozmoz_contract.md, write ALL views in trial mode (OZ_PROTOTYPE=true), then start the dev server and ask the user to validate.
632
632
  `)}finally{if(i.existsSync(n))try{i.unlinkSync(n)}catch{}}}async function Ue(e){let t=process.env.FLEETBO_DEV_TOKEN;if(!t){let O=a.join(A.homedir(),".fleetbo","credentials.json");if(i.existsSync(O))try{t=JSON.parse(i.readFileSync(O,"utf8")).devToken}catch{}}let o=B(e).OZ_KEY_APP;(!o||!t)&&(y("Cannot update: project uninitialized or dev token missing."),process.exit(1));let s=i.existsSync(a.join(e,"src"))?a.join(e,"src"):e,n=new Set([".jsx",".tsx",".vue",".svelte",".js",".ts",".html"]),d=[],c=0;function h(O){let l=[];try{l=i.readdirSync(O,{withFileTypes:!0})}catch{return}for(let z of l){if(/^(node_modules|\.git|dist|build|\.next|\.svelte-kit)$/.test(z.name))continue;let S=a.join(O,z.name);if(z.isDirectory())h(S);else if(n.has(a.extname(z.name))&&!z.name.endsWith(".d.ts"))try{let T=i.statSync(S);if(T.size>3e5)continue;let F=i.readFileSync(S,"utf8");/oz\.|<oz-/i.test(F)&&(c+=T.size,d.push({name:a.relative(e,S).split(a.sep).join("/"),content:F}))}catch{}}}let f=C.find(O=>O.startsWith("--files=")),p=f?f.slice(8).split(",").map(O=>O.trim()).filter(Boolean):null;if(p&&p.length>0)for(let O of p){let l=a.resolve(e,O);if(i.existsSync(l)){let z=i.readFileSync(l,"utf8");c+=i.statSync(l).size,d.push({name:a.relative(e,l).split(a.sep).join("/"),content:z})}}else h(s);d.length===0&&(y("Cannot update: no components using oz.* found."),process.exit(1)),c>8*1024*1024&&(y("Payload too large: total UI source files exceed 8 MB limit."),process.exit(1));let m=C.find(O=>O.startsWith("--rules=")),g=m?m.slice(8).trim():"",w=C.find(O=>O.startsWith("--reasoning=")),E=w?w.slice(12).trim().toLowerCase():void 0;E!=="standard"&&E!=="high"&&(y("Missing or invalid --reasoning=<standard|high>."),y("If you are an AI agent: ask the user which analysis depth they want (numbered [1]/[2] choice, recommended option first) before running this command, then pass --reasoning=standard or --reasoning=high accordingly. Never pick it yourself."),process.exit(1)),u(`[OZmoz] Sending ${d.length} component(s) to Cloud Engine for modeling...`);try{let O,l,z;for(let S=1;S<=3&&(O=await fetch("https://updateprojectlight-jqycakhlxa-uc.a.run.app",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({data:{keyApp:o,name:o,newViewFiles:d,oz_rules:g,reasoning:E}})}),l=await O.json().catch(()=>({})),z=l.result?.data||l.data||l,!(O.status<500||S===3));S++)u("\u2192 The modeling service is busy (attempt "+S+"/3). Retrying in 20s..."),await new Promise(T=>setTimeout(T,2e4));if(!O.ok||l.error||z.success===!1){let S=l.error?.message||z.warnings?.join(", ")||l.message||"Server error";y(`Update failed: ${S}`),process.exit(1)}u("\u2192 Cloud modeling response: "+JSON.stringify(l).slice(0,800))}catch(O){y(`Network error: ${O.message}`),process.exit(1)}u("\u2192 Structure modeled. Sealing into OZmoz SVRO Kernel...");let b=N(process.execPath,[__filename,"sync"],{stdio:"inherit",cwd:e}),v=Date.now();for(let O=1;O<=5&&b.status===0;O++){let l=!1;try{let z=JSON.parse(i.readFileSync(a.join(e,"svro.schema.json"),"utf8")),S=JSON.parse(i.readFileSync(a.join(e,"svro.workflow.json"),"utf8"));l=Object.keys(z.collections||{}).length>0&&(S.sequences||[]).length>0}catch{}if(l)break;u("\u2192 Contract still empty, waiting for the cloud (attempt "+O+"/5, "+Math.round((Date.now()-v)/1e3)+"s elapsed)..."),await new Promise(z=>setTimeout(z,6e3)),b=N(process.execPath,[__filename,"sync"],{stdio:"inherit",cwd:e})}let _=!1,I=!1;try{let O=JSON.parse(i.readFileSync(a.join(e,"svro.schema.json"),"utf8"));_=Object.keys(O.collections||{}).length>0,I=(JSON.parse(i.readFileSync(a.join(e,"svro.workflow.json"),"utf8")).sequences||[]).length>0}catch{}b.status===0&&_&&I?u(`
633
633
  [OZmoz] Contract locked into SVRO Kernel.
@@ -642,12 +642,12 @@ ${JSON.stringify(t||{},null,2)}
642
642
  [OZmoz] Configuration completed successfully!
643
643
  `),u(`
644
644
  Next step:`),u(` npx ozmoz sync (Sync cloud schema & generate IDE types)
645
- `);else if(k==="sync"){let r=C.includes("--dry-run"),o=C.includes("--check-only");u(`[OZmoz] Syncing schema...${r?" (dry-run)":""}${o?" (check-only, no network)":""}`),r||de(e);let s=a.join(e,"svro.schema.json"),n=a.join(e,"svro.workflow.json"),d=a.join(e,"ozmoz_contract.md"),c=a.join(e,"src","ozmoz.d.ts"),f=B(e).OZ_ENTERPRISE_ID,p=null,m=null;if(o)u("\u2192 Mode check-only : Local contract used, no cloud fetch..");else if(f)try{u("\u2192 Fetching latest contracts from Cloud..."),p=await W(f,"svro.schema.json"),p&&(i.writeFileSync(s,JSON.stringify(p,null,2)+`
646
- `),u("\u2192 Local svro.schema.json updated.")),m=await W(f,"svro.workflow.json"),m&&(i.writeFileSync(n,JSON.stringify(m,null,2)+`
647
- `),u("\u2192 Local svro.workflow.json updated."))}catch(v){y(`\u26A0\uFE0F Cloud fetch bypassed: ${v.message}. Using local file fallback.`)}else y("\u26A0\uFE0F OZ_ENTERPRISE_ID missing in .env. Skipping cloud fetch.");let g=p;if(!g&&i.existsSync(s))try{g=JSON.parse(i.readFileSync(s,"utf8"))}catch{}g||(g={context:"Application en cours de mod\xE9lisation initiale.",collections:{}},i.writeFileSync(s,JSON.stringify(g,null,2)+`
645
+ `);else if(k==="sync"){let r=C.includes("--dry-run"),o=C.includes("--check-only");u(`[OZmoz] Syncing schema...${r?" (dry-run)":""}${o?" (check-only, no network)":""}`),r||de(e);let s=a.join(e,"svro.schema.json"),n=a.join(e,"svro.workflow.json"),d=a.join(e,"ozmoz_contract.md"),c=a.join(e,"src","ozmoz.d.ts"),f=B(e).OZ_ENTERPRISE_ID,p=null,m=null;if(o)u("\u2192 Mode check-only : Local contract used, no cloud fetch..");else if(f)try{u(" \u2192 Fetching latest contracts from OZmoz..."),p=await W(f,"svro.schema.json"),p&&(i.writeFileSync(s,JSON.stringify(p,null,2)+`
646
+ `),u(" \u2192 Local svro.schema.json updated.")),m=await W(f,"svro.workflow.json"),m&&(i.writeFileSync(n,JSON.stringify(m,null,2)+`
647
+ `),u(" \u2192 Local svro.workflow.json updated."))}catch(v){y(`\u26A0\uFE0F Cloud fetch bypassed: ${v.message}. Using local file fallback.`)}else y("\u26A0\uFE0F OZ_ENTERPRISE_ID missing in .env. Skipping cloud fetch.");let g=p;if(!g&&i.existsSync(s))try{g=JSON.parse(i.readFileSync(s,"utf8"))}catch{}g||(g={context:"Application en cours de mod\xE9lisation initiale.",collections:{}},i.writeFileSync(s,JSON.stringify(g,null,2)+`
648
648
  `,"utf8"),u("\u2192 Initial blank svro.schema.json created."));let w=m;if(!w&&i.existsSync(n))try{w=JSON.parse(i.readFileSync(n,"utf8"))}catch{}w||(w={actors:{},sequences:[]},i.writeFileSync(n,JSON.stringify(w,null,2)+`
649
649
  `,"utf8"),u("\u2192 Initial blank svro.workflow.json created."));{let v=De(g);v.changed&&(g=v.schema,i.writeFileSync(s,JSON.stringify(g,null,2)+`
650
- `,"utf8"),u("\u2192 Managed by system, no longer required from your code: "+v.notes.join(", ")+"."))}let{protocol:E}=await Q(),b=Le(g,w,E);i.writeFileSync(d,b,"utf8"),u("\u2192 Contract markdown successfully generated at project root.");try{let v=Object.keys(g.collections||{});if(f&&!o&&Object.keys(g.collections||{}).length>0)try{await Pe(f,g,w),u("\u2192 Schema successfully sealed into OZmoz Kernel.")}catch(l){y(`\u26A0\uFE0F Kernel Shield sync warning: ${l.message}`)}let _=g.collections||{},I=Object.entries(_).map(([l,z])=>{let S=z.fields||z.schema||{},T=Object.entries(S).map(([F,P])=>{let L="any",j=String(typeof P=="string"?P:P.type||"").toLowerCase();return j==="string"||j==="text"||j==="media"?L="string":j==="number"?L="number":j==="boolean"||j==="toggle"?L="boolean":j==="array"&&(L="any[]"),` ${F}?:${L};`}).join(`
650
+ `,"utf8"),u("\u2192 Managed by system, no longer required from your code: "+v.notes.join(", ")+"."))}let{protocol:E}=await Q(),b=Le(g,w,E);i.writeFileSync(d,b,"utf8"),u(" \u2192 Contract markdown successfully generated at project root.");try{let v=Object.keys(g.collections||{});if(f&&!o&&Object.keys(g.collections||{}).length>0)try{await Pe(f,g,w),u(" \u2192 Schema successfully sealed into OZmoz Kernel.")}catch(l){y(`\u26A0\uFE0F Kernel Shield sync warning: ${l.message}`)}let _=g.collections||{},I=Object.entries(_).map(([l,z])=>{let S=z.fields||z.schema||{},T=Object.entries(S).map(([F,P])=>{let L="any",j=String(typeof P=="string"?P:P.type||"").toLowerCase();return j==="string"||j==="text"||j==="media"?L="string":j==="number"?L="number":j==="boolean"||j==="toggle"?L="boolean":j==="array"&&(L="any[]"),` ${F}?:${L};`}).join(`
651
651
  `);return` ${l}: {
652
652
  ${T}
653
653
  };`}).join(`
@@ -799,7 +799,7 @@ declare module 'svelte/elements' {
799
799
  'oz-reference': OzProp;
800
800
  }
801
801
  }
802
- `;i.writeFileSync(c,l)}ae(e),ce(e,t),le(e),ue(e),u(` [OZmoz] Schema synced successfully (${v.length} collection(s)).`),r&&u("\u2192 [Dry-run] Schema is valid.")}catch(v){y(`Error during synchronization: ${v.message}`),process.exit(1)}}else if(k==="create"){let r=C.slice(1).filter(o=>!o.startsWith("--")).join(" ");await Ze(e,r),process.exit(0)}else if(k==="update")await Ue(e),process.exit(0);else if(k==="mcp"){let r=C.includes("--run"),o=!1;if(!r&&!process.stdin.isTTY&&(r=await new Promise(s=>{let n=process.stdin,d=null,c=p=>{clearTimeout(d),n.removeListener("data",h),n.removeListener("end",f),n.removeListener("error",f),s(p)},h=p=>{n.pause(),n.unshift(p),o=!0,c(!0)},f=()=>c(!1);d=setTimeout(()=>{n.pause(),c(!1)},1500),n.on("data",h),n.once("end",f),n.once("error",f)})),r){try{await import(`file://${ee()}`),o&&process.stdin.resume()}catch(s){y(`Failed to start MCP server: ${s.message}`),process.exit(1)}return}await te(e,C),process.exit(0)}else k==="login"?(await _e(e),process.exit(0)):k==="start"?xe(e,C):["--help","-h","help"].includes(k)?(u(`OZmoz CLI
802
+ `;i.writeFileSync(c,l)}ae(e),ce(e,t),le(e),ue(e),u(`[OZmoz] Schema synced successfully (${v.length} collection(s)).`),r&&u(" \u2192 [Dry-run] Schema is valid.")}catch(v){y(`Error during synchronization: ${v.message}`),process.exit(1)}}else if(k==="create"){let r=C.slice(1).filter(o=>!o.startsWith("--")).join(" ");await Me(e,r),process.exit(0)}else if(k==="update")await Ue(e),process.exit(0);else if(k==="mcp"){let r=C.includes("--run"),o=!1;if(!r&&!process.stdin.isTTY&&(r=await new Promise(s=>{let n=process.stdin,d=null,c=p=>{clearTimeout(d),n.removeListener("data",h),n.removeListener("end",f),n.removeListener("error",f),s(p)},h=p=>{n.pause(),n.unshift(p),o=!0,c(!0)},f=()=>c(!1);d=setTimeout(()=>{n.pause(),c(!1)},1500),n.on("data",h),n.once("end",f),n.once("error",f)})),r){try{await import(`file://${ee()}`),o&&process.stdin.resume()}catch(s){y(`Failed to start MCP server: ${s.message}`),process.exit(1)}return}await te(e,C),process.exit(0)}else k==="login"?(await _e(e),process.exit(0)):k==="start"?xe(e,C):["--help","-h","help"].includes(k)?(u(`OZmoz CLI
803
803
 
804
804
  Commands:
805
805
  login Authenticate this machine (opens the browser: approve once, the command exits by itself)
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "ozmoz",
3
- "version": "0.1.45",
3
+ "version": "0.1.47",
4
+ "mcpName": "io.ozmoz/ozmoz",
4
5
  "description": "SDK and CLI for the oz.* data API and the <oz-*> web components.",
5
6
  "license": "UNLICENSED",
6
7
  "keywords": [