lindoai-cli 1.3.0 → 1.3.1

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/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';var lt=require('http'),$=require('fs'),P=require('path'),De=require('os'),commander=require('commander'),lindoai=require('lindoai'),child_process=require('child_process'),Ee=require('cheerio'),url=require('url'),vt=require('crypto'),module$1=require('module');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var lt__namespace=/*#__PURE__*/_interopNamespace(lt);var $__namespace=/*#__PURE__*/_interopNamespace($);var P__namespace=/*#__PURE__*/_interopNamespace(P);var De__namespace=/*#__PURE__*/_interopNamespace(De);var Ee__namespace=/*#__PURE__*/_interopNamespace(Ee);var vt__namespace=/*#__PURE__*/_interopNamespace(vt);var Ft=Object.defineProperty;var Pt=(o,e)=>()=>(o&&(e=o(o=0)),e);var It=(o,e)=>{for(var n in e)Ft(o,n,{get:e[n],enumerable:true});};var Ne={};It(Ne,{LIVE_RELOAD_SCRIPT:()=>je,injectLiveReload:()=>ct,startLivePreviewServer:()=>uo});function ct(o){let e=/<\/body>/i,n=o.match(e);return n&&n.index!==void 0?o.slice(0,n.index)+je+o.slice(n.index):o+je}function uo(o){return new Promise((e,n)=>{let t=P__namespace.resolve(o),i=new Set,r=null,c=100;function s(){for(let u of i)try{u.write(`data: reload
2
+ 'use strict';var lt=require('http'),$=require('fs'),P=require('path'),De=require('os'),commander=require('commander'),lindoai=require('lindoai'),child_process=require('child_process'),Ee=require('cheerio'),url=require('url'),vt=require('crypto'),module$1=require('module');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var lt__namespace=/*#__PURE__*/_interopNamespace(lt);var $__namespace=/*#__PURE__*/_interopNamespace($);var P__namespace=/*#__PURE__*/_interopNamespace(P);var De__namespace=/*#__PURE__*/_interopNamespace(De);var Ee__namespace=/*#__PURE__*/_interopNamespace(Ee);var vt__namespace=/*#__PURE__*/_interopNamespace(vt);var Ft=Object.defineProperty;var Pt=(o,e)=>()=>(o&&(e=o(o=0)),e);var It=(o,e)=>{for(var n in e)Ft(o,n,{get:e[n],enumerable:true});};var Ne={};It(Ne,{LIVE_RELOAD_SCRIPT:()=>je,injectLiveReload:()=>ct,startLivePreviewServer:()=>uo});function ct(o){let e=/<\/body>/i,n=o.match(e);return n&&n.index!==void 0?o.slice(0,n.index)+je+o.slice(n.index):o+je}function uo(o){return new Promise((e,n)=>{let t=P__namespace.resolve(o),i=new Set,a=null,c=100;function s(){for(let u of i)try{u.write(`data: reload
3
3
 
4
- `);}catch{i.delete(u);}}function d(){r&&clearTimeout(r),r=setTimeout(()=>{s(),r=null;},c);}function m(u,x){let g=u.url||"/";if((u.method||"GET")!=="GET"){x.writeHead(405,{"Content-Type":"text/plain"}),x.end("Method Not Allowed");return}if(g==="/__live-reload"){x.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*"}),x.write(`data: connected
4
+ `);}catch{i.delete(u);}}function d(){a&&clearTimeout(a),a=setTimeout(()=>{s(),a=null;},c);}function m(u,x){let g=u.url||"/";if((u.method||"GET")!=="GET"){x.writeHead(405,{"Content-Type":"text/plain"}),x.end("Method Not Allowed");return}if(g==="/__live-reload"){x.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*"}),x.write(`data: connected
5
5
 
6
6
  `),i.add(x),u.on("close",()=>{i.delete(x);});return}if(g==="/"||g==="/index.html"){try{let p=$__namespace.readFileSync(t,"utf-8"),h=ct(p);x.writeHead(200,{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-cache"}),x.end(h);}catch(p){let h=p instanceof Error?p.message:"Unknown error";x.writeHead(500,{"Content-Type":"text/html; charset=utf-8"}),x.end(`<!DOCTYPE html>
7
7
  <html>
@@ -17,7 +17,7 @@
17
17
  <h1>404 Not Found</h1>
18
18
  <p>The requested resource was not found.</p>
19
19
  </body>
20
- </html>`);}let v=lt__namespace.createServer(m),b=null;v.on("error",u=>{n(new Error(`Failed to start preview server: ${u.message}`));}),v.listen(0,"127.0.0.1",()=>{let u=v.address();if(!u||typeof u=="string"){n(new Error("Failed to get server address"));return}let x=u.port;try{b=$__namespace.watch(t,f=>{f==="change"&&d();}),b.on("error",f=>{console.error(`[Live Preview] File watcher error: ${f.message}`);});}catch(f){let p=f instanceof Error?f.message:"Unknown error";console.error(`[Live Preview] Failed to watch file: ${p}`);}let g=()=>{b&&(b.close(),b=null),r&&(clearTimeout(r),r=null);for(let h of i)try{h.end();}catch{}i.clear();let f=P__namespace.join(De__namespace.tmpdir(),"lindoai-pages-preview.pid"),p=P__namespace.join(De__namespace.tmpdir(),"lindoai-pages-preview.port");try{$__namespace.existsSync(f)&&$__namespace.unlinkSync(f);}catch{}try{$__namespace.existsSync(p)&&$__namespace.unlinkSync(p);}catch{}v.close(()=>{process.exit(0);}),setTimeout(()=>{process.exit(0);},1e3);};process.on("SIGTERM",g),process.on("SIGINT",g),e(x);});})}var je,Ue=Pt(()=>{je=`<script>
20
+ </html>`);}let v=lt__namespace.createServer(m),b=null;v.on("error",u=>{n(new Error(`Failed to start preview server: ${u.message}`));}),v.listen(0,"127.0.0.1",()=>{let u=v.address();if(!u||typeof u=="string"){n(new Error("Failed to get server address"));return}let x=u.port;try{b=$__namespace.watch(t,f=>{f==="change"&&d();}),b.on("error",f=>{console.error(`[Live Preview] File watcher error: ${f.message}`);});}catch(f){let p=f instanceof Error?f.message:"Unknown error";console.error(`[Live Preview] Failed to watch file: ${p}`);}let g=()=>{b&&(b.close(),b=null),a&&(clearTimeout(a),a=null);for(let h of i)try{h.end();}catch{}i.clear();let f=P__namespace.join(De__namespace.tmpdir(),"lindoai-pages-preview.pid"),p=P__namespace.join(De__namespace.tmpdir(),"lindoai-pages-preview.port");try{$__namespace.existsSync(f)&&$__namespace.unlinkSync(f);}catch{}try{$__namespace.existsSync(p)&&$__namespace.unlinkSync(p);}catch{}v.close(()=>{process.exit(0);}),setTimeout(()=>{process.exit(0);},1e3);};process.on("SIGTERM",g),process.on("SIGINT",g),e(x);});})}var je,Ue=Pt(()=>{je=`<script>
21
21
  (function() {
22
22
  var eventSource = new EventSource('/__live-reload');
23
23
  eventSource.onmessage = function(event) {
@@ -29,13 +29,13 @@
29
29
  console.log('[Live Reload] Connection lost, attempting to reconnect...');
30
30
  };
31
31
  })();
32
- </script>`;});var At="LINDO_API_KEY",Et="LINDO_BASE_URL",Lt=".lindo",Rt="config.json",Dt="https://api.lindo.ai";function Ze(){return P__namespace.join(De__namespace.homedir(),Lt)}function W(){return P__namespace.join(Ze(),Rt)}function ve(){let o=W();try{if($__namespace.existsSync(o)){let e=$__namespace.readFileSync(o,"utf-8");return JSON.parse(e)}}catch{}return {}}function et(o){let e=Ze(),n=W();$__namespace.existsSync(e)||$__namespace.mkdirSync(e,{recursive:true}),$__namespace.writeFileSync(n,JSON.stringify(o,null,2),"utf-8");}function O(){let o=ve(),e=process.env[At]||o.apiKey,n=process.env[Et]||o.baseUrl||Dt;return {apiKey:e,baseUrl:n}}function tt(o){let e=ve();e.apiKey=o,et(e);}function ot(o,e){let n=ve();switch(o){case "apiKey":n.apiKey=e;break;case "baseUrl":n.baseUrl=e;break;default:throw new Error(`Unknown configuration key: ${o}`)}et(n);}function nt(o){let e=O();switch(o){case "apiKey":return e.apiKey;case "baseUrl":return e.baseUrl;default:return}}function F(){return !!O().apiKey}var K={reset:"\x1B[0m",red:"\x1B[31m",green:"\x1B[32m",blue:"\x1B[34m",cyan:"\x1B[36m",gray:"\x1B[90m",bold:"\x1B[1m"};function jt(){return !process.env.NO_COLOR&&process.stdout.isTTY!==false}function q(o,e){return jt()?`${e}${o}${K.reset}`:o}function w(o){console.log(q(`\u2713 ${o}`,K.green));}function l(o){console.error(q(`\u2717 ${o}`,K.red));}function a(o){console.log(q(`\u2139 ${o}`,K.blue));}function Nt(o){return JSON.stringify(o,null,2)}function Ut(o){if(o==null)return "";if(Array.isArray(o)){if(o.length===0)return "No data";let e=new Set;for(let t of o)typeof t=="object"&&t!==null&&Object.keys(t).forEach(i=>e.add(i));if(e.size===0)return o.map(t=>String(t)).join(`
33
- `);let n=Array.from(e);return Mt(n,o)}if(typeof o=="object"){let n=Object.entries(o);if(n.length===0)return "No data";let t=Math.max(...n.map(([i])=>i.length));return n.map(([i,r])=>{let c=i.padEnd(t),s=Ce(r);return `${q(c,K.cyan)} ${s}`}).join(`
34
- `)}return String(o)}function Mt(o,e){let n={};for(let c of o)n[c]=c.length;for(let c of e)if(typeof c=="object"&&c!==null){let s=c;for(let d of o){let m=Ce(s[d]);n[d]=Math.max(n[d],m.length);}}let t=o.map(c=>q(c.padEnd(n[c]),K.bold)).join(" "),i=o.map(c=>"-".repeat(n[c])).join(" "),r=e.map(c=>{if(typeof c=="object"&&c!==null){let s=c;return o.map(d=>Ce(s[d]).padEnd(n[d])).join(" ")}return String(c)});return [t,i,...r].join(`
35
- `)}function Ce(o){return o==null?q("-",K.gray):typeof o=="boolean"?o?q("true",K.green):q("false",K.red):typeof o=="number"?String(o):typeof o=="object"?Array.isArray(o)?`[${o.length} items]`:JSON.stringify(o):String(o)}function y(o,e){console.log(e==="json"?Nt(o):Ut(o));}var it=["apiKey","baseUrl"];function _e(){let o=new commander.Command("config").description("Manage CLI configuration");return o.command("set <key> <value>").description("Set a configuration value").action((e,n)=>{it.includes(e)||(l(`Invalid configuration key: ${e}`),a(`Valid keys: ${it.join(", ")}`),process.exit(1));try{ot(e,n),w(`Configuration saved: ${e}`),a(`Config file: ${W()}`);}catch(t){l(`Failed to save configuration: ${t instanceof Error?t.message:String(t)}`),process.exit(1);}}),o.command("get <key>").description("Get a configuration value").option("-f, --format <format>","Output format (json, table)","table").action((e,n)=>{let t=nt(e);if(t===void 0){n.format==="json"?y({key:e,value:null},n.format):a(`Configuration key '${e}' is not set`);return}if(n.format==="json")y({key:e,value:t},n.format);else {let i=e==="apiKey"?ke(t):t;console.log(`${e}: ${i}`);}}),o.command("list").description("List all configuration values").option("-f, --format <format>","Output format (json, table)","table").action(e=>{let n=O(),t={apiKey:n.apiKey?ke(n.apiKey):"(not set)",baseUrl:n.baseUrl,configFile:W()};e.format==="json"?y({apiKey:n.apiKey?ke(n.apiKey):null,baseUrl:n.baseUrl,configFile:W()},e.format):y(t,e.format);}),o.command("path").description("Show the config file path").action(()=>{console.log(W());}),o}function ke(o){return o.length<=8?"*".repeat(o.length):`${o.slice(0,4)}${"*".repeat(o.length-8)}${o.slice(-4)}`}function Se(){let o=new commander.Command("agents").description("Run AI agents");return o.command("run <agent-id>").description("Run an AI agent").option("-i, --input <json>","Input data as JSON string","{}").option("-s, --stream","Stream the response",false).option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let t=O(),i=new lindoai.LindoClient({apiKey:t.apiKey,baseUrl:t.baseUrl}),r;try{r=JSON.parse(n.input);}catch{l("Invalid JSON input"),a(`Example: --input '{"prompt": "Hello!"}'`),process.exit(1);}try{a(`Running agent: ${e}`);let c=await i.agents.run({agent_id:e,input:r,stream:n.stream});c.success?(w("Agent run completed"),y(c,n.format)):(l(`Agent run failed: ${c.error||"Unknown error"}`),y(c,n.format),process.exit(1));}catch(c){qt(c);}}),o}function qt(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function $e(){let o=new commander.Command("workflows").description("Manage workflows");return o.command("list").description("List workflow logs").option("-n, --name <name>","Filter by workflow name").option("-s, --status <status>","Filter by status").option("-w, --website <id>","Filter by website ID").option("-c, --client <id>","Filter by client ID").option("-l, --limit <number>","Maximum number of results","50").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=ne();try{let t=await n.workflows.list({workflow_name:e.name,status:e.status,website_id:e.website,client_id:e.client,limit:parseInt(e.limit)});t.success?y(t.data,e.format):(l("Failed to list workflows"),process.exit(1));}catch(t){ie(t);}}),o.command("start <workflow-name>").description("Start a workflow").option("-p, --params <json>","Workflow parameters as JSON string","{}").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne(),i;try{i=JSON.parse(n.params);}catch{l("Invalid JSON params"),a(`Example: --params '{"page_id": "page-123"}'`),process.exit(1);}try{a(`Starting workflow: ${e}`);let r=await t.workflows.start({workflow_name:e,params:i});r.success?(w(`Workflow started: ${r.instance_id}`),y(r,n.format)):(l("Failed to start workflow"),y(r,n.format),process.exit(1));}catch(r){ie(r);}}),o.command("status <instance-id>").description("Get workflow status").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{let i=await t.workflows.getStatus(e);y(i,n.format);}catch(i){ie(i);}}),o.command("pause <instance-id>").description("Pause a running workflow").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{a(`Pausing workflow: ${e}`);let i=await t.workflows.pause(e);i.success?w(i.message):(l(i.message),process.exit(1)),y(i,n.format);}catch(i){ie(i);}}),o.command("resume <instance-id>").description("Resume a paused workflow").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{a(`Resuming workflow: ${e}`);let i=await t.workflows.resume(e);i.success?w(i.message):(l(i.message),process.exit(1)),y(i,n.format);}catch(i){ie(i);}}),o.command("terminate <instance-id>").description("Terminate a workflow").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{a(`Terminating workflow: ${e}`);let i=await t.workflows.terminate(e);i.success?w(i.message):(l(i.message),process.exit(1)),y(i,n.format);}catch(i){ie(i);}}),o}function ne(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function ie(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Oe(){let o=new commander.Command("workspace").description("Workspace operations");return o.command("get").description("Get workspace details").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.get();y(t,e.format);}catch(t){U(t);}}),o.command("credits").description("Get workspace credit balance").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.getCredits();y(t,e.format);}catch(t){U(t);}}),o.command("client-credits").description("Get credit balance for a specific client").requiredOption("-c, --client <id>","Client ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.getClientCredits(e.client);y(t,e.format);}catch(t){U(t);}}),o.command("update").description("Update workspace settings").option("-n, --name <name>","Workspace name").option("-l, --language <lang>","Workspace language").option("-w, --webhook <url>","Webhook URL").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.update({workspace_name:e.name,workspace_language:e.language,webhook_url:e.webhook});t.success&&w("Workspace updated"),y(t,e.format);}catch(t){U(t);}}),o.command("team-add").description("Add a team member to the workspace").requiredOption("-e, --email <email>","Team member email").option("-r, --role <role>","Role (Team)","Team").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.addTeamMember(e.email,e.role);t.success&&w("Team member added"),y(t,e.format);}catch(t){U(t);}}),o.command("team-remove").description("Remove a team member from the workspace").requiredOption("-m, --member <id>","Member ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.removeTeamMember(e.member);t.success&&w("Team member removed"),y(t,e.format);}catch(t){U(t);}}),o.command("integration-add").description("Add an integration to the workspace").requiredOption("-t, --type <type>","Integration type (e.g., matomo)").requiredOption("-c, --config <json>","Integration config as JSON").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N(),t;try{t=JSON.parse(e.config);}catch{l("Invalid JSON config"),process.exit(1);}try{let i=await n.workspace.addIntegration({integration_type:e.type,config:t});i.success&&w("Integration added"),y(i,e.format);}catch(i){U(i);}}),o.command("integration-remove").description("Remove an integration from the workspace").requiredOption("-t, --type <type>","Integration type").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.removeIntegration(e.type);t.success&&w("Integration removed"),y(t,e.format);}catch(t){U(t);}}),o.command("whitelabel").description("Setup or update whitelabel settings").option("-d, --domain <domain>","Custom domain").option("-s, --subdomain <domain>","Subdomain domain").option("-e, --email-sender <email>","Email sender address").option("--enable-register","Enable client registration").option("--disable-register","Disable client registration").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.setupWhitelabel({domain:e.domain,subdomain_domain:e.subdomain,email_sender:e.emailSender,wl_client_register:e.enableRegister?!0:e.disableRegister?!1:void 0});t.success&&w("Whitelabel settings updated"),y(t,e.format);}catch(t){U(t);}}),o.command("appearance").description("Update workspace appearance settings").option("-p, --primary <color>","Primary color (hex)").option("-s, --secondary <color>","Secondary color (hex)").option("-m, --mode <mode>","Theme mode (light/dark)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.updateAppearance({primary_color:e.primary,secondary_color:e.secondary,theme_mode:e.mode});t.success&&w("Appearance settings updated"),y(t,e.format);}catch(t){U(t);}}),o}function N(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function U(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Te(){let o=new commander.Command("analytics").description("Analytics operations");return o.command("workspace").description("Get workspace analytics").option("--from <date>","Start date (ISO format)").option("--to <date>","End date (ISO format)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=rt();try{let t=await n.analytics.getWorkspace({from:e.from,to:e.to});y(t,e.format);}catch(t){at(t);}}),o.command("website").description("Get website analytics").requiredOption("-w, --website <id>","Website ID (required)").option("--from <date>","Start date (ISO format)").option("--to <date>","End date (ISO format)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=rt();try{let t=await n.analytics.getWebsite({website_id:e.website,from:e.from,to:e.to});y(t,e.format);}catch(t){at(t);}}),o}function rt(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function at(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Fe(){let o=new commander.Command("clients").description("Client management operations");return o.command("list").description("List all workspace clients").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.list({page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else if(t.clients&&t.clients.length>0){console.log(`
36
- Clients:`),console.log("--------");for(let i of t.clients)console.log(` ID: ${i.record_id}`),console.log(` Email: ${i.email}`),console.log(` Website Limit: ${i.website_limit??"N/A"}`),console.log(` Suspended: ${i.suspended??!1}`),console.log("");console.log(`Total: ${t.total??t.clients.length}`);}else a("No clients found");}catch(t){pe(t);}}),o.command("create").description("Create a new workspace client").requiredOption("-e, --email <email>","Client email address").option("-l, --limit <limit>","Website limit","5").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.create({email:e.email,website_limit:parseInt(e.limit,10)});if(t.success&&t.client)w(`Client created: ${t.client.record_id}`),y(t.client,e.format);else if(l("Failed to create client"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o.command("update").description("Update a workspace client").requiredOption("-i, --id <id>","Client ID").option("-l, --limit <limit>","Website limit").option("--suspend","Suspend the client").option("--unsuspend","Unsuspend the client").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.update({client_id:e.id,website_limit:e.limit?parseInt(e.limit,10):void 0,suspended:e.suspend?!0:e.unsuspend?!1:void 0});if(t.success)w("Client updated"),t.client&&y(t.client,e.format);else if(l("Failed to update client"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o.command("delete").description("Delete a workspace client").requiredOption("-i, --id <id>","Client ID").action(async e=>{let n=me();try{let t=await n.clients.delete(e.id);if(t.success)w("Client deleted");else if(l("Failed to delete client"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o.command("magic-link").description("Create a magic link for client authentication").requiredOption("-e, --email <email>","Client email address").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.createMagicLink(e.email);if(t.success)w("Magic link created"),y(t,e.format);else if(l("Failed to create magic link"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o}function me(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function pe(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Pe(){let o=new commander.Command("websites").description("Website management operations");return o.command("list").description("List all workspace websites").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.list({page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else {let i=t.result?.list??[];if(i.length>0){console.log(`
37
- Websites:`),console.log("---------");for(let r of i)console.log(` ID: ${r.website_id}`),console.log(` Name: ${r.website_name??"N/A"}`),console.log(` Domain: ${r.domain??"N/A"}`),console.log(` Activated: ${r.activated??!1}`),console.log("");console.log(`Total: ${t.result?.total??i.length}`);}else a("No websites found");}}catch(t){R(t);}}),o.command("get").description("Get website details").requiredOption("-i, --id <id>","Website ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.getDetails(e.id);y(t,e.format);}catch(t){R(t);}}),o.command("update").description("Update a website").requiredOption("-i, --id <id>","Website ID").option("-n, --name <name>","Business name").option("--activate","Activate the website").option("--deactivate","Deactivate the website").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.update({website_id:e.id,business_name:e.name,activated:e.activate?!0:e.deactivate?!1:void 0});if(t.success)w("Website updated"),t.website&&y(t.website,e.format);else if(l("Failed to update website"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){R(t);}}),o.command("settings").description("Update website settings").requiredOption("-i, --id <id>","Website ID").option("-n, --name <name>","Business name").option("-l, --language <lang>","Language").option("-d, --description <desc>","Business description").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.updateSettings(e.id,{business_name:e.name,language:e.language,business_description:e.description});t.success&&w("Website settings updated"),y(t,e.format);}catch(t){R(t);}}),o.command("delete").description("Delete a website").requiredOption("-i, --id <id>","Website ID").action(async e=>{let n=L();try{let t=await n.websites.delete(e.id);if(t.success)w("Website deleted");else if(l("Failed to delete website"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){R(t);}}),o.command("assign").description("Assign a website to a client").requiredOption("-w, --website <id>","Website ID").requiredOption("-c, --client <id>","Client ID").action(async e=>{let n=L();try{let t=await n.websites.assign({website_id:e.website,client_id:e.client});if(t.success)w("Website assigned to client");else if(l("Failed to assign website"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){R(t);}}),o.command("domain-add").description("Add a custom domain to a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-d, --domain <domain>","Custom domain").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.addDomain(e.id,e.domain);if(t.success&&(w("Domain added"),t.result?.dns_records)){console.log(`
38
- DNS Records to configure:`);for(let i of t.result.dns_records)console.log(` ${i.record_type} ${i.host} -> ${i.value}`);}y(t,e.format);}catch(t){R(t);}}),o.command("domain-remove").description("Remove a custom domain from a website").requiredOption("-i, --id <id>","Website ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.removeDomain(e.id);t.success&&w("Domain removed"),y(t,e.format);}catch(t){R(t);}}),o.command("integration-add").description("Add an integration to a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-t, --type <type>","Integration type (e.g., matomo)").requiredOption("-c, --config <json>","Integration config as JSON").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L(),t;try{t=JSON.parse(e.config);}catch{l("Invalid JSON config"),process.exit(1);}try{let i=await n.websites.addIntegration(e.id,{integration_type:e.type,config:t});i.success&&w("Integration added"),y(i,e.format);}catch(i){R(i);}}),o.command("integration-remove").description("Remove an integration from a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-t, --type <type>","Integration type").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.removeIntegration(e.id,e.type);t.success&&w("Integration removed"),y(t,e.format);}catch(t){R(t);}}),o.command("team-add").description("Add a team member to a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-e, --email <email>","Team member email").requiredOption("-r, --role <role>","Role (Editor or Commenter)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.addTeamMember(e.id,e.email,e.role);t.success&&w("Team member added"),y(t,e.format);}catch(t){R(t);}}),o.command("team-remove").description("Remove a team member from a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-m, --member <memberId>","Member ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.removeTeamMember(e.id,e.member);t.success&&w("Team member removed"),y(t,e.format);}catch(t){R(t);}}),o}function L(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function R(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function G(o){return new Promise(e=>{let n=De.platform(),t;switch(n){case "darwin":t=`open "${o}"`;break;case "win32":t=`start "" "${o}"`;break;default:t=`xdg-open "${o}"`;break}child_process.exec(t,i=>{e(!i);});})}function co(o){let e=o.filter(t=>!!(t&&t.trim()));return e.length===0?"":`https://fonts.googleapis.com/css2?family=${e.map(t=>`${t.trim().replace(/ /g,"+")}:wght@300;400;700`).join("&family=")}&display=swap`}function ue(o){let e=[o.font,o.title_font].filter(Boolean);if(e.length===0)return "";let n=co(e);if(!n)return "";let t=o.font||o.title_font,i=o.title_font||o.font,r=`
32
+ </script>`;});var At="LINDO_API_KEY",Et="LINDO_BASE_URL",Lt=".lindo",Rt="config.json",Dt="https://api.lindo.ai";function Ze(){return P__namespace.join(De__namespace.homedir(),Lt)}function W(){return P__namespace.join(Ze(),Rt)}function ve(){let o=W();try{if($__namespace.existsSync(o)){let e=$__namespace.readFileSync(o,"utf-8");return JSON.parse(e)}}catch{}return {}}function et(o){let e=Ze(),n=W();$__namespace.existsSync(e)||$__namespace.mkdirSync(e,{recursive:true}),$__namespace.writeFileSync(n,JSON.stringify(o,null,2),"utf-8");}function O(){let o=ve(),e=process.env[At]||o.apiKey,n=process.env[Et]||o.baseUrl||Dt;return {apiKey:e,baseUrl:n}}function tt(o){let e=ve();e.apiKey=o,et(e);}function ot(o,e){let n=ve();switch(o){case "apiKey":n.apiKey=e;break;case "baseUrl":n.baseUrl=e;break;default:throw new Error(`Unknown configuration key: ${o}`)}et(n);}function nt(o){let e=O();switch(o){case "apiKey":return e.apiKey;case "baseUrl":return e.baseUrl;default:return}}function F(){return !!O().apiKey}var B={reset:"\x1B[0m",red:"\x1B[31m",green:"\x1B[32m",blue:"\x1B[34m",cyan:"\x1B[36m",gray:"\x1B[90m",bold:"\x1B[1m"};function jt(){return !process.env.NO_COLOR&&process.stdout.isTTY!==false}function q(o,e){return jt()?`${e}${o}${B.reset}`:o}function w(o){console.log(q(`\u2713 ${o}`,B.green));}function l(o){console.error(q(`\u2717 ${o}`,B.red));}function r(o){console.log(q(`\u2139 ${o}`,B.blue));}function Nt(o){return JSON.stringify(o,null,2)}function Ut(o){if(o==null)return "";if(Array.isArray(o)){if(o.length===0)return "No data";let e=new Set;for(let t of o)typeof t=="object"&&t!==null&&Object.keys(t).forEach(i=>e.add(i));if(e.size===0)return o.map(t=>String(t)).join(`
33
+ `);let n=Array.from(e);return Mt(n,o)}if(typeof o=="object"){let n=Object.entries(o);if(n.length===0)return "No data";let t=Math.max(...n.map(([i])=>i.length));return n.map(([i,a])=>{let c=i.padEnd(t),s=Ce(a);return `${q(c,B.cyan)} ${s}`}).join(`
34
+ `)}return String(o)}function Mt(o,e){let n={};for(let c of o)n[c]=c.length;for(let c of e)if(typeof c=="object"&&c!==null){let s=c;for(let d of o){let m=Ce(s[d]);n[d]=Math.max(n[d],m.length);}}let t=o.map(c=>q(c.padEnd(n[c]),B.bold)).join(" "),i=o.map(c=>"-".repeat(n[c])).join(" "),a=e.map(c=>{if(typeof c=="object"&&c!==null){let s=c;return o.map(d=>Ce(s[d]).padEnd(n[d])).join(" ")}return String(c)});return [t,i,...a].join(`
35
+ `)}function Ce(o){return o==null?q("-",B.gray):typeof o=="boolean"?o?q("true",B.green):q("false",B.red):typeof o=="number"?String(o):typeof o=="object"?Array.isArray(o)?`[${o.length} items]`:JSON.stringify(o):String(o)}function y(o,e){console.log(e==="json"?Nt(o):Ut(o));}var it=["apiKey","baseUrl"];function _e(){let o=new commander.Command("config").description("Manage CLI configuration");return o.command("set <key> <value>").description("Set a configuration value").action((e,n)=>{it.includes(e)||(l(`Invalid configuration key: ${e}`),r(`Valid keys: ${it.join(", ")}`),process.exit(1));try{ot(e,n),w(`Configuration saved: ${e}`),r(`Config file: ${W()}`);}catch(t){l(`Failed to save configuration: ${t instanceof Error?t.message:String(t)}`),process.exit(1);}}),o.command("get <key>").description("Get a configuration value").option("-f, --format <format>","Output format (json, table)","table").action((e,n)=>{let t=nt(e);if(t===void 0){n.format==="json"?y({key:e,value:null},n.format):r(`Configuration key '${e}' is not set`);return}if(n.format==="json")y({key:e,value:t},n.format);else {let i=e==="apiKey"?ke(t):t;console.log(`${e}: ${i}`);}}),o.command("list").description("List all configuration values").option("-f, --format <format>","Output format (json, table)","table").action(e=>{let n=O(),t={apiKey:n.apiKey?ke(n.apiKey):"(not set)",baseUrl:n.baseUrl,configFile:W()};e.format==="json"?y({apiKey:n.apiKey?ke(n.apiKey):null,baseUrl:n.baseUrl,configFile:W()},e.format):y(t,e.format);}),o.command("path").description("Show the config file path").action(()=>{console.log(W());}),o}function ke(o){return o.length<=8?"*".repeat(o.length):`${o.slice(0,4)}${"*".repeat(o.length-8)}${o.slice(-4)}`}function Se(){let o=new commander.Command("agents").description("Run AI agents");return o.command("run <agent-id>").description("Run an AI agent").option("-i, --input <json>","Input data as JSON string","{}").option("-s, --stream","Stream the response",false).option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let t=O(),i=new lindoai.LindoClient({apiKey:t.apiKey,baseUrl:t.baseUrl}),a;try{a=JSON.parse(n.input);}catch{l("Invalid JSON input"),r(`Example: --input '{"prompt": "Hello!"}'`),process.exit(1);}try{r(`Running agent: ${e}`);let c=await i.agents.run({agent_id:e,input:a,stream:n.stream});c.success?(w("Agent run completed"),y(c,n.format)):(l(`Agent run failed: ${c.error||"Unknown error"}`),y(c,n.format),process.exit(1));}catch(c){qt(c);}}),o}function qt(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function $e(){let o=new commander.Command("workflows").description("Manage workflows");return o.command("list").description("List workflow logs").option("-n, --name <name>","Filter by workflow name").option("-s, --status <status>","Filter by status").option("-w, --website <id>","Filter by website ID").option("-c, --client <id>","Filter by client ID").option("-l, --limit <number>","Maximum number of results","50").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=ne();try{let t=await n.workflows.list({workflow_name:e.name,status:e.status,website_id:e.website,client_id:e.client,limit:parseInt(e.limit)});t.success?y(t.data,e.format):(l("Failed to list workflows"),process.exit(1));}catch(t){ie(t);}}),o.command("start <workflow-name>").description("Start a workflow").option("-p, --params <json>","Workflow parameters as JSON string","{}").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne(),i;try{i=JSON.parse(n.params);}catch{l("Invalid JSON params"),r(`Example: --params '{"page_id": "page-123"}'`),process.exit(1);}try{r(`Starting workflow: ${e}`);let a=await t.workflows.start({workflow_name:e,params:i});a.success?(w(`Workflow started: ${a.instance_id}`),y(a,n.format)):(l("Failed to start workflow"),y(a,n.format),process.exit(1));}catch(a){ie(a);}}),o.command("status <instance-id>").description("Get workflow status").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{let i=await t.workflows.getStatus(e);y(i,n.format);}catch(i){ie(i);}}),o.command("pause <instance-id>").description("Pause a running workflow").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{r(`Pausing workflow: ${e}`);let i=await t.workflows.pause(e);i.success?w(i.message):(l(i.message),process.exit(1)),y(i,n.format);}catch(i){ie(i);}}),o.command("resume <instance-id>").description("Resume a paused workflow").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{r(`Resuming workflow: ${e}`);let i=await t.workflows.resume(e);i.success?w(i.message):(l(i.message),process.exit(1)),y(i,n.format);}catch(i){ie(i);}}),o.command("terminate <instance-id>").description("Terminate a workflow").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{r(`Terminating workflow: ${e}`);let i=await t.workflows.terminate(e);i.success?w(i.message):(l(i.message),process.exit(1)),y(i,n.format);}catch(i){ie(i);}}),o}function ne(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function ie(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Oe(){let o=new commander.Command("workspace").description("Workspace operations");return o.command("get").description("Get workspace details").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.get();y(t,e.format);}catch(t){U(t);}}),o.command("credits").description("Get workspace credit balance").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.getCredits();y(t,e.format);}catch(t){U(t);}}),o.command("client-credits").description("Get credit balance for a specific client").requiredOption("-c, --client <id>","Client ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.getClientCredits(e.client);y(t,e.format);}catch(t){U(t);}}),o.command("update").description("Update workspace settings").option("-n, --name <name>","Workspace name").option("-l, --language <lang>","Workspace language").option("-w, --webhook <url>","Webhook URL").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.update({workspace_name:e.name,workspace_language:e.language,webhook_url:e.webhook});t.success&&w("Workspace updated"),y(t,e.format);}catch(t){U(t);}}),o.command("team-add").description("Add a team member to the workspace").requiredOption("-e, --email <email>","Team member email").option("-r, --role <role>","Role (Team)","Team").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.addTeamMember(e.email,e.role);t.success&&w("Team member added"),y(t,e.format);}catch(t){U(t);}}),o.command("team-remove").description("Remove a team member from the workspace").requiredOption("-m, --member <id>","Member ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.removeTeamMember(e.member);t.success&&w("Team member removed"),y(t,e.format);}catch(t){U(t);}}),o.command("integration-add").description("Add an integration to the workspace").requiredOption("-t, --type <type>","Integration type (e.g., matomo)").requiredOption("-c, --config <json>","Integration config as JSON").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N(),t;try{t=JSON.parse(e.config);}catch{l("Invalid JSON config"),process.exit(1);}try{let i=await n.workspace.addIntegration({integration_type:e.type,config:t});i.success&&w("Integration added"),y(i,e.format);}catch(i){U(i);}}),o.command("integration-remove").description("Remove an integration from the workspace").requiredOption("-t, --type <type>","Integration type").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.removeIntegration(e.type);t.success&&w("Integration removed"),y(t,e.format);}catch(t){U(t);}}),o.command("whitelabel").description("Setup or update whitelabel settings").option("-d, --domain <domain>","Custom domain").option("-s, --subdomain <domain>","Subdomain domain").option("-e, --email-sender <email>","Email sender address").option("--enable-register","Enable client registration").option("--disable-register","Disable client registration").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.setupWhitelabel({domain:e.domain,subdomain_domain:e.subdomain,email_sender:e.emailSender,wl_client_register:e.enableRegister?!0:e.disableRegister?!1:void 0});t.success&&w("Whitelabel settings updated"),y(t,e.format);}catch(t){U(t);}}),o.command("appearance").description("Update workspace appearance settings").option("-p, --primary <color>","Primary color (hex)").option("-s, --secondary <color>","Secondary color (hex)").option("-m, --mode <mode>","Theme mode (light/dark)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.updateAppearance({primary_color:e.primary,secondary_color:e.secondary,theme_mode:e.mode});t.success&&w("Appearance settings updated"),y(t,e.format);}catch(t){U(t);}}),o}function N(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function U(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Te(){let o=new commander.Command("analytics").description("Analytics operations");return o.command("workspace").description("Get workspace analytics").option("--from <date>","Start date (ISO format)").option("--to <date>","End date (ISO format)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=rt();try{let t=await n.analytics.getWorkspace({from:e.from,to:e.to});y(t,e.format);}catch(t){at(t);}}),o.command("website").description("Get website analytics").requiredOption("-w, --website <id>","Website ID (required)").option("--from <date>","Start date (ISO format)").option("--to <date>","End date (ISO format)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=rt();try{let t=await n.analytics.getWebsite({website_id:e.website,from:e.from,to:e.to});y(t,e.format);}catch(t){at(t);}}),o}function rt(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function at(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Fe(){let o=new commander.Command("clients").description("Client management operations");return o.command("list").description("List all workspace clients").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.list({page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else if(t.clients&&t.clients.length>0){console.log(`
36
+ Clients:`),console.log("--------");for(let i of t.clients)console.log(` ID: ${i.record_id}`),console.log(` Email: ${i.email}`),console.log(` Website Limit: ${i.website_limit??"N/A"}`),console.log(` Suspended: ${i.suspended??!1}`),console.log("");console.log(`Total: ${t.total??t.clients.length}`);}else r("No clients found");}catch(t){pe(t);}}),o.command("create").description("Create a new workspace client").requiredOption("-e, --email <email>","Client email address").option("-l, --limit <limit>","Website limit","5").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.create({email:e.email,website_limit:parseInt(e.limit,10)});if(t.success&&t.client)w(`Client created: ${t.client.record_id}`),y(t.client,e.format);else if(l("Failed to create client"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o.command("update").description("Update a workspace client").requiredOption("-i, --id <id>","Client ID").option("-l, --limit <limit>","Website limit").option("--suspend","Suspend the client").option("--unsuspend","Unsuspend the client").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.update({client_id:e.id,website_limit:e.limit?parseInt(e.limit,10):void 0,suspended:e.suspend?!0:e.unsuspend?!1:void 0});if(t.success)w("Client updated"),t.client&&y(t.client,e.format);else if(l("Failed to update client"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o.command("delete").description("Delete a workspace client").requiredOption("-i, --id <id>","Client ID").action(async e=>{let n=me();try{let t=await n.clients.delete(e.id);if(t.success)w("Client deleted");else if(l("Failed to delete client"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o.command("magic-link").description("Create a magic link for client authentication").requiredOption("-e, --email <email>","Client email address").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.createMagicLink(e.email);if(t.success)w("Magic link created"),y(t,e.format);else if(l("Failed to create magic link"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o}function me(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function pe(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Pe(){let o=new commander.Command("websites").description("Website management operations");return o.command("list").description("List all workspace websites").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.list({page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else {let i=t.result?.list??[];if(i.length>0){console.log(`
37
+ Websites:`),console.log("---------");for(let a of i)console.log(` ID: ${a.website_id}`),console.log(` Name: ${a.website_name??"N/A"}`),console.log(` Domain: ${a.domain??"N/A"}`),console.log(` Activated: ${a.activated??!1}`),console.log("");console.log(`Total: ${t.result?.total??i.length}`);}else r("No websites found");}}catch(t){R(t);}}),o.command("get").description("Get website details").requiredOption("-i, --id <id>","Website ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.getDetails(e.id);y(t,e.format);}catch(t){R(t);}}),o.command("update").description("Update a website").requiredOption("-i, --id <id>","Website ID").option("-n, --name <name>","Business name").option("--activate","Activate the website").option("--deactivate","Deactivate the website").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.update({website_id:e.id,business_name:e.name,activated:e.activate?!0:e.deactivate?!1:void 0});if(t.success)w("Website updated"),t.website&&y(t.website,e.format);else if(l("Failed to update website"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){R(t);}}),o.command("settings").description("Update website settings").requiredOption("-i, --id <id>","Website ID").option("-n, --name <name>","Business name").option("-l, --language <lang>","Language").option("-d, --description <desc>","Business description").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.updateSettings(e.id,{business_name:e.name,language:e.language,business_description:e.description});t.success&&w("Website settings updated"),y(t,e.format);}catch(t){R(t);}}),o.command("delete").description("Delete a website").requiredOption("-i, --id <id>","Website ID").action(async e=>{let n=L();try{let t=await n.websites.delete(e.id);if(t.success)w("Website deleted");else if(l("Failed to delete website"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){R(t);}}),o.command("assign").description("Assign a website to a client").requiredOption("-w, --website <id>","Website ID").requiredOption("-c, --client <id>","Client ID").action(async e=>{let n=L();try{let t=await n.websites.assign({website_id:e.website,client_id:e.client});if(t.success)w("Website assigned to client");else if(l("Failed to assign website"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){R(t);}}),o.command("domain-add").description("Add a custom domain to a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-d, --domain <domain>","Custom domain").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.addDomain(e.id,e.domain);if(t.success&&(w("Domain added"),t.result?.dns_records)){console.log(`
38
+ DNS Records to configure:`);for(let i of t.result.dns_records)console.log(` ${i.record_type} ${i.host} -> ${i.value}`);}y(t,e.format);}catch(t){R(t);}}),o.command("domain-remove").description("Remove a custom domain from a website").requiredOption("-i, --id <id>","Website ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.removeDomain(e.id);t.success&&w("Domain removed"),y(t,e.format);}catch(t){R(t);}}),o.command("integration-add").description("Add an integration to a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-t, --type <type>","Integration type (e.g., matomo)").requiredOption("-c, --config <json>","Integration config as JSON").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L(),t;try{t=JSON.parse(e.config);}catch{l("Invalid JSON config"),process.exit(1);}try{let i=await n.websites.addIntegration(e.id,{integration_type:e.type,config:t});i.success&&w("Integration added"),y(i,e.format);}catch(i){R(i);}}),o.command("integration-remove").description("Remove an integration from a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-t, --type <type>","Integration type").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.removeIntegration(e.id,e.type);t.success&&w("Integration removed"),y(t,e.format);}catch(t){R(t);}}),o.command("team-add").description("Add a team member to a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-e, --email <email>","Team member email").requiredOption("-r, --role <role>","Role (Editor or Commenter)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.addTeamMember(e.id,e.email,e.role);t.success&&w("Team member added"),y(t,e.format);}catch(t){R(t);}}),o.command("team-remove").description("Remove a team member from a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-m, --member <memberId>","Member ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.removeTeamMember(e.id,e.member);t.success&&w("Team member removed"),y(t,e.format);}catch(t){R(t);}}),o}function L(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function R(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function G(o){return new Promise(e=>{let n=De.platform(),t;switch(n){case "darwin":t=`open "${o}"`;break;case "win32":t=`start "" "${o}"`;break;default:t=`xdg-open "${o}"`;break}child_process.exec(t,i=>{e(!i);});})}function co(o){let e=o.filter(t=>!!(t&&t.trim()));return e.length===0?"":`https://fonts.googleapis.com/css2?family=${e.map(t=>`${t.trim().replace(/ /g,"+")}:wght@300;400;700`).join("&family=")}&display=swap`}function ue(o){let e=[o.font,o.title_font].filter(Boolean);if(e.length===0)return "";let n=co(e);if(!n)return "";let t=o.font||o.title_font,i=o.title_font||o.font,a=`
39
39
  <style>
40
40
  /* Apply website fonts from theme */
41
41
  body, main, .prose {
@@ -46,12 +46,12 @@ DNS Records to configure:`);for(let i of t.result.dns_records)console.log(` ${i
46
46
  }
47
47
  </style>`;return `<link rel="preconnect" href="https://fonts.googleapis.com">
48
48
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
49
- <link href="${n}" rel="stylesheet">${r}`}function st(o,e){let n=new RegExp(`<${e}\\b[^>]*>`,"gi"),t,i=null;for(;(t=n.exec(o))!==null;){let _=o.slice(0,t.index);if(mo(_)){i=t;break}}if(!i||i.index===void 0)return {section:void 0,remainingHtml:o};let r=i.index,c=r+i[0].length,s=`</${e}>`,d=o.slice(c),m=new RegExp(`<${e}\\b`,"gi"),v=new RegExp(`</${e}>`,"gi"),b=[],u=[],x;for(;(x=m.exec(d))!==null;)b.push(x.index+c);for(;(x=v.exec(d))!==null;)u.push(x.index+c);let g=[...b.map(_=>({pos:_,type:"open"})),...u.map(_=>({pos:_,type:"close"}))].sort((_,A)=>_.pos-A.pos),f=1,p=-1;for(let _ of g)if(_.type==="open")f++;else if(f--,f===0){p=_.pos+s.length;break}if(p===-1)return {section:void 0,remainingHtml:o};let h=o.slice(r,p),C=o.slice(0,r),k=o.slice(p),S=(C+k).replace(/\n\s*\n\s*\n/g,`
49
+ <link href="${n}" rel="stylesheet">${a}`}function st(o,e){let n=new RegExp(`<${e}\\b[^>]*>`,"gi"),t,i=null;for(;(t=n.exec(o))!==null;){let _=o.slice(0,t.index);if(mo(_)){i=t;break}}if(!i||i.index===void 0)return {section:void 0,remainingHtml:o};let a=i.index,c=a+i[0].length,s=`</${e}>`,d=o.slice(c),m=new RegExp(`<${e}\\b`,"gi"),v=new RegExp(`</${e}>`,"gi"),b=[],u=[],x;for(;(x=m.exec(d))!==null;)b.push(x.index+c);for(;(x=v.exec(d))!==null;)u.push(x.index+c);let g=[...b.map(_=>({pos:_,type:"open"})),...u.map(_=>({pos:_,type:"close"}))].sort((_,A)=>_.pos-A.pos),f=1,p=-1;for(let _ of g)if(_.type==="open")f++;else if(f--,f===0){p=_.pos+s.length;break}if(p===-1)return {section:void 0,remainingHtml:o};let h=o.slice(a,p),C=o.slice(0,a),k=o.slice(p),S=(C+k).replace(/\n\s*\n\s*\n/g,`
50
50
 
51
- `);return {section:h,remainingHtml:S}}function mo(o){let e=["section","header","footer"],n=0;for(let t of e){let i=new RegExp(`<${t}\\b`,"gi"),r=new RegExp(`</${t}>`,"gi"),c=(o.match(i)||[]).length,s=(o.match(r)||[]).length;n+=c-s;}return n===0}function be(o){let e=st(o,"header"),n=st(e.remainingHtml,"footer");return {globalHeader:e.section,globalFooter:n.section,mainContent:n.remainingHtml.trim()}}function Ie(o,e,n){let t=[];return e&&e.trim()&&t.push(e.trim()),o.trim()&&t.push(o.trim()),n&&n.trim()&&t.push(n.trim()),t.join(`
52
- `)}function re(o){return !(!o||o.startsWith("http://")||o.startsWith("https://")||o.startsWith("//")||o.startsWith("data:")||o.startsWith("blob:")||o.startsWith("#"))}function we(o){let e=o.toLowerCase().split(".").pop()||"",n=["jpg","jpeg","png","gif","webp","svg","ico","avif","bmp","tiff"],t=["mp4","webm","mov","avi","mkv","ogv"],i=["woff","woff2","ttf","otf","eot"];return n.includes(e)?"images":t.includes(e)?"videos":i.includes(e)?"fonts":"documents"}function ae(o){let e=o.toLowerCase().split(".").pop()||"";return {jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",ico:"image/x-icon",avif:"image/avif",bmp:"image/bmp",tiff:"image/tiff",mp4:"video/mp4",webm:"video/webm",mov:"video/quicktime",avi:"video/x-msvideo",mkv:"video/x-matroska",ogv:"video/ogg",pdf:"application/pdf",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",otf:"font/otf",eot:"application/vnd.ms-fontobject"}[e]||"application/octet-stream"}function po(o,e){let n=Ee__namespace.load(o),t=[],i=new Set;return n("img[src]").each((r,c)=>{let s=n(c).attr("src");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P__namespace.resolve(e,s);$__namespace.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P__namespace.basename(s),mediaType:we(s),contentType:ae(s)});}}),n("img[srcset]").each((r,c)=>{let s=n(c).attr("srcset");if(s){let d=s.split(",").map(m=>m.trim().split(/\s+/)[0]);for(let m of d)if(m&&re(m)&&!i.has(m)){i.add(m);let v=P__namespace.resolve(e,m);$__namespace.existsSync(v)&&t.push({originalPath:m,absolutePath:v,fileName:P__namespace.basename(m),mediaType:we(m),contentType:ae(m)});}}}),n("source[src]").each((r,c)=>{let s=n(c).attr("src");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P__namespace.resolve(e,s);$__namespace.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P__namespace.basename(s),mediaType:we(s),contentType:ae(s)});}}),n("video[poster]").each((r,c)=>{let s=n(c).attr("poster");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P__namespace.resolve(e,s);$__namespace.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P__namespace.basename(s),mediaType:"images",contentType:ae(s)});}}),n('[style*="background"]').each((r,c)=>{let d=(n(c).attr("style")||"").match(/url\(['"]?([^'")\s]+)['"]?\)/);if(d&&d[1]){let m=d[1];if(re(m)&&!i.has(m)){i.add(m);let v=P__namespace.resolve(e,m);$__namespace.existsSync(v)&&t.push({originalPath:m,absolutePath:v,fileName:P__namespace.basename(m),mediaType:we(m),contentType:ae(m)});}}}),n('link[href][rel*="icon"]').each((r,c)=>{let s=n(c).attr("href");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P__namespace.resolve(e,s);$__namespace.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P__namespace.basename(s),mediaType:"images",contentType:ae(s)});}}),t}async function Le(o,e,n,t,i,r){let c=po(o,e);if(c.length===0)return {html:o,uploadedCount:0,failedCount:0,urlMap:new Map,sourceFileUpdated:false};i?.(`Found ${c.length} local asset(s) to upload`);let s=new Map,d=0,m=0,v=10;for(let g=0;g<c.length;g+=v){let f=c.slice(g,g+v),p=f.map(h=>({file_base64:$__namespace.readFileSync(h.absolutePath).toString("base64"),file_name:h.fileName,media_type:h.mediaType,content_type:h.contentType}));try{if(p.length>1&&t.media.uploadBatch){let h=await t.media.uploadBatch(n,{files:p});for(let C=0;C<h.result.uploaded.length;C++){let k=h.result.uploaded[C],S=f[C];k.success?(s.set(S.originalPath,k.url),d++,i?.(`Uploaded: ${S.fileName} \u2192 ${k.url}`)):(m++,i?.(`Failed: ${S.fileName} - ${k.error}`));}}else for(let h=0;h<p.length;h++){let C=p[h],k=f[h];try{let S=await t.media.upload(n,C);s.set(k.originalPath,S.result.url),d++,i?.(`Uploaded: ${k.fileName} \u2192 ${S.result.url}`);}catch(S){m++,i?.(`Failed: ${k.fileName} - ${S instanceof Error?S.message:"Unknown error"}`);}}}catch{for(let C=0;C<p.length;C++){let k=p[C],S=f[C];try{let _=await t.media.upload(n,k);s.set(S.originalPath,_.result.url),d++,i?.(`Uploaded: ${S.fileName} \u2192 ${_.result.url}`);}catch(_){m++,i?.(`Failed: ${S.fileName} - ${_ instanceof Error?_.message:"Unknown error"}`);}}}}let b=Ee__namespace.load(o);b("img[src]").each((g,f)=>{let p=b(f).attr("src");p&&s.has(p)&&b(f).attr("src",s.get(p));}),b("img[srcset]").each((g,f)=>{let p=b(f).attr("srcset");if(p){let h=p;for(let[C,k]of s)h=h.replace(new RegExp(Ae(C),"g"),k);b(f).attr("srcset",h);}}),b("source[src]").each((g,f)=>{let p=b(f).attr("src");p&&s.has(p)&&b(f).attr("src",s.get(p));}),b("video[poster]").each((g,f)=>{let p=b(f).attr("poster");p&&s.has(p)&&b(f).attr("poster",s.get(p));}),b('[style*="background"]').each((g,f)=>{let p=b(f).attr("style")||"";for(let[h,C]of s)p=p.replace(new RegExp(Ae(h),"g"),C);b(f).attr("style",p);}),b("link[href]").each((g,f)=>{let p=b(f).attr("href");p&&s.has(p)&&b(f).attr("href",s.get(p));});let u=b.html(),x=false;if(r&&d>0)try{let g=$__namespace.readFileSync(r,"utf-8"),f=g;for(let[p,h]of s)f=f.replace(new RegExp(Ae(p),"g"),h);f!==g&&($__namespace.writeFileSync(r,f,"utf-8"),x=!0,i?.(`Updated source file with CDN URLs: ${r}`));}catch(g){i?.(`Warning: Could not update source file: ${g instanceof Error?g.message:"Unknown error"}`);}return {html:u,uploadedCount:d,failedCount:m,urlMap:s,sourceFileUpdated:x}}function Ae(o){return o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Re(o,e){let n,t=o.match(/<main[^>]*>([\s\S]*)<\/main>/i),i=o.match(/<body[^>]*>([\s\S]*)<\/body>/i);t?n=t[1].trim():i?n=i[1].trim():n=o;let r=be(n),c=r.mainContent,s=o.match(/<title>([^<]*)<\/title>/i),d=s?s[1].trim():e,m="",v="",b=o.match(/<!-- Page Custom Code \(Header\) -->\s*([\s\S]*?)\s*<!-- End Page Custom Code \(Header\) -->/i);b&&b[1].trim()&&(m=b[1].trim());let u=o.match(/<!-- Page Custom Code \(Footer\) -->\s*([\s\S]*?)\s*<!-- End Page Custom Code \(Footer\) -->/i);u&&u[1].trim()&&(v=u[1].trim());let x=o.match(/<html[^>]*class="([^"]*)"/i),g=x?x[1].includes("dark"):true,f=o.match(/<main[^>]*>/i),p="ltr",h="";if(f){let X=f[0].match(/dir="([^"]*)"/i);X&&(p=X[1]);let Xe=f[0].match(/class="([^"]*)"/i);Xe&&(h=Xe[1]);}let C=!o.includes("motion@latest"),k=o.match(/<meta\s+name="description"\s+content="([^"]*)"/i),S=o.match(/<meta\s+property="og:title"\s+content="([^"]*)"/i),_=o.match(/<meta\s+property="og:description"\s+content="([^"]*)"/i),A=o.match(/<meta\s+property="og:image"\s+content="([^"]*)"/i),I=o.match(/<link\s+rel="canonical"\s+href="([^"]*)"/i),ee=o.match(/noindex/i),de=o.match(/nofollow/i),E={};d&&(E.page_title=d),k&&k[1]&&(E.meta_description=k[1]),S&&S[1]&&(E.social_title=S[1]),_&&_[1]&&(E.social_description=_[1]),A&&A[1]&&(E.social_image=A[1]),I&&I[1]&&(E.canonical_url=I[1]),E.noindex=!!ee,E.nofollow=!!de;let te={theme:{mode:g?"Dark":"Light",direction:p,main_classes:h,animations_deactivated:C},should_convert:true},oe=m||v?{}:void 0;return oe&&(m&&(oe.header=m),v&&(oe.footer=v)),{html:c,globalHeader:r.globalHeader,globalFooter:r.globalFooter,templateName:d,headerCode:m||void 0,footerCode:v||void 0,settings:te,seo:E,customCodes:oe}}var Q=P__namespace.join(De__namespace.tmpdir(),"lindoai-pages-preview.pid"),ge=P__namespace.join(De__namespace.tmpdir(),"lindoai-pages-preview.port");function We(){let o=new commander.Command("pages").description("Page management operations");return o.command("list").description("List all pages for a website").requiredOption("-w, --website <id>","Website ID").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.list(e.website,{page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else {let i=t.result;if(i?.list&&i.list.length>0){console.log(`
53
- Pages:`),console.log("------");for(let r of i.list)console.log(` ID: ${r.page_id}`),console.log(` Name: ${r.name??"N/A"}`),console.log(` Path: ${r.path??"N/A"}`),console.log(` Status: ${r.status??"N/A"}`),console.log(` Published: ${r.publish_date?"Yes":"No"}`),console.log("");console.log(`Total: ${i.total??i.list.length}`);}else a("No pages found");}}catch(t){z(t);}}),o.command("get").description("Get details of a specific page").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Page ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.get(e.website,e.id);if(e.format==="json")y(t,"json");else {let i=t.result;i?(console.log(`
54
- Page Details:`),console.log("-------------"),console.log(` ID: ${i.page_id}`),console.log(` Name: ${i.name??"N/A"}`),console.log(` Path: ${i.path??"N/A"}`),console.log(` Status: ${i.status??"N/A"}`),console.log(` Published: ${i.publish_date?"Yes":"No"}`),console.log(` Created: ${i.created_date??"N/A"}`)):l("Page not found");}}catch(t){z(t);}}),o.command("unpublish").description("Unpublish a page").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Page ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.unpublish(e.website,e.id);e.format==="json"?y(t,"json"):t.success?(w("Page unpublished successfully"),console.log(` Page ID: ${t.result?.page_id}`)):l("Failed to unpublish page");}catch(t){z(t);}}),o.command("delete").description("Delete a page").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Page ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.deletePage(e.website,e.id);if(e.format==="json")y(t,"json");else if(t.success){if(w("Page deleted successfully"),console.log(` Page ID: ${t.result?.page_id}`),t.result?.warnings&&t.result.warnings.length>0){console.log(" Warnings:");for(let i of t.result.warnings)console.log(` - ${i}`);}}else l("Failed to delete page");}catch(t){z(t);}}),o.command("create-empty").description("Create a new empty page with starter template and live preview").argument("<website_id>","Website ID").argument("<path>","URL path for the page (e.g., /about-us)").option("--title <title>","Page title","New Page").option("--file <path>","Output file path","./page.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=Y();try{a("Fetching website details...");let c=(await i.websites.getDetails(e)).result,s=c?.theme||{},d=c?.global_header||null,m=c?.global_footer||null,v=c?.custom_codes||{header:null,footer:null},b={font:s.font,title_font:s.title_font},u=t.title,x=`<!-- Hero Section -->
51
+ `);return {section:h,remainingHtml:S}}function mo(o){let e=["section","header","footer"],n=0;for(let t of e){let i=new RegExp(`<${t}\\b`,"gi"),a=new RegExp(`</${t}>`,"gi"),c=(o.match(i)||[]).length,s=(o.match(a)||[]).length;n+=c-s;}return n===0}function be(o){let e=st(o,"header"),n=st(e.remainingHtml,"footer");return {globalHeader:e.section,globalFooter:n.section,mainContent:n.remainingHtml.trim()}}function Ie(o,e,n){let t=[];return e&&e.trim()&&t.push(e.trim()),o.trim()&&t.push(o.trim()),n&&n.trim()&&t.push(n.trim()),t.join(`
52
+ `)}function re(o){return !(!o||o.startsWith("http://")||o.startsWith("https://")||o.startsWith("//")||o.startsWith("data:")||o.startsWith("blob:")||o.startsWith("#"))}function we(o){let e=o.toLowerCase().split(".").pop()||"",n=["jpg","jpeg","png","gif","webp","svg","ico","avif","bmp","tiff"],t=["mp4","webm","mov","avi","mkv","ogv"],i=["woff","woff2","ttf","otf","eot"];return n.includes(e)?"images":t.includes(e)?"videos":i.includes(e)?"fonts":"documents"}function ae(o){let e=o.toLowerCase().split(".").pop()||"";return {jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",ico:"image/x-icon",avif:"image/avif",bmp:"image/bmp",tiff:"image/tiff",mp4:"video/mp4",webm:"video/webm",mov:"video/quicktime",avi:"video/x-msvideo",mkv:"video/x-matroska",ogv:"video/ogg",pdf:"application/pdf",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",otf:"font/otf",eot:"application/vnd.ms-fontobject"}[e]||"application/octet-stream"}function po(o,e){let n=Ee__namespace.load(o),t=[],i=new Set;return n("img[src]").each((a,c)=>{let s=n(c).attr("src");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P__namespace.resolve(e,s);$__namespace.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P__namespace.basename(s),mediaType:we(s),contentType:ae(s)});}}),n("img[srcset]").each((a,c)=>{let s=n(c).attr("srcset");if(s){let d=s.split(",").map(m=>m.trim().split(/\s+/)[0]);for(let m of d)if(m&&re(m)&&!i.has(m)){i.add(m);let v=P__namespace.resolve(e,m);$__namespace.existsSync(v)&&t.push({originalPath:m,absolutePath:v,fileName:P__namespace.basename(m),mediaType:we(m),contentType:ae(m)});}}}),n("source[src]").each((a,c)=>{let s=n(c).attr("src");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P__namespace.resolve(e,s);$__namespace.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P__namespace.basename(s),mediaType:we(s),contentType:ae(s)});}}),n("video[poster]").each((a,c)=>{let s=n(c).attr("poster");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P__namespace.resolve(e,s);$__namespace.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P__namespace.basename(s),mediaType:"images",contentType:ae(s)});}}),n('[style*="background"]').each((a,c)=>{let d=(n(c).attr("style")||"").match(/url\(['"]?([^'")\s]+)['"]?\)/);if(d&&d[1]){let m=d[1];if(re(m)&&!i.has(m)){i.add(m);let v=P__namespace.resolve(e,m);$__namespace.existsSync(v)&&t.push({originalPath:m,absolutePath:v,fileName:P__namespace.basename(m),mediaType:we(m),contentType:ae(m)});}}}),n('link[href][rel*="icon"]').each((a,c)=>{let s=n(c).attr("href");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P__namespace.resolve(e,s);$__namespace.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P__namespace.basename(s),mediaType:"images",contentType:ae(s)});}}),t}async function Le(o,e,n,t,i,a){let c=po(o,e);if(c.length===0)return {html:o,uploadedCount:0,failedCount:0,urlMap:new Map,sourceFileUpdated:false};i?.(`Found ${c.length} local asset(s) to upload`);let s=new Map,d=0,m=0,v=10;for(let g=0;g<c.length;g+=v){let f=c.slice(g,g+v),p=f.map(h=>({file_base64:$__namespace.readFileSync(h.absolutePath).toString("base64"),file_name:h.fileName,media_type:h.mediaType,content_type:h.contentType}));try{if(p.length>1&&t.media.uploadBatch){let h=await t.media.uploadBatch(n,{files:p});for(let C=0;C<h.result.uploaded.length;C++){let k=h.result.uploaded[C],S=f[C];k.success?(s.set(S.originalPath,k.url),d++,i?.(`Uploaded: ${S.fileName} \u2192 ${k.url}`)):(m++,i?.(`Failed: ${S.fileName} - ${k.error}`));}}else for(let h=0;h<p.length;h++){let C=p[h],k=f[h];try{let S=await t.media.upload(n,C);s.set(k.originalPath,S.result.url),d++,i?.(`Uploaded: ${k.fileName} \u2192 ${S.result.url}`);}catch(S){m++,i?.(`Failed: ${k.fileName} - ${S instanceof Error?S.message:"Unknown error"}`);}}}catch{for(let C=0;C<p.length;C++){let k=p[C],S=f[C];try{let _=await t.media.upload(n,k);s.set(S.originalPath,_.result.url),d++,i?.(`Uploaded: ${S.fileName} \u2192 ${_.result.url}`);}catch(_){m++,i?.(`Failed: ${S.fileName} - ${_ instanceof Error?_.message:"Unknown error"}`);}}}}let b=Ee__namespace.load(o);b("img[src]").each((g,f)=>{let p=b(f).attr("src");p&&s.has(p)&&b(f).attr("src",s.get(p));}),b("img[srcset]").each((g,f)=>{let p=b(f).attr("srcset");if(p){let h=p;for(let[C,k]of s)h=h.replace(new RegExp(Ae(C),"g"),k);b(f).attr("srcset",h);}}),b("source[src]").each((g,f)=>{let p=b(f).attr("src");p&&s.has(p)&&b(f).attr("src",s.get(p));}),b("video[poster]").each((g,f)=>{let p=b(f).attr("poster");p&&s.has(p)&&b(f).attr("poster",s.get(p));}),b('[style*="background"]').each((g,f)=>{let p=b(f).attr("style")||"";for(let[h,C]of s)p=p.replace(new RegExp(Ae(h),"g"),C);b(f).attr("style",p);}),b("link[href]").each((g,f)=>{let p=b(f).attr("href");p&&s.has(p)&&b(f).attr("href",s.get(p));});let u=b.html(),x=false;if(a&&d>0)try{let g=$__namespace.readFileSync(a,"utf-8"),f=g;for(let[p,h]of s)f=f.replace(new RegExp(Ae(p),"g"),h);f!==g&&($__namespace.writeFileSync(a,f,"utf-8"),x=!0,i?.(`Updated source file with CDN URLs: ${a}`));}catch(g){i?.(`Warning: Could not update source file: ${g instanceof Error?g.message:"Unknown error"}`);}return {html:u,uploadedCount:d,failedCount:m,urlMap:s,sourceFileUpdated:x}}function Ae(o){return o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Re(o,e){let n,t=o.match(/<main[^>]*>([\s\S]*)<\/main>/i),i=o.match(/<body[^>]*>([\s\S]*)<\/body>/i);t?n=t[1].trim():i?n=i[1].trim():n=o;let a=be(n),c=a.mainContent,s=o.match(/<title>([^<]*)<\/title>/i),d=s?s[1].trim():e,m="",v="",b=o.match(/<!-- Page Custom Code \(Header\) -->\s*([\s\S]*?)\s*<!-- End Page Custom Code \(Header\) -->/i);b&&b[1].trim()&&(m=b[1].trim());let u=o.match(/<!-- Page Custom Code \(Footer\) -->\s*([\s\S]*?)\s*<!-- End Page Custom Code \(Footer\) -->/i);u&&u[1].trim()&&(v=u[1].trim());let x=o.match(/<html[^>]*class="([^"]*)"/i),g=x?x[1].includes("dark"):true,f=o.match(/<main[^>]*>/i),p="ltr",h="";if(f){let X=f[0].match(/dir="([^"]*)"/i);X&&(p=X[1]);let Xe=f[0].match(/class="([^"]*)"/i);Xe&&(h=Xe[1]);}let C=!o.includes("motion@latest"),k=o.match(/<meta\s+name="description"\s+content="([^"]*)"/i),S=o.match(/<meta\s+property="og:title"\s+content="([^"]*)"/i),_=o.match(/<meta\s+property="og:description"\s+content="([^"]*)"/i),A=o.match(/<meta\s+property="og:image"\s+content="([^"]*)"/i),I=o.match(/<link\s+rel="canonical"\s+href="([^"]*)"/i),ee=o.match(/noindex/i),de=o.match(/nofollow/i),E={};d&&(E.page_title=d),k&&k[1]&&(E.meta_description=k[1]),S&&S[1]&&(E.social_title=S[1]),_&&_[1]&&(E.social_description=_[1]),A&&A[1]&&(E.social_image=A[1]),I&&I[1]&&(E.canonical_url=I[1]),E.noindex=!!ee,E.nofollow=!!de;let te={theme:{mode:g?"Dark":"Light",direction:p,main_classes:h,animations_deactivated:C},should_convert:true},oe=m||v?{}:void 0;return oe&&(m&&(oe.header=m),v&&(oe.footer=v)),{html:c,globalHeader:a.globalHeader,globalFooter:a.globalFooter,templateName:d,headerCode:m||void 0,footerCode:v||void 0,settings:te,seo:E,customCodes:oe}}var Q=P__namespace.join(De__namespace.tmpdir(),"lindoai-pages-preview.pid"),ge=P__namespace.join(De__namespace.tmpdir(),"lindoai-pages-preview.port");function We(){let o=new commander.Command("pages").description("Page management operations");return o.command("list").description("List all pages for a website").requiredOption("-w, --website <id>","Website ID").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.list(e.website,{page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else {let i=t.result;if(i?.list&&i.list.length>0){console.log(`
53
+ Pages:`),console.log("------");for(let a of i.list)console.log(` ID: ${a.page_id}`),console.log(` Name: ${a.name??"N/A"}`),console.log(` Path: ${a.path??"N/A"}`),console.log(` Status: ${a.status??"N/A"}`),console.log(` Published: ${a.publish_date?"Yes":"No"}`),console.log("");console.log(`Total: ${i.total??i.list.length}`);}else r("No pages found");}}catch(t){z(t);}}),o.command("get").description("Get details of a specific page").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Page ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.get(e.website,e.id);if(e.format==="json")y(t,"json");else {let i=t.result;i?(console.log(`
54
+ Page Details:`),console.log("-------------"),console.log(` ID: ${i.page_id}`),console.log(` Name: ${i.name??"N/A"}`),console.log(` Path: ${i.path??"N/A"}`),console.log(` Status: ${i.status??"N/A"}`),console.log(` Published: ${i.publish_date?"Yes":"No"}`),console.log(` Created: ${i.created_date??"N/A"}`)):l("Page not found");}}catch(t){z(t);}}),o.command("unpublish").description("Unpublish a page").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Page ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.unpublish(e.website,e.id);e.format==="json"?y(t,"json"):t.success?(w("Page unpublished successfully"),console.log(` Page ID: ${t.result?.page_id}`)):l("Failed to unpublish page");}catch(t){z(t);}}),o.command("delete").description("Delete a page").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Page ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.deletePage(e.website,e.id);if(e.format==="json")y(t,"json");else if(t.success){if(w("Page deleted successfully"),console.log(` Page ID: ${t.result?.page_id}`),t.result?.warnings&&t.result.warnings.length>0){console.log(" Warnings:");for(let i of t.result.warnings)console.log(` - ${i}`);}}else l("Failed to delete page");}catch(t){z(t);}}),o.command("create-empty").description("Create a new empty page with starter template and live preview").argument("<website_id>","Website ID").argument("<path>","URL path for the page (e.g., /about-us)").option("--title <title>","Page title","New Page").option("--file <path>","Output file path","./page.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=Y();try{r("Fetching website details...");let c=(await i.websites.getDetails(e)).result,s=c?.theme||{},d=c?.global_header||null,m=c?.global_footer||null,v=c?.custom_codes||{header:null,footer:null},b={font:s.font,title_font:s.title_font},u=t.title,x=`<!-- Hero Section -->
55
55
  <section class="relative min-h-[80vh] flex items-center justify-center bg-gradient-to-br from-neutral-50 to-neutral-100 dark:from-neutral-900 dark:to-neutral-800">
56
56
  <div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
57
57
  <h1 class="text-4xl sm:text-5xl lg:text-6xl font-bold text-neutral-900 dark:text-white mb-6">
@@ -127,7 +127,7 @@ Page Details:`),console.log("-------------"),console.log(` ID: ${i.page_id}`),c
127
127
  Contact Us
128
128
  </a>
129
129
  </div>
130
- </section>`,g={theme:{mode:"Dark",direction:"ltr",main_classes:"bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-100",animations_deactivated:!1},should_convert:!0},f={page_title:u,meta_description:"",social_title:u,social_description:"",noindex:!1,nofollow:!1};a("Creating page...");let p=await i.pages.create(e,{html:x,path:n,settings:g,template_name:u,seo:f});p.success||(l("Failed to create page"),process.exit(1));let h=p.result.page_id,C=p.result.published_url;w(`Page created: ${h}`),C&&console.log(` Published URL: ${C}`);let k=ue(b),S=Ie(x,d??void 0,m??void 0),_={header:v.header||"",footer:v.footer||""},A=`<!DOCTYPE html>
130
+ </section>`,g={theme:{mode:"Dark",direction:"ltr",main_classes:"bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-100",animations_deactivated:!1},should_convert:!0},f={page_title:u,meta_description:"",social_title:u,social_description:"",noindex:!1,nofollow:!1};r("Creating page...");let p=await i.pages.create(e,{html:x,path:n,settings:g,template_name:u,seo:f});p.success||(l("Failed to create page"),process.exit(1));let h=p.result.page_id,C=p.result.published_url;w(`Page created: ${h}`),C&&console.log(` Published URL: ${C}`);let k=ue(b),S=Ie(x,d??void 0,m??void 0),_={header:v.header||"",footer:v.footer||""},A=`<!DOCTYPE html>
131
131
  <html class="dark" lang="en">
132
132
  <head>
133
133
  <meta charset="UTF-8">
@@ -176,7 +176,7 @@ ${S}
176
176
  ${_.footer}
177
177
  <!-- End Page Custom Code (Footer) -->
178
178
  </body>
179
- </html>`,I=P__namespace.resolve(t.file);$__namespace.writeFileSync(I,A,"utf-8"),w(`HTML saved to ${I}`),await dt(),t.background?await mt(I):await pt(I),console.log(""),a(`To save changes: lindoai pages update ${e} ${h} --html-file ${t.file}`);}catch(r){z(r);}}),o.command("edit").description("Edit a page with live preview").argument("<website_id>","Website ID").argument("<page_id>","Page ID").option("--file <path>","Output file path","./page.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=Y();try{a("Fetching page HTML...");let r=await i.pages.getHtml(e,n);r.result||(l("Page not found"),process.exit(1));let c=r.result.html;c||(l("Page has no HTML content"),a("Make sure the page has been created with HTML content"),process.exit(1)),a("Fetching website details...");let d=(await i.websites.getDetails(e)).result,m=d?.theme||{},v=d?.global_header||null,b=d?.global_footer||null,u=d?.custom_codes||{header:null,footer:null},x=r.result.name||"Page",g=r.result.seo||{},f=r.result.settings||{},p=r.result.custom_codes||{},h={header:p.header||u.header||"",footer:p.footer||u.footer||""},C=f.theme||{},k=C.mode!=="Light",S=C.direction||"ltr",_=C.main_classes||"",A=C.animations_deactivated||!1,I={font:C.font||m.font,title_font:C.title_font||m.title_font},ee=ue(I),E=be(c).mainContent,te=Ie(E,v??void 0,b??void 0),oe=`<!DOCTYPE html>
179
+ </html>`,I=P__namespace.resolve(t.file);$__namespace.writeFileSync(I,A,"utf-8"),w(`HTML saved to ${I}`),await dt(),t.background?await mt(I):await pt(I),console.log(""),r(`To save changes: lindoai pages update ${e} ${h} --html-file ${t.file}`);}catch(a){z(a);}}),o.command("edit").description("Edit a page with live preview").argument("<website_id>","Website ID").argument("<page_id>","Page ID").option("--file <path>","Output file path","./page.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=Y();try{r("Fetching page HTML...");let a=await i.pages.getHtml(e,n);a.result||(l("Page not found"),process.exit(1));let c=a.result.html;c||(l("Page has no HTML content"),r("Make sure the page has been created with HTML content"),process.exit(1)),r("Fetching website details...");let d=(await i.websites.getDetails(e)).result,m=d?.theme||{},v=d?.global_header||null,b=d?.global_footer||null,u=d?.custom_codes||{header:null,footer:null},x=a.result.name||"Page",g=a.result.seo||{},f=a.result.settings||{},p=a.result.custom_codes||{},h={header:p.header||u.header||"",footer:p.footer||u.footer||""},C=f.theme||{},k=C.mode!=="Light",S=C.direction||"ltr",_=C.main_classes||"",A=C.animations_deactivated||!1,I={font:C.font||m.font,title_font:C.title_font||m.title_font},ee=ue(I),E=be(c).mainContent,te=Ie(E,v??void 0,b??void 0),oe=`<!DOCTYPE html>
180
180
  <html class="${k?"dark":""}" lang="en">
181
181
  <head>
182
182
  <meta charset="UTF-8">
@@ -232,10 +232,10 @@ ${te}
232
232
  ${h.footer}
233
233
  <!-- End Page Custom Code (Footer) -->
234
234
  </body>
235
- </html>`,X=P__namespace.resolve(t.file);$__namespace.writeFileSync(X,oe,"utf-8"),w(`HTML saved to ${X}`),await dt(),t.background?await mt(X):await pt(X);}catch(r){z(r);}}),o.command("update").description("Update a page from HTML file (note: global header/footer changes are page-specific only)").argument("<website_id>","Website ID").argument("<page_id>","Page ID").option("--html-file <path>","Path to local HTML file to upload").option("--upload-assets","Upload local images/assets to CDN before publishing").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=Y();try{t.htmlFile||(l("--html-file option is required"),a("Usage: lindoai pages update <website_id> <page_id> --html-file <path>"),process.exit(1));let r=P__namespace.resolve(t.htmlFile);$__namespace.existsSync(r)||(l(`File not found: ${r}`),process.exit(1));let c=$__namespace.readFileSync(r,"utf-8");if(a(`Read ${c.length} bytes from ${r}`),t.uploadAssets){let u=P__namespace.dirname(r);a("Processing local assets...");let x=await Le(c,u,e,i,g=>a(g),r);x.uploadedCount>0&&(c=x.html,w(`Uploaded ${x.uploadedCount} asset(s) to CDN`),x.failedCount>0&&a(`Warning: ${x.failedCount} asset(s) failed to upload`),x.sourceFileUpdated&&a("Source file updated with CDN URLs (prevents duplicate uploads)"));}let s=Re(c);s.globalHeader&&a("Detected global header section"),s.globalFooter&&a("Detected global footer section"),s.templateName&&a(`Extracted page title: ${s.templateName}`),s.headerCode&&a("Extracted header custom code"),s.footerCode&&a("Extracted footer custom code"),Object.keys(s.seo).length>2&&a("Extracted SEO metadata");let d=await i.pages.get(e,n);d.result||(l("Page not found"),process.exit(1));let m=d.result.path,v={...d.result.settings||{},theme:{...d.result.settings?.theme||{},...s.settings.theme},should_convert:!0};a("Updating page...");let b=await i.pages.publish(e,n,{html:s.html,path:m,settings:v,template_name:s.templateName,custom_codes:s.customCodes,seo:Object.keys(s.seo).length>0?s.seo:void 0,global_header:s.globalHeader,global_footer:s.globalFooter});t.format==="json"?y(b,"json"):b.success?(w("Page updated successfully"),console.log(` Page ID: ${b.result?.page_id}`),b.result?.published_url&&console.log(` Published URL: ${b.result.published_url}`)):l("Failed to update page");}catch(r){z(r);}}),o.command("stop-preview").description("Stop the background preview server").action(async()=>{try{if(!$__namespace.existsSync(Q)){a("No preview server is running");return}let e=parseInt($__namespace.readFileSync(Q,"utf-8").trim(),10);if(isNaN(e)){l("Invalid PID file"),Me();return}try{process.kill(e,"SIGTERM"),w(`Preview server (PID ${e}) stopped`);}catch(n){n.code==="ESRCH"?a("Preview server process not found (may have already stopped)"):l(`Failed to stop preview server: ${n.message}`);}Me();}catch(e){e instanceof Error?l(e.message):l("An unexpected error occurred"),process.exit(1);}}),o.command("create-with-content").description("Create pages from HTML files in a local folder with automatic asset upload").argument("<website_id>","Website ID").argument("<folder>","Path to folder containing HTML files").option("--path-prefix <prefix>","URL path prefix for pages (e.g., /blog)","").option("--dry-run","Show what would be created without actually creating").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=Y();try{let r=P__namespace.resolve(n);$__namespace.existsSync(r)||(l(`Folder not found: ${r}`),process.exit(1)),$__namespace.statSync(r).isDirectory()||(l(`Not a directory: ${r}`),process.exit(1));let d=$__namespace.readdirSync(r).filter(u=>u.endsWith(".html"));if(d.length===0&&(l("No HTML files found in folder"),process.exit(1)),a(`Found ${d.length} HTML file(s) to create`),t.dryRun){console.log(`
236
- Dry run - would create:`);for(let u of d){let x=u==="index.html"?t.pathPrefix||"/":`${t.pathPrefix}/${u.replace(".html","")}`;console.log(` ${u} \u2192 ${x}`);}return}let m=[];for(let u of d){let x=P__namespace.join(r,u),g=$__namespace.readFileSync(x,"utf-8");a(`
237
- Processing: ${u}`),a("Uploading local assets...");let f=await Le(g,r,e,i,C=>a(` ${C}`));f.uploadedCount>0&&(g=f.html,w(` Uploaded ${f.uploadedCount} asset(s)`));let p=Re(g,u.replace(".html",""));p.globalHeader&&a(" Detected global header section"),p.globalFooter&&a(" Detected global footer section"),p.templateName&&a(` Extracted page title: ${p.templateName}`),p.headerCode&&a(" Extracted header custom code"),p.footerCode&&a(" Extracted footer custom code"),Object.keys(p.seo).length>2&&a(" Extracted SEO metadata");let h=u==="index.html"?t.pathPrefix||"/":`${t.pathPrefix}/${u.replace(".html","")}`;try{a(` Creating page at ${h}...`);let C=await i.pages.create(e,{html:p.html,path:h,template_name:p.templateName,seo:Object.keys(p.seo).length>0?p.seo:void 0,settings:p.settings,custom_codes:p.customCodes,global_header:p.globalHeader,global_footer:p.globalFooter});if(C.success){let k=C.result.published_url;w(` Created: ${u} \u2192 ${h} (${C.result.page_id})`),k&&console.log(` URL: ${k}`),m.push({file:u,pageId:C.result.page_id,success:!0});}else l(` Failed to create: ${u}`),m.push({file:u,success:!1,error:"API returned failure"});}catch(C){let k=C instanceof Error?C.message:"Unknown error";l(` Failed to create: ${u} - ${k}`),m.push({file:u,success:!1,error:k});}}console.log(`
238
- --- Summary ---`);let v=m.filter(u=>u.success).length,b=m.filter(u=>!u.success).length;if(t.format==="json")y({results:m,successCount:v,failCount:b},"json");else if(console.log(`Created: ${v}/${m.length} pages`),b>0){console.log(`Failed: ${b} pages`);for(let u of m.filter(x=>!x.success))console.log(` - ${u.file}: ${u.error}`);}}catch(r){z(r);}}),o}function Y(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function z(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Me(){try{$__namespace.existsSync(Q)&&$__namespace.unlinkSync(Q);}catch{}try{$__namespace.existsSync(ge)&&$__namespace.unlinkSync(ge);}catch{}}async function dt(){if($__namespace.existsSync(Q)){try{let o=parseInt($__namespace.readFileSync(Q,"utf-8").trim(),10);if(!isNaN(o))try{process.kill(o,"SIGTERM"),a(`Terminated existing preview server (PID ${o})`),await new Promise(e=>setTimeout(e,500));}catch{}}catch{}Me();}}async function mt(o){let e=P__namespace.resolve(o),n=`
235
+ </html>`,X=P__namespace.resolve(t.file);$__namespace.writeFileSync(X,oe,"utf-8"),w(`HTML saved to ${X}`),await dt(),t.background?await mt(X):await pt(X);}catch(a){z(a);}}),o.command("update").description("Update a page from HTML file (note: global header/footer changes are page-specific only)").argument("<website_id>","Website ID").argument("<page_id>","Page ID").option("--html-file <path>","Path to local HTML file to upload").option("--upload-assets","Upload local images/assets to CDN before publishing").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=Y();try{t.htmlFile||(l("--html-file option is required"),r("Usage: lindoai pages update <website_id> <page_id> --html-file <path>"),process.exit(1));let a=P__namespace.resolve(t.htmlFile);$__namespace.existsSync(a)||(l(`File not found: ${a}`),process.exit(1));let c=$__namespace.readFileSync(a,"utf-8");if(r(`Read ${c.length} bytes from ${a}`),t.uploadAssets){let u=P__namespace.dirname(a);r("Processing local assets...");let x=await Le(c,u,e,i,g=>r(g),a);x.uploadedCount>0&&(c=x.html,w(`Uploaded ${x.uploadedCount} asset(s) to CDN`),x.failedCount>0&&r(`Warning: ${x.failedCount} asset(s) failed to upload`),x.sourceFileUpdated&&r("Source file updated with CDN URLs (prevents duplicate uploads)"));}let s=Re(c);s.globalHeader&&r("Detected global header section"),s.globalFooter&&r("Detected global footer section"),s.templateName&&r(`Extracted page title: ${s.templateName}`),s.headerCode&&r("Extracted header custom code"),s.footerCode&&r("Extracted footer custom code"),Object.keys(s.seo).length>2&&r("Extracted SEO metadata");let d=await i.pages.get(e,n);d.result||(l("Page not found"),process.exit(1));let m=d.result.path,v={...d.result.settings||{},theme:{...d.result.settings?.theme||{},...s.settings.theme},should_convert:!0};r("Updating page...");let b=await i.pages.publish(e,n,{html:s.html,path:m,settings:v,template_name:s.templateName,custom_codes:s.customCodes,seo:Object.keys(s.seo).length>0?s.seo:void 0,global_header:s.globalHeader,global_footer:s.globalFooter});t.format==="json"?y(b,"json"):b.success?(w("Page updated successfully"),console.log(` Page ID: ${b.result?.page_id}`),b.result?.published_url&&console.log(` Published URL: ${b.result.published_url}`)):l("Failed to update page");}catch(a){z(a);}}),o.command("stop-preview").description("Stop the background preview server").action(async()=>{try{if(!$__namespace.existsSync(Q)){r("No preview server is running");return}let e=parseInt($__namespace.readFileSync(Q,"utf-8").trim(),10);if(isNaN(e)){l("Invalid PID file"),Me();return}try{process.kill(e,"SIGTERM"),w(`Preview server (PID ${e}) stopped`);}catch(n){n.code==="ESRCH"?r("Preview server process not found (may have already stopped)"):l(`Failed to stop preview server: ${n.message}`);}Me();}catch(e){e instanceof Error?l(e.message):l("An unexpected error occurred"),process.exit(1);}}),o.command("create-with-content").description("Create pages from HTML files in a local folder with automatic asset upload").argument("<website_id>","Website ID").argument("<folder>","Path to folder containing HTML files").option("--path-prefix <prefix>","URL path prefix for pages (e.g., /blog)","").option("--dry-run","Show what would be created without actually creating").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=Y();try{let a=P__namespace.resolve(n);$__namespace.existsSync(a)||(l(`Folder not found: ${a}`),process.exit(1)),$__namespace.statSync(a).isDirectory()||(l(`Not a directory: ${a}`),process.exit(1));let d=$__namespace.readdirSync(a).filter(u=>u.endsWith(".html"));if(d.length===0&&(l("No HTML files found in folder"),process.exit(1)),r(`Found ${d.length} HTML file(s) to create`),t.dryRun){console.log(`
236
+ Dry run - would create:`);for(let u of d){let x=u==="index.html"?t.pathPrefix||"/":`${t.pathPrefix}/${u.replace(".html","")}`;console.log(` ${u} \u2192 ${x}`);}return}let m=[];for(let u of d){let x=P__namespace.join(a,u),g=$__namespace.readFileSync(x,"utf-8");r(`
237
+ Processing: ${u}`),r("Uploading local assets...");let f=await Le(g,a,e,i,C=>r(` ${C}`));f.uploadedCount>0&&(g=f.html,w(` Uploaded ${f.uploadedCount} asset(s)`));let p=Re(g,u.replace(".html",""));p.globalHeader&&r(" Detected global header section"),p.globalFooter&&r(" Detected global footer section"),p.templateName&&r(` Extracted page title: ${p.templateName}`),p.headerCode&&r(" Extracted header custom code"),p.footerCode&&r(" Extracted footer custom code"),Object.keys(p.seo).length>2&&r(" Extracted SEO metadata");let h=u==="index.html"?t.pathPrefix||"/":`${t.pathPrefix}/${u.replace(".html","")}`;try{r(` Creating page at ${h}...`);let C=await i.pages.create(e,{html:p.html,path:h,template_name:p.templateName,seo:Object.keys(p.seo).length>0?p.seo:void 0,settings:p.settings,custom_codes:p.customCodes,global_header:p.globalHeader,global_footer:p.globalFooter});if(C.success){let k=C.result.published_url;w(` Created: ${u} \u2192 ${h} (${C.result.page_id})`),k&&console.log(` URL: ${k}`),m.push({file:u,pageId:C.result.page_id,success:!0});}else l(` Failed to create: ${u}`),m.push({file:u,success:!1,error:"API returned failure"});}catch(C){let k=C instanceof Error?C.message:"Unknown error";l(` Failed to create: ${u} - ${k}`),m.push({file:u,success:!1,error:k});}}console.log(`
238
+ --- Summary ---`);let v=m.filter(u=>u.success).length,b=m.filter(u=>!u.success).length;if(t.format==="json")y({results:m,successCount:v,failCount:b},"json");else if(console.log(`Created: ${v}/${m.length} pages`),b>0){console.log(`Failed: ${b} pages`);for(let u of m.filter(x=>!x.success))console.log(` - ${u.file}: ${u.error}`);}}catch(a){z(a);}}),o}function Y(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function z(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Me(){try{$__namespace.existsSync(Q)&&$__namespace.unlinkSync(Q);}catch{}try{$__namespace.existsSync(ge)&&$__namespace.unlinkSync(ge);}catch{}}async function dt(){if($__namespace.existsSync(Q)){try{let o=parseInt($__namespace.readFileSync(Q,"utf-8").trim(),10);if(!isNaN(o))try{process.kill(o,"SIGTERM"),r(`Terminated existing preview server (PID ${o})`),await new Promise(e=>setTimeout(e,500));}catch{}}catch{}Me();}}async function mt(o){let e=P__namespace.resolve(o),n=`
239
239
  const http = require('node:http');
240
240
  const fs = require('node:fs');
241
241
  const path = require('node:path');
@@ -355,9 +355,9 @@ Processing: ${u}`),a("Uploading local assets...");let f=await Le(g,r,e,i,C=>a(`
355
355
  });
356
356
  } catch {}
357
357
  });
358
- `,t=child_process.spawn(process.execPath,["-e",n],{detached:true,stdio:"ignore"});t.unref();let i=null;for(let s=0;s<50;s++)if(await new Promise(d=>setTimeout(d,100)),$__namespace.existsSync(ge))try{if(i=parseInt($__namespace.readFileSync(ge,"utf-8").trim(),10),!isNaN(i))break}catch{}i||(l("Failed to start preview server"),process.exit(1));let r=`http://127.0.0.1:${i}/`;await G(r)||a(`Could not open browser. Visit: ${r}`),w("Preview server started in background"),console.log(` URL: ${r}`),console.log(` PID: ${t.pid}`),console.log(""),a("To update the page: lindoai pages update <website_id> <page_id> --html-file <path>"),a("To stop the server: lindoai pages stop-preview");}async function pt(o){let{startLivePreviewServer:e}=await Promise.resolve().then(()=>(Ue(),Ne));a("Starting preview server...");let n=await e(o),t=`http://127.0.0.1:${n}/`;$__namespace.writeFileSync(Q,process.pid.toString(),"utf-8"),$__namespace.writeFileSync(ge,n.toString(),"utf-8"),await G(t)||a(`Could not open browser. Visit: ${t}`),w("Preview server started"),console.log(` URL: ${t}`),console.log(""),a("Press Ctrl+C to stop the server"),a("Edit the HTML file and save to see changes in the browser");}var Z=P__namespace.join(De__namespace.tmpdir(),"lindoai-blogs-preview.pid"),he=P__namespace.join(De__namespace.tmpdir(),"lindoai-blogs-preview.port");function qe(){let o=new commander.Command("blogs").description("Blog management operations");return o.command("list").description("List all blogs for a website").requiredOption("-w, --website <id>","Website ID").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.list(e.website,{page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else {let i=t.result;if(i?.list&&i.list.length>0){console.log(`
359
- Blogs:`),console.log("------");for(let r of i.list)console.log(` ID: ${r.blog_id}`),console.log(` Name: ${r.name??"N/A"}`),console.log(` Path: ${r.path??"N/A"}`),console.log(` Status: ${r.status??"N/A"}`),console.log(` Published: ${r.publish_date?new Date(r.publish_date*1e3).toISOString():"No"}`),console.log("");console.log(`Total: ${i.total??i.list.length}`);}else a("No blogs found");}}catch(t){J(t);}}),o.command("get").description("Get details of a specific blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.get(e.website,e.id);if(e.format==="json")y(t,"json");else {let i=t.result;i?(console.log(`
360
- Blog Details:`),console.log("-------------"),console.log(` ID: ${i.blog_id}`),console.log(` Name: ${i.name??"N/A"}`),console.log(` Path: ${i.path??"N/A"}`),console.log(` Status: ${i.status??"N/A"}`),console.log(` Published: ${i.publish_date?new Date(i.publish_date*1e3).toISOString():"No"}`),console.log(` Created: ${i.created_date??"N/A"}`)):l("Blog not found");}}catch(t){J(t);}}),o.command("publish").description("Publish a blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.publish(e.website,e.id);e.format==="json"?y(t,"json"):t.success?(w("Blog published successfully"),console.log(` Blog ID: ${t.result?.blog_id}`),console.log(` Published at: ${t.result?.publish_date?new Date(t.result.publish_date*1e3).toISOString():"N/A"}`),t.result?.published_url&&console.log(` Published URL: ${t.result.published_url}`)):l("Failed to publish blog");}catch(t){J(t);}}),o.command("unpublish").description("Unpublish a blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.unpublish(e.website,e.id);e.format==="json"?y(t,"json"):t.success?(w("Blog unpublished successfully"),console.log(` Blog ID: ${t.result?.blog_id}`)):l("Failed to unpublish blog");}catch(t){J(t);}}),o.command("delete").description("Delete a blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.delete(e.website,e.id);if(e.format==="json")y(t,"json");else if(t.success){if(w("Blog deleted successfully"),console.log(` Blog ID: ${t.result?.blog_id}`),t.result?.warnings&&t.result.warnings.length>0){console.log(" Warnings:");for(let i of t.result.warnings)console.log(` - ${i}`);}}else l("Failed to delete blog");}catch(t){J(t);}}),o.command("edit").description("Edit a blog with live preview").argument("<website_id>","Website ID").argument("<blog_id>","Blog ID").option("--file <path>","Output file path","./blog.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=V();try{a("Fetching blog content...");let r=await i.blogs.getHtml(e,n);r.result||(l("Blog not found"),process.exit(1));let c=r.result,s=await i.websites.getDetails(e);s.result||(l("Website not found"),process.exit(1));let d=s.result,m=d,v=m?.theme||{},b=m?.custom_codes||{header:null,footer:null},u={font:v.font,title_font:v.title_font},x=c.seo||{},g=c.blog_settings||{},f=c.blog_content||"<p>Start writing your blog content here...</p>",p=ht({seo:x,blogSettings:g,blogContent:f,websiteName:d.business_name||"Blog",blogPath:v.blog_path||"blog",websiteTheme:u,customCodes:{header:b.header||void 0,footer:b.footer||void 0}}),h=P__namespace.resolve(t.file);$__namespace.writeFileSync(h,p,"utf-8"),w(`HTML saved to ${h}`),await ut(),t.background?await ft(h):await gt(h),console.log(""),a(`To save changes: lindoai blogs update ${e} ${n} --html-file ${t.file}`);}catch(r){J(r);}}),o.command("update").description("Update a blog from HTML file").argument("<website_id>","Website ID").argument("<blog_id>","Blog ID").option("--html-file <path>","Path to local HTML file").option("--md-file <path>","Path to local Markdown file").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=V();try{!t.htmlFile&&!t.mdFile&&(l("Either --html-file or --md-file option is required"),a("Usage: lindoai blogs update <website_id> <blog_id> --html-file <path>"),a(" or: lindoai blogs update <website_id> <blog_id> --md-file <path>"),process.exit(1));let r,c={},s={};if(t.mdFile){let g=P__namespace.resolve(t.mdFile);$__namespace.existsSync(g)||(l(`File not found: ${g}`),process.exit(1));let f=$__namespace.readFileSync(g,"utf-8");a(`Read ${f.length} bytes from ${g}`);let{content:p,frontmatter:h}=ko(f);r=_o(p),h.title&&(c.page_title=h.title),h.description&&(c.meta_description=h.description),h.image&&(c.social_image=h.image),h.author&&(s.author=h.author),h.excerpt&&(s.excerpt=h.excerpt),h.category&&(s.category=h.category),h.date&&(s.publish_date=h.date);}else {let g=P__namespace.resolve(t.htmlFile);$__namespace.existsSync(g)||(l(`File not found: ${g}`),process.exit(1));let f=$__namespace.readFileSync(g,"utf-8");a(`Read ${f.length} bytes from ${g}`);let p=f.match(/<article[^>]*class="[^"]*prose[^"]*"[^>]*>([\s\S]*?)<\/article>/i);r=p?p[1].trim():"",r||(l("Could not extract blog content from HTML"),a('Make sure the blog content is inside <article class="...prose...">...</article>'),process.exit(1));let h=f.match(/<title>([^<]*)<\/title>/i),C=f.match(/<meta\s+name="description"\s+content="([^"]*)"/i),k=f.match(/<meta\s+property="og:image"\s+content="([^"]*)"/i);h&&(c.page_title=h[1].trim()),C&&(c.meta_description=C[1]),k&&(c.social_image=k[1]);let S=f.match(/id="blog-author-display"[^>]*>([\s\S]*?)<\/span>/i),_=f.match(/class="[^"]*bg-blue-500\/10[^"]*"[^>]*>([^<]*)</i),A=f.match(/class="[^"]*border-l-4 border-blue-500[^"]*"[^>]*>([\s\S]*?)<\/div>/i),I=f.match(/<time[^>]*>([^<]*)<\/time>/i),ee=f.match(/<span>(\d+\s*min\s*read)<\/span>/i),de=f.match(/<div class="aspect-video[^"]*"[^>]*>\s*<img[^>]*src="([^"]*)"/i);if(S){let te=S[1].replace(/<[^>]*>/g,"").trim();te&&(s.author=te);}_&&(s.category=_[1].trim()),A&&(s.excerpt=A[1].trim()),I&&(s.publish_date=I[1].trim()),ee&&(s.read_time=ee[1].trim()),de&&!c.social_image&&(c.social_image=de[1]),a("Extracted blog content and metadata");}let d=await i.blogs.get(e,n);d.result||(l("Blog not found"),process.exit(1));let m=d.result,v=m.path,b={page_title:c.page_title||m.seo?.page_title||"Untitled",meta_description:c.meta_description||m.seo?.meta_description,social_title:c.social_title||m.seo?.social_title,social_description:c.social_description||m.seo?.social_description,social_image:c.social_image||m.seo?.social_image},u={author:s.author||m.blog_settings?.author||"Anonymous",excerpt:s.excerpt||m.blog_settings?.excerpt,category:s.category||m.blog_settings?.category,publish_date:s.publish_date||m.blog_settings?.publish_date,read_time:s.read_time||m.blog_settings?.read_time,author_image:s.author_image||m.blog_settings?.author_image};a("Updating blog...");let x=await i.blogs.publish(e,n,{path:v,blog_content:r,seo:b,blog_settings:u});t.format==="json"?y(x,"json"):x.success?(w("Blog updated successfully"),console.log(` Blog ID: ${x.result?.blog_id}`),x.result?.published_url&&console.log(` Published URL: ${x.result.published_url}`)):l("Failed to update blog");}catch(r){J(r);}}),o.command("create").description("Create a new blog with live preview").argument("<website_id>","Website ID").argument("<path>","URL path for the blog (e.g., /blog/my-first-post)").option("--title <title>","Blog title","New Blog Post").option("--author <author>","Author name","Anonymous").option("--file <path>","Output file path","./blog.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=V();try{let r=await i.websites.getDetails(e);r.result||(l("Website not found"),process.exit(1));let c=r.result,s=c,d=s?.theme||{},m=s?.custom_codes||{header:null,footer:null},v={font:d.font,title_font:d.title_font},b=t.title,u=t.author,x=new Date().toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"}),g=`<h2>Introduction</h2>
358
+ `,t=child_process.spawn(process.execPath,["-e",n],{detached:true,stdio:"ignore"});t.unref();let i=null;for(let s=0;s<50;s++)if(await new Promise(d=>setTimeout(d,100)),$__namespace.existsSync(ge))try{if(i=parseInt($__namespace.readFileSync(ge,"utf-8").trim(),10),!isNaN(i))break}catch{}i||(l("Failed to start preview server"),process.exit(1));let a=`http://127.0.0.1:${i}/`;await G(a)||r(`Could not open browser. Visit: ${a}`),w("Preview server started in background"),console.log(` URL: ${a}`),console.log(` PID: ${t.pid}`),console.log(""),r("To update the page: lindoai pages update <website_id> <page_id> --html-file <path>"),r("To stop the server: lindoai pages stop-preview");}async function pt(o){let{startLivePreviewServer:e}=await Promise.resolve().then(()=>(Ue(),Ne));r("Starting preview server...");let n=await e(o),t=`http://127.0.0.1:${n}/`;$__namespace.writeFileSync(Q,process.pid.toString(),"utf-8"),$__namespace.writeFileSync(ge,n.toString(),"utf-8"),await G(t)||r(`Could not open browser. Visit: ${t}`),w("Preview server started"),console.log(` URL: ${t}`),console.log(""),r("Press Ctrl+C to stop the server"),r("Edit the HTML file and save to see changes in the browser");}var Z=P__namespace.join(De__namespace.tmpdir(),"lindoai-blogs-preview.pid"),he=P__namespace.join(De__namespace.tmpdir(),"lindoai-blogs-preview.port");function qe(){let o=new commander.Command("blogs").description("Blog management operations");return o.command("list").description("List all blogs for a website").requiredOption("-w, --website <id>","Website ID").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.list(e.website,{page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else {let i=t.result;if(i?.list&&i.list.length>0){console.log(`
359
+ Blogs:`),console.log("------");for(let a of i.list)console.log(` ID: ${a.blog_id}`),console.log(` Name: ${a.name??"N/A"}`),console.log(` Path: ${a.path??"N/A"}`),console.log(` Status: ${a.status??"N/A"}`),console.log(` Published: ${a.publish_date?new Date(a.publish_date*1e3).toISOString():"No"}`),console.log("");console.log(`Total: ${i.total??i.list.length}`);}else r("No blogs found");}}catch(t){J(t);}}),o.command("get").description("Get details of a specific blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.get(e.website,e.id);if(e.format==="json")y(t,"json");else {let i=t.result;i?(console.log(`
360
+ Blog Details:`),console.log("-------------"),console.log(` ID: ${i.blog_id}`),console.log(` Name: ${i.name??"N/A"}`),console.log(` Path: ${i.path??"N/A"}`),console.log(` Status: ${i.status??"N/A"}`),console.log(` Published: ${i.publish_date?new Date(i.publish_date*1e3).toISOString():"No"}`),console.log(` Created: ${i.created_date??"N/A"}`)):l("Blog not found");}}catch(t){J(t);}}),o.command("publish").description("Publish a blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.publish(e.website,e.id);e.format==="json"?y(t,"json"):t.success?(w("Blog published successfully"),console.log(` Blog ID: ${t.result?.blog_id}`),console.log(` Published at: ${t.result?.publish_date?new Date(t.result.publish_date*1e3).toISOString():"N/A"}`),t.result?.published_url&&console.log(` Published URL: ${t.result.published_url}`)):l("Failed to publish blog");}catch(t){J(t);}}),o.command("unpublish").description("Unpublish a blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.unpublish(e.website,e.id);e.format==="json"?y(t,"json"):t.success?(w("Blog unpublished successfully"),console.log(` Blog ID: ${t.result?.blog_id}`)):l("Failed to unpublish blog");}catch(t){J(t);}}),o.command("delete").description("Delete a blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.delete(e.website,e.id);if(e.format==="json")y(t,"json");else if(t.success){if(w("Blog deleted successfully"),console.log(` Blog ID: ${t.result?.blog_id}`),t.result?.warnings&&t.result.warnings.length>0){console.log(" Warnings:");for(let i of t.result.warnings)console.log(` - ${i}`);}}else l("Failed to delete blog");}catch(t){J(t);}}),o.command("edit").description("Edit a blog with live preview").argument("<website_id>","Website ID").argument("<blog_id>","Blog ID").option("--file <path>","Output file path","./blog.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=V();try{r("Fetching blog content...");let a=await i.blogs.getHtml(e,n);a.result||(l("Blog not found"),process.exit(1));let c=a.result,s=await i.websites.getDetails(e);s.result||(l("Website not found"),process.exit(1));let d=s.result,m=d,v=m?.theme||{},b=m?.custom_codes||{header:null,footer:null},u={font:v.font,title_font:v.title_font},x=c.seo||{},g=c.blog_settings||{},f=c.blog_content||"<p>Start writing your blog content here...</p>",p=ht({seo:x,blogSettings:g,blogContent:f,websiteName:d.business_name||"Blog",blogPath:v.blog_path||"blog",websiteTheme:u,customCodes:{header:b.header||void 0,footer:b.footer||void 0}}),h=P__namespace.resolve(t.file);$__namespace.writeFileSync(h,p,"utf-8"),w(`HTML saved to ${h}`),await ut(),t.background?await ft(h):await gt(h),console.log(""),r(`To save changes: lindoai blogs update ${e} ${n} --html-file ${t.file}`);}catch(a){J(a);}}),o.command("update").description("Update a blog from HTML or Markdown file. Blog metadata (excerpt, social image, author, etc.) can be set via CLI flags, extracted from HTML meta tags/structure, or from Markdown frontmatter. CLI flags take highest priority.").argument("<website_id>","Website ID").argument("<blog_id>","Blog ID").option("--html-file <path>",'Path to local HTML file (extracts content from <article class="prose">)').option("--md-file <path>","Path to local Markdown file (supports frontmatter for metadata)").option("--excerpt <text>","Blog excerpt/summary shown in blog listings and previews").option("--social-image <url>","Social image URL for og:image and twitter:image meta tags (must be a full URL, e.g. https://cdn.ln-cdn.com/...)").option("--author <name>","Author name displayed on the blog post").option("--category <name>","Blog category").option("--date <date>",'Publish date (e.g. "January 15, 2025")').option("--read-time <time>",'Read time (e.g. "5 min read")').option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=V();try{!t.htmlFile&&!t.mdFile&&(l("Either --html-file or --md-file option is required"),r("Usage: lindoai blogs update <website_id> <blog_id> --html-file <path>"),r(" or: lindoai blogs update <website_id> <blog_id> --md-file <path>"),r(""),r("Metadata options (override values extracted from file):"),r(" --excerpt <text> Blog excerpt for listings"),r(" --social-image <url> Social sharing image URL (og:image)"),r(" --author <name> Author name"),r(" --category <name> Blog category"),r(" --date <date> Publish date"),r(' --read-time <time> Read time (e.g. "5 min read")'),r(""),r("For Markdown files, you can also set metadata via frontmatter:"),r(" ---"),r(" title: My Blog Post"),r(" description: A great post"),r(" image: https://cdn.ln-cdn.com/.../hero.jpg"),r(" excerpt: A short summary of the post"),r(" author: John Doe"),r(" category: Tech"),r(" date: January 15, 2025"),r(" ---"),process.exit(1));let a,c={},s={};if(t.mdFile){let g=P__namespace.resolve(t.mdFile);$__namespace.existsSync(g)||(l(`File not found: ${g}`),process.exit(1));let f=$__namespace.readFileSync(g,"utf-8");r(`Read ${f.length} bytes from ${g}`);let{content:p,frontmatter:h}=ko(f);a=_o(p),h.title&&(c.page_title=h.title),h.description&&(c.meta_description=h.description),h.image&&(c.social_image=h.image),h.author&&(s.author=h.author),h.excerpt&&(s.excerpt=h.excerpt),h.category&&(s.category=h.category),h.date&&(s.publish_date=h.date);}else {let g=P__namespace.resolve(t.htmlFile);$__namespace.existsSync(g)||(l(`File not found: ${g}`),process.exit(1));let f=$__namespace.readFileSync(g,"utf-8");r(`Read ${f.length} bytes from ${g}`);let p=f.match(/<article[^>]*class="[^"]*prose[^"]*"[^>]*>([\s\S]*?)<\/article>/i);a=p?p[1].trim():"",a||(l("Could not extract blog content from HTML"),r('Make sure the blog content is inside <article class="...prose...">...</article>'),process.exit(1));let h=f.match(/<title>([^<]*)<\/title>/i),C=f.match(/<meta\s+name="description"\s+content="([^"]*)"/i),k=f.match(/<meta\s+property="og:image"\s+content="([^"]*)"/i);h&&(c.page_title=h[1].trim()),C&&(c.meta_description=C[1]),k&&(c.social_image=k[1]);let S=f.match(/id="blog-author-display"[^>]*>([\s\S]*?)<\/span>/i),_=f.match(/class="[^"]*bg-blue-500\/10[^"]*"[^>]*>([^<]*)</i),A=f.match(/class="[^"]*border-l-4 border-blue-500[^"]*"[^>]*>([\s\S]*?)<\/div>/i),I=f.match(/<time[^>]*>([^<]*)<\/time>/i),ee=f.match(/<span>(\d+\s*min\s*read)<\/span>/i),de=f.match(/<div class="aspect-video[^"]*"[^>]*>\s*<img[^>]*src="([^"]*)"/i);if(S){let te=S[1].replace(/<[^>]*>/g,"").trim();te&&(s.author=te);}_&&(s.category=_[1].trim()),A&&(s.excerpt=A[1].trim()),I&&(s.publish_date=I[1].trim()),ee&&(s.read_time=ee[1].trim()),de&&!c.social_image&&(c.social_image=de[1]),r("Extracted blog content and metadata");}t.socialImage&&(c.social_image=t.socialImage),t.excerpt&&(s.excerpt=t.excerpt),t.author&&(s.author=t.author),t.category&&(s.category=t.category),t.date&&(s.publish_date=t.date),t.readTime&&(s.read_time=t.readTime);let d=await i.blogs.get(e,n);d.result||(l("Blog not found"),process.exit(1));let m=d.result,v=m.path,b={page_title:c.page_title||m.seo?.page_title||"Untitled",meta_description:c.meta_description||m.seo?.meta_description,social_title:c.social_title||m.seo?.social_title,social_description:c.social_description||m.seo?.social_description,social_image:c.social_image||m.seo?.social_image},u={author:s.author||m.blog_settings?.author||"Anonymous",excerpt:s.excerpt||m.blog_settings?.excerpt,category:s.category||m.blog_settings?.category,publish_date:s.publish_date||m.blog_settings?.publish_date,read_time:s.read_time||m.blog_settings?.read_time,author_image:s.author_image||m.blog_settings?.author_image};r("Updating blog...");let x=await i.blogs.publish(e,n,{path:v,blog_content:a,seo:b,blog_settings:u});t.format==="json"?y(x,"json"):x.success?(w("Blog updated successfully"),console.log(` Blog ID: ${x.result?.blog_id}`),x.result?.published_url&&console.log(` Published URL: ${x.result.published_url}`)):l("Failed to update blog");}catch(a){J(a);}}),o.command("create").description("Create a new blog with live preview").argument("<website_id>","Website ID").argument("<path>","URL path for the blog (e.g., /blog/my-first-post)").option("--title <title>","Blog title","New Blog Post").option("--author <author>","Author name","Anonymous").option("--file <path>","Output file path","./blog.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=V();try{let a=await i.websites.getDetails(e);a.result||(l("Website not found"),process.exit(1));let c=a.result,s=c,d=s?.theme||{},m=s?.custom_codes||{header:null,footer:null},v={font:d.font,title_font:d.title_font},b=t.title,u=t.author,x=new Date().toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"}),g=`<h2>Introduction</h2>
361
361
  <p>Welcome to your new blog post! This is a starter template to help you get started. Edit this content to create your own amazing blog post.</p>
362
362
 
363
363
  <h2>Getting Started</h2>
@@ -379,7 +379,7 @@ Blog Details:`),console.log("-------------"),console.log(` ID: ${i.blog_id}`),c
379
379
  console.log(greet('World'));</code></pre>
380
380
 
381
381
  <h2>Conclusion</h2>
382
- <p>Now it's your turn! Replace this content with your own ideas and publish your blog post to share it with the world.</p>`,f={page_title:b,meta_description:`Read ${b} by ${u}`,social_title:b,social_description:`Read ${b} by ${u}`},p={author:u,excerpt:"A new blog post. Edit this excerpt to provide a summary of your content.",publish_date:x,read_time:"3 min read"};a("Creating blog...");let h=await i.blogs.create(e,{path:n,blog_content:g,seo:f,blog_settings:p});h.success||(l("Failed to create blog"),process.exit(1));let C=h.result.blog_id,k=h.result.published_url;w(`Blog created: ${C}`),k&&console.log(` Published URL: ${k}`);let S=ht({seo:f,blogSettings:p,blogContent:g,websiteName:c.business_name||"Blog",blogPath:d.blog_path||"blog",websiteTheme:v,customCodes:{header:m.header||void 0,footer:m.footer||void 0}}),_=P__namespace.resolve(t.file);$__namespace.writeFileSync(_,S,"utf-8"),w(`HTML saved to ${_}`),await ut(),t.background?await ft(_):await gt(_),console.log(""),a(`To save changes: lindoai blogs update ${e} ${C} --html-file ${t.file}`);}catch(r){J(r);}}),o.command("stop-preview").description("Stop the background preview server").action(async()=>{try{if(!$__namespace.existsSync(Z)){a("No preview server is running");return}let e=parseInt($__namespace.readFileSync(Z,"utf-8").trim(),10);if(isNaN(e)){l("Invalid PID file"),Ke();return}try{process.kill(e,"SIGTERM"),w(`Preview server (PID ${e}) stopped`);}catch(n){n.code==="ESRCH"?a("Preview server process not found (may have already stopped)"):l(`Failed to stop preview server: ${n.message}`);}Ke();}catch(e){e instanceof Error?l(e.message):l("An unexpected error occurred"),process.exit(1);}}),o}function V(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function J(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Ke(){try{$__namespace.existsSync(Z)&&$__namespace.unlinkSync(Z);}catch{}try{$__namespace.existsSync(he)&&$__namespace.unlinkSync(he);}catch{}}async function ut(){if($__namespace.existsSync(Z)){try{let o=parseInt($__namespace.readFileSync(Z,"utf-8").trim(),10);if(!isNaN(o))try{process.kill(o,"SIGTERM"),a(`Terminated existing preview server (PID ${o})`),await new Promise(e=>setTimeout(e,500));}catch{}}catch{}Ke();}}async function ft(o){let e=P__namespace.resolve(o),n=`
382
+ <p>Now it's your turn! Replace this content with your own ideas and publish your blog post to share it with the world.</p>`,f={page_title:b,meta_description:`Read ${b} by ${u}`,social_title:b,social_description:`Read ${b} by ${u}`},p={author:u,excerpt:"A new blog post. Edit this excerpt to provide a summary of your content.",publish_date:x,read_time:"3 min read"};r("Creating blog...");let h=await i.blogs.create(e,{path:n,blog_content:g,seo:f,blog_settings:p});h.success||(l("Failed to create blog"),process.exit(1));let C=h.result.blog_id,k=h.result.published_url;w(`Blog created: ${C}`),k&&console.log(` Published URL: ${k}`);let S=ht({seo:f,blogSettings:p,blogContent:g,websiteName:c.business_name||"Blog",blogPath:d.blog_path||"blog",websiteTheme:v,customCodes:{header:m.header||void 0,footer:m.footer||void 0}}),_=P__namespace.resolve(t.file);$__namespace.writeFileSync(_,S,"utf-8"),w(`HTML saved to ${_}`),await ut(),t.background?await ft(_):await gt(_),console.log(""),r(`To save changes: lindoai blogs update ${e} ${C} --html-file ${t.file}`);}catch(a){J(a);}}),o.command("stop-preview").description("Stop the background preview server").action(async()=>{try{if(!$__namespace.existsSync(Z)){r("No preview server is running");return}let e=parseInt($__namespace.readFileSync(Z,"utf-8").trim(),10);if(isNaN(e)){l("Invalid PID file"),Be();return}try{process.kill(e,"SIGTERM"),w(`Preview server (PID ${e}) stopped`);}catch(n){n.code==="ESRCH"?r("Preview server process not found (may have already stopped)"):l(`Failed to stop preview server: ${n.message}`);}Be();}catch(e){e instanceof Error?l(e.message):l("An unexpected error occurred"),process.exit(1);}}),o}function V(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function J(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Be(){try{$__namespace.existsSync(Z)&&$__namespace.unlinkSync(Z);}catch{}try{$__namespace.existsSync(he)&&$__namespace.unlinkSync(he);}catch{}}async function ut(){if($__namespace.existsSync(Z)){try{let o=parseInt($__namespace.readFileSync(Z,"utf-8").trim(),10);if(!isNaN(o))try{process.kill(o,"SIGTERM"),r(`Terminated existing preview server (PID ${o})`),await new Promise(e=>setTimeout(e,500));}catch{}}catch{}Be();}}async function ft(o){let e=P__namespace.resolve(o),n=`
383
383
  const http = require('node:http');
384
384
  const fs = require('node:fs');
385
385
  const path = require('node:path');
@@ -499,7 +499,7 @@ console.log(greet('World'));</code></pre>
499
499
  });
500
500
  } catch {}
501
501
  });
502
- `,t=child_process.spawn(process.execPath,["-e",n],{detached:true,stdio:"ignore"});t.unref();let i=null;for(let s=0;s<50;s++)if(await new Promise(d=>setTimeout(d,100)),$__namespace.existsSync(he))try{if(i=parseInt($__namespace.readFileSync(he,"utf-8").trim(),10),!isNaN(i))break}catch{}i||(l("Failed to start preview server"),process.exit(1));let r=`http://127.0.0.1:${i}/`;await G(r)||a(`Could not open browser. Visit: ${r}`),w("Preview server started in background"),console.log(` URL: ${r}`),console.log(` PID: ${t.pid}`),console.log(""),a("To update the blog: lindoai blogs update <website_id> <blog_id> --html-file <path>"),a("To stop the server: lindoai blogs stop-preview");}async function gt(o){let{startLivePreviewServer:e}=await Promise.resolve().then(()=>(Ue(),Ne));a("Starting preview server...");let n=await e(o),t=`http://127.0.0.1:${n}/`;$__namespace.writeFileSync(Z,process.pid.toString(),"utf-8"),$__namespace.writeFileSync(he,n.toString(),"utf-8"),await G(t)||a(`Could not open browser. Visit: ${t}`),w("Preview server started"),console.log(` URL: ${t}`),console.log(""),a("Press Ctrl+C to stop the server"),a("Edit the HTML file and save to see changes in the browser");}function Co(o){return o?o.split(" ").map(e=>e.charAt(0).toUpperCase()).slice(0,2).join(""):"?"}function ht(o){let{seo:e,blogSettings:n,blogContent:t,websiteName:i,blogPath:r,websiteTheme:c,customCodes:s}=o,d=c?ue(c):"";return `<!DOCTYPE html>
502
+ `,t=child_process.spawn(process.execPath,["-e",n],{detached:true,stdio:"ignore"});t.unref();let i=null;for(let s=0;s<50;s++)if(await new Promise(d=>setTimeout(d,100)),$__namespace.existsSync(he))try{if(i=parseInt($__namespace.readFileSync(he,"utf-8").trim(),10),!isNaN(i))break}catch{}i||(l("Failed to start preview server"),process.exit(1));let a=`http://127.0.0.1:${i}/`;await G(a)||r(`Could not open browser. Visit: ${a}`),w("Preview server started in background"),console.log(` URL: ${a}`),console.log(` PID: ${t.pid}`),console.log(""),r("To update the blog: lindoai blogs update <website_id> <blog_id> --html-file <path>"),r("To stop the server: lindoai blogs stop-preview");}async function gt(o){let{startLivePreviewServer:e}=await Promise.resolve().then(()=>(Ue(),Ne));r("Starting preview server...");let n=await e(o),t=`http://127.0.0.1:${n}/`;$__namespace.writeFileSync(Z,process.pid.toString(),"utf-8"),$__namespace.writeFileSync(he,n.toString(),"utf-8"),await G(t)||r(`Could not open browser. Visit: ${t}`),w("Preview server started"),console.log(` URL: ${t}`),console.log(""),r("Press Ctrl+C to stop the server"),r("Edit the HTML file and save to see changes in the browser");}function Co(o){return o?o.split(" ").map(e=>e.charAt(0).toUpperCase()).slice(0,2).join(""):"?"}function ht(o){let{seo:e,blogSettings:n,blogContent:t,websiteName:i,blogPath:a,websiteTheme:c,customCodes:s}=o,d=c?ue(c):"";return `<!DOCTYPE html>
503
503
  <html class="dark" lang="en">
504
504
  <head>
505
505
  <meta charset="UTF-8">
@@ -565,7 +565,7 @@ console.log(greet('World'));</code></pre>
565
565
  <div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
566
566
  <div class="flex justify-between items-center py-4">
567
567
  <div class="flex items-center space-x-2">
568
- <a href="/${r}" class="flex items-center space-x-2 text-gray-600 dark:text-neutral-300 hover:text-gray-900 dark:hover:text-white transition-colors">
568
+ <a href="/${a}" class="flex items-center space-x-2 text-gray-600 dark:text-neutral-300 hover:text-gray-900 dark:hover:text-white transition-colors">
569
569
  <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
570
570
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
571
571
  </svg>
@@ -685,10 +685,10 @@ console.log(greet('World'));</code></pre>
685
685
  <!-- Custom Code (Footer) -->
686
686
  ${s?.footer||""}
687
687
  </body>
688
- </html>`}function ko(o){let e={},n=o;if(o.startsWith("---")){let t=o.indexOf("---",3);if(t!==-1){let i=o.slice(3,t).trim();n=o.slice(t+3).trim();for(let r of i.split(`
689
- `)){let c=r.indexOf(":");if(c!==-1){let s=r.slice(0,c).trim(),d=r.slice(c+1).trim();(d.startsWith('"')&&d.endsWith('"')||d.startsWith("'")&&d.endsWith("'"))&&(d=d.slice(1,-1)),e[s]=d;}}}}return {content:n,frontmatter:e}}function _o(o){let e=o;return e=e.replace(/^### (.+)$/gm,"<h3>$1</h3>"),e=e.replace(/^## (.+)$/gm,"<h2>$1</h2>"),e=e.replace(/^# (.+)$/gm,"<h1>$1</h1>"),e=e.replace(/\*\*\*(.+?)\*\*\*/g,"<strong><em>$1</em></strong>"),e=e.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),e=e.replace(/\*(.+?)\*/g,"<em>$1</em>"),e=e.replace(/```(\w*)\n([\s\S]*?)```/g,"<pre><code>$2</code></pre>"),e=e.replace(/`([^`]+)`/g,"<code>$1</code>"),e=e.replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2">$1</a>'),e=e.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,'<img src="$2" alt="$1">'),e=e.replace(/^- (.+)$/gm,"<li>$1</li>"),e=e.replace(/(<li>.*<\/li>\n?)+/g,"<ul>$&</ul>"),e=e.replace(/^\d+\. (.+)$/gm,"<li>$1</li>"),e=e.split(`
690
- `).map(i=>{let r=i.trim();return r?r.startsWith("<")?i:`<p>${r}</p>`:""}).join(`
691
- `),e=e.replace(/<p><\/p>/g,""),e}function bt(o){let e=o.toLowerCase().split(".").pop()||"";return {jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",ico:"image/x-icon",avif:"image/avif",mp4:"video/mp4",webm:"video/webm",mov:"video/quicktime",pdf:"application/pdf",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",otf:"font/otf"}[e]||"application/octet-stream"}function wt(o){let e=o.toLowerCase().split(".").pop()||"",n=["jpg","jpeg","png","gif","webp","svg","ico","avif","bmp","tiff"],t=["mp4","webm","mov","avi","mkv"],i=["woff","woff2","ttf","otf","eot"];return n.includes(e)?"images":t.includes(e)?"videos":i.includes(e)?"fonts":"documents"}function Ge(){let o=new commander.Command("media").description("Media upload operations");return o.command("upload").description("Upload a single media file to website CDN").argument("<website_id>","Website ID").argument("<file_path>","Path to the file to upload").option("-t, --type <type>","Media type (images, videos, documents, fonts)").option("-n, --name <name>","Override file name for CDN").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=yt();try{let r=P__namespace.resolve(n);$__namespace.existsSync(r)||(l(`File not found: ${r}`),process.exit(1));let c=t.name||P__namespace.basename(r),d=$__namespace.readFileSync(r).toString("base64"),m=t.type||wt(c),v=bt(c);a(`Uploading ${c} (${m}) to website ${e}...`);let b=await i.media.upload(e,{file_base64:d,file_name:c,media_type:m,content_type:v});w(`Uploaded: ${b.result.url}`),y(b.result,t.format);}catch(r){xt(r);}}),o.command("upload-batch").description("Upload multiple media files to website CDN (max 20)").argument("<website_id>","Website ID").argument("<file_paths...>","Paths to files to upload").option("-t, --type <type>","Media type override for all files").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=yt();try{n.length>20&&(l("Maximum 20 files per batch upload"),process.exit(1));let r=n.map(s=>{let d=P__namespace.resolve(s);$__namespace.existsSync(d)||(l(`File not found: ${d}`),process.exit(1));let m=P__namespace.basename(d),b=$__namespace.readFileSync(d).toString("base64"),u=t.type||wt(m),x=bt(m);return {file_base64:b,file_name:m,media_type:u,content_type:x}});a(`Uploading ${r.length} file(s) to website ${e}...`);let c=await i.media.uploadBatch(e,{files:r});w(`Uploaded ${c.result.successful} of ${c.result.total} files`),c.result.failed>0&&a(`${c.result.failed} file(s) failed`),y(c.result,t.format);}catch(r){xt(r);}}),o}function yt(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function xt(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Ct(){return vt__namespace.randomBytes(32).toString("hex")}function kt(o,e){return o===e}function Fo(o){try{let e=o.startsWith("http")?o:`http://localhost${o}`,t=new url.URL(e).searchParams;return {key:t.get("key")??void 0,state:t.get("state")??void 0,error:t.get("error")??void 0,message:t.get("message")??void 0}}catch{return {}}}function Po(){return `<!DOCTYPE html>
688
+ </html>`}function ko(o){let e={},n=o;if(o.startsWith("---")){let t=o.indexOf("---",3);if(t!==-1){let i=o.slice(3,t).trim();n=o.slice(t+3).trim();for(let a of i.split(`
689
+ `)){let c=a.indexOf(":");if(c!==-1){let s=a.slice(0,c).trim(),d=a.slice(c+1).trim();(d.startsWith('"')&&d.endsWith('"')||d.startsWith("'")&&d.endsWith("'"))&&(d=d.slice(1,-1)),e[s]=d;}}}}return {content:n,frontmatter:e}}function _o(o){let e=o;return e=e.replace(/^### (.+)$/gm,"<h3>$1</h3>"),e=e.replace(/^## (.+)$/gm,"<h2>$1</h2>"),e=e.replace(/^# (.+)$/gm,"<h1>$1</h1>"),e=e.replace(/\*\*\*(.+?)\*\*\*/g,"<strong><em>$1</em></strong>"),e=e.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),e=e.replace(/\*(.+?)\*/g,"<em>$1</em>"),e=e.replace(/```(\w*)\n([\s\S]*?)```/g,"<pre><code>$2</code></pre>"),e=e.replace(/`([^`]+)`/g,"<code>$1</code>"),e=e.replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2">$1</a>'),e=e.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,'<img src="$2" alt="$1">'),e=e.replace(/^- (.+)$/gm,"<li>$1</li>"),e=e.replace(/(<li>.*<\/li>\n?)+/g,"<ul>$&</ul>"),e=e.replace(/^\d+\. (.+)$/gm,"<li>$1</li>"),e=e.split(`
690
+ `).map(i=>{let a=i.trim();return a?a.startsWith("<")?i:`<p>${a}</p>`:""}).join(`
691
+ `),e=e.replace(/<p><\/p>/g,""),e}function bt(o){let e=o.toLowerCase().split(".").pop()||"";return {jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",ico:"image/x-icon",avif:"image/avif",mp4:"video/mp4",webm:"video/webm",mov:"video/quicktime",pdf:"application/pdf",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",otf:"font/otf"}[e]||"application/octet-stream"}function wt(o){let e=o.toLowerCase().split(".").pop()||"",n=["jpg","jpeg","png","gif","webp","svg","ico","avif","bmp","tiff"],t=["mp4","webm","mov","avi","mkv"],i=["woff","woff2","ttf","otf","eot"];return n.includes(e)?"images":t.includes(e)?"videos":i.includes(e)?"fonts":"documents"}function Ge(){let o=new commander.Command("media").description("Media upload operations");return o.command("upload").description("Upload a single media file to website CDN").argument("<website_id>","Website ID").argument("<file_path>","Path to the file to upload").option("-t, --type <type>","Media type (images, videos, documents, fonts)").option("-n, --name <name>","Override file name for CDN").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=yt();try{let a=P__namespace.resolve(n);$__namespace.existsSync(a)||(l(`File not found: ${a}`),process.exit(1));let c=t.name||P__namespace.basename(a),d=$__namespace.readFileSync(a).toString("base64"),m=t.type||wt(c),v=bt(c);r(`Uploading ${c} (${m}) to website ${e}...`);let b=await i.media.upload(e,{file_base64:d,file_name:c,media_type:m,content_type:v});w(`Uploaded: ${b.result.url}`),y(b.result,t.format);}catch(a){xt(a);}}),o.command("upload-batch").description("Upload multiple media files to website CDN (max 20)").argument("<website_id>","Website ID").argument("<file_paths...>","Paths to files to upload").option("-t, --type <type>","Media type override for all files").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=yt();try{n.length>20&&(l("Maximum 20 files per batch upload"),process.exit(1));let a=n.map(s=>{let d=P__namespace.resolve(s);$__namespace.existsSync(d)||(l(`File not found: ${d}`),process.exit(1));let m=P__namespace.basename(d),b=$__namespace.readFileSync(d).toString("base64"),u=t.type||wt(m),x=bt(m);return {file_base64:b,file_name:m,media_type:u,content_type:x}});r(`Uploading ${a.length} file(s) to website ${e}...`);let c=await i.media.uploadBatch(e,{files:a});w(`Uploaded ${c.result.successful} of ${c.result.total} files`),c.result.failed>0&&r(`${c.result.failed} file(s) failed`),y(c.result,t.format);}catch(a){xt(a);}}),o}function yt(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new lindoai.LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function xt(o){o instanceof lindoai.AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Ct(){return vt__namespace.randomBytes(32).toString("hex")}function kt(o,e){return o===e}function Fo(o){try{let e=o.startsWith("http")?o:`http://localhost${o}`,t=new url.URL(e).searchParams;return {key:t.get("key")??void 0,state:t.get("state")??void 0,error:t.get("error")??void 0,message:t.get("message")??void 0}}catch{return {}}}function Po(){return `<!DOCTYPE html>
692
692
  <html lang="en">
693
693
  <head>
694
694
  <meta charset="UTF-8">
@@ -827,13 +827,13 @@ ${s?.footer||""}
827
827
  <p>This endpoint is not available.</p>
828
828
  </div>
829
829
  </body>
830
- </html>`}function St(){let o=null,e=null;function n(t,i){let r=t.url||"/",c=t.method||"GET",s=r==="/callback"||r.startsWith("/callback?");if(c!=="GET"||!s){i.writeHead(404,{"Content-Type":"text/html; charset=utf-8"}),i.end(Io());return}let d=Fo(r);if(!e){i.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye("No pending authorization request"));return}let{expectedState:m,resolve:v,timeoutId:b}=e;if(clearTimeout(b),e=null,d.error){let u=d.message||d.error;i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye(u)),v({success:false,error:u});return}if(!d.state||!kt(d.state,m)){let u="State token mismatch - possible CSRF attack";i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye(u)),v({success:false,error:u});return}if(!d.key){let u="No API key received";i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye(u)),v({success:false,error:u});return}i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(Po()),v({success:true,apiKey:d.key});}return {async start(){return new Promise((t,i)=>{o=lt__namespace.createServer(n),o.on("error",r=>{i(new Error(`Failed to start callback server: ${r.message}`));}),o.listen(0,"127.0.0.1",()=>{let r=o.address();if(!r||typeof r=="string"){i(new Error("Failed to get server address"));return}let c=r.port,s=`http://127.0.0.1:${c}/callback`;t({port:c,url:s});});})},waitForCallback(t,i){return new Promise(r=>{let c=setTimeout(()=>{e&&(e=null,r({success:false,error:"Login timed out waiting for authorization"}));},i);e={expectedState:t,resolve:r,timeoutId:c};})},async stop(){return new Promise(t=>{e&&(clearTimeout(e.timeoutId),e=null),o?o.close(()=>{o=null,t();}):t();})}}}var Eo="https://app.lindo.ai",Lo=120;function Ro(o,e){let n=`http://127.0.0.1:${e}/callback`,t=new URLSearchParams({state:o,callback_url:n});return `${Eo}/cli/authorize?${t.toString()}`}function Ye(){return new commander.Command("login").description("Authenticate via browser to configure your API key").option("-t, --timeout <seconds>","Timeout in seconds for the login flow",String(Lo)).option("--no-browser","Display the authorization URL without opening the browser").action(async e=>{let n=parseInt(e.timeout,10),t=n*1e3,i=e.browser,r=St(),c=false;try{a("Starting authentication flow...");let{port:s}=await r.start();c=!0;let d=Ct(),m=Ro(d,s);i?(a("Opening browser for authorization..."),await G(m)||(a("Could not open browser automatically."),console.log(`
830
+ </html>`}function St(){let o=null,e=null;function n(t,i){let a=t.url||"/",c=t.method||"GET",s=a==="/callback"||a.startsWith("/callback?");if(c!=="GET"||!s){i.writeHead(404,{"Content-Type":"text/html; charset=utf-8"}),i.end(Io());return}let d=Fo(a);if(!e){i.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye("No pending authorization request"));return}let{expectedState:m,resolve:v,timeoutId:b}=e;if(clearTimeout(b),e=null,d.error){let u=d.message||d.error;i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye(u)),v({success:false,error:u});return}if(!d.state||!kt(d.state,m)){let u="State token mismatch - possible CSRF attack";i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye(u)),v({success:false,error:u});return}if(!d.key){let u="No API key received";i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye(u)),v({success:false,error:u});return}i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(Po()),v({success:true,apiKey:d.key});}return {async start(){return new Promise((t,i)=>{o=lt__namespace.createServer(n),o.on("error",a=>{i(new Error(`Failed to start callback server: ${a.message}`));}),o.listen(0,"127.0.0.1",()=>{let a=o.address();if(!a||typeof a=="string"){i(new Error("Failed to get server address"));return}let c=a.port,s=`http://127.0.0.1:${c}/callback`;t({port:c,url:s});});})},waitForCallback(t,i){return new Promise(a=>{let c=setTimeout(()=>{e&&(e=null,a({success:false,error:"Login timed out waiting for authorization"}));},i);e={expectedState:t,resolve:a,timeoutId:c};})},async stop(){return new Promise(t=>{e&&(clearTimeout(e.timeoutId),e=null),o?o.close(()=>{o=null,t();}):t();})}}}var Eo="https://app.lindo.ai",Lo=120;function Ro(o,e){let n=`http://127.0.0.1:${e}/callback`,t=new URLSearchParams({state:o,callback_url:n});return `${Eo}/cli/authorize?${t.toString()}`}function Ye(){return new commander.Command("login").description("Authenticate via browser to configure your API key").option("-t, --timeout <seconds>","Timeout in seconds for the login flow",String(Lo)).option("--no-browser","Display the authorization URL without opening the browser").action(async e=>{let n=parseInt(e.timeout,10),t=n*1e3,i=e.browser,a=St(),c=false;try{r("Starting authentication flow...");let{port:s}=await a.start();c=!0;let d=Ct(),m=Ro(d,s);i?(r("Opening browser for authorization..."),await G(m)||(r("Could not open browser automatically."),console.log(`
831
831
  Please open this URL in your browser:`),console.log(`
832
832
  ${m}
833
833
  `))):(console.log(`
834
834
  Please open this URL in your browser:`),console.log(`
835
835
  ${m}
836
- `)),a(`Waiting for authorization (timeout: ${n}s)...`);let v=await r.waitForCallback(d,t);v.success&&v.apiKey?(tt(v.apiKey),w("Successfully authenticated!"),a(`API key saved to: ${W()}`)):(l(v.error||"Authentication failed"),process.exit(1));}catch(s){l(s instanceof Error?s.message:"An unexpected error occurred"),process.exit(1);}finally{c&&await r.stop();}})}var ze=P__namespace.join(De__namespace.homedir(),".config","opencode","skills","lindoai"),Tt=P__namespace.join(ze,"SKILL.md"),No=`---
836
+ `)),r(`Waiting for authorization (timeout: ${n}s)...`);let v=await a.waitForCallback(d,t);v.success&&v.apiKey?(tt(v.apiKey),w("Successfully authenticated!"),r(`API key saved to: ${W()}`)):(l(v.error||"Authentication failed"),process.exit(1));}catch(s){l(s instanceof Error?s.message:"An unexpected error occurred"),process.exit(1);}finally{c&&await a.stop();}})}var ze=P__namespace.join(De__namespace.homedir(),".config","opencode","skills","lindoai"),Tt=P__namespace.join(ze,"SKILL.md"),No=`---
837
837
  name: lindoai
838
838
  description: Lindo AI CLI - Command-line interface for the Lindo API
839
839
  ---
@@ -1194,5 +1194,5 @@ Follow these core rules when building pages:
1194
1194
  6. **Container patterns**:
1195
1195
  - Use \`container mx-auto px-4\` for consistent content width
1196
1196
  - Apply consistent vertical padding: \`py-12 md:py-16 lg:py-20\`
1197
- `;function Uo(){try{let o=process.platform==="win32"?"where opencode":"which opencode";return child_process.execSync(o,{stdio:"ignore"}),!0}catch{return false}}function Mo(){try{return a("Installing OpenCode..."),child_process.execSync("npm install -g opencode-ai@latest",{stdio:"inherit"}),!0}catch{return false}}function Ho(){$__namespace.existsSync(ze)||$__namespace.mkdirSync(ze,{recursive:true}),$__namespace.writeFileSync(Tt,No,"utf-8");}function Je(){return new commander.Command("agent").description("Launch an AI agent that understands all CLI commands").option("--install","Install OpenCode if not already installed").option("--model <model>","Specify the model to use with OpenCode").action(async e=>{Uo()||(e.install?(Mo()||(l("Failed to install OpenCode"),a("Please install manually: npm install -g opencode-ai@latest"),process.exit(1)),w("OpenCode installed successfully")):(l("OpenCode is not installed"),a(""),a("To install OpenCode, run one of the following:"),a(" lindoai agent --install"),a(" npm install -g opencode-ai@latest"),process.exit(1)));try{Ho(),a(`Skill file installed to: ${Tt}`);}catch(i){l(`Failed to install skill file: ${i instanceof Error?i.message:"Unknown error"}`),process.exit(1);}let n=[];e.model&&n.push("--model",e.model),a("Launching OpenCode...");let t=child_process.spawn("opencode",n,{stdio:"inherit",shell:true});t.on("error",i=>{l(`Failed to launch OpenCode: ${i.message}`),process.exit(1);}),t.on("close",i=>{process.exit(i??0);});})}var qo=module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))),Go=qo("../package.json"),Yo=Go.version;function zo(){let o=new commander.Command;return o.name("lindo").description("Command-line interface for the Lindo API").version(Yo,"-v, --version","Output the current version").helpOption("-h, --help","Display help for command"),o.addCommand(_e()),o.addCommand(Se()),o.addCommand($e()),o.addCommand(Oe()),o.addCommand(Te()),o.addCommand(Fe()),o.addCommand(Pe()),o.addCommand(We()),o.addCommand(qe()),o.addCommand(Ge()),o.addCommand(Ye()),o.addCommand(Je()),o.exitOverride(e=>{throw e.code==="commander.help"&&process.exit(0),e.code==="commander.version"&&process.exit(0),e.code==="commander.missingArgument"&&(l(e.message),process.exit(1)),e.code==="commander.unknownCommand"&&(l(e.message),a('Run "lindo --help" for available commands'),process.exit(1)),e}),o}function Vo(o){l("Authentication failed"),a(""),a("Your API key may be invalid or expired."),a(""),a("To configure your API key:"),a(" 1. Run: lindo config set apiKey <your-api-key>"),a(" 2. Or set the LINDO_API_KEY environment variable"),a(""),a("To get an API key:"),a(" Visit https://app.lindo.ai/settings/api-keys");}async function Jo(){let o=zo();try{await o.parseAsync(process.argv);}catch(e){throw e instanceof lindoai.AuthenticationError&&(Vo(),process.exit(1)),e}}Jo().catch(o=>{o instanceof Error?l(`Unexpected error: ${o.message}`):l("An unexpected error occurred"),process.exit(1);});
1197
+ `;function Uo(){try{let o=process.platform==="win32"?"where opencode":"which opencode";return child_process.execSync(o,{stdio:"ignore"}),!0}catch{return false}}function Mo(){try{return r("Installing OpenCode..."),child_process.execSync("npm install -g opencode-ai@latest",{stdio:"inherit"}),!0}catch{return false}}function Ho(){$__namespace.existsSync(ze)||$__namespace.mkdirSync(ze,{recursive:true}),$__namespace.writeFileSync(Tt,No,"utf-8");}function Je(){return new commander.Command("agent").description("Launch an AI agent that understands all CLI commands").option("--install","Install OpenCode if not already installed").option("--model <model>","Specify the model to use with OpenCode").action(async e=>{Uo()||(e.install?(Mo()||(l("Failed to install OpenCode"),r("Please install manually: npm install -g opencode-ai@latest"),process.exit(1)),w("OpenCode installed successfully")):(l("OpenCode is not installed"),r(""),r("To install OpenCode, run one of the following:"),r(" lindoai agent --install"),r(" npm install -g opencode-ai@latest"),process.exit(1)));try{Ho(),r(`Skill file installed to: ${Tt}`);}catch(i){l(`Failed to install skill file: ${i instanceof Error?i.message:"Unknown error"}`),process.exit(1);}let n=[];e.model&&n.push("--model",e.model),r("Launching OpenCode...");let t=child_process.spawn("opencode",n,{stdio:"inherit",shell:true});t.on("error",i=>{l(`Failed to launch OpenCode: ${i.message}`),process.exit(1);}),t.on("close",i=>{process.exit(i??0);});})}var qo=module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))),Go=qo("../package.json"),Yo=Go.version;function zo(){let o=new commander.Command;return o.name("lindo").description("Command-line interface for the Lindo API").version(Yo,"-v, --version","Output the current version").helpOption("-h, --help","Display help for command"),o.addCommand(_e()),o.addCommand(Se()),o.addCommand($e()),o.addCommand(Oe()),o.addCommand(Te()),o.addCommand(Fe()),o.addCommand(Pe()),o.addCommand(We()),o.addCommand(qe()),o.addCommand(Ge()),o.addCommand(Ye()),o.addCommand(Je()),o.exitOverride(e=>{throw e.code==="commander.help"&&process.exit(0),e.code==="commander.version"&&process.exit(0),e.code==="commander.missingArgument"&&(l(e.message),process.exit(1)),e.code==="commander.unknownCommand"&&(l(e.message),r('Run "lindo --help" for available commands'),process.exit(1)),e}),o}function Vo(o){l("Authentication failed"),r(""),r("Your API key may be invalid or expired."),r(""),r("To configure your API key:"),r(" 1. Run: lindo config set apiKey <your-api-key>"),r(" 2. Or set the LINDO_API_KEY environment variable"),r(""),r("To get an API key:"),r(" Visit https://app.lindo.ai/settings/api-keys");}async function Jo(){let o=zo();try{await o.parseAsync(process.argv);}catch(e){throw e instanceof lindoai.AuthenticationError&&(Vo(),process.exit(1)),e}}Jo().catch(o=>{o instanceof Error?l(`Unexpected error: ${o.message}`):l("An unexpected error occurred"),process.exit(1);});
1198
1198
  exports.createProgram=zo;
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import*as lt from'http';import*as $ from'fs';import*as P from'path';import*as De from'os';import {platform}from'os';import {Command}from'commander';import {AuthenticationError,LindoClient}from'lindoai';import {spawn,exec,execSync}from'child_process';import*as Ee from'cheerio';import {URL}from'url';import*as vt from'crypto';import {createRequire}from'module';var Ft=Object.defineProperty;var Pt=(o,e)=>()=>(o&&(e=o(o=0)),e);var It=(o,e)=>{for(var n in e)Ft(o,n,{get:e[n],enumerable:true});};var Ne={};It(Ne,{LIVE_RELOAD_SCRIPT:()=>je,injectLiveReload:()=>ct,startLivePreviewServer:()=>uo});function ct(o){let e=/<\/body>/i,n=o.match(e);return n&&n.index!==void 0?o.slice(0,n.index)+je+o.slice(n.index):o+je}function uo(o){return new Promise((e,n)=>{let t=P.resolve(o),i=new Set,r=null,c=100;function s(){for(let u of i)try{u.write(`data: reload
2
+ import*as lt from'http';import*as $ from'fs';import*as P from'path';import*as De from'os';import {platform}from'os';import {Command}from'commander';import {AuthenticationError,LindoClient}from'lindoai';import {spawn,exec,execSync}from'child_process';import*as Ee from'cheerio';import {URL}from'url';import*as vt from'crypto';import {createRequire}from'module';var Ft=Object.defineProperty;var Pt=(o,e)=>()=>(o&&(e=o(o=0)),e);var It=(o,e)=>{for(var n in e)Ft(o,n,{get:e[n],enumerable:true});};var Ne={};It(Ne,{LIVE_RELOAD_SCRIPT:()=>je,injectLiveReload:()=>ct,startLivePreviewServer:()=>uo});function ct(o){let e=/<\/body>/i,n=o.match(e);return n&&n.index!==void 0?o.slice(0,n.index)+je+o.slice(n.index):o+je}function uo(o){return new Promise((e,n)=>{let t=P.resolve(o),i=new Set,a=null,c=100;function s(){for(let u of i)try{u.write(`data: reload
3
3
 
4
- `);}catch{i.delete(u);}}function d(){r&&clearTimeout(r),r=setTimeout(()=>{s(),r=null;},c);}function m(u,x){let g=u.url||"/";if((u.method||"GET")!=="GET"){x.writeHead(405,{"Content-Type":"text/plain"}),x.end("Method Not Allowed");return}if(g==="/__live-reload"){x.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*"}),x.write(`data: connected
4
+ `);}catch{i.delete(u);}}function d(){a&&clearTimeout(a),a=setTimeout(()=>{s(),a=null;},c);}function m(u,x){let g=u.url||"/";if((u.method||"GET")!=="GET"){x.writeHead(405,{"Content-Type":"text/plain"}),x.end("Method Not Allowed");return}if(g==="/__live-reload"){x.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*"}),x.write(`data: connected
5
5
 
6
6
  `),i.add(x),u.on("close",()=>{i.delete(x);});return}if(g==="/"||g==="/index.html"){try{let p=$.readFileSync(t,"utf-8"),h=ct(p);x.writeHead(200,{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-cache"}),x.end(h);}catch(p){let h=p instanceof Error?p.message:"Unknown error";x.writeHead(500,{"Content-Type":"text/html; charset=utf-8"}),x.end(`<!DOCTYPE html>
7
7
  <html>
@@ -17,7 +17,7 @@ import*as lt from'http';import*as $ from'fs';import*as P from'path';import*as De
17
17
  <h1>404 Not Found</h1>
18
18
  <p>The requested resource was not found.</p>
19
19
  </body>
20
- </html>`);}let v=lt.createServer(m),b=null;v.on("error",u=>{n(new Error(`Failed to start preview server: ${u.message}`));}),v.listen(0,"127.0.0.1",()=>{let u=v.address();if(!u||typeof u=="string"){n(new Error("Failed to get server address"));return}let x=u.port;try{b=$.watch(t,f=>{f==="change"&&d();}),b.on("error",f=>{console.error(`[Live Preview] File watcher error: ${f.message}`);});}catch(f){let p=f instanceof Error?f.message:"Unknown error";console.error(`[Live Preview] Failed to watch file: ${p}`);}let g=()=>{b&&(b.close(),b=null),r&&(clearTimeout(r),r=null);for(let h of i)try{h.end();}catch{}i.clear();let f=P.join(De.tmpdir(),"lindoai-pages-preview.pid"),p=P.join(De.tmpdir(),"lindoai-pages-preview.port");try{$.existsSync(f)&&$.unlinkSync(f);}catch{}try{$.existsSync(p)&&$.unlinkSync(p);}catch{}v.close(()=>{process.exit(0);}),setTimeout(()=>{process.exit(0);},1e3);};process.on("SIGTERM",g),process.on("SIGINT",g),e(x);});})}var je,Ue=Pt(()=>{je=`<script>
20
+ </html>`);}let v=lt.createServer(m),b=null;v.on("error",u=>{n(new Error(`Failed to start preview server: ${u.message}`));}),v.listen(0,"127.0.0.1",()=>{let u=v.address();if(!u||typeof u=="string"){n(new Error("Failed to get server address"));return}let x=u.port;try{b=$.watch(t,f=>{f==="change"&&d();}),b.on("error",f=>{console.error(`[Live Preview] File watcher error: ${f.message}`);});}catch(f){let p=f instanceof Error?f.message:"Unknown error";console.error(`[Live Preview] Failed to watch file: ${p}`);}let g=()=>{b&&(b.close(),b=null),a&&(clearTimeout(a),a=null);for(let h of i)try{h.end();}catch{}i.clear();let f=P.join(De.tmpdir(),"lindoai-pages-preview.pid"),p=P.join(De.tmpdir(),"lindoai-pages-preview.port");try{$.existsSync(f)&&$.unlinkSync(f);}catch{}try{$.existsSync(p)&&$.unlinkSync(p);}catch{}v.close(()=>{process.exit(0);}),setTimeout(()=>{process.exit(0);},1e3);};process.on("SIGTERM",g),process.on("SIGINT",g),e(x);});})}var je,Ue=Pt(()=>{je=`<script>
21
21
  (function() {
22
22
  var eventSource = new EventSource('/__live-reload');
23
23
  eventSource.onmessage = function(event) {
@@ -29,13 +29,13 @@ import*as lt from'http';import*as $ from'fs';import*as P from'path';import*as De
29
29
  console.log('[Live Reload] Connection lost, attempting to reconnect...');
30
30
  };
31
31
  })();
32
- </script>`;});var At="LINDO_API_KEY",Et="LINDO_BASE_URL",Lt=".lindo",Rt="config.json",Dt="https://api.lindo.ai";function Ze(){return P.join(De.homedir(),Lt)}function W(){return P.join(Ze(),Rt)}function ve(){let o=W();try{if($.existsSync(o)){let e=$.readFileSync(o,"utf-8");return JSON.parse(e)}}catch{}return {}}function et(o){let e=Ze(),n=W();$.existsSync(e)||$.mkdirSync(e,{recursive:true}),$.writeFileSync(n,JSON.stringify(o,null,2),"utf-8");}function O(){let o=ve(),e=process.env[At]||o.apiKey,n=process.env[Et]||o.baseUrl||Dt;return {apiKey:e,baseUrl:n}}function tt(o){let e=ve();e.apiKey=o,et(e);}function ot(o,e){let n=ve();switch(o){case "apiKey":n.apiKey=e;break;case "baseUrl":n.baseUrl=e;break;default:throw new Error(`Unknown configuration key: ${o}`)}et(n);}function nt(o){let e=O();switch(o){case "apiKey":return e.apiKey;case "baseUrl":return e.baseUrl;default:return}}function F(){return !!O().apiKey}var K={reset:"\x1B[0m",red:"\x1B[31m",green:"\x1B[32m",blue:"\x1B[34m",cyan:"\x1B[36m",gray:"\x1B[90m",bold:"\x1B[1m"};function jt(){return !process.env.NO_COLOR&&process.stdout.isTTY!==false}function q(o,e){return jt()?`${e}${o}${K.reset}`:o}function w(o){console.log(q(`\u2713 ${o}`,K.green));}function l(o){console.error(q(`\u2717 ${o}`,K.red));}function a(o){console.log(q(`\u2139 ${o}`,K.blue));}function Nt(o){return JSON.stringify(o,null,2)}function Ut(o){if(o==null)return "";if(Array.isArray(o)){if(o.length===0)return "No data";let e=new Set;for(let t of o)typeof t=="object"&&t!==null&&Object.keys(t).forEach(i=>e.add(i));if(e.size===0)return o.map(t=>String(t)).join(`
33
- `);let n=Array.from(e);return Mt(n,o)}if(typeof o=="object"){let n=Object.entries(o);if(n.length===0)return "No data";let t=Math.max(...n.map(([i])=>i.length));return n.map(([i,r])=>{let c=i.padEnd(t),s=Ce(r);return `${q(c,K.cyan)} ${s}`}).join(`
34
- `)}return String(o)}function Mt(o,e){let n={};for(let c of o)n[c]=c.length;for(let c of e)if(typeof c=="object"&&c!==null){let s=c;for(let d of o){let m=Ce(s[d]);n[d]=Math.max(n[d],m.length);}}let t=o.map(c=>q(c.padEnd(n[c]),K.bold)).join(" "),i=o.map(c=>"-".repeat(n[c])).join(" "),r=e.map(c=>{if(typeof c=="object"&&c!==null){let s=c;return o.map(d=>Ce(s[d]).padEnd(n[d])).join(" ")}return String(c)});return [t,i,...r].join(`
35
- `)}function Ce(o){return o==null?q("-",K.gray):typeof o=="boolean"?o?q("true",K.green):q("false",K.red):typeof o=="number"?String(o):typeof o=="object"?Array.isArray(o)?`[${o.length} items]`:JSON.stringify(o):String(o)}function y(o,e){console.log(e==="json"?Nt(o):Ut(o));}var it=["apiKey","baseUrl"];function _e(){let o=new Command("config").description("Manage CLI configuration");return o.command("set <key> <value>").description("Set a configuration value").action((e,n)=>{it.includes(e)||(l(`Invalid configuration key: ${e}`),a(`Valid keys: ${it.join(", ")}`),process.exit(1));try{ot(e,n),w(`Configuration saved: ${e}`),a(`Config file: ${W()}`);}catch(t){l(`Failed to save configuration: ${t instanceof Error?t.message:String(t)}`),process.exit(1);}}),o.command("get <key>").description("Get a configuration value").option("-f, --format <format>","Output format (json, table)","table").action((e,n)=>{let t=nt(e);if(t===void 0){n.format==="json"?y({key:e,value:null},n.format):a(`Configuration key '${e}' is not set`);return}if(n.format==="json")y({key:e,value:t},n.format);else {let i=e==="apiKey"?ke(t):t;console.log(`${e}: ${i}`);}}),o.command("list").description("List all configuration values").option("-f, --format <format>","Output format (json, table)","table").action(e=>{let n=O(),t={apiKey:n.apiKey?ke(n.apiKey):"(not set)",baseUrl:n.baseUrl,configFile:W()};e.format==="json"?y({apiKey:n.apiKey?ke(n.apiKey):null,baseUrl:n.baseUrl,configFile:W()},e.format):y(t,e.format);}),o.command("path").description("Show the config file path").action(()=>{console.log(W());}),o}function ke(o){return o.length<=8?"*".repeat(o.length):`${o.slice(0,4)}${"*".repeat(o.length-8)}${o.slice(-4)}`}function Se(){let o=new Command("agents").description("Run AI agents");return o.command("run <agent-id>").description("Run an AI agent").option("-i, --input <json>","Input data as JSON string","{}").option("-s, --stream","Stream the response",false).option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let t=O(),i=new LindoClient({apiKey:t.apiKey,baseUrl:t.baseUrl}),r;try{r=JSON.parse(n.input);}catch{l("Invalid JSON input"),a(`Example: --input '{"prompt": "Hello!"}'`),process.exit(1);}try{a(`Running agent: ${e}`);let c=await i.agents.run({agent_id:e,input:r,stream:n.stream});c.success?(w("Agent run completed"),y(c,n.format)):(l(`Agent run failed: ${c.error||"Unknown error"}`),y(c,n.format),process.exit(1));}catch(c){qt(c);}}),o}function qt(o){o instanceof AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function $e(){let o=new Command("workflows").description("Manage workflows");return o.command("list").description("List workflow logs").option("-n, --name <name>","Filter by workflow name").option("-s, --status <status>","Filter by status").option("-w, --website <id>","Filter by website ID").option("-c, --client <id>","Filter by client ID").option("-l, --limit <number>","Maximum number of results","50").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=ne();try{let t=await n.workflows.list({workflow_name:e.name,status:e.status,website_id:e.website,client_id:e.client,limit:parseInt(e.limit)});t.success?y(t.data,e.format):(l("Failed to list workflows"),process.exit(1));}catch(t){ie(t);}}),o.command("start <workflow-name>").description("Start a workflow").option("-p, --params <json>","Workflow parameters as JSON string","{}").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne(),i;try{i=JSON.parse(n.params);}catch{l("Invalid JSON params"),a(`Example: --params '{"page_id": "page-123"}'`),process.exit(1);}try{a(`Starting workflow: ${e}`);let r=await t.workflows.start({workflow_name:e,params:i});r.success?(w(`Workflow started: ${r.instance_id}`),y(r,n.format)):(l("Failed to start workflow"),y(r,n.format),process.exit(1));}catch(r){ie(r);}}),o.command("status <instance-id>").description("Get workflow status").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{let i=await t.workflows.getStatus(e);y(i,n.format);}catch(i){ie(i);}}),o.command("pause <instance-id>").description("Pause a running workflow").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{a(`Pausing workflow: ${e}`);let i=await t.workflows.pause(e);i.success?w(i.message):(l(i.message),process.exit(1)),y(i,n.format);}catch(i){ie(i);}}),o.command("resume <instance-id>").description("Resume a paused workflow").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{a(`Resuming workflow: ${e}`);let i=await t.workflows.resume(e);i.success?w(i.message):(l(i.message),process.exit(1)),y(i,n.format);}catch(i){ie(i);}}),o.command("terminate <instance-id>").description("Terminate a workflow").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{a(`Terminating workflow: ${e}`);let i=await t.workflows.terminate(e);i.success?w(i.message):(l(i.message),process.exit(1)),y(i,n.format);}catch(i){ie(i);}}),o}function ne(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function ie(o){o instanceof AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Oe(){let o=new Command("workspace").description("Workspace operations");return o.command("get").description("Get workspace details").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.get();y(t,e.format);}catch(t){U(t);}}),o.command("credits").description("Get workspace credit balance").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.getCredits();y(t,e.format);}catch(t){U(t);}}),o.command("client-credits").description("Get credit balance for a specific client").requiredOption("-c, --client <id>","Client ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.getClientCredits(e.client);y(t,e.format);}catch(t){U(t);}}),o.command("update").description("Update workspace settings").option("-n, --name <name>","Workspace name").option("-l, --language <lang>","Workspace language").option("-w, --webhook <url>","Webhook URL").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.update({workspace_name:e.name,workspace_language:e.language,webhook_url:e.webhook});t.success&&w("Workspace updated"),y(t,e.format);}catch(t){U(t);}}),o.command("team-add").description("Add a team member to the workspace").requiredOption("-e, --email <email>","Team member email").option("-r, --role <role>","Role (Team)","Team").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.addTeamMember(e.email,e.role);t.success&&w("Team member added"),y(t,e.format);}catch(t){U(t);}}),o.command("team-remove").description("Remove a team member from the workspace").requiredOption("-m, --member <id>","Member ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.removeTeamMember(e.member);t.success&&w("Team member removed"),y(t,e.format);}catch(t){U(t);}}),o.command("integration-add").description("Add an integration to the workspace").requiredOption("-t, --type <type>","Integration type (e.g., matomo)").requiredOption("-c, --config <json>","Integration config as JSON").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N(),t;try{t=JSON.parse(e.config);}catch{l("Invalid JSON config"),process.exit(1);}try{let i=await n.workspace.addIntegration({integration_type:e.type,config:t});i.success&&w("Integration added"),y(i,e.format);}catch(i){U(i);}}),o.command("integration-remove").description("Remove an integration from the workspace").requiredOption("-t, --type <type>","Integration type").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.removeIntegration(e.type);t.success&&w("Integration removed"),y(t,e.format);}catch(t){U(t);}}),o.command("whitelabel").description("Setup or update whitelabel settings").option("-d, --domain <domain>","Custom domain").option("-s, --subdomain <domain>","Subdomain domain").option("-e, --email-sender <email>","Email sender address").option("--enable-register","Enable client registration").option("--disable-register","Disable client registration").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.setupWhitelabel({domain:e.domain,subdomain_domain:e.subdomain,email_sender:e.emailSender,wl_client_register:e.enableRegister?!0:e.disableRegister?!1:void 0});t.success&&w("Whitelabel settings updated"),y(t,e.format);}catch(t){U(t);}}),o.command("appearance").description("Update workspace appearance settings").option("-p, --primary <color>","Primary color (hex)").option("-s, --secondary <color>","Secondary color (hex)").option("-m, --mode <mode>","Theme mode (light/dark)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.updateAppearance({primary_color:e.primary,secondary_color:e.secondary,theme_mode:e.mode});t.success&&w("Appearance settings updated"),y(t,e.format);}catch(t){U(t);}}),o}function N(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function U(o){o instanceof AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Te(){let o=new Command("analytics").description("Analytics operations");return o.command("workspace").description("Get workspace analytics").option("--from <date>","Start date (ISO format)").option("--to <date>","End date (ISO format)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=rt();try{let t=await n.analytics.getWorkspace({from:e.from,to:e.to});y(t,e.format);}catch(t){at(t);}}),o.command("website").description("Get website analytics").requiredOption("-w, --website <id>","Website ID (required)").option("--from <date>","Start date (ISO format)").option("--to <date>","End date (ISO format)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=rt();try{let t=await n.analytics.getWebsite({website_id:e.website,from:e.from,to:e.to});y(t,e.format);}catch(t){at(t);}}),o}function rt(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function at(o){o instanceof AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Fe(){let o=new Command("clients").description("Client management operations");return o.command("list").description("List all workspace clients").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.list({page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else if(t.clients&&t.clients.length>0){console.log(`
36
- Clients:`),console.log("--------");for(let i of t.clients)console.log(` ID: ${i.record_id}`),console.log(` Email: ${i.email}`),console.log(` Website Limit: ${i.website_limit??"N/A"}`),console.log(` Suspended: ${i.suspended??!1}`),console.log("");console.log(`Total: ${t.total??t.clients.length}`);}else a("No clients found");}catch(t){pe(t);}}),o.command("create").description("Create a new workspace client").requiredOption("-e, --email <email>","Client email address").option("-l, --limit <limit>","Website limit","5").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.create({email:e.email,website_limit:parseInt(e.limit,10)});if(t.success&&t.client)w(`Client created: ${t.client.record_id}`),y(t.client,e.format);else if(l("Failed to create client"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o.command("update").description("Update a workspace client").requiredOption("-i, --id <id>","Client ID").option("-l, --limit <limit>","Website limit").option("--suspend","Suspend the client").option("--unsuspend","Unsuspend the client").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.update({client_id:e.id,website_limit:e.limit?parseInt(e.limit,10):void 0,suspended:e.suspend?!0:e.unsuspend?!1:void 0});if(t.success)w("Client updated"),t.client&&y(t.client,e.format);else if(l("Failed to update client"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o.command("delete").description("Delete a workspace client").requiredOption("-i, --id <id>","Client ID").action(async e=>{let n=me();try{let t=await n.clients.delete(e.id);if(t.success)w("Client deleted");else if(l("Failed to delete client"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o.command("magic-link").description("Create a magic link for client authentication").requiredOption("-e, --email <email>","Client email address").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.createMagicLink(e.email);if(t.success)w("Magic link created"),y(t,e.format);else if(l("Failed to create magic link"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o}function me(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function pe(o){o instanceof AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Pe(){let o=new Command("websites").description("Website management operations");return o.command("list").description("List all workspace websites").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.list({page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else {let i=t.result?.list??[];if(i.length>0){console.log(`
37
- Websites:`),console.log("---------");for(let r of i)console.log(` ID: ${r.website_id}`),console.log(` Name: ${r.website_name??"N/A"}`),console.log(` Domain: ${r.domain??"N/A"}`),console.log(` Activated: ${r.activated??!1}`),console.log("");console.log(`Total: ${t.result?.total??i.length}`);}else a("No websites found");}}catch(t){R(t);}}),o.command("get").description("Get website details").requiredOption("-i, --id <id>","Website ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.getDetails(e.id);y(t,e.format);}catch(t){R(t);}}),o.command("update").description("Update a website").requiredOption("-i, --id <id>","Website ID").option("-n, --name <name>","Business name").option("--activate","Activate the website").option("--deactivate","Deactivate the website").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.update({website_id:e.id,business_name:e.name,activated:e.activate?!0:e.deactivate?!1:void 0});if(t.success)w("Website updated"),t.website&&y(t.website,e.format);else if(l("Failed to update website"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){R(t);}}),o.command("settings").description("Update website settings").requiredOption("-i, --id <id>","Website ID").option("-n, --name <name>","Business name").option("-l, --language <lang>","Language").option("-d, --description <desc>","Business description").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.updateSettings(e.id,{business_name:e.name,language:e.language,business_description:e.description});t.success&&w("Website settings updated"),y(t,e.format);}catch(t){R(t);}}),o.command("delete").description("Delete a website").requiredOption("-i, --id <id>","Website ID").action(async e=>{let n=L();try{let t=await n.websites.delete(e.id);if(t.success)w("Website deleted");else if(l("Failed to delete website"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){R(t);}}),o.command("assign").description("Assign a website to a client").requiredOption("-w, --website <id>","Website ID").requiredOption("-c, --client <id>","Client ID").action(async e=>{let n=L();try{let t=await n.websites.assign({website_id:e.website,client_id:e.client});if(t.success)w("Website assigned to client");else if(l("Failed to assign website"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){R(t);}}),o.command("domain-add").description("Add a custom domain to a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-d, --domain <domain>","Custom domain").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.addDomain(e.id,e.domain);if(t.success&&(w("Domain added"),t.result?.dns_records)){console.log(`
38
- DNS Records to configure:`);for(let i of t.result.dns_records)console.log(` ${i.record_type} ${i.host} -> ${i.value}`);}y(t,e.format);}catch(t){R(t);}}),o.command("domain-remove").description("Remove a custom domain from a website").requiredOption("-i, --id <id>","Website ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.removeDomain(e.id);t.success&&w("Domain removed"),y(t,e.format);}catch(t){R(t);}}),o.command("integration-add").description("Add an integration to a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-t, --type <type>","Integration type (e.g., matomo)").requiredOption("-c, --config <json>","Integration config as JSON").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L(),t;try{t=JSON.parse(e.config);}catch{l("Invalid JSON config"),process.exit(1);}try{let i=await n.websites.addIntegration(e.id,{integration_type:e.type,config:t});i.success&&w("Integration added"),y(i,e.format);}catch(i){R(i);}}),o.command("integration-remove").description("Remove an integration from a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-t, --type <type>","Integration type").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.removeIntegration(e.id,e.type);t.success&&w("Integration removed"),y(t,e.format);}catch(t){R(t);}}),o.command("team-add").description("Add a team member to a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-e, --email <email>","Team member email").requiredOption("-r, --role <role>","Role (Editor or Commenter)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.addTeamMember(e.id,e.email,e.role);t.success&&w("Team member added"),y(t,e.format);}catch(t){R(t);}}),o.command("team-remove").description("Remove a team member from a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-m, --member <memberId>","Member ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.removeTeamMember(e.id,e.member);t.success&&w("Team member removed"),y(t,e.format);}catch(t){R(t);}}),o}function L(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function R(o){o instanceof AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function G(o){return new Promise(e=>{let n=platform(),t;switch(n){case "darwin":t=`open "${o}"`;break;case "win32":t=`start "" "${o}"`;break;default:t=`xdg-open "${o}"`;break}exec(t,i=>{e(!i);});})}function co(o){let e=o.filter(t=>!!(t&&t.trim()));return e.length===0?"":`https://fonts.googleapis.com/css2?family=${e.map(t=>`${t.trim().replace(/ /g,"+")}:wght@300;400;700`).join("&family=")}&display=swap`}function ue(o){let e=[o.font,o.title_font].filter(Boolean);if(e.length===0)return "";let n=co(e);if(!n)return "";let t=o.font||o.title_font,i=o.title_font||o.font,r=`
32
+ </script>`;});var At="LINDO_API_KEY",Et="LINDO_BASE_URL",Lt=".lindo",Rt="config.json",Dt="https://api.lindo.ai";function Ze(){return P.join(De.homedir(),Lt)}function W(){return P.join(Ze(),Rt)}function ve(){let o=W();try{if($.existsSync(o)){let e=$.readFileSync(o,"utf-8");return JSON.parse(e)}}catch{}return {}}function et(o){let e=Ze(),n=W();$.existsSync(e)||$.mkdirSync(e,{recursive:true}),$.writeFileSync(n,JSON.stringify(o,null,2),"utf-8");}function O(){let o=ve(),e=process.env[At]||o.apiKey,n=process.env[Et]||o.baseUrl||Dt;return {apiKey:e,baseUrl:n}}function tt(o){let e=ve();e.apiKey=o,et(e);}function ot(o,e){let n=ve();switch(o){case "apiKey":n.apiKey=e;break;case "baseUrl":n.baseUrl=e;break;default:throw new Error(`Unknown configuration key: ${o}`)}et(n);}function nt(o){let e=O();switch(o){case "apiKey":return e.apiKey;case "baseUrl":return e.baseUrl;default:return}}function F(){return !!O().apiKey}var B={reset:"\x1B[0m",red:"\x1B[31m",green:"\x1B[32m",blue:"\x1B[34m",cyan:"\x1B[36m",gray:"\x1B[90m",bold:"\x1B[1m"};function jt(){return !process.env.NO_COLOR&&process.stdout.isTTY!==false}function q(o,e){return jt()?`${e}${o}${B.reset}`:o}function w(o){console.log(q(`\u2713 ${o}`,B.green));}function l(o){console.error(q(`\u2717 ${o}`,B.red));}function r(o){console.log(q(`\u2139 ${o}`,B.blue));}function Nt(o){return JSON.stringify(o,null,2)}function Ut(o){if(o==null)return "";if(Array.isArray(o)){if(o.length===0)return "No data";let e=new Set;for(let t of o)typeof t=="object"&&t!==null&&Object.keys(t).forEach(i=>e.add(i));if(e.size===0)return o.map(t=>String(t)).join(`
33
+ `);let n=Array.from(e);return Mt(n,o)}if(typeof o=="object"){let n=Object.entries(o);if(n.length===0)return "No data";let t=Math.max(...n.map(([i])=>i.length));return n.map(([i,a])=>{let c=i.padEnd(t),s=Ce(a);return `${q(c,B.cyan)} ${s}`}).join(`
34
+ `)}return String(o)}function Mt(o,e){let n={};for(let c of o)n[c]=c.length;for(let c of e)if(typeof c=="object"&&c!==null){let s=c;for(let d of o){let m=Ce(s[d]);n[d]=Math.max(n[d],m.length);}}let t=o.map(c=>q(c.padEnd(n[c]),B.bold)).join(" "),i=o.map(c=>"-".repeat(n[c])).join(" "),a=e.map(c=>{if(typeof c=="object"&&c!==null){let s=c;return o.map(d=>Ce(s[d]).padEnd(n[d])).join(" ")}return String(c)});return [t,i,...a].join(`
35
+ `)}function Ce(o){return o==null?q("-",B.gray):typeof o=="boolean"?o?q("true",B.green):q("false",B.red):typeof o=="number"?String(o):typeof o=="object"?Array.isArray(o)?`[${o.length} items]`:JSON.stringify(o):String(o)}function y(o,e){console.log(e==="json"?Nt(o):Ut(o));}var it=["apiKey","baseUrl"];function _e(){let o=new Command("config").description("Manage CLI configuration");return o.command("set <key> <value>").description("Set a configuration value").action((e,n)=>{it.includes(e)||(l(`Invalid configuration key: ${e}`),r(`Valid keys: ${it.join(", ")}`),process.exit(1));try{ot(e,n),w(`Configuration saved: ${e}`),r(`Config file: ${W()}`);}catch(t){l(`Failed to save configuration: ${t instanceof Error?t.message:String(t)}`),process.exit(1);}}),o.command("get <key>").description("Get a configuration value").option("-f, --format <format>","Output format (json, table)","table").action((e,n)=>{let t=nt(e);if(t===void 0){n.format==="json"?y({key:e,value:null},n.format):r(`Configuration key '${e}' is not set`);return}if(n.format==="json")y({key:e,value:t},n.format);else {let i=e==="apiKey"?ke(t):t;console.log(`${e}: ${i}`);}}),o.command("list").description("List all configuration values").option("-f, --format <format>","Output format (json, table)","table").action(e=>{let n=O(),t={apiKey:n.apiKey?ke(n.apiKey):"(not set)",baseUrl:n.baseUrl,configFile:W()};e.format==="json"?y({apiKey:n.apiKey?ke(n.apiKey):null,baseUrl:n.baseUrl,configFile:W()},e.format):y(t,e.format);}),o.command("path").description("Show the config file path").action(()=>{console.log(W());}),o}function ke(o){return o.length<=8?"*".repeat(o.length):`${o.slice(0,4)}${"*".repeat(o.length-8)}${o.slice(-4)}`}function Se(){let o=new Command("agents").description("Run AI agents");return o.command("run <agent-id>").description("Run an AI agent").option("-i, --input <json>","Input data as JSON string","{}").option("-s, --stream","Stream the response",false).option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let t=O(),i=new LindoClient({apiKey:t.apiKey,baseUrl:t.baseUrl}),a;try{a=JSON.parse(n.input);}catch{l("Invalid JSON input"),r(`Example: --input '{"prompt": "Hello!"}'`),process.exit(1);}try{r(`Running agent: ${e}`);let c=await i.agents.run({agent_id:e,input:a,stream:n.stream});c.success?(w("Agent run completed"),y(c,n.format)):(l(`Agent run failed: ${c.error||"Unknown error"}`),y(c,n.format),process.exit(1));}catch(c){qt(c);}}),o}function qt(o){o instanceof AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function $e(){let o=new Command("workflows").description("Manage workflows");return o.command("list").description("List workflow logs").option("-n, --name <name>","Filter by workflow name").option("-s, --status <status>","Filter by status").option("-w, --website <id>","Filter by website ID").option("-c, --client <id>","Filter by client ID").option("-l, --limit <number>","Maximum number of results","50").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=ne();try{let t=await n.workflows.list({workflow_name:e.name,status:e.status,website_id:e.website,client_id:e.client,limit:parseInt(e.limit)});t.success?y(t.data,e.format):(l("Failed to list workflows"),process.exit(1));}catch(t){ie(t);}}),o.command("start <workflow-name>").description("Start a workflow").option("-p, --params <json>","Workflow parameters as JSON string","{}").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne(),i;try{i=JSON.parse(n.params);}catch{l("Invalid JSON params"),r(`Example: --params '{"page_id": "page-123"}'`),process.exit(1);}try{r(`Starting workflow: ${e}`);let a=await t.workflows.start({workflow_name:e,params:i});a.success?(w(`Workflow started: ${a.instance_id}`),y(a,n.format)):(l("Failed to start workflow"),y(a,n.format),process.exit(1));}catch(a){ie(a);}}),o.command("status <instance-id>").description("Get workflow status").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{let i=await t.workflows.getStatus(e);y(i,n.format);}catch(i){ie(i);}}),o.command("pause <instance-id>").description("Pause a running workflow").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{r(`Pausing workflow: ${e}`);let i=await t.workflows.pause(e);i.success?w(i.message):(l(i.message),process.exit(1)),y(i,n.format);}catch(i){ie(i);}}),o.command("resume <instance-id>").description("Resume a paused workflow").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{r(`Resuming workflow: ${e}`);let i=await t.workflows.resume(e);i.success?w(i.message):(l(i.message),process.exit(1)),y(i,n.format);}catch(i){ie(i);}}),o.command("terminate <instance-id>").description("Terminate a workflow").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n)=>{let t=ne();try{r(`Terminating workflow: ${e}`);let i=await t.workflows.terminate(e);i.success?w(i.message):(l(i.message),process.exit(1)),y(i,n.format);}catch(i){ie(i);}}),o}function ne(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function ie(o){o instanceof AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Oe(){let o=new Command("workspace").description("Workspace operations");return o.command("get").description("Get workspace details").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.get();y(t,e.format);}catch(t){U(t);}}),o.command("credits").description("Get workspace credit balance").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.getCredits();y(t,e.format);}catch(t){U(t);}}),o.command("client-credits").description("Get credit balance for a specific client").requiredOption("-c, --client <id>","Client ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.getClientCredits(e.client);y(t,e.format);}catch(t){U(t);}}),o.command("update").description("Update workspace settings").option("-n, --name <name>","Workspace name").option("-l, --language <lang>","Workspace language").option("-w, --webhook <url>","Webhook URL").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.update({workspace_name:e.name,workspace_language:e.language,webhook_url:e.webhook});t.success&&w("Workspace updated"),y(t,e.format);}catch(t){U(t);}}),o.command("team-add").description("Add a team member to the workspace").requiredOption("-e, --email <email>","Team member email").option("-r, --role <role>","Role (Team)","Team").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.addTeamMember(e.email,e.role);t.success&&w("Team member added"),y(t,e.format);}catch(t){U(t);}}),o.command("team-remove").description("Remove a team member from the workspace").requiredOption("-m, --member <id>","Member ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.removeTeamMember(e.member);t.success&&w("Team member removed"),y(t,e.format);}catch(t){U(t);}}),o.command("integration-add").description("Add an integration to the workspace").requiredOption("-t, --type <type>","Integration type (e.g., matomo)").requiredOption("-c, --config <json>","Integration config as JSON").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N(),t;try{t=JSON.parse(e.config);}catch{l("Invalid JSON config"),process.exit(1);}try{let i=await n.workspace.addIntegration({integration_type:e.type,config:t});i.success&&w("Integration added"),y(i,e.format);}catch(i){U(i);}}),o.command("integration-remove").description("Remove an integration from the workspace").requiredOption("-t, --type <type>","Integration type").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.removeIntegration(e.type);t.success&&w("Integration removed"),y(t,e.format);}catch(t){U(t);}}),o.command("whitelabel").description("Setup or update whitelabel settings").option("-d, --domain <domain>","Custom domain").option("-s, --subdomain <domain>","Subdomain domain").option("-e, --email-sender <email>","Email sender address").option("--enable-register","Enable client registration").option("--disable-register","Disable client registration").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.setupWhitelabel({domain:e.domain,subdomain_domain:e.subdomain,email_sender:e.emailSender,wl_client_register:e.enableRegister?!0:e.disableRegister?!1:void 0});t.success&&w("Whitelabel settings updated"),y(t,e.format);}catch(t){U(t);}}),o.command("appearance").description("Update workspace appearance settings").option("-p, --primary <color>","Primary color (hex)").option("-s, --secondary <color>","Secondary color (hex)").option("-m, --mode <mode>","Theme mode (light/dark)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=N();try{let t=await n.workspace.updateAppearance({primary_color:e.primary,secondary_color:e.secondary,theme_mode:e.mode});t.success&&w("Appearance settings updated"),y(t,e.format);}catch(t){U(t);}}),o}function N(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function U(o){o instanceof AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Te(){let o=new Command("analytics").description("Analytics operations");return o.command("workspace").description("Get workspace analytics").option("--from <date>","Start date (ISO format)").option("--to <date>","End date (ISO format)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=rt();try{let t=await n.analytics.getWorkspace({from:e.from,to:e.to});y(t,e.format);}catch(t){at(t);}}),o.command("website").description("Get website analytics").requiredOption("-w, --website <id>","Website ID (required)").option("--from <date>","Start date (ISO format)").option("--to <date>","End date (ISO format)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=rt();try{let t=await n.analytics.getWebsite({website_id:e.website,from:e.from,to:e.to});y(t,e.format);}catch(t){at(t);}}),o}function rt(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function at(o){o instanceof AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Fe(){let o=new Command("clients").description("Client management operations");return o.command("list").description("List all workspace clients").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.list({page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else if(t.clients&&t.clients.length>0){console.log(`
36
+ Clients:`),console.log("--------");for(let i of t.clients)console.log(` ID: ${i.record_id}`),console.log(` Email: ${i.email}`),console.log(` Website Limit: ${i.website_limit??"N/A"}`),console.log(` Suspended: ${i.suspended??!1}`),console.log("");console.log(`Total: ${t.total??t.clients.length}`);}else r("No clients found");}catch(t){pe(t);}}),o.command("create").description("Create a new workspace client").requiredOption("-e, --email <email>","Client email address").option("-l, --limit <limit>","Website limit","5").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.create({email:e.email,website_limit:parseInt(e.limit,10)});if(t.success&&t.client)w(`Client created: ${t.client.record_id}`),y(t.client,e.format);else if(l("Failed to create client"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o.command("update").description("Update a workspace client").requiredOption("-i, --id <id>","Client ID").option("-l, --limit <limit>","Website limit").option("--suspend","Suspend the client").option("--unsuspend","Unsuspend the client").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.update({client_id:e.id,website_limit:e.limit?parseInt(e.limit,10):void 0,suspended:e.suspend?!0:e.unsuspend?!1:void 0});if(t.success)w("Client updated"),t.client&&y(t.client,e.format);else if(l("Failed to update client"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o.command("delete").description("Delete a workspace client").requiredOption("-i, --id <id>","Client ID").action(async e=>{let n=me();try{let t=await n.clients.delete(e.id);if(t.success)w("Client deleted");else if(l("Failed to delete client"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o.command("magic-link").description("Create a magic link for client authentication").requiredOption("-e, --email <email>","Client email address").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=me();try{let t=await n.clients.createMagicLink(e.email);if(t.success)w("Magic link created"),y(t,e.format);else if(l("Failed to create magic link"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){pe(t);}}),o}function me(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function pe(o){o instanceof AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Pe(){let o=new Command("websites").description("Website management operations");return o.command("list").description("List all workspace websites").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.list({page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else {let i=t.result?.list??[];if(i.length>0){console.log(`
37
+ Websites:`),console.log("---------");for(let a of i)console.log(` ID: ${a.website_id}`),console.log(` Name: ${a.website_name??"N/A"}`),console.log(` Domain: ${a.domain??"N/A"}`),console.log(` Activated: ${a.activated??!1}`),console.log("");console.log(`Total: ${t.result?.total??i.length}`);}else r("No websites found");}}catch(t){R(t);}}),o.command("get").description("Get website details").requiredOption("-i, --id <id>","Website ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.getDetails(e.id);y(t,e.format);}catch(t){R(t);}}),o.command("update").description("Update a website").requiredOption("-i, --id <id>","Website ID").option("-n, --name <name>","Business name").option("--activate","Activate the website").option("--deactivate","Deactivate the website").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.update({website_id:e.id,business_name:e.name,activated:e.activate?!0:e.deactivate?!1:void 0});if(t.success)w("Website updated"),t.website&&y(t.website,e.format);else if(l("Failed to update website"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){R(t);}}),o.command("settings").description("Update website settings").requiredOption("-i, --id <id>","Website ID").option("-n, --name <name>","Business name").option("-l, --language <lang>","Language").option("-d, --description <desc>","Business description").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.updateSettings(e.id,{business_name:e.name,language:e.language,business_description:e.description});t.success&&w("Website settings updated"),y(t,e.format);}catch(t){R(t);}}),o.command("delete").description("Delete a website").requiredOption("-i, --id <id>","Website ID").action(async e=>{let n=L();try{let t=await n.websites.delete(e.id);if(t.success)w("Website deleted");else if(l("Failed to delete website"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){R(t);}}),o.command("assign").description("Assign a website to a client").requiredOption("-w, --website <id>","Website ID").requiredOption("-c, --client <id>","Client ID").action(async e=>{let n=L();try{let t=await n.websites.assign({website_id:e.website,client_id:e.client});if(t.success)w("Website assigned to client");else if(l("Failed to assign website"),t.errors)for(let i of t.errors)l(` ${i}`);}catch(t){R(t);}}),o.command("domain-add").description("Add a custom domain to a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-d, --domain <domain>","Custom domain").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.addDomain(e.id,e.domain);if(t.success&&(w("Domain added"),t.result?.dns_records)){console.log(`
38
+ DNS Records to configure:`);for(let i of t.result.dns_records)console.log(` ${i.record_type} ${i.host} -> ${i.value}`);}y(t,e.format);}catch(t){R(t);}}),o.command("domain-remove").description("Remove a custom domain from a website").requiredOption("-i, --id <id>","Website ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.removeDomain(e.id);t.success&&w("Domain removed"),y(t,e.format);}catch(t){R(t);}}),o.command("integration-add").description("Add an integration to a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-t, --type <type>","Integration type (e.g., matomo)").requiredOption("-c, --config <json>","Integration config as JSON").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L(),t;try{t=JSON.parse(e.config);}catch{l("Invalid JSON config"),process.exit(1);}try{let i=await n.websites.addIntegration(e.id,{integration_type:e.type,config:t});i.success&&w("Integration added"),y(i,e.format);}catch(i){R(i);}}),o.command("integration-remove").description("Remove an integration from a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-t, --type <type>","Integration type").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.removeIntegration(e.id,e.type);t.success&&w("Integration removed"),y(t,e.format);}catch(t){R(t);}}),o.command("team-add").description("Add a team member to a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-e, --email <email>","Team member email").requiredOption("-r, --role <role>","Role (Editor or Commenter)").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.addTeamMember(e.id,e.email,e.role);t.success&&w("Team member added"),y(t,e.format);}catch(t){R(t);}}),o.command("team-remove").description("Remove a team member from a website").requiredOption("-i, --id <id>","Website ID").requiredOption("-m, --member <memberId>","Member ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=L();try{let t=await n.websites.removeTeamMember(e.id,e.member);t.success&&w("Team member removed"),y(t,e.format);}catch(t){R(t);}}),o}function L(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function R(o){o instanceof AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function G(o){return new Promise(e=>{let n=platform(),t;switch(n){case "darwin":t=`open "${o}"`;break;case "win32":t=`start "" "${o}"`;break;default:t=`xdg-open "${o}"`;break}exec(t,i=>{e(!i);});})}function co(o){let e=o.filter(t=>!!(t&&t.trim()));return e.length===0?"":`https://fonts.googleapis.com/css2?family=${e.map(t=>`${t.trim().replace(/ /g,"+")}:wght@300;400;700`).join("&family=")}&display=swap`}function ue(o){let e=[o.font,o.title_font].filter(Boolean);if(e.length===0)return "";let n=co(e);if(!n)return "";let t=o.font||o.title_font,i=o.title_font||o.font,a=`
39
39
  <style>
40
40
  /* Apply website fonts from theme */
41
41
  body, main, .prose {
@@ -46,12 +46,12 @@ DNS Records to configure:`);for(let i of t.result.dns_records)console.log(` ${i
46
46
  }
47
47
  </style>`;return `<link rel="preconnect" href="https://fonts.googleapis.com">
48
48
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
49
- <link href="${n}" rel="stylesheet">${r}`}function st(o,e){let n=new RegExp(`<${e}\\b[^>]*>`,"gi"),t,i=null;for(;(t=n.exec(o))!==null;){let _=o.slice(0,t.index);if(mo(_)){i=t;break}}if(!i||i.index===void 0)return {section:void 0,remainingHtml:o};let r=i.index,c=r+i[0].length,s=`</${e}>`,d=o.slice(c),m=new RegExp(`<${e}\\b`,"gi"),v=new RegExp(`</${e}>`,"gi"),b=[],u=[],x;for(;(x=m.exec(d))!==null;)b.push(x.index+c);for(;(x=v.exec(d))!==null;)u.push(x.index+c);let g=[...b.map(_=>({pos:_,type:"open"})),...u.map(_=>({pos:_,type:"close"}))].sort((_,A)=>_.pos-A.pos),f=1,p=-1;for(let _ of g)if(_.type==="open")f++;else if(f--,f===0){p=_.pos+s.length;break}if(p===-1)return {section:void 0,remainingHtml:o};let h=o.slice(r,p),C=o.slice(0,r),k=o.slice(p),S=(C+k).replace(/\n\s*\n\s*\n/g,`
49
+ <link href="${n}" rel="stylesheet">${a}`}function st(o,e){let n=new RegExp(`<${e}\\b[^>]*>`,"gi"),t,i=null;for(;(t=n.exec(o))!==null;){let _=o.slice(0,t.index);if(mo(_)){i=t;break}}if(!i||i.index===void 0)return {section:void 0,remainingHtml:o};let a=i.index,c=a+i[0].length,s=`</${e}>`,d=o.slice(c),m=new RegExp(`<${e}\\b`,"gi"),v=new RegExp(`</${e}>`,"gi"),b=[],u=[],x;for(;(x=m.exec(d))!==null;)b.push(x.index+c);for(;(x=v.exec(d))!==null;)u.push(x.index+c);let g=[...b.map(_=>({pos:_,type:"open"})),...u.map(_=>({pos:_,type:"close"}))].sort((_,A)=>_.pos-A.pos),f=1,p=-1;for(let _ of g)if(_.type==="open")f++;else if(f--,f===0){p=_.pos+s.length;break}if(p===-1)return {section:void 0,remainingHtml:o};let h=o.slice(a,p),C=o.slice(0,a),k=o.slice(p),S=(C+k).replace(/\n\s*\n\s*\n/g,`
50
50
 
51
- `);return {section:h,remainingHtml:S}}function mo(o){let e=["section","header","footer"],n=0;for(let t of e){let i=new RegExp(`<${t}\\b`,"gi"),r=new RegExp(`</${t}>`,"gi"),c=(o.match(i)||[]).length,s=(o.match(r)||[]).length;n+=c-s;}return n===0}function be(o){let e=st(o,"header"),n=st(e.remainingHtml,"footer");return {globalHeader:e.section,globalFooter:n.section,mainContent:n.remainingHtml.trim()}}function Ie(o,e,n){let t=[];return e&&e.trim()&&t.push(e.trim()),o.trim()&&t.push(o.trim()),n&&n.trim()&&t.push(n.trim()),t.join(`
52
- `)}function re(o){return !(!o||o.startsWith("http://")||o.startsWith("https://")||o.startsWith("//")||o.startsWith("data:")||o.startsWith("blob:")||o.startsWith("#"))}function we(o){let e=o.toLowerCase().split(".").pop()||"",n=["jpg","jpeg","png","gif","webp","svg","ico","avif","bmp","tiff"],t=["mp4","webm","mov","avi","mkv","ogv"],i=["woff","woff2","ttf","otf","eot"];return n.includes(e)?"images":t.includes(e)?"videos":i.includes(e)?"fonts":"documents"}function ae(o){let e=o.toLowerCase().split(".").pop()||"";return {jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",ico:"image/x-icon",avif:"image/avif",bmp:"image/bmp",tiff:"image/tiff",mp4:"video/mp4",webm:"video/webm",mov:"video/quicktime",avi:"video/x-msvideo",mkv:"video/x-matroska",ogv:"video/ogg",pdf:"application/pdf",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",otf:"font/otf",eot:"application/vnd.ms-fontobject"}[e]||"application/octet-stream"}function po(o,e){let n=Ee.load(o),t=[],i=new Set;return n("img[src]").each((r,c)=>{let s=n(c).attr("src");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P.resolve(e,s);$.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P.basename(s),mediaType:we(s),contentType:ae(s)});}}),n("img[srcset]").each((r,c)=>{let s=n(c).attr("srcset");if(s){let d=s.split(",").map(m=>m.trim().split(/\s+/)[0]);for(let m of d)if(m&&re(m)&&!i.has(m)){i.add(m);let v=P.resolve(e,m);$.existsSync(v)&&t.push({originalPath:m,absolutePath:v,fileName:P.basename(m),mediaType:we(m),contentType:ae(m)});}}}),n("source[src]").each((r,c)=>{let s=n(c).attr("src");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P.resolve(e,s);$.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P.basename(s),mediaType:we(s),contentType:ae(s)});}}),n("video[poster]").each((r,c)=>{let s=n(c).attr("poster");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P.resolve(e,s);$.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P.basename(s),mediaType:"images",contentType:ae(s)});}}),n('[style*="background"]').each((r,c)=>{let d=(n(c).attr("style")||"").match(/url\(['"]?([^'")\s]+)['"]?\)/);if(d&&d[1]){let m=d[1];if(re(m)&&!i.has(m)){i.add(m);let v=P.resolve(e,m);$.existsSync(v)&&t.push({originalPath:m,absolutePath:v,fileName:P.basename(m),mediaType:we(m),contentType:ae(m)});}}}),n('link[href][rel*="icon"]').each((r,c)=>{let s=n(c).attr("href");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P.resolve(e,s);$.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P.basename(s),mediaType:"images",contentType:ae(s)});}}),t}async function Le(o,e,n,t,i,r){let c=po(o,e);if(c.length===0)return {html:o,uploadedCount:0,failedCount:0,urlMap:new Map,sourceFileUpdated:false};i?.(`Found ${c.length} local asset(s) to upload`);let s=new Map,d=0,m=0,v=10;for(let g=0;g<c.length;g+=v){let f=c.slice(g,g+v),p=f.map(h=>({file_base64:$.readFileSync(h.absolutePath).toString("base64"),file_name:h.fileName,media_type:h.mediaType,content_type:h.contentType}));try{if(p.length>1&&t.media.uploadBatch){let h=await t.media.uploadBatch(n,{files:p});for(let C=0;C<h.result.uploaded.length;C++){let k=h.result.uploaded[C],S=f[C];k.success?(s.set(S.originalPath,k.url),d++,i?.(`Uploaded: ${S.fileName} \u2192 ${k.url}`)):(m++,i?.(`Failed: ${S.fileName} - ${k.error}`));}}else for(let h=0;h<p.length;h++){let C=p[h],k=f[h];try{let S=await t.media.upload(n,C);s.set(k.originalPath,S.result.url),d++,i?.(`Uploaded: ${k.fileName} \u2192 ${S.result.url}`);}catch(S){m++,i?.(`Failed: ${k.fileName} - ${S instanceof Error?S.message:"Unknown error"}`);}}}catch{for(let C=0;C<p.length;C++){let k=p[C],S=f[C];try{let _=await t.media.upload(n,k);s.set(S.originalPath,_.result.url),d++,i?.(`Uploaded: ${S.fileName} \u2192 ${_.result.url}`);}catch(_){m++,i?.(`Failed: ${S.fileName} - ${_ instanceof Error?_.message:"Unknown error"}`);}}}}let b=Ee.load(o);b("img[src]").each((g,f)=>{let p=b(f).attr("src");p&&s.has(p)&&b(f).attr("src",s.get(p));}),b("img[srcset]").each((g,f)=>{let p=b(f).attr("srcset");if(p){let h=p;for(let[C,k]of s)h=h.replace(new RegExp(Ae(C),"g"),k);b(f).attr("srcset",h);}}),b("source[src]").each((g,f)=>{let p=b(f).attr("src");p&&s.has(p)&&b(f).attr("src",s.get(p));}),b("video[poster]").each((g,f)=>{let p=b(f).attr("poster");p&&s.has(p)&&b(f).attr("poster",s.get(p));}),b('[style*="background"]').each((g,f)=>{let p=b(f).attr("style")||"";for(let[h,C]of s)p=p.replace(new RegExp(Ae(h),"g"),C);b(f).attr("style",p);}),b("link[href]").each((g,f)=>{let p=b(f).attr("href");p&&s.has(p)&&b(f).attr("href",s.get(p));});let u=b.html(),x=false;if(r&&d>0)try{let g=$.readFileSync(r,"utf-8"),f=g;for(let[p,h]of s)f=f.replace(new RegExp(Ae(p),"g"),h);f!==g&&($.writeFileSync(r,f,"utf-8"),x=!0,i?.(`Updated source file with CDN URLs: ${r}`));}catch(g){i?.(`Warning: Could not update source file: ${g instanceof Error?g.message:"Unknown error"}`);}return {html:u,uploadedCount:d,failedCount:m,urlMap:s,sourceFileUpdated:x}}function Ae(o){return o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Re(o,e){let n,t=o.match(/<main[^>]*>([\s\S]*)<\/main>/i),i=o.match(/<body[^>]*>([\s\S]*)<\/body>/i);t?n=t[1].trim():i?n=i[1].trim():n=o;let r=be(n),c=r.mainContent,s=o.match(/<title>([^<]*)<\/title>/i),d=s?s[1].trim():e,m="",v="",b=o.match(/<!-- Page Custom Code \(Header\) -->\s*([\s\S]*?)\s*<!-- End Page Custom Code \(Header\) -->/i);b&&b[1].trim()&&(m=b[1].trim());let u=o.match(/<!-- Page Custom Code \(Footer\) -->\s*([\s\S]*?)\s*<!-- End Page Custom Code \(Footer\) -->/i);u&&u[1].trim()&&(v=u[1].trim());let x=o.match(/<html[^>]*class="([^"]*)"/i),g=x?x[1].includes("dark"):true,f=o.match(/<main[^>]*>/i),p="ltr",h="";if(f){let X=f[0].match(/dir="([^"]*)"/i);X&&(p=X[1]);let Xe=f[0].match(/class="([^"]*)"/i);Xe&&(h=Xe[1]);}let C=!o.includes("motion@latest"),k=o.match(/<meta\s+name="description"\s+content="([^"]*)"/i),S=o.match(/<meta\s+property="og:title"\s+content="([^"]*)"/i),_=o.match(/<meta\s+property="og:description"\s+content="([^"]*)"/i),A=o.match(/<meta\s+property="og:image"\s+content="([^"]*)"/i),I=o.match(/<link\s+rel="canonical"\s+href="([^"]*)"/i),ee=o.match(/noindex/i),de=o.match(/nofollow/i),E={};d&&(E.page_title=d),k&&k[1]&&(E.meta_description=k[1]),S&&S[1]&&(E.social_title=S[1]),_&&_[1]&&(E.social_description=_[1]),A&&A[1]&&(E.social_image=A[1]),I&&I[1]&&(E.canonical_url=I[1]),E.noindex=!!ee,E.nofollow=!!de;let te={theme:{mode:g?"Dark":"Light",direction:p,main_classes:h,animations_deactivated:C},should_convert:true},oe=m||v?{}:void 0;return oe&&(m&&(oe.header=m),v&&(oe.footer=v)),{html:c,globalHeader:r.globalHeader,globalFooter:r.globalFooter,templateName:d,headerCode:m||void 0,footerCode:v||void 0,settings:te,seo:E,customCodes:oe}}var Q=P.join(De.tmpdir(),"lindoai-pages-preview.pid"),ge=P.join(De.tmpdir(),"lindoai-pages-preview.port");function We(){let o=new Command("pages").description("Page management operations");return o.command("list").description("List all pages for a website").requiredOption("-w, --website <id>","Website ID").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.list(e.website,{page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else {let i=t.result;if(i?.list&&i.list.length>0){console.log(`
53
- Pages:`),console.log("------");for(let r of i.list)console.log(` ID: ${r.page_id}`),console.log(` Name: ${r.name??"N/A"}`),console.log(` Path: ${r.path??"N/A"}`),console.log(` Status: ${r.status??"N/A"}`),console.log(` Published: ${r.publish_date?"Yes":"No"}`),console.log("");console.log(`Total: ${i.total??i.list.length}`);}else a("No pages found");}}catch(t){z(t);}}),o.command("get").description("Get details of a specific page").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Page ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.get(e.website,e.id);if(e.format==="json")y(t,"json");else {let i=t.result;i?(console.log(`
54
- Page Details:`),console.log("-------------"),console.log(` ID: ${i.page_id}`),console.log(` Name: ${i.name??"N/A"}`),console.log(` Path: ${i.path??"N/A"}`),console.log(` Status: ${i.status??"N/A"}`),console.log(` Published: ${i.publish_date?"Yes":"No"}`),console.log(` Created: ${i.created_date??"N/A"}`)):l("Page not found");}}catch(t){z(t);}}),o.command("unpublish").description("Unpublish a page").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Page ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.unpublish(e.website,e.id);e.format==="json"?y(t,"json"):t.success?(w("Page unpublished successfully"),console.log(` Page ID: ${t.result?.page_id}`)):l("Failed to unpublish page");}catch(t){z(t);}}),o.command("delete").description("Delete a page").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Page ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.deletePage(e.website,e.id);if(e.format==="json")y(t,"json");else if(t.success){if(w("Page deleted successfully"),console.log(` Page ID: ${t.result?.page_id}`),t.result?.warnings&&t.result.warnings.length>0){console.log(" Warnings:");for(let i of t.result.warnings)console.log(` - ${i}`);}}else l("Failed to delete page");}catch(t){z(t);}}),o.command("create-empty").description("Create a new empty page with starter template and live preview").argument("<website_id>","Website ID").argument("<path>","URL path for the page (e.g., /about-us)").option("--title <title>","Page title","New Page").option("--file <path>","Output file path","./page.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=Y();try{a("Fetching website details...");let c=(await i.websites.getDetails(e)).result,s=c?.theme||{},d=c?.global_header||null,m=c?.global_footer||null,v=c?.custom_codes||{header:null,footer:null},b={font:s.font,title_font:s.title_font},u=t.title,x=`<!-- Hero Section -->
51
+ `);return {section:h,remainingHtml:S}}function mo(o){let e=["section","header","footer"],n=0;for(let t of e){let i=new RegExp(`<${t}\\b`,"gi"),a=new RegExp(`</${t}>`,"gi"),c=(o.match(i)||[]).length,s=(o.match(a)||[]).length;n+=c-s;}return n===0}function be(o){let e=st(o,"header"),n=st(e.remainingHtml,"footer");return {globalHeader:e.section,globalFooter:n.section,mainContent:n.remainingHtml.trim()}}function Ie(o,e,n){let t=[];return e&&e.trim()&&t.push(e.trim()),o.trim()&&t.push(o.trim()),n&&n.trim()&&t.push(n.trim()),t.join(`
52
+ `)}function re(o){return !(!o||o.startsWith("http://")||o.startsWith("https://")||o.startsWith("//")||o.startsWith("data:")||o.startsWith("blob:")||o.startsWith("#"))}function we(o){let e=o.toLowerCase().split(".").pop()||"",n=["jpg","jpeg","png","gif","webp","svg","ico","avif","bmp","tiff"],t=["mp4","webm","mov","avi","mkv","ogv"],i=["woff","woff2","ttf","otf","eot"];return n.includes(e)?"images":t.includes(e)?"videos":i.includes(e)?"fonts":"documents"}function ae(o){let e=o.toLowerCase().split(".").pop()||"";return {jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",ico:"image/x-icon",avif:"image/avif",bmp:"image/bmp",tiff:"image/tiff",mp4:"video/mp4",webm:"video/webm",mov:"video/quicktime",avi:"video/x-msvideo",mkv:"video/x-matroska",ogv:"video/ogg",pdf:"application/pdf",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",otf:"font/otf",eot:"application/vnd.ms-fontobject"}[e]||"application/octet-stream"}function po(o,e){let n=Ee.load(o),t=[],i=new Set;return n("img[src]").each((a,c)=>{let s=n(c).attr("src");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P.resolve(e,s);$.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P.basename(s),mediaType:we(s),contentType:ae(s)});}}),n("img[srcset]").each((a,c)=>{let s=n(c).attr("srcset");if(s){let d=s.split(",").map(m=>m.trim().split(/\s+/)[0]);for(let m of d)if(m&&re(m)&&!i.has(m)){i.add(m);let v=P.resolve(e,m);$.existsSync(v)&&t.push({originalPath:m,absolutePath:v,fileName:P.basename(m),mediaType:we(m),contentType:ae(m)});}}}),n("source[src]").each((a,c)=>{let s=n(c).attr("src");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P.resolve(e,s);$.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P.basename(s),mediaType:we(s),contentType:ae(s)});}}),n("video[poster]").each((a,c)=>{let s=n(c).attr("poster");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P.resolve(e,s);$.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P.basename(s),mediaType:"images",contentType:ae(s)});}}),n('[style*="background"]').each((a,c)=>{let d=(n(c).attr("style")||"").match(/url\(['"]?([^'")\s]+)['"]?\)/);if(d&&d[1]){let m=d[1];if(re(m)&&!i.has(m)){i.add(m);let v=P.resolve(e,m);$.existsSync(v)&&t.push({originalPath:m,absolutePath:v,fileName:P.basename(m),mediaType:we(m),contentType:ae(m)});}}}),n('link[href][rel*="icon"]').each((a,c)=>{let s=n(c).attr("href");if(s&&re(s)&&!i.has(s)){i.add(s);let d=P.resolve(e,s);$.existsSync(d)&&t.push({originalPath:s,absolutePath:d,fileName:P.basename(s),mediaType:"images",contentType:ae(s)});}}),t}async function Le(o,e,n,t,i,a){let c=po(o,e);if(c.length===0)return {html:o,uploadedCount:0,failedCount:0,urlMap:new Map,sourceFileUpdated:false};i?.(`Found ${c.length} local asset(s) to upload`);let s=new Map,d=0,m=0,v=10;for(let g=0;g<c.length;g+=v){let f=c.slice(g,g+v),p=f.map(h=>({file_base64:$.readFileSync(h.absolutePath).toString("base64"),file_name:h.fileName,media_type:h.mediaType,content_type:h.contentType}));try{if(p.length>1&&t.media.uploadBatch){let h=await t.media.uploadBatch(n,{files:p});for(let C=0;C<h.result.uploaded.length;C++){let k=h.result.uploaded[C],S=f[C];k.success?(s.set(S.originalPath,k.url),d++,i?.(`Uploaded: ${S.fileName} \u2192 ${k.url}`)):(m++,i?.(`Failed: ${S.fileName} - ${k.error}`));}}else for(let h=0;h<p.length;h++){let C=p[h],k=f[h];try{let S=await t.media.upload(n,C);s.set(k.originalPath,S.result.url),d++,i?.(`Uploaded: ${k.fileName} \u2192 ${S.result.url}`);}catch(S){m++,i?.(`Failed: ${k.fileName} - ${S instanceof Error?S.message:"Unknown error"}`);}}}catch{for(let C=0;C<p.length;C++){let k=p[C],S=f[C];try{let _=await t.media.upload(n,k);s.set(S.originalPath,_.result.url),d++,i?.(`Uploaded: ${S.fileName} \u2192 ${_.result.url}`);}catch(_){m++,i?.(`Failed: ${S.fileName} - ${_ instanceof Error?_.message:"Unknown error"}`);}}}}let b=Ee.load(o);b("img[src]").each((g,f)=>{let p=b(f).attr("src");p&&s.has(p)&&b(f).attr("src",s.get(p));}),b("img[srcset]").each((g,f)=>{let p=b(f).attr("srcset");if(p){let h=p;for(let[C,k]of s)h=h.replace(new RegExp(Ae(C),"g"),k);b(f).attr("srcset",h);}}),b("source[src]").each((g,f)=>{let p=b(f).attr("src");p&&s.has(p)&&b(f).attr("src",s.get(p));}),b("video[poster]").each((g,f)=>{let p=b(f).attr("poster");p&&s.has(p)&&b(f).attr("poster",s.get(p));}),b('[style*="background"]').each((g,f)=>{let p=b(f).attr("style")||"";for(let[h,C]of s)p=p.replace(new RegExp(Ae(h),"g"),C);b(f).attr("style",p);}),b("link[href]").each((g,f)=>{let p=b(f).attr("href");p&&s.has(p)&&b(f).attr("href",s.get(p));});let u=b.html(),x=false;if(a&&d>0)try{let g=$.readFileSync(a,"utf-8"),f=g;for(let[p,h]of s)f=f.replace(new RegExp(Ae(p),"g"),h);f!==g&&($.writeFileSync(a,f,"utf-8"),x=!0,i?.(`Updated source file with CDN URLs: ${a}`));}catch(g){i?.(`Warning: Could not update source file: ${g instanceof Error?g.message:"Unknown error"}`);}return {html:u,uploadedCount:d,failedCount:m,urlMap:s,sourceFileUpdated:x}}function Ae(o){return o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Re(o,e){let n,t=o.match(/<main[^>]*>([\s\S]*)<\/main>/i),i=o.match(/<body[^>]*>([\s\S]*)<\/body>/i);t?n=t[1].trim():i?n=i[1].trim():n=o;let a=be(n),c=a.mainContent,s=o.match(/<title>([^<]*)<\/title>/i),d=s?s[1].trim():e,m="",v="",b=o.match(/<!-- Page Custom Code \(Header\) -->\s*([\s\S]*?)\s*<!-- End Page Custom Code \(Header\) -->/i);b&&b[1].trim()&&(m=b[1].trim());let u=o.match(/<!-- Page Custom Code \(Footer\) -->\s*([\s\S]*?)\s*<!-- End Page Custom Code \(Footer\) -->/i);u&&u[1].trim()&&(v=u[1].trim());let x=o.match(/<html[^>]*class="([^"]*)"/i),g=x?x[1].includes("dark"):true,f=o.match(/<main[^>]*>/i),p="ltr",h="";if(f){let X=f[0].match(/dir="([^"]*)"/i);X&&(p=X[1]);let Xe=f[0].match(/class="([^"]*)"/i);Xe&&(h=Xe[1]);}let C=!o.includes("motion@latest"),k=o.match(/<meta\s+name="description"\s+content="([^"]*)"/i),S=o.match(/<meta\s+property="og:title"\s+content="([^"]*)"/i),_=o.match(/<meta\s+property="og:description"\s+content="([^"]*)"/i),A=o.match(/<meta\s+property="og:image"\s+content="([^"]*)"/i),I=o.match(/<link\s+rel="canonical"\s+href="([^"]*)"/i),ee=o.match(/noindex/i),de=o.match(/nofollow/i),E={};d&&(E.page_title=d),k&&k[1]&&(E.meta_description=k[1]),S&&S[1]&&(E.social_title=S[1]),_&&_[1]&&(E.social_description=_[1]),A&&A[1]&&(E.social_image=A[1]),I&&I[1]&&(E.canonical_url=I[1]),E.noindex=!!ee,E.nofollow=!!de;let te={theme:{mode:g?"Dark":"Light",direction:p,main_classes:h,animations_deactivated:C},should_convert:true},oe=m||v?{}:void 0;return oe&&(m&&(oe.header=m),v&&(oe.footer=v)),{html:c,globalHeader:a.globalHeader,globalFooter:a.globalFooter,templateName:d,headerCode:m||void 0,footerCode:v||void 0,settings:te,seo:E,customCodes:oe}}var Q=P.join(De.tmpdir(),"lindoai-pages-preview.pid"),ge=P.join(De.tmpdir(),"lindoai-pages-preview.port");function We(){let o=new Command("pages").description("Page management operations");return o.command("list").description("List all pages for a website").requiredOption("-w, --website <id>","Website ID").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.list(e.website,{page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else {let i=t.result;if(i?.list&&i.list.length>0){console.log(`
53
+ Pages:`),console.log("------");for(let a of i.list)console.log(` ID: ${a.page_id}`),console.log(` Name: ${a.name??"N/A"}`),console.log(` Path: ${a.path??"N/A"}`),console.log(` Status: ${a.status??"N/A"}`),console.log(` Published: ${a.publish_date?"Yes":"No"}`),console.log("");console.log(`Total: ${i.total??i.list.length}`);}else r("No pages found");}}catch(t){z(t);}}),o.command("get").description("Get details of a specific page").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Page ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.get(e.website,e.id);if(e.format==="json")y(t,"json");else {let i=t.result;i?(console.log(`
54
+ Page Details:`),console.log("-------------"),console.log(` ID: ${i.page_id}`),console.log(` Name: ${i.name??"N/A"}`),console.log(` Path: ${i.path??"N/A"}`),console.log(` Status: ${i.status??"N/A"}`),console.log(` Published: ${i.publish_date?"Yes":"No"}`),console.log(` Created: ${i.created_date??"N/A"}`)):l("Page not found");}}catch(t){z(t);}}),o.command("unpublish").description("Unpublish a page").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Page ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.unpublish(e.website,e.id);e.format==="json"?y(t,"json"):t.success?(w("Page unpublished successfully"),console.log(` Page ID: ${t.result?.page_id}`)):l("Failed to unpublish page");}catch(t){z(t);}}),o.command("delete").description("Delete a page").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Page ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=Y();try{let t=await n.pages.deletePage(e.website,e.id);if(e.format==="json")y(t,"json");else if(t.success){if(w("Page deleted successfully"),console.log(` Page ID: ${t.result?.page_id}`),t.result?.warnings&&t.result.warnings.length>0){console.log(" Warnings:");for(let i of t.result.warnings)console.log(` - ${i}`);}}else l("Failed to delete page");}catch(t){z(t);}}),o.command("create-empty").description("Create a new empty page with starter template and live preview").argument("<website_id>","Website ID").argument("<path>","URL path for the page (e.g., /about-us)").option("--title <title>","Page title","New Page").option("--file <path>","Output file path","./page.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=Y();try{r("Fetching website details...");let c=(await i.websites.getDetails(e)).result,s=c?.theme||{},d=c?.global_header||null,m=c?.global_footer||null,v=c?.custom_codes||{header:null,footer:null},b={font:s.font,title_font:s.title_font},u=t.title,x=`<!-- Hero Section -->
55
55
  <section class="relative min-h-[80vh] flex items-center justify-center bg-gradient-to-br from-neutral-50 to-neutral-100 dark:from-neutral-900 dark:to-neutral-800">
56
56
  <div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
57
57
  <h1 class="text-4xl sm:text-5xl lg:text-6xl font-bold text-neutral-900 dark:text-white mb-6">
@@ -127,7 +127,7 @@ Page Details:`),console.log("-------------"),console.log(` ID: ${i.page_id}`),c
127
127
  Contact Us
128
128
  </a>
129
129
  </div>
130
- </section>`,g={theme:{mode:"Dark",direction:"ltr",main_classes:"bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-100",animations_deactivated:!1},should_convert:!0},f={page_title:u,meta_description:"",social_title:u,social_description:"",noindex:!1,nofollow:!1};a("Creating page...");let p=await i.pages.create(e,{html:x,path:n,settings:g,template_name:u,seo:f});p.success||(l("Failed to create page"),process.exit(1));let h=p.result.page_id,C=p.result.published_url;w(`Page created: ${h}`),C&&console.log(` Published URL: ${C}`);let k=ue(b),S=Ie(x,d??void 0,m??void 0),_={header:v.header||"",footer:v.footer||""},A=`<!DOCTYPE html>
130
+ </section>`,g={theme:{mode:"Dark",direction:"ltr",main_classes:"bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-100",animations_deactivated:!1},should_convert:!0},f={page_title:u,meta_description:"",social_title:u,social_description:"",noindex:!1,nofollow:!1};r("Creating page...");let p=await i.pages.create(e,{html:x,path:n,settings:g,template_name:u,seo:f});p.success||(l("Failed to create page"),process.exit(1));let h=p.result.page_id,C=p.result.published_url;w(`Page created: ${h}`),C&&console.log(` Published URL: ${C}`);let k=ue(b),S=Ie(x,d??void 0,m??void 0),_={header:v.header||"",footer:v.footer||""},A=`<!DOCTYPE html>
131
131
  <html class="dark" lang="en">
132
132
  <head>
133
133
  <meta charset="UTF-8">
@@ -176,7 +176,7 @@ ${S}
176
176
  ${_.footer}
177
177
  <!-- End Page Custom Code (Footer) -->
178
178
  </body>
179
- </html>`,I=P.resolve(t.file);$.writeFileSync(I,A,"utf-8"),w(`HTML saved to ${I}`),await dt(),t.background?await mt(I):await pt(I),console.log(""),a(`To save changes: lindoai pages update ${e} ${h} --html-file ${t.file}`);}catch(r){z(r);}}),o.command("edit").description("Edit a page with live preview").argument("<website_id>","Website ID").argument("<page_id>","Page ID").option("--file <path>","Output file path","./page.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=Y();try{a("Fetching page HTML...");let r=await i.pages.getHtml(e,n);r.result||(l("Page not found"),process.exit(1));let c=r.result.html;c||(l("Page has no HTML content"),a("Make sure the page has been created with HTML content"),process.exit(1)),a("Fetching website details...");let d=(await i.websites.getDetails(e)).result,m=d?.theme||{},v=d?.global_header||null,b=d?.global_footer||null,u=d?.custom_codes||{header:null,footer:null},x=r.result.name||"Page",g=r.result.seo||{},f=r.result.settings||{},p=r.result.custom_codes||{},h={header:p.header||u.header||"",footer:p.footer||u.footer||""},C=f.theme||{},k=C.mode!=="Light",S=C.direction||"ltr",_=C.main_classes||"",A=C.animations_deactivated||!1,I={font:C.font||m.font,title_font:C.title_font||m.title_font},ee=ue(I),E=be(c).mainContent,te=Ie(E,v??void 0,b??void 0),oe=`<!DOCTYPE html>
179
+ </html>`,I=P.resolve(t.file);$.writeFileSync(I,A,"utf-8"),w(`HTML saved to ${I}`),await dt(),t.background?await mt(I):await pt(I),console.log(""),r(`To save changes: lindoai pages update ${e} ${h} --html-file ${t.file}`);}catch(a){z(a);}}),o.command("edit").description("Edit a page with live preview").argument("<website_id>","Website ID").argument("<page_id>","Page ID").option("--file <path>","Output file path","./page.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=Y();try{r("Fetching page HTML...");let a=await i.pages.getHtml(e,n);a.result||(l("Page not found"),process.exit(1));let c=a.result.html;c||(l("Page has no HTML content"),r("Make sure the page has been created with HTML content"),process.exit(1)),r("Fetching website details...");let d=(await i.websites.getDetails(e)).result,m=d?.theme||{},v=d?.global_header||null,b=d?.global_footer||null,u=d?.custom_codes||{header:null,footer:null},x=a.result.name||"Page",g=a.result.seo||{},f=a.result.settings||{},p=a.result.custom_codes||{},h={header:p.header||u.header||"",footer:p.footer||u.footer||""},C=f.theme||{},k=C.mode!=="Light",S=C.direction||"ltr",_=C.main_classes||"",A=C.animations_deactivated||!1,I={font:C.font||m.font,title_font:C.title_font||m.title_font},ee=ue(I),E=be(c).mainContent,te=Ie(E,v??void 0,b??void 0),oe=`<!DOCTYPE html>
180
180
  <html class="${k?"dark":""}" lang="en">
181
181
  <head>
182
182
  <meta charset="UTF-8">
@@ -232,10 +232,10 @@ ${te}
232
232
  ${h.footer}
233
233
  <!-- End Page Custom Code (Footer) -->
234
234
  </body>
235
- </html>`,X=P.resolve(t.file);$.writeFileSync(X,oe,"utf-8"),w(`HTML saved to ${X}`),await dt(),t.background?await mt(X):await pt(X);}catch(r){z(r);}}),o.command("update").description("Update a page from HTML file (note: global header/footer changes are page-specific only)").argument("<website_id>","Website ID").argument("<page_id>","Page ID").option("--html-file <path>","Path to local HTML file to upload").option("--upload-assets","Upload local images/assets to CDN before publishing").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=Y();try{t.htmlFile||(l("--html-file option is required"),a("Usage: lindoai pages update <website_id> <page_id> --html-file <path>"),process.exit(1));let r=P.resolve(t.htmlFile);$.existsSync(r)||(l(`File not found: ${r}`),process.exit(1));let c=$.readFileSync(r,"utf-8");if(a(`Read ${c.length} bytes from ${r}`),t.uploadAssets){let u=P.dirname(r);a("Processing local assets...");let x=await Le(c,u,e,i,g=>a(g),r);x.uploadedCount>0&&(c=x.html,w(`Uploaded ${x.uploadedCount} asset(s) to CDN`),x.failedCount>0&&a(`Warning: ${x.failedCount} asset(s) failed to upload`),x.sourceFileUpdated&&a("Source file updated with CDN URLs (prevents duplicate uploads)"));}let s=Re(c);s.globalHeader&&a("Detected global header section"),s.globalFooter&&a("Detected global footer section"),s.templateName&&a(`Extracted page title: ${s.templateName}`),s.headerCode&&a("Extracted header custom code"),s.footerCode&&a("Extracted footer custom code"),Object.keys(s.seo).length>2&&a("Extracted SEO metadata");let d=await i.pages.get(e,n);d.result||(l("Page not found"),process.exit(1));let m=d.result.path,v={...d.result.settings||{},theme:{...d.result.settings?.theme||{},...s.settings.theme},should_convert:!0};a("Updating page...");let b=await i.pages.publish(e,n,{html:s.html,path:m,settings:v,template_name:s.templateName,custom_codes:s.customCodes,seo:Object.keys(s.seo).length>0?s.seo:void 0,global_header:s.globalHeader,global_footer:s.globalFooter});t.format==="json"?y(b,"json"):b.success?(w("Page updated successfully"),console.log(` Page ID: ${b.result?.page_id}`),b.result?.published_url&&console.log(` Published URL: ${b.result.published_url}`)):l("Failed to update page");}catch(r){z(r);}}),o.command("stop-preview").description("Stop the background preview server").action(async()=>{try{if(!$.existsSync(Q)){a("No preview server is running");return}let e=parseInt($.readFileSync(Q,"utf-8").trim(),10);if(isNaN(e)){l("Invalid PID file"),Me();return}try{process.kill(e,"SIGTERM"),w(`Preview server (PID ${e}) stopped`);}catch(n){n.code==="ESRCH"?a("Preview server process not found (may have already stopped)"):l(`Failed to stop preview server: ${n.message}`);}Me();}catch(e){e instanceof Error?l(e.message):l("An unexpected error occurred"),process.exit(1);}}),o.command("create-with-content").description("Create pages from HTML files in a local folder with automatic asset upload").argument("<website_id>","Website ID").argument("<folder>","Path to folder containing HTML files").option("--path-prefix <prefix>","URL path prefix for pages (e.g., /blog)","").option("--dry-run","Show what would be created without actually creating").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=Y();try{let r=P.resolve(n);$.existsSync(r)||(l(`Folder not found: ${r}`),process.exit(1)),$.statSync(r).isDirectory()||(l(`Not a directory: ${r}`),process.exit(1));let d=$.readdirSync(r).filter(u=>u.endsWith(".html"));if(d.length===0&&(l("No HTML files found in folder"),process.exit(1)),a(`Found ${d.length} HTML file(s) to create`),t.dryRun){console.log(`
236
- Dry run - would create:`);for(let u of d){let x=u==="index.html"?t.pathPrefix||"/":`${t.pathPrefix}/${u.replace(".html","")}`;console.log(` ${u} \u2192 ${x}`);}return}let m=[];for(let u of d){let x=P.join(r,u),g=$.readFileSync(x,"utf-8");a(`
237
- Processing: ${u}`),a("Uploading local assets...");let f=await Le(g,r,e,i,C=>a(` ${C}`));f.uploadedCount>0&&(g=f.html,w(` Uploaded ${f.uploadedCount} asset(s)`));let p=Re(g,u.replace(".html",""));p.globalHeader&&a(" Detected global header section"),p.globalFooter&&a(" Detected global footer section"),p.templateName&&a(` Extracted page title: ${p.templateName}`),p.headerCode&&a(" Extracted header custom code"),p.footerCode&&a(" Extracted footer custom code"),Object.keys(p.seo).length>2&&a(" Extracted SEO metadata");let h=u==="index.html"?t.pathPrefix||"/":`${t.pathPrefix}/${u.replace(".html","")}`;try{a(` Creating page at ${h}...`);let C=await i.pages.create(e,{html:p.html,path:h,template_name:p.templateName,seo:Object.keys(p.seo).length>0?p.seo:void 0,settings:p.settings,custom_codes:p.customCodes,global_header:p.globalHeader,global_footer:p.globalFooter});if(C.success){let k=C.result.published_url;w(` Created: ${u} \u2192 ${h} (${C.result.page_id})`),k&&console.log(` URL: ${k}`),m.push({file:u,pageId:C.result.page_id,success:!0});}else l(` Failed to create: ${u}`),m.push({file:u,success:!1,error:"API returned failure"});}catch(C){let k=C instanceof Error?C.message:"Unknown error";l(` Failed to create: ${u} - ${k}`),m.push({file:u,success:!1,error:k});}}console.log(`
238
- --- Summary ---`);let v=m.filter(u=>u.success).length,b=m.filter(u=>!u.success).length;if(t.format==="json")y({results:m,successCount:v,failCount:b},"json");else if(console.log(`Created: ${v}/${m.length} pages`),b>0){console.log(`Failed: ${b} pages`);for(let u of m.filter(x=>!x.success))console.log(` - ${u.file}: ${u.error}`);}}catch(r){z(r);}}),o}function Y(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function z(o){o instanceof AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Me(){try{$.existsSync(Q)&&$.unlinkSync(Q);}catch{}try{$.existsSync(ge)&&$.unlinkSync(ge);}catch{}}async function dt(){if($.existsSync(Q)){try{let o=parseInt($.readFileSync(Q,"utf-8").trim(),10);if(!isNaN(o))try{process.kill(o,"SIGTERM"),a(`Terminated existing preview server (PID ${o})`),await new Promise(e=>setTimeout(e,500));}catch{}}catch{}Me();}}async function mt(o){let e=P.resolve(o),n=`
235
+ </html>`,X=P.resolve(t.file);$.writeFileSync(X,oe,"utf-8"),w(`HTML saved to ${X}`),await dt(),t.background?await mt(X):await pt(X);}catch(a){z(a);}}),o.command("update").description("Update a page from HTML file (note: global header/footer changes are page-specific only)").argument("<website_id>","Website ID").argument("<page_id>","Page ID").option("--html-file <path>","Path to local HTML file to upload").option("--upload-assets","Upload local images/assets to CDN before publishing").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=Y();try{t.htmlFile||(l("--html-file option is required"),r("Usage: lindoai pages update <website_id> <page_id> --html-file <path>"),process.exit(1));let a=P.resolve(t.htmlFile);$.existsSync(a)||(l(`File not found: ${a}`),process.exit(1));let c=$.readFileSync(a,"utf-8");if(r(`Read ${c.length} bytes from ${a}`),t.uploadAssets){let u=P.dirname(a);r("Processing local assets...");let x=await Le(c,u,e,i,g=>r(g),a);x.uploadedCount>0&&(c=x.html,w(`Uploaded ${x.uploadedCount} asset(s) to CDN`),x.failedCount>0&&r(`Warning: ${x.failedCount} asset(s) failed to upload`),x.sourceFileUpdated&&r("Source file updated with CDN URLs (prevents duplicate uploads)"));}let s=Re(c);s.globalHeader&&r("Detected global header section"),s.globalFooter&&r("Detected global footer section"),s.templateName&&r(`Extracted page title: ${s.templateName}`),s.headerCode&&r("Extracted header custom code"),s.footerCode&&r("Extracted footer custom code"),Object.keys(s.seo).length>2&&r("Extracted SEO metadata");let d=await i.pages.get(e,n);d.result||(l("Page not found"),process.exit(1));let m=d.result.path,v={...d.result.settings||{},theme:{...d.result.settings?.theme||{},...s.settings.theme},should_convert:!0};r("Updating page...");let b=await i.pages.publish(e,n,{html:s.html,path:m,settings:v,template_name:s.templateName,custom_codes:s.customCodes,seo:Object.keys(s.seo).length>0?s.seo:void 0,global_header:s.globalHeader,global_footer:s.globalFooter});t.format==="json"?y(b,"json"):b.success?(w("Page updated successfully"),console.log(` Page ID: ${b.result?.page_id}`),b.result?.published_url&&console.log(` Published URL: ${b.result.published_url}`)):l("Failed to update page");}catch(a){z(a);}}),o.command("stop-preview").description("Stop the background preview server").action(async()=>{try{if(!$.existsSync(Q)){r("No preview server is running");return}let e=parseInt($.readFileSync(Q,"utf-8").trim(),10);if(isNaN(e)){l("Invalid PID file"),Me();return}try{process.kill(e,"SIGTERM"),w(`Preview server (PID ${e}) stopped`);}catch(n){n.code==="ESRCH"?r("Preview server process not found (may have already stopped)"):l(`Failed to stop preview server: ${n.message}`);}Me();}catch(e){e instanceof Error?l(e.message):l("An unexpected error occurred"),process.exit(1);}}),o.command("create-with-content").description("Create pages from HTML files in a local folder with automatic asset upload").argument("<website_id>","Website ID").argument("<folder>","Path to folder containing HTML files").option("--path-prefix <prefix>","URL path prefix for pages (e.g., /blog)","").option("--dry-run","Show what would be created without actually creating").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=Y();try{let a=P.resolve(n);$.existsSync(a)||(l(`Folder not found: ${a}`),process.exit(1)),$.statSync(a).isDirectory()||(l(`Not a directory: ${a}`),process.exit(1));let d=$.readdirSync(a).filter(u=>u.endsWith(".html"));if(d.length===0&&(l("No HTML files found in folder"),process.exit(1)),r(`Found ${d.length} HTML file(s) to create`),t.dryRun){console.log(`
236
+ Dry run - would create:`);for(let u of d){let x=u==="index.html"?t.pathPrefix||"/":`${t.pathPrefix}/${u.replace(".html","")}`;console.log(` ${u} \u2192 ${x}`);}return}let m=[];for(let u of d){let x=P.join(a,u),g=$.readFileSync(x,"utf-8");r(`
237
+ Processing: ${u}`),r("Uploading local assets...");let f=await Le(g,a,e,i,C=>r(` ${C}`));f.uploadedCount>0&&(g=f.html,w(` Uploaded ${f.uploadedCount} asset(s)`));let p=Re(g,u.replace(".html",""));p.globalHeader&&r(" Detected global header section"),p.globalFooter&&r(" Detected global footer section"),p.templateName&&r(` Extracted page title: ${p.templateName}`),p.headerCode&&r(" Extracted header custom code"),p.footerCode&&r(" Extracted footer custom code"),Object.keys(p.seo).length>2&&r(" Extracted SEO metadata");let h=u==="index.html"?t.pathPrefix||"/":`${t.pathPrefix}/${u.replace(".html","")}`;try{r(` Creating page at ${h}...`);let C=await i.pages.create(e,{html:p.html,path:h,template_name:p.templateName,seo:Object.keys(p.seo).length>0?p.seo:void 0,settings:p.settings,custom_codes:p.customCodes,global_header:p.globalHeader,global_footer:p.globalFooter});if(C.success){let k=C.result.published_url;w(` Created: ${u} \u2192 ${h} (${C.result.page_id})`),k&&console.log(` URL: ${k}`),m.push({file:u,pageId:C.result.page_id,success:!0});}else l(` Failed to create: ${u}`),m.push({file:u,success:!1,error:"API returned failure"});}catch(C){let k=C instanceof Error?C.message:"Unknown error";l(` Failed to create: ${u} - ${k}`),m.push({file:u,success:!1,error:k});}}console.log(`
238
+ --- Summary ---`);let v=m.filter(u=>u.success).length,b=m.filter(u=>!u.success).length;if(t.format==="json")y({results:m,successCount:v,failCount:b},"json");else if(console.log(`Created: ${v}/${m.length} pages`),b>0){console.log(`Failed: ${b} pages`);for(let u of m.filter(x=>!x.success))console.log(` - ${u.file}: ${u.error}`);}}catch(a){z(a);}}),o}function Y(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function z(o){o instanceof AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Me(){try{$.existsSync(Q)&&$.unlinkSync(Q);}catch{}try{$.existsSync(ge)&&$.unlinkSync(ge);}catch{}}async function dt(){if($.existsSync(Q)){try{let o=parseInt($.readFileSync(Q,"utf-8").trim(),10);if(!isNaN(o))try{process.kill(o,"SIGTERM"),r(`Terminated existing preview server (PID ${o})`),await new Promise(e=>setTimeout(e,500));}catch{}}catch{}Me();}}async function mt(o){let e=P.resolve(o),n=`
239
239
  const http = require('node:http');
240
240
  const fs = require('node:fs');
241
241
  const path = require('node:path');
@@ -355,9 +355,9 @@ Processing: ${u}`),a("Uploading local assets...");let f=await Le(g,r,e,i,C=>a(`
355
355
  });
356
356
  } catch {}
357
357
  });
358
- `,t=spawn(process.execPath,["-e",n],{detached:true,stdio:"ignore"});t.unref();let i=null;for(let s=0;s<50;s++)if(await new Promise(d=>setTimeout(d,100)),$.existsSync(ge))try{if(i=parseInt($.readFileSync(ge,"utf-8").trim(),10),!isNaN(i))break}catch{}i||(l("Failed to start preview server"),process.exit(1));let r=`http://127.0.0.1:${i}/`;await G(r)||a(`Could not open browser. Visit: ${r}`),w("Preview server started in background"),console.log(` URL: ${r}`),console.log(` PID: ${t.pid}`),console.log(""),a("To update the page: lindoai pages update <website_id> <page_id> --html-file <path>"),a("To stop the server: lindoai pages stop-preview");}async function pt(o){let{startLivePreviewServer:e}=await Promise.resolve().then(()=>(Ue(),Ne));a("Starting preview server...");let n=await e(o),t=`http://127.0.0.1:${n}/`;$.writeFileSync(Q,process.pid.toString(),"utf-8"),$.writeFileSync(ge,n.toString(),"utf-8"),await G(t)||a(`Could not open browser. Visit: ${t}`),w("Preview server started"),console.log(` URL: ${t}`),console.log(""),a("Press Ctrl+C to stop the server"),a("Edit the HTML file and save to see changes in the browser");}var Z=P.join(De.tmpdir(),"lindoai-blogs-preview.pid"),he=P.join(De.tmpdir(),"lindoai-blogs-preview.port");function qe(){let o=new Command("blogs").description("Blog management operations");return o.command("list").description("List all blogs for a website").requiredOption("-w, --website <id>","Website ID").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.list(e.website,{page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else {let i=t.result;if(i?.list&&i.list.length>0){console.log(`
359
- Blogs:`),console.log("------");for(let r of i.list)console.log(` ID: ${r.blog_id}`),console.log(` Name: ${r.name??"N/A"}`),console.log(` Path: ${r.path??"N/A"}`),console.log(` Status: ${r.status??"N/A"}`),console.log(` Published: ${r.publish_date?new Date(r.publish_date*1e3).toISOString():"No"}`),console.log("");console.log(`Total: ${i.total??i.list.length}`);}else a("No blogs found");}}catch(t){J(t);}}),o.command("get").description("Get details of a specific blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.get(e.website,e.id);if(e.format==="json")y(t,"json");else {let i=t.result;i?(console.log(`
360
- Blog Details:`),console.log("-------------"),console.log(` ID: ${i.blog_id}`),console.log(` Name: ${i.name??"N/A"}`),console.log(` Path: ${i.path??"N/A"}`),console.log(` Status: ${i.status??"N/A"}`),console.log(` Published: ${i.publish_date?new Date(i.publish_date*1e3).toISOString():"No"}`),console.log(` Created: ${i.created_date??"N/A"}`)):l("Blog not found");}}catch(t){J(t);}}),o.command("publish").description("Publish a blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.publish(e.website,e.id);e.format==="json"?y(t,"json"):t.success?(w("Blog published successfully"),console.log(` Blog ID: ${t.result?.blog_id}`),console.log(` Published at: ${t.result?.publish_date?new Date(t.result.publish_date*1e3).toISOString():"N/A"}`),t.result?.published_url&&console.log(` Published URL: ${t.result.published_url}`)):l("Failed to publish blog");}catch(t){J(t);}}),o.command("unpublish").description("Unpublish a blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.unpublish(e.website,e.id);e.format==="json"?y(t,"json"):t.success?(w("Blog unpublished successfully"),console.log(` Blog ID: ${t.result?.blog_id}`)):l("Failed to unpublish blog");}catch(t){J(t);}}),o.command("delete").description("Delete a blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.delete(e.website,e.id);if(e.format==="json")y(t,"json");else if(t.success){if(w("Blog deleted successfully"),console.log(` Blog ID: ${t.result?.blog_id}`),t.result?.warnings&&t.result.warnings.length>0){console.log(" Warnings:");for(let i of t.result.warnings)console.log(` - ${i}`);}}else l("Failed to delete blog");}catch(t){J(t);}}),o.command("edit").description("Edit a blog with live preview").argument("<website_id>","Website ID").argument("<blog_id>","Blog ID").option("--file <path>","Output file path","./blog.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=V();try{a("Fetching blog content...");let r=await i.blogs.getHtml(e,n);r.result||(l("Blog not found"),process.exit(1));let c=r.result,s=await i.websites.getDetails(e);s.result||(l("Website not found"),process.exit(1));let d=s.result,m=d,v=m?.theme||{},b=m?.custom_codes||{header:null,footer:null},u={font:v.font,title_font:v.title_font},x=c.seo||{},g=c.blog_settings||{},f=c.blog_content||"<p>Start writing your blog content here...</p>",p=ht({seo:x,blogSettings:g,blogContent:f,websiteName:d.business_name||"Blog",blogPath:v.blog_path||"blog",websiteTheme:u,customCodes:{header:b.header||void 0,footer:b.footer||void 0}}),h=P.resolve(t.file);$.writeFileSync(h,p,"utf-8"),w(`HTML saved to ${h}`),await ut(),t.background?await ft(h):await gt(h),console.log(""),a(`To save changes: lindoai blogs update ${e} ${n} --html-file ${t.file}`);}catch(r){J(r);}}),o.command("update").description("Update a blog from HTML file").argument("<website_id>","Website ID").argument("<blog_id>","Blog ID").option("--html-file <path>","Path to local HTML file").option("--md-file <path>","Path to local Markdown file").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=V();try{!t.htmlFile&&!t.mdFile&&(l("Either --html-file or --md-file option is required"),a("Usage: lindoai blogs update <website_id> <blog_id> --html-file <path>"),a(" or: lindoai blogs update <website_id> <blog_id> --md-file <path>"),process.exit(1));let r,c={},s={};if(t.mdFile){let g=P.resolve(t.mdFile);$.existsSync(g)||(l(`File not found: ${g}`),process.exit(1));let f=$.readFileSync(g,"utf-8");a(`Read ${f.length} bytes from ${g}`);let{content:p,frontmatter:h}=ko(f);r=_o(p),h.title&&(c.page_title=h.title),h.description&&(c.meta_description=h.description),h.image&&(c.social_image=h.image),h.author&&(s.author=h.author),h.excerpt&&(s.excerpt=h.excerpt),h.category&&(s.category=h.category),h.date&&(s.publish_date=h.date);}else {let g=P.resolve(t.htmlFile);$.existsSync(g)||(l(`File not found: ${g}`),process.exit(1));let f=$.readFileSync(g,"utf-8");a(`Read ${f.length} bytes from ${g}`);let p=f.match(/<article[^>]*class="[^"]*prose[^"]*"[^>]*>([\s\S]*?)<\/article>/i);r=p?p[1].trim():"",r||(l("Could not extract blog content from HTML"),a('Make sure the blog content is inside <article class="...prose...">...</article>'),process.exit(1));let h=f.match(/<title>([^<]*)<\/title>/i),C=f.match(/<meta\s+name="description"\s+content="([^"]*)"/i),k=f.match(/<meta\s+property="og:image"\s+content="([^"]*)"/i);h&&(c.page_title=h[1].trim()),C&&(c.meta_description=C[1]),k&&(c.social_image=k[1]);let S=f.match(/id="blog-author-display"[^>]*>([\s\S]*?)<\/span>/i),_=f.match(/class="[^"]*bg-blue-500\/10[^"]*"[^>]*>([^<]*)</i),A=f.match(/class="[^"]*border-l-4 border-blue-500[^"]*"[^>]*>([\s\S]*?)<\/div>/i),I=f.match(/<time[^>]*>([^<]*)<\/time>/i),ee=f.match(/<span>(\d+\s*min\s*read)<\/span>/i),de=f.match(/<div class="aspect-video[^"]*"[^>]*>\s*<img[^>]*src="([^"]*)"/i);if(S){let te=S[1].replace(/<[^>]*>/g,"").trim();te&&(s.author=te);}_&&(s.category=_[1].trim()),A&&(s.excerpt=A[1].trim()),I&&(s.publish_date=I[1].trim()),ee&&(s.read_time=ee[1].trim()),de&&!c.social_image&&(c.social_image=de[1]),a("Extracted blog content and metadata");}let d=await i.blogs.get(e,n);d.result||(l("Blog not found"),process.exit(1));let m=d.result,v=m.path,b={page_title:c.page_title||m.seo?.page_title||"Untitled",meta_description:c.meta_description||m.seo?.meta_description,social_title:c.social_title||m.seo?.social_title,social_description:c.social_description||m.seo?.social_description,social_image:c.social_image||m.seo?.social_image},u={author:s.author||m.blog_settings?.author||"Anonymous",excerpt:s.excerpt||m.blog_settings?.excerpt,category:s.category||m.blog_settings?.category,publish_date:s.publish_date||m.blog_settings?.publish_date,read_time:s.read_time||m.blog_settings?.read_time,author_image:s.author_image||m.blog_settings?.author_image};a("Updating blog...");let x=await i.blogs.publish(e,n,{path:v,blog_content:r,seo:b,blog_settings:u});t.format==="json"?y(x,"json"):x.success?(w("Blog updated successfully"),console.log(` Blog ID: ${x.result?.blog_id}`),x.result?.published_url&&console.log(` Published URL: ${x.result.published_url}`)):l("Failed to update blog");}catch(r){J(r);}}),o.command("create").description("Create a new blog with live preview").argument("<website_id>","Website ID").argument("<path>","URL path for the blog (e.g., /blog/my-first-post)").option("--title <title>","Blog title","New Blog Post").option("--author <author>","Author name","Anonymous").option("--file <path>","Output file path","./blog.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=V();try{let r=await i.websites.getDetails(e);r.result||(l("Website not found"),process.exit(1));let c=r.result,s=c,d=s?.theme||{},m=s?.custom_codes||{header:null,footer:null},v={font:d.font,title_font:d.title_font},b=t.title,u=t.author,x=new Date().toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"}),g=`<h2>Introduction</h2>
358
+ `,t=spawn(process.execPath,["-e",n],{detached:true,stdio:"ignore"});t.unref();let i=null;for(let s=0;s<50;s++)if(await new Promise(d=>setTimeout(d,100)),$.existsSync(ge))try{if(i=parseInt($.readFileSync(ge,"utf-8").trim(),10),!isNaN(i))break}catch{}i||(l("Failed to start preview server"),process.exit(1));let a=`http://127.0.0.1:${i}/`;await G(a)||r(`Could not open browser. Visit: ${a}`),w("Preview server started in background"),console.log(` URL: ${a}`),console.log(` PID: ${t.pid}`),console.log(""),r("To update the page: lindoai pages update <website_id> <page_id> --html-file <path>"),r("To stop the server: lindoai pages stop-preview");}async function pt(o){let{startLivePreviewServer:e}=await Promise.resolve().then(()=>(Ue(),Ne));r("Starting preview server...");let n=await e(o),t=`http://127.0.0.1:${n}/`;$.writeFileSync(Q,process.pid.toString(),"utf-8"),$.writeFileSync(ge,n.toString(),"utf-8"),await G(t)||r(`Could not open browser. Visit: ${t}`),w("Preview server started"),console.log(` URL: ${t}`),console.log(""),r("Press Ctrl+C to stop the server"),r("Edit the HTML file and save to see changes in the browser");}var Z=P.join(De.tmpdir(),"lindoai-blogs-preview.pid"),he=P.join(De.tmpdir(),"lindoai-blogs-preview.port");function qe(){let o=new Command("blogs").description("Blog management operations");return o.command("list").description("List all blogs for a website").requiredOption("-w, --website <id>","Website ID").option("-p, --page <page>","Page number","1").option("-s, --search <search>","Search term").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.list(e.website,{page:parseInt(e.page,10),search:e.search});if(e.format==="json")y(t,"json");else {let i=t.result;if(i?.list&&i.list.length>0){console.log(`
359
+ Blogs:`),console.log("------");for(let a of i.list)console.log(` ID: ${a.blog_id}`),console.log(` Name: ${a.name??"N/A"}`),console.log(` Path: ${a.path??"N/A"}`),console.log(` Status: ${a.status??"N/A"}`),console.log(` Published: ${a.publish_date?new Date(a.publish_date*1e3).toISOString():"No"}`),console.log("");console.log(`Total: ${i.total??i.list.length}`);}else r("No blogs found");}}catch(t){J(t);}}),o.command("get").description("Get details of a specific blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.get(e.website,e.id);if(e.format==="json")y(t,"json");else {let i=t.result;i?(console.log(`
360
+ Blog Details:`),console.log("-------------"),console.log(` ID: ${i.blog_id}`),console.log(` Name: ${i.name??"N/A"}`),console.log(` Path: ${i.path??"N/A"}`),console.log(` Status: ${i.status??"N/A"}`),console.log(` Published: ${i.publish_date?new Date(i.publish_date*1e3).toISOString():"No"}`),console.log(` Created: ${i.created_date??"N/A"}`)):l("Blog not found");}}catch(t){J(t);}}),o.command("publish").description("Publish a blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.publish(e.website,e.id);e.format==="json"?y(t,"json"):t.success?(w("Blog published successfully"),console.log(` Blog ID: ${t.result?.blog_id}`),console.log(` Published at: ${t.result?.publish_date?new Date(t.result.publish_date*1e3).toISOString():"N/A"}`),t.result?.published_url&&console.log(` Published URL: ${t.result.published_url}`)):l("Failed to publish blog");}catch(t){J(t);}}),o.command("unpublish").description("Unpublish a blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.unpublish(e.website,e.id);e.format==="json"?y(t,"json"):t.success?(w("Blog unpublished successfully"),console.log(` Blog ID: ${t.result?.blog_id}`)):l("Failed to unpublish blog");}catch(t){J(t);}}),o.command("delete").description("Delete a blog").requiredOption("-w, --website <id>","Website ID").requiredOption("-i, --id <id>","Blog ID").option("-f, --format <format>","Output format (json, table)","table").action(async e=>{let n=V();try{let t=await n.blogs.delete(e.website,e.id);if(e.format==="json")y(t,"json");else if(t.success){if(w("Blog deleted successfully"),console.log(` Blog ID: ${t.result?.blog_id}`),t.result?.warnings&&t.result.warnings.length>0){console.log(" Warnings:");for(let i of t.result.warnings)console.log(` - ${i}`);}}else l("Failed to delete blog");}catch(t){J(t);}}),o.command("edit").description("Edit a blog with live preview").argument("<website_id>","Website ID").argument("<blog_id>","Blog ID").option("--file <path>","Output file path","./blog.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=V();try{r("Fetching blog content...");let a=await i.blogs.getHtml(e,n);a.result||(l("Blog not found"),process.exit(1));let c=a.result,s=await i.websites.getDetails(e);s.result||(l("Website not found"),process.exit(1));let d=s.result,m=d,v=m?.theme||{},b=m?.custom_codes||{header:null,footer:null},u={font:v.font,title_font:v.title_font},x=c.seo||{},g=c.blog_settings||{},f=c.blog_content||"<p>Start writing your blog content here...</p>",p=ht({seo:x,blogSettings:g,blogContent:f,websiteName:d.business_name||"Blog",blogPath:v.blog_path||"blog",websiteTheme:u,customCodes:{header:b.header||void 0,footer:b.footer||void 0}}),h=P.resolve(t.file);$.writeFileSync(h,p,"utf-8"),w(`HTML saved to ${h}`),await ut(),t.background?await ft(h):await gt(h),console.log(""),r(`To save changes: lindoai blogs update ${e} ${n} --html-file ${t.file}`);}catch(a){J(a);}}),o.command("update").description("Update a blog from HTML or Markdown file. Blog metadata (excerpt, social image, author, etc.) can be set via CLI flags, extracted from HTML meta tags/structure, or from Markdown frontmatter. CLI flags take highest priority.").argument("<website_id>","Website ID").argument("<blog_id>","Blog ID").option("--html-file <path>",'Path to local HTML file (extracts content from <article class="prose">)').option("--md-file <path>","Path to local Markdown file (supports frontmatter for metadata)").option("--excerpt <text>","Blog excerpt/summary shown in blog listings and previews").option("--social-image <url>","Social image URL for og:image and twitter:image meta tags (must be a full URL, e.g. https://cdn.ln-cdn.com/...)").option("--author <name>","Author name displayed on the blog post").option("--category <name>","Blog category").option("--date <date>",'Publish date (e.g. "January 15, 2025")').option("--read-time <time>",'Read time (e.g. "5 min read")').option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=V();try{!t.htmlFile&&!t.mdFile&&(l("Either --html-file or --md-file option is required"),r("Usage: lindoai blogs update <website_id> <blog_id> --html-file <path>"),r(" or: lindoai blogs update <website_id> <blog_id> --md-file <path>"),r(""),r("Metadata options (override values extracted from file):"),r(" --excerpt <text> Blog excerpt for listings"),r(" --social-image <url> Social sharing image URL (og:image)"),r(" --author <name> Author name"),r(" --category <name> Blog category"),r(" --date <date> Publish date"),r(' --read-time <time> Read time (e.g. "5 min read")'),r(""),r("For Markdown files, you can also set metadata via frontmatter:"),r(" ---"),r(" title: My Blog Post"),r(" description: A great post"),r(" image: https://cdn.ln-cdn.com/.../hero.jpg"),r(" excerpt: A short summary of the post"),r(" author: John Doe"),r(" category: Tech"),r(" date: January 15, 2025"),r(" ---"),process.exit(1));let a,c={},s={};if(t.mdFile){let g=P.resolve(t.mdFile);$.existsSync(g)||(l(`File not found: ${g}`),process.exit(1));let f=$.readFileSync(g,"utf-8");r(`Read ${f.length} bytes from ${g}`);let{content:p,frontmatter:h}=ko(f);a=_o(p),h.title&&(c.page_title=h.title),h.description&&(c.meta_description=h.description),h.image&&(c.social_image=h.image),h.author&&(s.author=h.author),h.excerpt&&(s.excerpt=h.excerpt),h.category&&(s.category=h.category),h.date&&(s.publish_date=h.date);}else {let g=P.resolve(t.htmlFile);$.existsSync(g)||(l(`File not found: ${g}`),process.exit(1));let f=$.readFileSync(g,"utf-8");r(`Read ${f.length} bytes from ${g}`);let p=f.match(/<article[^>]*class="[^"]*prose[^"]*"[^>]*>([\s\S]*?)<\/article>/i);a=p?p[1].trim():"",a||(l("Could not extract blog content from HTML"),r('Make sure the blog content is inside <article class="...prose...">...</article>'),process.exit(1));let h=f.match(/<title>([^<]*)<\/title>/i),C=f.match(/<meta\s+name="description"\s+content="([^"]*)"/i),k=f.match(/<meta\s+property="og:image"\s+content="([^"]*)"/i);h&&(c.page_title=h[1].trim()),C&&(c.meta_description=C[1]),k&&(c.social_image=k[1]);let S=f.match(/id="blog-author-display"[^>]*>([\s\S]*?)<\/span>/i),_=f.match(/class="[^"]*bg-blue-500\/10[^"]*"[^>]*>([^<]*)</i),A=f.match(/class="[^"]*border-l-4 border-blue-500[^"]*"[^>]*>([\s\S]*?)<\/div>/i),I=f.match(/<time[^>]*>([^<]*)<\/time>/i),ee=f.match(/<span>(\d+\s*min\s*read)<\/span>/i),de=f.match(/<div class="aspect-video[^"]*"[^>]*>\s*<img[^>]*src="([^"]*)"/i);if(S){let te=S[1].replace(/<[^>]*>/g,"").trim();te&&(s.author=te);}_&&(s.category=_[1].trim()),A&&(s.excerpt=A[1].trim()),I&&(s.publish_date=I[1].trim()),ee&&(s.read_time=ee[1].trim()),de&&!c.social_image&&(c.social_image=de[1]),r("Extracted blog content and metadata");}t.socialImage&&(c.social_image=t.socialImage),t.excerpt&&(s.excerpt=t.excerpt),t.author&&(s.author=t.author),t.category&&(s.category=t.category),t.date&&(s.publish_date=t.date),t.readTime&&(s.read_time=t.readTime);let d=await i.blogs.get(e,n);d.result||(l("Blog not found"),process.exit(1));let m=d.result,v=m.path,b={page_title:c.page_title||m.seo?.page_title||"Untitled",meta_description:c.meta_description||m.seo?.meta_description,social_title:c.social_title||m.seo?.social_title,social_description:c.social_description||m.seo?.social_description,social_image:c.social_image||m.seo?.social_image},u={author:s.author||m.blog_settings?.author||"Anonymous",excerpt:s.excerpt||m.blog_settings?.excerpt,category:s.category||m.blog_settings?.category,publish_date:s.publish_date||m.blog_settings?.publish_date,read_time:s.read_time||m.blog_settings?.read_time,author_image:s.author_image||m.blog_settings?.author_image};r("Updating blog...");let x=await i.blogs.publish(e,n,{path:v,blog_content:a,seo:b,blog_settings:u});t.format==="json"?y(x,"json"):x.success?(w("Blog updated successfully"),console.log(` Blog ID: ${x.result?.blog_id}`),x.result?.published_url&&console.log(` Published URL: ${x.result.published_url}`)):l("Failed to update blog");}catch(a){J(a);}}),o.command("create").description("Create a new blog with live preview").argument("<website_id>","Website ID").argument("<path>","URL path for the blog (e.g., /blog/my-first-post)").option("--title <title>","Blog title","New Blog Post").option("--author <author>","Author name","Anonymous").option("--file <path>","Output file path","./blog.html").option("--background","Run preview server in background").action(async(e,n,t)=>{let i=V();try{let a=await i.websites.getDetails(e);a.result||(l("Website not found"),process.exit(1));let c=a.result,s=c,d=s?.theme||{},m=s?.custom_codes||{header:null,footer:null},v={font:d.font,title_font:d.title_font},b=t.title,u=t.author,x=new Date().toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"}),g=`<h2>Introduction</h2>
361
361
  <p>Welcome to your new blog post! This is a starter template to help you get started. Edit this content to create your own amazing blog post.</p>
362
362
 
363
363
  <h2>Getting Started</h2>
@@ -379,7 +379,7 @@ Blog Details:`),console.log("-------------"),console.log(` ID: ${i.blog_id}`),c
379
379
  console.log(greet('World'));</code></pre>
380
380
 
381
381
  <h2>Conclusion</h2>
382
- <p>Now it's your turn! Replace this content with your own ideas and publish your blog post to share it with the world.</p>`,f={page_title:b,meta_description:`Read ${b} by ${u}`,social_title:b,social_description:`Read ${b} by ${u}`},p={author:u,excerpt:"A new blog post. Edit this excerpt to provide a summary of your content.",publish_date:x,read_time:"3 min read"};a("Creating blog...");let h=await i.blogs.create(e,{path:n,blog_content:g,seo:f,blog_settings:p});h.success||(l("Failed to create blog"),process.exit(1));let C=h.result.blog_id,k=h.result.published_url;w(`Blog created: ${C}`),k&&console.log(` Published URL: ${k}`);let S=ht({seo:f,blogSettings:p,blogContent:g,websiteName:c.business_name||"Blog",blogPath:d.blog_path||"blog",websiteTheme:v,customCodes:{header:m.header||void 0,footer:m.footer||void 0}}),_=P.resolve(t.file);$.writeFileSync(_,S,"utf-8"),w(`HTML saved to ${_}`),await ut(),t.background?await ft(_):await gt(_),console.log(""),a(`To save changes: lindoai blogs update ${e} ${C} --html-file ${t.file}`);}catch(r){J(r);}}),o.command("stop-preview").description("Stop the background preview server").action(async()=>{try{if(!$.existsSync(Z)){a("No preview server is running");return}let e=parseInt($.readFileSync(Z,"utf-8").trim(),10);if(isNaN(e)){l("Invalid PID file"),Ke();return}try{process.kill(e,"SIGTERM"),w(`Preview server (PID ${e}) stopped`);}catch(n){n.code==="ESRCH"?a("Preview server process not found (may have already stopped)"):l(`Failed to stop preview server: ${n.message}`);}Ke();}catch(e){e instanceof Error?l(e.message):l("An unexpected error occurred"),process.exit(1);}}),o}function V(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function J(o){o instanceof AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Ke(){try{$.existsSync(Z)&&$.unlinkSync(Z);}catch{}try{$.existsSync(he)&&$.unlinkSync(he);}catch{}}async function ut(){if($.existsSync(Z)){try{let o=parseInt($.readFileSync(Z,"utf-8").trim(),10);if(!isNaN(o))try{process.kill(o,"SIGTERM"),a(`Terminated existing preview server (PID ${o})`),await new Promise(e=>setTimeout(e,500));}catch{}}catch{}Ke();}}async function ft(o){let e=P.resolve(o),n=`
382
+ <p>Now it's your turn! Replace this content with your own ideas and publish your blog post to share it with the world.</p>`,f={page_title:b,meta_description:`Read ${b} by ${u}`,social_title:b,social_description:`Read ${b} by ${u}`},p={author:u,excerpt:"A new blog post. Edit this excerpt to provide a summary of your content.",publish_date:x,read_time:"3 min read"};r("Creating blog...");let h=await i.blogs.create(e,{path:n,blog_content:g,seo:f,blog_settings:p});h.success||(l("Failed to create blog"),process.exit(1));let C=h.result.blog_id,k=h.result.published_url;w(`Blog created: ${C}`),k&&console.log(` Published URL: ${k}`);let S=ht({seo:f,blogSettings:p,blogContent:g,websiteName:c.business_name||"Blog",blogPath:d.blog_path||"blog",websiteTheme:v,customCodes:{header:m.header||void 0,footer:m.footer||void 0}}),_=P.resolve(t.file);$.writeFileSync(_,S,"utf-8"),w(`HTML saved to ${_}`),await ut(),t.background?await ft(_):await gt(_),console.log(""),r(`To save changes: lindoai blogs update ${e} ${C} --html-file ${t.file}`);}catch(a){J(a);}}),o.command("stop-preview").description("Stop the background preview server").action(async()=>{try{if(!$.existsSync(Z)){r("No preview server is running");return}let e=parseInt($.readFileSync(Z,"utf-8").trim(),10);if(isNaN(e)){l("Invalid PID file"),Be();return}try{process.kill(e,"SIGTERM"),w(`Preview server (PID ${e}) stopped`);}catch(n){n.code==="ESRCH"?r("Preview server process not found (may have already stopped)"):l(`Failed to stop preview server: ${n.message}`);}Be();}catch(e){e instanceof Error?l(e.message):l("An unexpected error occurred"),process.exit(1);}}),o}function V(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function J(o){o instanceof AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Be(){try{$.existsSync(Z)&&$.unlinkSync(Z);}catch{}try{$.existsSync(he)&&$.unlinkSync(he);}catch{}}async function ut(){if($.existsSync(Z)){try{let o=parseInt($.readFileSync(Z,"utf-8").trim(),10);if(!isNaN(o))try{process.kill(o,"SIGTERM"),r(`Terminated existing preview server (PID ${o})`),await new Promise(e=>setTimeout(e,500));}catch{}}catch{}Be();}}async function ft(o){let e=P.resolve(o),n=`
383
383
  const http = require('node:http');
384
384
  const fs = require('node:fs');
385
385
  const path = require('node:path');
@@ -499,7 +499,7 @@ console.log(greet('World'));</code></pre>
499
499
  });
500
500
  } catch {}
501
501
  });
502
- `,t=spawn(process.execPath,["-e",n],{detached:true,stdio:"ignore"});t.unref();let i=null;for(let s=0;s<50;s++)if(await new Promise(d=>setTimeout(d,100)),$.existsSync(he))try{if(i=parseInt($.readFileSync(he,"utf-8").trim(),10),!isNaN(i))break}catch{}i||(l("Failed to start preview server"),process.exit(1));let r=`http://127.0.0.1:${i}/`;await G(r)||a(`Could not open browser. Visit: ${r}`),w("Preview server started in background"),console.log(` URL: ${r}`),console.log(` PID: ${t.pid}`),console.log(""),a("To update the blog: lindoai blogs update <website_id> <blog_id> --html-file <path>"),a("To stop the server: lindoai blogs stop-preview");}async function gt(o){let{startLivePreviewServer:e}=await Promise.resolve().then(()=>(Ue(),Ne));a("Starting preview server...");let n=await e(o),t=`http://127.0.0.1:${n}/`;$.writeFileSync(Z,process.pid.toString(),"utf-8"),$.writeFileSync(he,n.toString(),"utf-8"),await G(t)||a(`Could not open browser. Visit: ${t}`),w("Preview server started"),console.log(` URL: ${t}`),console.log(""),a("Press Ctrl+C to stop the server"),a("Edit the HTML file and save to see changes in the browser");}function Co(o){return o?o.split(" ").map(e=>e.charAt(0).toUpperCase()).slice(0,2).join(""):"?"}function ht(o){let{seo:e,blogSettings:n,blogContent:t,websiteName:i,blogPath:r,websiteTheme:c,customCodes:s}=o,d=c?ue(c):"";return `<!DOCTYPE html>
502
+ `,t=spawn(process.execPath,["-e",n],{detached:true,stdio:"ignore"});t.unref();let i=null;for(let s=0;s<50;s++)if(await new Promise(d=>setTimeout(d,100)),$.existsSync(he))try{if(i=parseInt($.readFileSync(he,"utf-8").trim(),10),!isNaN(i))break}catch{}i||(l("Failed to start preview server"),process.exit(1));let a=`http://127.0.0.1:${i}/`;await G(a)||r(`Could not open browser. Visit: ${a}`),w("Preview server started in background"),console.log(` URL: ${a}`),console.log(` PID: ${t.pid}`),console.log(""),r("To update the blog: lindoai blogs update <website_id> <blog_id> --html-file <path>"),r("To stop the server: lindoai blogs stop-preview");}async function gt(o){let{startLivePreviewServer:e}=await Promise.resolve().then(()=>(Ue(),Ne));r("Starting preview server...");let n=await e(o),t=`http://127.0.0.1:${n}/`;$.writeFileSync(Z,process.pid.toString(),"utf-8"),$.writeFileSync(he,n.toString(),"utf-8"),await G(t)||r(`Could not open browser. Visit: ${t}`),w("Preview server started"),console.log(` URL: ${t}`),console.log(""),r("Press Ctrl+C to stop the server"),r("Edit the HTML file and save to see changes in the browser");}function Co(o){return o?o.split(" ").map(e=>e.charAt(0).toUpperCase()).slice(0,2).join(""):"?"}function ht(o){let{seo:e,blogSettings:n,blogContent:t,websiteName:i,blogPath:a,websiteTheme:c,customCodes:s}=o,d=c?ue(c):"";return `<!DOCTYPE html>
503
503
  <html class="dark" lang="en">
504
504
  <head>
505
505
  <meta charset="UTF-8">
@@ -565,7 +565,7 @@ console.log(greet('World'));</code></pre>
565
565
  <div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
566
566
  <div class="flex justify-between items-center py-4">
567
567
  <div class="flex items-center space-x-2">
568
- <a href="/${r}" class="flex items-center space-x-2 text-gray-600 dark:text-neutral-300 hover:text-gray-900 dark:hover:text-white transition-colors">
568
+ <a href="/${a}" class="flex items-center space-x-2 text-gray-600 dark:text-neutral-300 hover:text-gray-900 dark:hover:text-white transition-colors">
569
569
  <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
570
570
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
571
571
  </svg>
@@ -685,10 +685,10 @@ console.log(greet('World'));</code></pre>
685
685
  <!-- Custom Code (Footer) -->
686
686
  ${s?.footer||""}
687
687
  </body>
688
- </html>`}function ko(o){let e={},n=o;if(o.startsWith("---")){let t=o.indexOf("---",3);if(t!==-1){let i=o.slice(3,t).trim();n=o.slice(t+3).trim();for(let r of i.split(`
689
- `)){let c=r.indexOf(":");if(c!==-1){let s=r.slice(0,c).trim(),d=r.slice(c+1).trim();(d.startsWith('"')&&d.endsWith('"')||d.startsWith("'")&&d.endsWith("'"))&&(d=d.slice(1,-1)),e[s]=d;}}}}return {content:n,frontmatter:e}}function _o(o){let e=o;return e=e.replace(/^### (.+)$/gm,"<h3>$1</h3>"),e=e.replace(/^## (.+)$/gm,"<h2>$1</h2>"),e=e.replace(/^# (.+)$/gm,"<h1>$1</h1>"),e=e.replace(/\*\*\*(.+?)\*\*\*/g,"<strong><em>$1</em></strong>"),e=e.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),e=e.replace(/\*(.+?)\*/g,"<em>$1</em>"),e=e.replace(/```(\w*)\n([\s\S]*?)```/g,"<pre><code>$2</code></pre>"),e=e.replace(/`([^`]+)`/g,"<code>$1</code>"),e=e.replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2">$1</a>'),e=e.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,'<img src="$2" alt="$1">'),e=e.replace(/^- (.+)$/gm,"<li>$1</li>"),e=e.replace(/(<li>.*<\/li>\n?)+/g,"<ul>$&</ul>"),e=e.replace(/^\d+\. (.+)$/gm,"<li>$1</li>"),e=e.split(`
690
- `).map(i=>{let r=i.trim();return r?r.startsWith("<")?i:`<p>${r}</p>`:""}).join(`
691
- `),e=e.replace(/<p><\/p>/g,""),e}function bt(o){let e=o.toLowerCase().split(".").pop()||"";return {jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",ico:"image/x-icon",avif:"image/avif",mp4:"video/mp4",webm:"video/webm",mov:"video/quicktime",pdf:"application/pdf",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",otf:"font/otf"}[e]||"application/octet-stream"}function wt(o){let e=o.toLowerCase().split(".").pop()||"",n=["jpg","jpeg","png","gif","webp","svg","ico","avif","bmp","tiff"],t=["mp4","webm","mov","avi","mkv"],i=["woff","woff2","ttf","otf","eot"];return n.includes(e)?"images":t.includes(e)?"videos":i.includes(e)?"fonts":"documents"}function Ge(){let o=new Command("media").description("Media upload operations");return o.command("upload").description("Upload a single media file to website CDN").argument("<website_id>","Website ID").argument("<file_path>","Path to the file to upload").option("-t, --type <type>","Media type (images, videos, documents, fonts)").option("-n, --name <name>","Override file name for CDN").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=yt();try{let r=P.resolve(n);$.existsSync(r)||(l(`File not found: ${r}`),process.exit(1));let c=t.name||P.basename(r),d=$.readFileSync(r).toString("base64"),m=t.type||wt(c),v=bt(c);a(`Uploading ${c} (${m}) to website ${e}...`);let b=await i.media.upload(e,{file_base64:d,file_name:c,media_type:m,content_type:v});w(`Uploaded: ${b.result.url}`),y(b.result,t.format);}catch(r){xt(r);}}),o.command("upload-batch").description("Upload multiple media files to website CDN (max 20)").argument("<website_id>","Website ID").argument("<file_paths...>","Paths to files to upload").option("-t, --type <type>","Media type override for all files").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=yt();try{n.length>20&&(l("Maximum 20 files per batch upload"),process.exit(1));let r=n.map(s=>{let d=P.resolve(s);$.existsSync(d)||(l(`File not found: ${d}`),process.exit(1));let m=P.basename(d),b=$.readFileSync(d).toString("base64"),u=t.type||wt(m),x=bt(m);return {file_base64:b,file_name:m,media_type:u,content_type:x}});a(`Uploading ${r.length} file(s) to website ${e}...`);let c=await i.media.uploadBatch(e,{files:r});w(`Uploaded ${c.result.successful} of ${c.result.total} files`),c.result.failed>0&&a(`${c.result.failed} file(s) failed`),y(c.result,t.format);}catch(r){xt(r);}}),o}function yt(){F()||(l("API key not configured"),a("Run: lindo config set apiKey <your-api-key>"),a("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function xt(o){o instanceof AuthenticationError&&(l("Authentication failed"),a("Your API key may be invalid or expired"),a("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Ct(){return vt.randomBytes(32).toString("hex")}function kt(o,e){return o===e}function Fo(o){try{let e=o.startsWith("http")?o:`http://localhost${o}`,t=new URL(e).searchParams;return {key:t.get("key")??void 0,state:t.get("state")??void 0,error:t.get("error")??void 0,message:t.get("message")??void 0}}catch{return {}}}function Po(){return `<!DOCTYPE html>
688
+ </html>`}function ko(o){let e={},n=o;if(o.startsWith("---")){let t=o.indexOf("---",3);if(t!==-1){let i=o.slice(3,t).trim();n=o.slice(t+3).trim();for(let a of i.split(`
689
+ `)){let c=a.indexOf(":");if(c!==-1){let s=a.slice(0,c).trim(),d=a.slice(c+1).trim();(d.startsWith('"')&&d.endsWith('"')||d.startsWith("'")&&d.endsWith("'"))&&(d=d.slice(1,-1)),e[s]=d;}}}}return {content:n,frontmatter:e}}function _o(o){let e=o;return e=e.replace(/^### (.+)$/gm,"<h3>$1</h3>"),e=e.replace(/^## (.+)$/gm,"<h2>$1</h2>"),e=e.replace(/^# (.+)$/gm,"<h1>$1</h1>"),e=e.replace(/\*\*\*(.+?)\*\*\*/g,"<strong><em>$1</em></strong>"),e=e.replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>"),e=e.replace(/\*(.+?)\*/g,"<em>$1</em>"),e=e.replace(/```(\w*)\n([\s\S]*?)```/g,"<pre><code>$2</code></pre>"),e=e.replace(/`([^`]+)`/g,"<code>$1</code>"),e=e.replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2">$1</a>'),e=e.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,'<img src="$2" alt="$1">'),e=e.replace(/^- (.+)$/gm,"<li>$1</li>"),e=e.replace(/(<li>.*<\/li>\n?)+/g,"<ul>$&</ul>"),e=e.replace(/^\d+\. (.+)$/gm,"<li>$1</li>"),e=e.split(`
690
+ `).map(i=>{let a=i.trim();return a?a.startsWith("<")?i:`<p>${a}</p>`:""}).join(`
691
+ `),e=e.replace(/<p><\/p>/g,""),e}function bt(o){let e=o.toLowerCase().split(".").pop()||"";return {jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",ico:"image/x-icon",avif:"image/avif",mp4:"video/mp4",webm:"video/webm",mov:"video/quicktime",pdf:"application/pdf",woff:"font/woff",woff2:"font/woff2",ttf:"font/ttf",otf:"font/otf"}[e]||"application/octet-stream"}function wt(o){let e=o.toLowerCase().split(".").pop()||"",n=["jpg","jpeg","png","gif","webp","svg","ico","avif","bmp","tiff"],t=["mp4","webm","mov","avi","mkv"],i=["woff","woff2","ttf","otf","eot"];return n.includes(e)?"images":t.includes(e)?"videos":i.includes(e)?"fonts":"documents"}function Ge(){let o=new Command("media").description("Media upload operations");return o.command("upload").description("Upload a single media file to website CDN").argument("<website_id>","Website ID").argument("<file_path>","Path to the file to upload").option("-t, --type <type>","Media type (images, videos, documents, fonts)").option("-n, --name <name>","Override file name for CDN").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=yt();try{let a=P.resolve(n);$.existsSync(a)||(l(`File not found: ${a}`),process.exit(1));let c=t.name||P.basename(a),d=$.readFileSync(a).toString("base64"),m=t.type||wt(c),v=bt(c);r(`Uploading ${c} (${m}) to website ${e}...`);let b=await i.media.upload(e,{file_base64:d,file_name:c,media_type:m,content_type:v});w(`Uploaded: ${b.result.url}`),y(b.result,t.format);}catch(a){xt(a);}}),o.command("upload-batch").description("Upload multiple media files to website CDN (max 20)").argument("<website_id>","Website ID").argument("<file_paths...>","Paths to files to upload").option("-t, --type <type>","Media type override for all files").option("-f, --format <format>","Output format (json, table)","table").action(async(e,n,t)=>{let i=yt();try{n.length>20&&(l("Maximum 20 files per batch upload"),process.exit(1));let a=n.map(s=>{let d=P.resolve(s);$.existsSync(d)||(l(`File not found: ${d}`),process.exit(1));let m=P.basename(d),b=$.readFileSync(d).toString("base64"),u=t.type||wt(m),x=bt(m);return {file_base64:b,file_name:m,media_type:u,content_type:x}});r(`Uploading ${a.length} file(s) to website ${e}...`);let c=await i.media.uploadBatch(e,{files:a});w(`Uploaded ${c.result.successful} of ${c.result.total} files`),c.result.failed>0&&r(`${c.result.failed} file(s) failed`),y(c.result,t.format);}catch(a){xt(a);}}),o}function yt(){F()||(l("API key not configured"),r("Run: lindo config set apiKey <your-api-key>"),r("Or set the LINDO_API_KEY environment variable"),process.exit(1));let o=O();return new LindoClient({apiKey:o.apiKey,baseUrl:o.baseUrl})}function xt(o){o instanceof AuthenticationError&&(l("Authentication failed"),r("Your API key may be invalid or expired"),r("Run: lindo config set apiKey <your-api-key>"),process.exit(1)),o instanceof Error?l(o.message):l("An unexpected error occurred"),process.exit(1);}function Ct(){return vt.randomBytes(32).toString("hex")}function kt(o,e){return o===e}function Fo(o){try{let e=o.startsWith("http")?o:`http://localhost${o}`,t=new URL(e).searchParams;return {key:t.get("key")??void 0,state:t.get("state")??void 0,error:t.get("error")??void 0,message:t.get("message")??void 0}}catch{return {}}}function Po(){return `<!DOCTYPE html>
692
692
  <html lang="en">
693
693
  <head>
694
694
  <meta charset="UTF-8">
@@ -827,13 +827,13 @@ ${s?.footer||""}
827
827
  <p>This endpoint is not available.</p>
828
828
  </div>
829
829
  </body>
830
- </html>`}function St(){let o=null,e=null;function n(t,i){let r=t.url||"/",c=t.method||"GET",s=r==="/callback"||r.startsWith("/callback?");if(c!=="GET"||!s){i.writeHead(404,{"Content-Type":"text/html; charset=utf-8"}),i.end(Io());return}let d=Fo(r);if(!e){i.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye("No pending authorization request"));return}let{expectedState:m,resolve:v,timeoutId:b}=e;if(clearTimeout(b),e=null,d.error){let u=d.message||d.error;i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye(u)),v({success:false,error:u});return}if(!d.state||!kt(d.state,m)){let u="State token mismatch - possible CSRF attack";i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye(u)),v({success:false,error:u});return}if(!d.key){let u="No API key received";i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye(u)),v({success:false,error:u});return}i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(Po()),v({success:true,apiKey:d.key});}return {async start(){return new Promise((t,i)=>{o=lt.createServer(n),o.on("error",r=>{i(new Error(`Failed to start callback server: ${r.message}`));}),o.listen(0,"127.0.0.1",()=>{let r=o.address();if(!r||typeof r=="string"){i(new Error("Failed to get server address"));return}let c=r.port,s=`http://127.0.0.1:${c}/callback`;t({port:c,url:s});});})},waitForCallback(t,i){return new Promise(r=>{let c=setTimeout(()=>{e&&(e=null,r({success:false,error:"Login timed out waiting for authorization"}));},i);e={expectedState:t,resolve:r,timeoutId:c};})},async stop(){return new Promise(t=>{e&&(clearTimeout(e.timeoutId),e=null),o?o.close(()=>{o=null,t();}):t();})}}}var Eo="https://app.lindo.ai",Lo=120;function Ro(o,e){let n=`http://127.0.0.1:${e}/callback`,t=new URLSearchParams({state:o,callback_url:n});return `${Eo}/cli/authorize?${t.toString()}`}function Ye(){return new Command("login").description("Authenticate via browser to configure your API key").option("-t, --timeout <seconds>","Timeout in seconds for the login flow",String(Lo)).option("--no-browser","Display the authorization URL without opening the browser").action(async e=>{let n=parseInt(e.timeout,10),t=n*1e3,i=e.browser,r=St(),c=false;try{a("Starting authentication flow...");let{port:s}=await r.start();c=!0;let d=Ct(),m=Ro(d,s);i?(a("Opening browser for authorization..."),await G(m)||(a("Could not open browser automatically."),console.log(`
830
+ </html>`}function St(){let o=null,e=null;function n(t,i){let a=t.url||"/",c=t.method||"GET",s=a==="/callback"||a.startsWith("/callback?");if(c!=="GET"||!s){i.writeHead(404,{"Content-Type":"text/html; charset=utf-8"}),i.end(Io());return}let d=Fo(a);if(!e){i.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye("No pending authorization request"));return}let{expectedState:m,resolve:v,timeoutId:b}=e;if(clearTimeout(b),e=null,d.error){let u=d.message||d.error;i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye(u)),v({success:false,error:u});return}if(!d.state||!kt(d.state,m)){let u="State token mismatch - possible CSRF attack";i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye(u)),v({success:false,error:u});return}if(!d.key){let u="No API key received";i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(ye(u)),v({success:false,error:u});return}i.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),i.end(Po()),v({success:true,apiKey:d.key});}return {async start(){return new Promise((t,i)=>{o=lt.createServer(n),o.on("error",a=>{i(new Error(`Failed to start callback server: ${a.message}`));}),o.listen(0,"127.0.0.1",()=>{let a=o.address();if(!a||typeof a=="string"){i(new Error("Failed to get server address"));return}let c=a.port,s=`http://127.0.0.1:${c}/callback`;t({port:c,url:s});});})},waitForCallback(t,i){return new Promise(a=>{let c=setTimeout(()=>{e&&(e=null,a({success:false,error:"Login timed out waiting for authorization"}));},i);e={expectedState:t,resolve:a,timeoutId:c};})},async stop(){return new Promise(t=>{e&&(clearTimeout(e.timeoutId),e=null),o?o.close(()=>{o=null,t();}):t();})}}}var Eo="https://app.lindo.ai",Lo=120;function Ro(o,e){let n=`http://127.0.0.1:${e}/callback`,t=new URLSearchParams({state:o,callback_url:n});return `${Eo}/cli/authorize?${t.toString()}`}function Ye(){return new Command("login").description("Authenticate via browser to configure your API key").option("-t, --timeout <seconds>","Timeout in seconds for the login flow",String(Lo)).option("--no-browser","Display the authorization URL without opening the browser").action(async e=>{let n=parseInt(e.timeout,10),t=n*1e3,i=e.browser,a=St(),c=false;try{r("Starting authentication flow...");let{port:s}=await a.start();c=!0;let d=Ct(),m=Ro(d,s);i?(r("Opening browser for authorization..."),await G(m)||(r("Could not open browser automatically."),console.log(`
831
831
  Please open this URL in your browser:`),console.log(`
832
832
  ${m}
833
833
  `))):(console.log(`
834
834
  Please open this URL in your browser:`),console.log(`
835
835
  ${m}
836
- `)),a(`Waiting for authorization (timeout: ${n}s)...`);let v=await r.waitForCallback(d,t);v.success&&v.apiKey?(tt(v.apiKey),w("Successfully authenticated!"),a(`API key saved to: ${W()}`)):(l(v.error||"Authentication failed"),process.exit(1));}catch(s){l(s instanceof Error?s.message:"An unexpected error occurred"),process.exit(1);}finally{c&&await r.stop();}})}var ze=P.join(De.homedir(),".config","opencode","skills","lindoai"),Tt=P.join(ze,"SKILL.md"),No=`---
836
+ `)),r(`Waiting for authorization (timeout: ${n}s)...`);let v=await a.waitForCallback(d,t);v.success&&v.apiKey?(tt(v.apiKey),w("Successfully authenticated!"),r(`API key saved to: ${W()}`)):(l(v.error||"Authentication failed"),process.exit(1));}catch(s){l(s instanceof Error?s.message:"An unexpected error occurred"),process.exit(1);}finally{c&&await a.stop();}})}var ze=P.join(De.homedir(),".config","opencode","skills","lindoai"),Tt=P.join(ze,"SKILL.md"),No=`---
837
837
  name: lindoai
838
838
  description: Lindo AI CLI - Command-line interface for the Lindo API
839
839
  ---
@@ -1194,5 +1194,5 @@ Follow these core rules when building pages:
1194
1194
  6. **Container patterns**:
1195
1195
  - Use \`container mx-auto px-4\` for consistent content width
1196
1196
  - Apply consistent vertical padding: \`py-12 md:py-16 lg:py-20\`
1197
- `;function Uo(){try{let o=process.platform==="win32"?"where opencode":"which opencode";return execSync(o,{stdio:"ignore"}),!0}catch{return false}}function Mo(){try{return a("Installing OpenCode..."),execSync("npm install -g opencode-ai@latest",{stdio:"inherit"}),!0}catch{return false}}function Ho(){$.existsSync(ze)||$.mkdirSync(ze,{recursive:true}),$.writeFileSync(Tt,No,"utf-8");}function Je(){return new Command("agent").description("Launch an AI agent that understands all CLI commands").option("--install","Install OpenCode if not already installed").option("--model <model>","Specify the model to use with OpenCode").action(async e=>{Uo()||(e.install?(Mo()||(l("Failed to install OpenCode"),a("Please install manually: npm install -g opencode-ai@latest"),process.exit(1)),w("OpenCode installed successfully")):(l("OpenCode is not installed"),a(""),a("To install OpenCode, run one of the following:"),a(" lindoai agent --install"),a(" npm install -g opencode-ai@latest"),process.exit(1)));try{Ho(),a(`Skill file installed to: ${Tt}`);}catch(i){l(`Failed to install skill file: ${i instanceof Error?i.message:"Unknown error"}`),process.exit(1);}let n=[];e.model&&n.push("--model",e.model),a("Launching OpenCode...");let t=spawn("opencode",n,{stdio:"inherit",shell:true});t.on("error",i=>{l(`Failed to launch OpenCode: ${i.message}`),process.exit(1);}),t.on("close",i=>{process.exit(i??0);});})}var qo=createRequire(import.meta.url),Go=qo("../package.json"),Yo=Go.version;function zo(){let o=new Command;return o.name("lindo").description("Command-line interface for the Lindo API").version(Yo,"-v, --version","Output the current version").helpOption("-h, --help","Display help for command"),o.addCommand(_e()),o.addCommand(Se()),o.addCommand($e()),o.addCommand(Oe()),o.addCommand(Te()),o.addCommand(Fe()),o.addCommand(Pe()),o.addCommand(We()),o.addCommand(qe()),o.addCommand(Ge()),o.addCommand(Ye()),o.addCommand(Je()),o.exitOverride(e=>{throw e.code==="commander.help"&&process.exit(0),e.code==="commander.version"&&process.exit(0),e.code==="commander.missingArgument"&&(l(e.message),process.exit(1)),e.code==="commander.unknownCommand"&&(l(e.message),a('Run "lindo --help" for available commands'),process.exit(1)),e}),o}function Vo(o){l("Authentication failed"),a(""),a("Your API key may be invalid or expired."),a(""),a("To configure your API key:"),a(" 1. Run: lindo config set apiKey <your-api-key>"),a(" 2. Or set the LINDO_API_KEY environment variable"),a(""),a("To get an API key:"),a(" Visit https://app.lindo.ai/settings/api-keys");}async function Jo(){let o=zo();try{await o.parseAsync(process.argv);}catch(e){throw e instanceof AuthenticationError&&(Vo(),process.exit(1)),e}}Jo().catch(o=>{o instanceof Error?l(`Unexpected error: ${o.message}`):l("An unexpected error occurred"),process.exit(1);});
1197
+ `;function Uo(){try{let o=process.platform==="win32"?"where opencode":"which opencode";return execSync(o,{stdio:"ignore"}),!0}catch{return false}}function Mo(){try{return r("Installing OpenCode..."),execSync("npm install -g opencode-ai@latest",{stdio:"inherit"}),!0}catch{return false}}function Ho(){$.existsSync(ze)||$.mkdirSync(ze,{recursive:true}),$.writeFileSync(Tt,No,"utf-8");}function Je(){return new Command("agent").description("Launch an AI agent that understands all CLI commands").option("--install","Install OpenCode if not already installed").option("--model <model>","Specify the model to use with OpenCode").action(async e=>{Uo()||(e.install?(Mo()||(l("Failed to install OpenCode"),r("Please install manually: npm install -g opencode-ai@latest"),process.exit(1)),w("OpenCode installed successfully")):(l("OpenCode is not installed"),r(""),r("To install OpenCode, run one of the following:"),r(" lindoai agent --install"),r(" npm install -g opencode-ai@latest"),process.exit(1)));try{Ho(),r(`Skill file installed to: ${Tt}`);}catch(i){l(`Failed to install skill file: ${i instanceof Error?i.message:"Unknown error"}`),process.exit(1);}let n=[];e.model&&n.push("--model",e.model),r("Launching OpenCode...");let t=spawn("opencode",n,{stdio:"inherit",shell:true});t.on("error",i=>{l(`Failed to launch OpenCode: ${i.message}`),process.exit(1);}),t.on("close",i=>{process.exit(i??0);});})}var qo=createRequire(import.meta.url),Go=qo("../package.json"),Yo=Go.version;function zo(){let o=new Command;return o.name("lindo").description("Command-line interface for the Lindo API").version(Yo,"-v, --version","Output the current version").helpOption("-h, --help","Display help for command"),o.addCommand(_e()),o.addCommand(Se()),o.addCommand($e()),o.addCommand(Oe()),o.addCommand(Te()),o.addCommand(Fe()),o.addCommand(Pe()),o.addCommand(We()),o.addCommand(qe()),o.addCommand(Ge()),o.addCommand(Ye()),o.addCommand(Je()),o.exitOverride(e=>{throw e.code==="commander.help"&&process.exit(0),e.code==="commander.version"&&process.exit(0),e.code==="commander.missingArgument"&&(l(e.message),process.exit(1)),e.code==="commander.unknownCommand"&&(l(e.message),r('Run "lindo --help" for available commands'),process.exit(1)),e}),o}function Vo(o){l("Authentication failed"),r(""),r("Your API key may be invalid or expired."),r(""),r("To configure your API key:"),r(" 1. Run: lindo config set apiKey <your-api-key>"),r(" 2. Or set the LINDO_API_KEY environment variable"),r(""),r("To get an API key:"),r(" Visit https://app.lindo.ai/settings/api-keys");}async function Jo(){let o=zo();try{await o.parseAsync(process.argv);}catch(e){throw e instanceof AuthenticationError&&(Vo(),process.exit(1)),e}}Jo().catch(o=>{o instanceof Error?l(`Unexpected error: ${o.message}`):l("An unexpected error occurred"),process.exit(1);});
1198
1198
  export{zo as createProgram};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lindoai-cli",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "Command-line interface for the Lindo API",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",