fleetbo-svro 1.0.65 → 1.0.66
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/cli.cjs +53 -52
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var ue=(e,o)=>()=>{try{return o||e((o={exports:{}}).exports,o),o.exports}catch(
|
|
3
|
-
`),F("\u2192 Created svro.schema.json at project root.")}function
|
|
2
|
+
var ue=(e,o)=>()=>{try{return o||e((o={exports:{}}).exports,o),o.exports}catch(t){throw o=0,t}};var X=ue((Ze,W)=>{var u=require("fs"),g=require("path"),de=require("https"),{execSync:pe}=require("child_process"),fe="\x1B[38;2;231;233;237m",me="\x1B[31m",$="\x1B[0m";function F(e){console.log(` ${fe}${e}${$}`)}function P(e){console.error(` ${me}${e}${$}`)}function be(e){let o={};return e.forEach(t=>{if(t.startsWith("--")){let[n,r]=t.slice(2).split("=");n&&r&&(o[n]=r)}}),o}function M(e,o){try{let t=JSON.parse(u.readFileSync(e,"utf8"));return!!(t.dependencies&&t.dependencies[o]||t.devDependencies&&t.devDependencies[o])}catch{return!1}}function ge(e,o){try{return u.existsSync(g.join(e,"node_modules",o,"package.json"))}catch{return!1}}function Ee(e,o){if(u.existsSync(g.join(e,"pnpm-lock.yaml")))return"pnpm";if(u.existsSync(g.join(e,"yarn.lock")))return"yarn";if(u.existsSync(g.join(e,"bun.lockb")))return"bun";try{let t=JSON.parse(u.readFileSync(o,"utf8"));if(typeof t.packageManager=="string"){if(t.packageManager.startsWith("pnpm"))return"pnpm";if(t.packageManager.startsWith("yarn"))return"yarn";if(t.packageManager.startsWith("bun"))return"bun"}}catch{}return"npm"}function he(e,o){if(!M(o,"fleetbo-svro")||!ge(e,"fleetbo-svro")){let t=Ee(e,o),n={pnpm:"pnpm add fleetbo-svro",yarn:"yarn add fleetbo-svro",bun:"bun add fleetbo-svro",npm:"npm install fleetbo-svro"}[t];F(`\u2192 Installing fleetbo-svro into the project (detected: ${t})...`);try{pe(n,{cwd:e,stdio:"inherit"}),F("fleetbo-svro installed successfully!")}catch(r){P(`\u26A0\uFE0F Automatic installation failed: ${r.message}`),P(`\u{1F449} Please run '${n}' manually.`)}}}function Te(e){let o=g.join(e,"svro.schema.json");if(u.existsSync(o))return;let t=new Date().toISOString(),n={createdAt:t,patchedAt:t,schemaVersion:1,collections:{}};u.writeFileSync(o,JSON.stringify(n,null,2)+`
|
|
3
|
+
`),F("\u2192 Created svro.schema.json at project root.")}function ye(e){let o=g.join(e,".env"),t=`
|
|
4
4
|
# Fleetbo UI Sandbox Mode
|
|
5
5
|
# true = Sandbox mode: simulates writes locally for fluid UI testing; no DB access and IDE alert.
|
|
6
6
|
# false = Strict production mode: enforces schema contracts and persists to DB
|
|
7
7
|
VITE_FLEETBO_PROTOTYPE=true
|
|
8
|
-
`;if(!u.existsSync(o))u.writeFileSync(o,
|
|
8
|
+
`;if(!u.existsSync(o))u.writeFileSync(o,t.trimStart()),F("\u2192 Created .env with VITE_FLEETBO_PROTOTYPE=true");else{let n=u.readFileSync(o,"utf8");!n.includes("VITE_FLEETBO_PROTOTYPE")&&!n.includes("FLEETBO_PROTOTYPE")&&(u.appendFileSync(o,t),F("\u2192 Injected VITE_FLEETBO_PROTOTYPE=true into existing .env"))}}function Fe(e){let o=g.join(e,"src");if(!u.existsSync(o))return;let t=g.join(o,"fleetbo.d.ts");if(u.existsSync(t))return;let n=`/* eslint-disable */
|
|
9
9
|
/* prettier-ignore */
|
|
10
10
|
// @ts-nocheck
|
|
11
11
|
export {}
|
|
@@ -70,16 +70,16 @@ declare global {
|
|
|
70
70
|
'fleetbo-reference': FleetboProp;
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
`;try{u.writeFileSync(n
|
|
73
|
+
`;try{u.writeFileSync(t,n),F("\u2192 Created src/fleetbo.d.ts stub for instant IDE auto-completion.")}catch(r){P(`\u26A0\uFE0F Unable to create src/fleetbo.d.ts: ${r.message}`)}}function ve(e){let o=g.join(e,"index.d.ts");u.existsSync(o)||F("\u2192 Verified index.d.ts presence.")}function Oe(e){let o=["tsconfig.json","jsconfig.json"];for(let t of o){let n=g.join(e,t);if(u.existsSync(n)){let r=new Date;u.utimesSync(n,r,r);break}}}function Se(e){return new Promise((o,t)=>{let n=JSON.stringify({token:e}),r={hostname:"bootstrapproject-jqycakhlxa-uc.a.run.app",path:"/",method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(n)}},i=de.request(r,s=>{let l="";s.on("data",a=>{l+=a}),s.on("end",()=>{if(s.statusCode>=200&&s.statusCode<300)try{o(JSON.parse(l))}catch{t(new Error("Invalid response received from Fleetbo server."))}else try{let a=JSON.parse(l);t(new Error(a.error||`Server error ${s.statusCode}`))}catch{t(new Error(`Server error ${s.statusCode}`))}})});i.on("error",s=>t(s)),i.write(n),i.end()})}async function Pe(e,o=[]){let t=g.join(e,".env");if(u.existsSync(t)&&u.readFileSync(t,"utf8").includes("VITE_FLEETBO_DB_KEY")){F("\u2192 Fleetbo environment variables already present in .env \u2014 skipping step.");return}let n=be(o),r=n.keyApp,i=n.token||n.bootstrapToken,s=n.email||"";(!r||!i)&&(P("\u26A0\uFE0F Missing required parameters."),P("\u{1F449} Usage: npx fleetbo-svro init --keyApp=YOUR_KEY --token=YOUR_TOKEN"),process.exit(1)),F("\u2192 Exchanging bootstrap token for project keys...");let l;try{l=await Se(i)}catch(b){P(`\u26A0\uFE0F Token exchange failed: ${b.message}`),P("\u{1F449} The token may have expired (15 min limit) or was already used. Please regenerate one from the Fleetbo dashboard."),process.exit(1)}(!l.enterpriseId||!l.fleetboDBKey)&&(P("\u26A0\uFE0F Incomplete response from Fleetbo server."),process.exit(1));let a=l.facebookAppId||n.fbAppId||n.facebookAppId||"11967268204758",c=`
|
|
74
74
|
VITE_FLEETBO_DB_KEY=${l.fleetboDBKey}
|
|
75
75
|
VITE_FLEETBO_ENTERPRISE_ID=${l.enterpriseId}
|
|
76
76
|
VITE_FLEETBO_KEY_APP=${r}
|
|
77
77
|
${s?`VITE_FLEETBO_TESTER_EMAIL=${s}
|
|
78
78
|
`:""}VITE_FLEETBO_FACEBOOK_APP_ID=${a}
|
|
79
|
-
`;u.appendFileSync(
|
|
80
|
-
`),F(`\u2192 Updated ${g.basename(r)}.`))}function G(e){let o=["src/app/layout.tsx","src/app/layout.jsx","app/layout.tsx","app/layout.jsx","src/pages/_app.tsx","src/pages/_app.jsx","pages/_app.tsx","pages/_app.jsx","src/main.tsx","src/main.jsx","src/main.ts","src/main.js","src/index.tsx","src/index.jsx","src/index.ts","src/index.js","src/App.tsx","src/App.jsx","src/App.vue","app.vue","src/routes/+layout.svelte","src/routes/+layout.ts","src/main.singletons.ts"];for(let
|
|
79
|
+
`;u.appendFileSync(t,c),F(".env file updated successfully with Fleetbo keys!")}function Y(e){let o=g.join(e,"svro.d.ts");if(u.existsSync(o))try{u.unlinkSync(o),F("\u2192 Removed legacy svro.d.ts from project root.")}catch{}}function K(e,o){if(process.env.FLEETBO_SKIP_TYPECHECK_SETUP)return;let t=g.join(e,"tsconfig.json"),n=g.join(e,"jsconfig.json"),r=u.existsSync(t)?t:n,i=!u.existsSync(r),s={};if(!i)try{s=JSON.parse(u.readFileSync(r,"utf8"))}catch{P(`\u26A0\uFE0F Unable to read ${g.basename(r)} (Invalid JSON).`);return}s.compilerOptions=s.compilerOptions||{};let l=!1,a=M(o,"react");i?(s.compilerOptions.checkJs=!0,s.compilerOptions.allowJs=!0,s.compilerOptions.target=s.compilerOptions.target||"ES2020",s.compilerOptions.module=s.compilerOptions.module||"ESNext",s.compilerOptions.moduleResolution=s.compilerOptions.moduleResolution||"bundler",s.include=["src/**/*"],l=!0):(s.compilerOptions.checkJs===void 0&&(s.compilerOptions.checkJs=!0,l=!0),s.compilerOptions.allowJs===void 0&&(s.compilerOptions.allowJs=!0,l=!0)),a&&s.compilerOptions.jsx===void 0&&(s.compilerOptions.jsx="react-jsx",l=!0),Array.isArray(s.compilerOptions.types)&&s.compilerOptions.types.includes("vite/client")&&(s.compilerOptions.types=s.compilerOptions.types.filter(c=>c!=="vite/client"),s.compilerOptions.types.length===0&&delete s.compilerOptions.types,l=!0,F(`\u2192 Removed legacy "vite/client" entry from ${g.basename(r)}.`)),l&&(u.writeFileSync(r,JSON.stringify(s,null,2)+`
|
|
80
|
+
`),F(`\u2192 Updated ${g.basename(r)}.`))}function G(e){let o=["src/app/layout.tsx","src/app/layout.jsx","app/layout.tsx","app/layout.jsx","src/pages/_app.tsx","src/pages/_app.jsx","pages/_app.tsx","pages/_app.jsx","src/main.tsx","src/main.jsx","src/main.ts","src/main.js","src/index.tsx","src/index.jsx","src/index.ts","src/index.js","src/App.tsx","src/App.jsx","src/App.vue","app.vue","src/routes/+layout.svelte","src/routes/+layout.ts","src/main.singletons.ts"];for(let t of o){let n=g.join(e,t);if(u.existsSync(n)){let r=u.readFileSync(n,"utf8");r.includes("fleetbo-svro")||(r.startsWith('"use client"')||r.startsWith("'use client'")?r=r.replace(/(['"]use client['"];?\r?\n)/,`$1import 'fleetbo-svro';
|
|
81
81
|
`):r=`import 'fleetbo-svro';
|
|
82
|
-
`+r,u.writeFileSync(
|
|
82
|
+
`+r,u.writeFileSync(n,r));return}}}function H(e,o){if(process.env.FLEETBO_SKIP_AUTOIMPORT_SETUP)return;let n=["vite.config.ts","vite.config.js","vite.config.mjs"].map(a=>g.join(e,a)).find(a=>u.existsSync(a));if(!n)return;let r;try{r=u.readFileSync(n,"utf8")}catch{return}let i="fleetbo-svro",s=r,l=`{
|
|
83
83
|
name: 'fleetbo-auto-runtime',
|
|
84
84
|
transform(code, id) {
|
|
85
85
|
if (!id.includes('node_modules') && !code.includes('fleetbo-svro') && /(src[\\\\/](main|index|App|root))\\.(jsx?|tsx?|vue|svelte)/i.test(id)) {
|
|
@@ -131,15 +131,15 @@ ${s?`VITE_FLEETBO_TESTER_EMAIL=${s}
|
|
|
131
131
|
watch: {
|
|
132
132
|
ignored: ['**/svro.schema.json', '**/src/auto-imports.d.ts']
|
|
133
133
|
}
|
|
134
|
-
},`))),!s.includes("unplugin-auto-import")){let a=s.match(/plugins\s*:\s*\[/);if(a){let c=a.index+a[0].length,
|
|
134
|
+
},`))),!s.includes("unplugin-auto-import")){let a=s.match(/plugins\s*:\s*\[/);if(a){let c=a.index+a[0].length,b=`
|
|
135
135
|
AutoImport({
|
|
136
136
|
imports: [{ '${i}': ['Fleetbo', 'FleetboUI'] }],
|
|
137
137
|
dts: 'src/auto-imports.d.ts'
|
|
138
|
-
}),`;if(s=s.slice(0,c)+
|
|
139
|
-
`;if(T){let
|
|
140
|
-
`+
|
|
141
|
-
`+l+s.slice(c)}}s!==r&&u.writeFileSync(
|
|
142
|
-
`),F("\u2192 Configured Fleetbo Cyan visual hints in .vscode/settings.json.")}catch{}}function Ie(e,o,
|
|
138
|
+
}),`;if(s=s.slice(0,c)+b+s.slice(c),!s.includes("import AutoImport")){let T=[...s.matchAll(/^import .+;?$/gm)].pop(),E=`import AutoImport from 'unplugin-auto-import/vite';
|
|
139
|
+
`;if(T){let y=T.index+T[0].length;s=s.slice(0,y)+`
|
|
140
|
+
`+E+s.slice(y)}else s=E+s}}}if(!s.includes("fleetbo-auto-runtime")){let a=s.match(/plugins\s*:\s*\[/);if(a){let c=a.index+a[0].length;s=s.slice(0,c)+`
|
|
141
|
+
`+l+s.slice(c)}}s!==r&&u.writeFileSync(n,s)}function xe(e){let o=g.join(e,".vscode"),t=g.join(o,"settings.json");try{u.existsSync(o)||u.mkdirSync(o,{recursive:!0});let n={};if(u.existsSync(t))try{n=JSON.parse(u.readFileSync(t,"utf8"))}catch{n={}}n["workbench.colorCustomizations"]=n["workbench.colorCustomizations"]||{},n["workbench.colorCustomizations"]["editorInfo.foreground"]="#00feae",n["workbench.colorCustomizations"]["editorHint.foreground"]="#00feae",u.writeFileSync(t,JSON.stringify(n,null,2)+`
|
|
142
|
+
`),F("\u2192 Configured Fleetbo Cyan visual hints in .vscode/settings.json.")}catch{}}function Ie(e,o,t={}){let{skipSelfInstall:n=!1}=t,r=g.join(__dirname,"..");n||he(e,o),Te(e),ye(e),ve(r),Fe(e),xe(e),Y(e),K(e,o),H(e,o),G(e)}W.exports={touchTsConfig:Oe,log:F,logError:P,handleAuthAndEnv:Pe,detectDependency:M,cleanupLegacyRootDts:Y,patchJsOrTsConfig:K,attemptViteAutoImportPatch:H,injectUniversalRuntime:G,runFullSetup:Ie}});var p=require("fs"),m=require("path"),Z=require("https"),Ae=require("http"),k=require("os"),{exec:Ce,spawnSync:ee}=require("child_process"),{runFullSetup:_e,handleAuthAndEnv:je,touchTsConfig:we,attemptViteAutoImportPatch:Le,injectUniversalRuntime:Ne}=X(),De="\x1B[34m",Re="\x1B[31m",te="\x1B[0m";function d(e){console.log(`${De}${e}${te}`)}function S(e){console.error(`${Re}${e}${te}`)}var oe=`1. TA LIBERT\xC9 : tout le front-end t'appartient (rendu, \xE9tat, styles, navigation, composants, logique d'interface, choix du framework). Fleetbo ne g\xE8re que les donn\xE9es, l'authentification et le stockage. Un changement qui ne touche pas aux donn\xE9es ne demande l'accord de personne.
|
|
143
143
|
|
|
144
144
|
2. TON INTERLOCUTEUR n'est pas d\xE9veloppeur. Dans tes messages \xE0 l'utilisateur (pas dans le code), parle fran\xE7ais simple et sans jargon : ne dis jamais prototype, true, false, .env, contrat, sch\xE9ma, sync, Edge, endpoint, collection ni fleetbo_update_project. Dis plut\xF4t :
|
|
145
145
|
- \xAB mode essai \xBB (donn\xE9es de d\xE9monstration) pour VITE_FLEETBO_PROTOTYPE=true, et \xAB mode r\xE9el \xBB (vraies donn\xE9es) pour false ;
|
|
@@ -174,7 +174,7 @@ ${s?`VITE_FLEETBO_TESTER_EMAIL=${s}
|
|
|
174
174
|
|
|
175
175
|
7. SYNCHRONISATION : apr\xE8s chaque mise \xE0 jour du backend Fleetbo (contrat, svro.schema.json, svro.workflow.json...), ex\xE9cute npx fleetbo-svro sync avant de continuer \xE0 coder. Cela vaut quelle que soit l'origine de la mise \xE0 jour : toi (fleetbo_update_project) ou Alex dans Fleetbo Studio (d\xE8s que l'utilisateur te dit qu'Alex a modifi\xE9 ou valid\xE9 quelque chose). Fais-le toi-m\xEAme, puis dis \xE0 l'utilisateur en une phrase que la nouvelle structure est enregistr\xE9e.
|
|
176
176
|
|
|
177
|
-
8. NE FAIS JAMAIS : modifier VITE_FLEETBO_PROTOTYPE de ta propre initiative (uniquement avec l'accord explicite de l'utilisateur, apr\xE8s lui avoir expliqu\xE9 en une phrase la diff\xE9rence entre mode essai et mode r\xE9el) ; concevoir ou \xE9diter svro.schema.json et svro.workflow.json (autorit\xE9 d'Alex) ; \xE9crire un backend, une route d'API ou un ORM ; inventer des m\xE9thodes Fleetbo.* ou des balises <fleetbo-*>.`,
|
|
177
|
+
8. NE FAIS JAMAIS : modifier VITE_FLEETBO_PROTOTYPE de ta propre initiative (uniquement avec l'accord explicite de l'utilisateur, apr\xE8s lui avoir expliqu\xE9 en une phrase la diff\xE9rence entre mode essai et mode r\xE9el) ; concevoir ou \xE9diter svro.schema.json et svro.workflow.json (autorit\xE9 d'Alex) ; \xE9crire un backend, une route d'API ou un ORM ; inventer des m\xE9thodes Fleetbo.* ou des balises <fleetbo-*>.`,x="fleetbo-svro",ne=["-y","fleetbo-svro@latest","mcp","--run"],V=/<!-- fleetbo:start[^>]*-->[\s\S]*?<!-- fleetbo:end -->/,ke="<!-- fleetbo:end -->",se="# FLEETBO DATA OS \u2014 DIRECTIVES SYST\xC8ME",N={claude:"Claude Code",cursor:"Cursor",windsurf:"Windsurf",devin:"Devin",codex:"Codex CLI",gemini:"Gemini CLI"},Be=`D1. TOUTE demande de cr\xE9ation d'une NOUVELLE application DOIT d\xE9clencher l'outil MCP 'fleetbo_create_project'. Mais si le '.env' du projet contient d\xE9j\xE0 VITE_FLEETBO_DB_KEY (ou si 'svro.schema.json' existe), le projet EXISTE : n'appelle JAMAIS 'fleetbo_create_project' ; utilise 'fleetbo_update_project' (le 'keyApp' est la valeur de VITE_FLEETBO_DB_KEY ; passe-le explicitement si la session n'a pas \xE9t\xE9 lanc\xE9e dans le dossier du projet).
|
|
178
178
|
|
|
179
179
|
D2. Le serveur MCP est d\xE9j\xE0 pr\xE9-authentifi\xE9 : n'inspecte pas le shell ('env', 'grep'), ne parcours pas le syst\xE8me de fichiers hors de la racine du projet et ne lance pas de connexion (lire le '.env' du projet est autoris\xE9). Seule exception : si un outil renvoie \xAB FLEETBO_DEV_TOKEN missing \xBB, ex\xE9cute UNE fois 'npx fleetbo-svro login', attends qu'elle se termine (l'utilisateur valide dans le navigateur : pr\xE9viens-le simplement), puis relance l'outil.
|
|
180
180
|
|
|
@@ -188,27 +188,27 @@ D6. Sources des r\xE8gles Fleetbo : ce fichier (protocole ci-dessous), 'Fleetbo_
|
|
|
188
188
|
|
|
189
189
|
D7. Avant d'\xE9crire du code de donn\xE9es, lis VITE_FLEETBO_PROTOTYPE dans le '.env' du projet : true = prototype purement visuel (bac \xE0 sable local du SDK : les \xE9critures sont relues par les lectures ; donn\xE9es de d\xE9mo via Fleetbo.seed) ; false = production ('Fleetbo.*' et la s\xE9curit\xE9 Edge prennent le relais). Zero-Rewrite (philosophie) : \xE9cris le code de la m\xEAme fa\xE7on en prototype et en production, sans chemin s\xE9par\xE9 par mode ; seules les donn\xE9es peuvent \xEAtre virtuelles. C'est un principe de conception, pas une interdiction de corriger le code. Ne modifie jamais cette valeur de ta propre initiative : uniquement avec l'accord explicite de l'utilisateur.
|
|
190
190
|
|
|
191
|
-
D8. Pour toute d\xE9cision touchant aux donn\xE9es (ce que tu fais selon le mode, quand passer la main \xE0 Alex, quand ne pas le faire, quand lancer la synchronisation), applique \xE0 la lettre le PROTOCOLE DONN\xC9ES ci-dessous (identique \xE0 celui de 'Fleetbo_contract.md'). L'utilisateur n'est pas d\xE9veloppeur : parle-lui en fran\xE7ais simple, sans jargon, et fais toi-m\xEAme toutes les manipulations techniques. En dehors des donn\xE9es, le front-end est enti\xE8rement libre.`,
|
|
191
|
+
D8. Pour toute d\xE9cision touchant aux donn\xE9es (ce que tu fais selon le mode, quand passer la main \xE0 Alex, quand ne pas le faire, quand lancer la synchronisation), applique \xE0 la lettre le PROTOCOLE DONN\xC9ES ci-dessous (identique \xE0 celui de 'Fleetbo_contract.md'). L'utilisateur n'est pas d\xE9veloppeur : parle-lui en fran\xE7ais simple, sans jargon, et fais toi-m\xEAme toutes les manipulations techniques. En dehors des donn\xE9es, le front-end est enti\xE8rement libre.`,_={created:"created",updated:"updated",unchanged:"already up to date",appended:"Fleetbo block appended (your own content was kept)",migrated:"old Fleetbo file replaced (backup: <file>.fleetbo-legacy.bak)",invalid:"skipped: the file is not valid JSON, fix or delete it first"};function Ue(){try{return JSON.parse(p.readFileSync(m.join(__dirname,"..","package.json"),"utf8")).version||"dev"}catch{return"dev"}}function Me(){return`# FLEETBO DATA OS \u2014 DIRECTIVES AGENT
|
|
192
192
|
|
|
193
193
|
`+Be+`
|
|
194
194
|
|
|
195
195
|
## PROTOCOLE DONN\xC9ES : QUI FAIT QUOI (AGENT FRONTEND \u2194 ALEX AI)
|
|
196
196
|
|
|
197
|
-
`+
|
|
197
|
+
`+oe}function z(e,o){return"<!-- fleetbo:start v"+e+` -->
|
|
198
198
|
`+o.trim()+`
|
|
199
199
|
`+ke+`
|
|
200
|
-
`}function qe(e,o,
|
|
201
|
-
|
|
202
|
-
`)+o),!
|
|
203
|
-
`,"utf8")),r?"updated":"created")}function
|
|
204
|
-
`):[],a
|
|
205
|
-
`).slice(-2).join(" "),legacy:
|
|
206
|
-
[Fleetbo] Configuring your AI agents`+(
|
|
207
|
-
@AGENTS.md`)]),(!i||i.includes("gemini"))&&
|
|
200
|
+
`}function qe(e,o,t){let n=p.existsSync(e)?p.readFileSync(e,"utf8"):null,r,i;return n===null?(r="created",i=o):V.test(n)?(i=n.replace(V,()=>o.trimEnd()),r=i===n?"unchanged":"updated"):n.includes(se)?(r="migrated",i=o):(r="appended",i=n.replace(/\s*$/,`
|
|
201
|
+
|
|
202
|
+
`)+o),!t&&r!=="unchanged"&&(r==="migrated"&&p.writeFileSync(e+".fleetbo-legacy.bak",n,"utf8"),p.mkdirSync(m.dirname(e),{recursive:!0}),p.writeFileSync(e,i,"utf8")),r}function B(e,o){let t={command:"npx",args:ne},n={};if(p.existsSync(e))try{let i=JSON.parse(p.readFileSync(e,"utf8"));if(!i||typeof i!="object"||Array.isArray(i))return"invalid";n=i}catch{return"invalid"}let r=n.mcpServers&&n.mcpServers[x];return r&&JSON.stringify(r)===JSON.stringify(t)?"unchanged":(n.mcpServers=n.mcpServers||{},n.mcpServers[x]=t,o||(p.mkdirSync(m.dirname(e),{recursive:!0}),p.writeFileSync(e,JSON.stringify(n,null,2)+`
|
|
203
|
+
`,"utf8")),r?"updated":"created")}function D(e){let o=process.platform==="win32"?"where":"which";return ee(o,[e],{stdio:"ignore"}).status===0}function q(e,o,t){let n=ee(e,o,{encoding:"utf8",timeout:t||3e4,shell:process.platform==="win32"});return{ok:n.status===0,out:(n.stdout||"")+(n.stderr||"")}}function Ve(e,o,t){let n=e==="claude"?["--scope",t||"user"]:[],r=["mcp","add"].concat(n,[x,"--","npx"],ne),i=["mcp","remove",x].concat(n),s=e+" "+r.join(" ");if(!D(e))return{status:"manual",detail:s};if(o)return{status:"planned",detail:s};let l=q(e,["mcp","list"],6e4),a=l.ok?l.out.split(`
|
|
204
|
+
`):[],c=a.find(E=>/^[\s|│┃]*fleetbo-svro(?![\w@-])/.test(E)),b=a.some(E=>/^\s*fleetbo:\s.*fleetbo-svro/.test(E));if(c&&c.includes("fleetbo-svro@latest"))return{status:"unchanged",legacy:b};if(c&&!q(e,i).ok)return{status:"manual",detail:e+" "+i.join(" ")+" && "+s,legacy:b};let T=q(e,r);return T.ok?{status:c?"updated":"created",legacy:b}:{status:"failed",detail:s,message:T.out.trim().split(`
|
|
205
|
+
`).slice(-2).join(" "),legacy:b}}function Je(e){let o={user:!1,local:!1,others:[]};try{let t=JSON.parse(p.readFileSync(m.join(k.homedir(),".claude.json"),"utf8")),n=l=>!!l&&typeof l=="object"&&/fleetbo-svro/.test(String(l.command||"")+" "+JSON.stringify(l.args||[])),r=(l,a)=>{!l||typeof l!="object"||Object.keys(l).forEach(c=>{c===x?o[a]=!0:n(l[c])&&o.others.push({name:c,where:a})})};r(t.mcpServers,"user");let i=e;try{i=p.realpathSync(e)}catch{}let s=t.projects||{};Array.from(new Set([e,i])).forEach(l=>r((s[l]||{}).mcpServers,"local"))}catch{}return o}function $e(e){let o=Je(e);o.user&&d(" \u26A0\uFE0F A global (user-scope) '"+x+"' entry from a previous version also exists: the Fleetbo tools appear in every project. To keep them in Fleetbo projects only: claude mcp remove "+x+" --scope user"),o.local&&d(" \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"),o.others.forEach(t=>{d(" \u26A0\uFE0F An old MCP entry named '"+t.name+"' ("+t.where+" scope) points to Fleetbo. Remove it: claude mcp remove "+t.name+" --scope "+t.where)})}function Ye(e){let o=k.homedir(),t=n=>p.existsSync(n);return{claude:D("claude")||t(m.join(o,".claude")),cursor:t(m.join(e,".cursor"))||t(m.join(o,".cursor"))||D("cursor"),windsurf:t(m.join(o,".codeium","windsurf"))||t(m.join(e,".windsurf")),devin:t(m.join(e,".devin")),codex:D("codex")||t(m.join(o,".codex")),gemini:D("gemini")||t(m.join(o,".gemini"))}}async function Ke(e,o){let t=o.includes("--dry-run"),n=o.find(f=>f.startsWith("--agent=")),r=n&&n.slice(8).trim()?n.slice(8).split(",").map(f=>f.trim().toLowerCase()).filter(Boolean):null,i=null;if(r){i=r.includes("all")?Object.keys(N):r;let f=i.filter(v=>!N[v]);f.length&&(S("Unknown agent(s): "+f.join(", ")+". Valid values: "+Object.keys(N).join(", ")+", all."),process.exit(1))}let s=o.find(f=>f.startsWith("--scope=")),l=s?s.slice(8).trim().toLowerCase():"project";["project","user","local"].includes(l)||(S("Unknown scope: "+l+". Valid values for Claude Code: project (default), user, local."),process.exit(1));let a=Ye(e),c=i||Object.keys(N).filter(f=>a[f]),b=Ue();d(`
|
|
206
|
+
[Fleetbo] Configuring your AI agents`+(t?" (dry run: nothing is written)":"")+"...");let T=z(b,Me()),E=[];(!i||i.some(f=>f!=="gemini"))&&E.push(["AGENTS.md",T]),(!i||i.includes("claude"))&&E.push(["CLAUDE.md",z(b,`# FLEETBO DATA OS \u2014 DIRECTIVES AGENT
|
|
207
|
+
@AGENTS.md`)]),(!i||i.includes("gemini"))&&E.push(["GEMINI.md",T]);let y=m.join(e,".cursorrules");if(p.existsSync(y)){let f=p.readFileSync(y,"utf8");(V.test(f)||f.includes(se))&&E.push([".cursorrules",T])}for(let f of E)d("\u2192 "+f[0]+": "+_[qe(m.join(e,f[0]),f[1],t)]);for(let f of c){let v=N[f];if(f==="cursor")d("\u2192 "+v+" MCP (.cursor/mcp.json): "+_[B(m.join(e,".cursor","mcp.json"),t)]);else if(f==="windsurf")d("\u2192 "+v+" MCP (~/.codeium/windsurf/mcp_config.json): "+_[B(m.join(k.homedir(),".codeium","windsurf","mcp_config.json"),t)]);else if(f==="gemini")d("\u2192 "+v+" MCP (.gemini/settings.json): "+_[B(m.join(e,".gemini","settings.json"),t)]);else if(f==="claude"&&l==="project"){let h=B(m.join(e,".mcp.json"),t);d("\u2192 "+v+" MCP (.mcp.json, project scope): "+_[h]),(h==="created"||h==="updated")&&d(" 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)."),$e(e)}else if(f==="claude"||f==="codex"){let h=Ve(f,t,l);h.status==="manual"?d("\u2192 "+v+": '"+f+"' not found or not scriptable. Run manually: "+h.detail):h.status==="planned"?d("\u2192 "+v+" MCP: would run: "+h.detail):h.status==="failed"?S("\u2192 "+v+" MCP: registration failed ("+h.message+"). Run manually: "+h.detail):d("\u2192 "+v+" MCP"+(f==="claude"?" ("+l+" scope)":" (~/.codex/config.toml, global)")+": "+_[h.status]),h.legacy&&d(" \u26A0\uFE0F An old MCP entry named 'fleetbo' exists. Remove it: "+f+" mcp remove fleetbo")}else f==="devin"&&d("\u2192 "+v+": reads AGENTS.md. Devin runs in its own environment: add the Fleetbo MCP server from Devin's settings (not automated).")}!i&&c.length===0&&d("\u2192 No agent detected: instruction files were written; re-run with --agent=<name> to register the MCP server.");let w=!!(re(e).FLEETBO_DEV_TOKEN||process.env.FLEETBO_DEV_TOKEN),O=m.join(k.homedir(),".fleetbo","credentials.json");if(p.existsSync(O))try{w=w||!!JSON.parse(p.readFileSync(O,"utf8")).devToken}catch{}w||S('\u26A0\uFE0F No developer token found. Run "npx fleetbo-svro login" once.'),d(`
|
|
208
208
|
[Fleetbo] Done. Restart your agent so it reloads the Fleetbo tools and the instruction files.
|
|
209
|
-
`)}function
|
|
209
|
+
`)}function Ge(e){let o=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";Ce(`${o} "${e}"`)}function He(e){return new Promise((o,t)=>{let n=Ae.createServer((r,i)=>{if(i.setHeader("Access-Control-Allow-Origin","*"),i.setHeader("Access-Control-Allow-Methods","GET, OPTIONS"),i.setHeader("Access-Control-Allow-Headers","Content-Type, Authorization"),i.setHeader("Access-Control-Allow-Private-Network","true"),r.method==="OPTIONS"){i.writeHead(204),i.end();return}let s=new URL(r.url,"http://127.0.0.1");if(s.pathname==="/callback"){let l=s.searchParams.get("token");if(!l){i.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),i.end("<h3>Error: Missing token.</h3>");return}let a=m.join(k.homedir(),".fleetbo");p.existsSync(a)||p.mkdirSync(a,{recursive:!0}),p.writeFileSync(m.join(a,"credentials.json"),JSON.stringify({devToken:l,updatedAt:new Date().toISOString()},null,2));let c=m.join(e,".env");if(p.existsSync(c)){let b=p.readFileSync(c,"utf8");b.includes("FLEETBO_DEV_TOKEN=")?b=b.replace(/FLEETBO_DEV_TOKEN=.*/g,`FLEETBO_DEV_TOKEN=${l}`):b+=`
|
|
210
210
|
FLEETBO_DEV_TOKEN=${l}
|
|
211
|
-
`,
|
|
211
|
+
`,p.writeFileSync(c,b,"utf8")}i.writeHead(200,{"Content-Type":"text/html; charset=utf-8",Connection:"close"}),i.end(`
|
|
212
212
|
<!DOCTYPE html>
|
|
213
213
|
<html>
|
|
214
214
|
<head>
|
|
@@ -226,12 +226,12 @@ FLEETBO_DEV_TOKEN=${l}
|
|
|
226
226
|
</div>
|
|
227
227
|
</body>
|
|
228
228
|
</html>
|
|
229
|
-
`),
|
|
230
|
-
[Fleetbo] Developer token received and stored successfully!`),
|
|
231
|
-
Next step to connect your AI agents:`),
|
|
232
|
-
`),typeof
|
|
233
|
-
[Fleetbo] Waiting for authentication...`),
|
|
234
|
-
`).forEach(r=>{let[i,...s]=r.split("=");i&&s.length>0&&(
|
|
229
|
+
`),d(`
|
|
230
|
+
[Fleetbo] Developer token received and stored successfully!`),d(`
|
|
231
|
+
Next step to connect your AI agents:`),d(` npx fleetbo-svro mcp (Configure Claude Code, Cursor, Windsurf, Devin, Codex CLI, Gemini CLI)
|
|
232
|
+
`),typeof n.closeAllConnections=="function"&&n.closeAllConnections(),n.close(()=>o()),setTimeout(()=>o(),300)}});n.listen(0,"127.0.0.1",()=>{let i=`https://fleetbo.io/cli-auth?port=${n.address().port}`;d(`
|
|
233
|
+
[Fleetbo] Waiting for authentication...`),d(`If your browser does not open automatically, visit: ${i}`),Ge(i);let s=Number(process.env.FLEETBO_LOGIN_TIMEOUT_MS)||12e4;setTimeout(()=>{try{typeof n.closeAllConnections=="function"&&n.closeAllConnections()}catch{}n.close(),t(new Error(`Login timed out after ${Math.round(s/1e3)}s: browser approval not received. Run "npx fleetbo-svro login" once more and approve in the browser.`))},s).unref()}),n.on("error",r=>t(r))})}function We(e,o){return new Promise((t,n)=>{let r=JSON.stringify({enterpriseID:e,schema:o}),i={hostname:"fleetbo-gatekeeper.fleetbo.workers.dev",path:"/sync-schema",method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(r)}},s=Z.request(i,l=>{let a="";l.on("data",c=>{a+=c}),l.on("end",()=>{l.statusCode>=200&&l.statusCode<300?t(JSON.parse(a)):n(new Error(`Edge sync failed with HTTP ${l.statusCode}`))})});s.on("error",l=>n(l)),s.write(r),s.end()})}function re(e){let o=m.join(e,".env");if(!p.existsSync(o))return{};let t=p.readFileSync(o,"utf8"),n={};return t.split(`
|
|
234
|
+
`).forEach(r=>{let[i,...s]=r.split("=");i&&s.length>0&&(n[i.trim()]=s.join("=").trim())}),n}function Q(e,o){return new Promise((t,n)=>{let r=JSON.stringify({projectId:e,moduleName:o}),i={hostname:"getmodulecache-jqycakhlxa-uc.a.run.app",path:"/",method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(r)}},s=Z.request(i,l=>{let a="";l.on("data",c=>{a+=c}),l.on("end",()=>{if(l.statusCode>=200&&l.statusCode<300)try{let c=JSON.parse(a);if(c.success&&c.found&&c.module){let b=c.module.code||c.module.mockCode;t(typeof b=="string"?JSON.parse(b):b)}else t(null)}catch{n(new Error(`Invalid JSON response for ${o}.`))}else n(new Error(`Server error ${l.statusCode} while fetching ${o}`))})});s.on("error",l=>n(l)),s.write(r),s.end()})}var R=process.argv.slice(2),j=R[0];function Xe(e,o){let t=e?.context||o?.context||"Aucun cahier des charges textuel renseign\xE9.";return`# LE CONTRAT DE DONN\xC9ES FLEETBO (FLEETBO DATA CONTRACT)
|
|
235
235
|
|
|
236
236
|
Ce document constitue le **Cahier des charges officiel et le Contrat bilat\xE9ral d'int\xE9grit\xE9** liant le code client (d\xE9veloppeur ou agent IA) et le moteur Data OS Fleetbo SVRO.
|
|
237
237
|
|
|
@@ -265,7 +265,7 @@ L'agent DOIT adapter son impl\xE9mentation selon la valeur de \`VITE_FLEETBO_PRO
|
|
|
265
265
|
---
|
|
266
266
|
|
|
267
267
|
### \u{1F9ED} PROTOCOLE DONN\xC9ES : QUI FAIT QUOI (AGENT FRONTEND \u2194 ALEX AI)
|
|
268
|
-
${
|
|
268
|
+
${oe}
|
|
269
269
|
|
|
270
270
|
---
|
|
271
271
|
|
|
@@ -282,7 +282,7 @@ ${ne}
|
|
|
282
282
|
---
|
|
283
283
|
|
|
284
284
|
## \u{1F4CB} CAHIER DES CHARGES M\xC9TIER (CONTEXTE DU PROJET)
|
|
285
|
-
${
|
|
285
|
+
${t}
|
|
286
286
|
|
|
287
287
|
---
|
|
288
288
|
|
|
@@ -345,26 +345,26 @@ ${JSON.stringify(e||{},null,2)}
|
|
|
345
345
|
\`\`\`json
|
|
346
346
|
${JSON.stringify(o||{},null,2)}
|
|
347
347
|
\`\`\`
|
|
348
|
-
`}async function
|
|
349
|
-
[Fleetbo] Initializing and configuring Fleetbo...`),await
|
|
348
|
+
`}async function ze(){let e=process.cwd(),o=m.join(e,"package.json");if(j==="init"||j==="doctor")d(`
|
|
349
|
+
[Fleetbo] Initializing and configuring Fleetbo...`),await je(e,R),_e(e,o),d(`
|
|
350
350
|
[Fleetbo] Configuration completed successfully!
|
|
351
|
-
`),
|
|
352
|
-
Next step:`),
|
|
353
|
-
`);else if(
|
|
354
|
-
`),
|
|
355
|
-
`),
|
|
356
|
-
`,"utf8"),
|
|
357
|
-
`,"utf8"),
|
|
358
|
-
`);return` ${
|
|
351
|
+
`),d(`
|
|
352
|
+
Next step:`),d(` npx fleetbo-svro sync (Sync cloud schema & generate IDE types)
|
|
353
|
+
`);else if(j==="sync"){let t=R.includes("--dry-run");d(`[Fleetbo] Syncing schema...${t?" (dry-run)":""}`);let n=m.join(e,"svro.schema.json"),r=m.join(e,"svro.workflow.json"),i=m.join(e,"Fleetbo_contract.md"),s=m.join(__dirname,".."),l=m.join(s,"index.d.ts"),a=m.join(e,"src","fleetbo.d.ts"),b=re(e).VITE_FLEETBO_ENTERPRISE_ID,T=null,E=null;if(b)try{d("\u2192 Fetching latest contracts from Fleetbo Cloud..."),T=await Q(b,"svro.schema.json"),T&&(p.writeFileSync(n,JSON.stringify(T,null,2)+`
|
|
354
|
+
`),d("\u2192 Local svro.schema.json updated.")),E=await Q(b,"svro.workflow.json"),E&&(p.writeFileSync(r,JSON.stringify(E,null,2)+`
|
|
355
|
+
`),d("\u2192 Local svro.workflow.json updated."))}catch(O){S(`\u26A0\uFE0F Cloud fetch bypassed: ${O.message}. Using local file fallback.`)}else S("\u26A0\uFE0F VITE_FLEETBO_ENTERPRISE_ID missing in .env. Skipping cloud fetch.");let y=T;if(!y&&p.existsSync(n))try{y=JSON.parse(p.readFileSync(n,"utf8"))}catch{}y||(y={context:"Application en cours de mod\xE9lisation initiale.",collections:{}},p.writeFileSync(n,JSON.stringify(y,null,2)+`
|
|
356
|
+
`,"utf8"),d("\u2192 Initial blank svro.schema.json created."));let I=E;if(!I&&p.existsSync(r))try{I=JSON.parse(p.readFileSync(r,"utf8"))}catch{}I||(I={actors:{},sequences:[]},p.writeFileSync(r,JSON.stringify(I,null,2)+`
|
|
357
|
+
`,"utf8"),d("\u2192 Initial blank svro.workflow.json created."));let w=Xe(y,I);p.writeFileSync(i,w,"utf8"),d("\u2192 Fleetbo_contract.md successfully generated at project root.");try{let O=Object.keys(y.collections||{});if(b)try{await We(b,y),d("\u2192 Schema successfully sealed at Fleetbo Global Edge (O(1)).")}catch(A){S(`\u26A0\uFE0F Fleetbo Edge Shield sync warning: ${A.message}`)}let f=y.collections||{},v=Object.entries(f).map(([A,J])=>{let le=J.fields||J.schema||{},ae=Object.entries(le).map(([ce,U])=>{let L="any",C=String(typeof U=="string"?U:U.type||"").toLowerCase();return C==="string"||C==="text"||C==="media"?L="string":C==="number"?L="number":C==="boolean"||C==="toggle"?L="boolean":C==="array"&&(L="any[]"),` ${ce}?:${L};`}).join(`
|
|
358
|
+
`);return` ${A}: {
|
|
359
359
|
${ae}
|
|
360
360
|
};`}).join(`
|
|
361
|
-
`),
|
|
361
|
+
`),h=O.length>0?O.map(A=>`'${A}'`).join(" | "):"string",ie=`// Generated by fleetbo-svro \u2014 Updated via fleetbo sync
|
|
362
362
|
|
|
363
363
|
export interface FleetboSchemaMap {
|
|
364
|
-
${
|
|
364
|
+
${v}
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
-
export type KnownFleetboTables = ${
|
|
367
|
+
export type KnownFleetboTables = ${h};
|
|
368
368
|
|
|
369
369
|
export type FleetboTables =
|
|
370
370
|
| KnownFleetboTables
|
|
@@ -634,7 +634,7 @@ declare module 'svelte/elements' {
|
|
|
634
634
|
'fleetbo-reference': FleetboProp;
|
|
635
635
|
}
|
|
636
636
|
}
|
|
637
|
-
`;if(
|
|
637
|
+
`;if(p.writeFileSync(l,ie),p.existsSync(m.dirname(a))){let A=`/* eslint-disable */
|
|
638
638
|
/* prettier-ignore */
|
|
639
639
|
// @ts-nocheck
|
|
640
640
|
// Generated by fleetbo-svro \u2014 Updated via fleetbo sync
|
|
@@ -663,11 +663,11 @@ type FleetboProp = {
|
|
|
663
663
|
};
|
|
664
664
|
|
|
665
665
|
interface FleetboSchemaMap {
|
|
666
|
-
${
|
|
666
|
+
${v}
|
|
667
667
|
}
|
|
668
668
|
|
|
669
669
|
declare global {
|
|
670
|
-
type KnownFleetboTables = ${
|
|
670
|
+
type KnownFleetboTables = ${h};
|
|
671
671
|
type FleetboTables = KnownFleetboTables | (string & { _fleetboPending?: never });
|
|
672
672
|
type FleetboData<T extends string> = T extends KnownFleetboTables
|
|
673
673
|
? Partial<FleetboSchemaMap[T]>
|
|
@@ -768,12 +768,13 @@ declare module 'svelte/elements' {
|
|
|
768
768
|
'fleetbo-reference': FleetboProp;
|
|
769
769
|
}
|
|
770
770
|
}
|
|
771
|
-
`;
|
|
771
|
+
`;p.writeFileSync(a,A)}we(e),Le(e,o),Ne(e),d(`[Fleetbo] Schema synced successfully (${O.length} collection(s)).`),t&&d("\u2192 [Dry-run] Schema is valid.")}catch(O){S(`Error during synchronization: ${O.message}`),process.exit(1)}}else if(j==="mcp"){let t=R.includes("--run"),n=!1;if(!t&&!process.stdin.isTTY&&(t=await new Promise(r=>{let i=process.stdin,s=null,l=b=>{clearTimeout(s),i.removeListener("data",a),i.removeListener("end",c),i.removeListener("error",c),r(b)},a=b=>{i.pause(),i.unshift(b),n=!0,l(!0)},c=()=>l(!1);s=setTimeout(()=>{i.pause(),l(!1)},1500),i.on("data",a),i.once("end",c),i.once("error",c)})),t){try{await import(`file://${m.join(__dirname,"fleetbo-mcp.js")}`),n&&process.stdin.resume()}catch(r){S(`Failed to start MCP server: ${r.message}`),process.exit(1)}return}await Ke(e,R),process.exit(0)}else j==="login"?(await He(e),process.exit(0)):["--help","-h","help"].includes(j)?(d(`Fleetbo CLI (fleetbo-svro)
|
|
772
772
|
|
|
773
773
|
Commands:
|
|
774
774
|
login Authenticate this machine (opens the browser: approve once, the command exits by itself)
|
|
775
775
|
mcp Connect your AI agent to Fleetbo and write its instruction files (AGENTS.md, CLAUDE.md, GEMINI.md).
|
|
776
776
|
--agent=claude,cursor,windsurf,devin,codex,gemini|all (default: files for all, MCP for detected agents)
|
|
777
|
+
--scope=project|user|local Claude Code registration scope (default: project = .mcp.json in the project)
|
|
777
778
|
--dry-run show what would change, write nothing
|
|
778
779
|
init Initialize the project: init --keyApp=<KEY> --token=<TOKEN>
|
|
779
780
|
sync Seal the schema/workflow on the Edge and generate Fleetbo_contract.md + IDE types
|
|
@@ -783,4 +784,4 @@ Modeling has NO shell command: to evolve the schema/workflow from your UI files,
|
|
|
783
784
|
"fleetbo_update_project" (keyApp is optional), then run "sync" once.
|
|
784
785
|
Run login / mcp at most once each and wait for them to finish. Nothing else needs to be
|
|
785
786
|
discovered: do not search the filesystem or read files outside the project.
|
|
786
|
-
`),process.exit(0)):(
|
|
787
|
+
`),process.exit(0)):(S('Unknown command. Run "npx fleetbo-svro --help".'),process.exit(1))}ze().catch(e=>{S(`Fleetbo CLI Error: ${e.message}`),process.exit(1)});
|