@visulima/cerebro 3.0.0-alpha.30 → 3.0.0-alpha.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/LICENSE.md +841 -6
  3. package/README.md +38 -8
  4. package/dist/commands/completion-command.d.ts +1 -1
  5. package/dist/commands/completion-command.js +5 -5
  6. package/dist/commands/help-command.d.ts +1 -1
  7. package/dist/commands/help-command.js +1 -1
  8. package/dist/commands/readme-command.d.ts +1 -1
  9. package/dist/commands/readme-command.js +20 -20
  10. package/dist/commands/version-command.d.ts +1 -1
  11. package/dist/commands/version-command.js +1 -1
  12. package/dist/index.d.ts +18 -3
  13. package/dist/index.js +1 -1
  14. package/dist/logger/create-pail-logger.d.ts +29 -4
  15. package/dist/logger/create-pail-logger.js +1 -1
  16. package/dist/packem_chunks/has-new-version.js +1 -1
  17. package/dist/packem_shared/Cerebro-BsroI2VY.js +4 -0
  18. package/dist/packem_shared/VisulimaError-DTMgXonA-CzaryRgZ.js +1 -0
  19. package/dist/packem_shared/VisulimaError-DyMHh9O-.js +76 -0
  20. package/dist/packem_shared/cerebro-error-z8DS5U8c.js +1 -0
  21. package/dist/packem_shared/{plugin-manager.d-BSQtHbWS.d.ts → command.d-DbhtfXF4.d.ts} +235 -216
  22. package/dist/packem_shared/index-BSKOOIL6.js +29 -0
  23. package/dist/packem_shared/{index.d-Br8HpP0A.d.ts → index.d-BL4NtVR3.d.ts} +37 -3
  24. package/dist/packem_shared/lazyNamed-DMUm8mZe.js +1 -0
  25. package/dist/packem_shared/renderError-Dqej8k13-BmipVhik.js +25 -0
  26. package/dist/packem_shared/runtime-process-Dmz0vCJy.js +1 -0
  27. package/dist/packem_shared/split-by-case-C-dbSFCl.js +1 -0
  28. package/dist/plugins/error-handler-plugin.d.ts +2 -2
  29. package/dist/plugins/error-handler-plugin.js +1 -1
  30. package/dist/plugins/runtime-version-check-plugin.d.ts +1 -1
  31. package/dist/plugins/runtime-version-check-plugin.js +1 -1
  32. package/dist/plugins/update-notifier/update-notifier-plugin.d.ts +11 -4
  33. package/dist/plugins/update-notifier/update-notifier-plugin.js +1 -1
  34. package/dist/util/general/compile-cache.js +1 -1
  35. package/dist/util/general/heap-tuning.js +1 -1
  36. package/package.json +7 -7
  37. package/dist/packem_shared/Cerebro-BN_nIZ8z.js +0 -4
  38. package/dist/packem_shared/VisulimaError-WfDZ45Qv.js +0 -76
  39. package/dist/packem_shared/cerebro-error-BnJTixb2.js +0 -1
  40. package/dist/packem_shared/constants-DmzZF6_u-BmMwILI_.js +0 -1
  41. package/dist/packem_shared/index-CkkDAMKi.js +0 -6
  42. package/dist/packem_shared/isVisulimaError-jVZgumOU-C4fgdbWg.js +0 -1
  43. package/dist/packem_shared/lazyNamed-DOmefeJM.js +0 -1
  44. package/dist/packem_shared/renderError-DxgI44AK-DFDWFoCr.js +0 -24
  45. package/dist/packem_shared/runtime-process-DKHFvYkv.js +0 -1
  46. /package/dist/packem_shared/{VERBOSITY_QUIET-XPultrIA.js → VERBOSITY_DEBUG-XPultrIA.js} +0 -0
@@ -0,0 +1,76 @@
1
+ import{g as b,n as N}from"./renderError-Dqej8k13-BmipVhik.js";import{S as re,s as ne,W as oe,X as ae,c as ie,Y as se,U as ue,R as le}from"./renderError-Dqej8k13-BmipVhik.js";import{h as fe,c as pe}from"./VisulimaError-DTMgXonA-CzaryRgZ.js";const S=(e,t)=>{let r=0,o=t.length-2;for(;r<o;){const n=r+(o-r>>1);if(e<t[n])o=n-1;else if(e>=t[n+1])r=n+1;else{r=n;break}}return r},E=/\n|\r(?!\n)/,P=e=>e.split(E).reduce((t,r)=>(t.push(t.at(-1)+r.length+1),t),[0]),K=(e,t,r)=>{const o=r?.skipChecks??!1;if(!o&&(!Array.isArray(e)&&typeof e!="string"||(typeof e=="string"||Array.isArray(e))&&e.length===0))return{column:0,line:0};if(!o&&(typeof t!="number"||typeof e=="string"&&t>=e.length||Array.isArray(e)&&t+1>=e.at(-1)))return{column:0,line:0};if(typeof e=="string"){const a=P(e),i=S(t,a);return{column:t-a[i]+1,line:i+1}}const n=S(t,e);return{column:t-e[n]+1,line:n+1}},B=({applicationType:e,error:t,file:r})=>`You are a very skilled ${r.language??"unknown"} programmer.
2
+
3
+ ${e?`You are working on a ${e} application.`:""}
4
+
5
+ Use the following context to find a possible fix for the exception message at the end. Limit your answer to 4 or 5 sentences. Also include a few links to documentation that might help.
6
+
7
+ Use this format in your answer, make sure links are json:
8
+
9
+ FIX
10
+ insert the possible fix here
11
+ ENDFIX
12
+ LINKS
13
+ {"title": "Title link 1", "url": "URL link 1"}
14
+ {"title": "Title link 2", "url": "URL link 2"}
15
+ ENDLINKS
16
+ ---
17
+
18
+ Here comes the context and the exception message:
19
+
20
+ Line: ${String(r.line)}
21
+
22
+ File:
23
+ ${r.file}
24
+
25
+ Snippet including line numbers:
26
+ ${r.snippet??""}
27
+
28
+ Exception class:
29
+ ${t.name}
30
+
31
+ Exception message:
32
+ ${t.message}`,j=(e,t,r)=>{const o=r.indexOf(e);if(o===-1)return"";const n=o+e.length,a=r.indexOf(t,n);return a===-1?"":r.slice(n,a).trim()},X=e=>{const t=j("FIX","ENDFIX",e);if(!t)return["No solution found.",'Provide this response to the Maintainer of <a href="https://github.com/visulima/visulima/issues/new?assignees=&labels=s%3A+pending+triage%2Cc%3A+bug&projects=&template=bug_report.yml" target="_blank" rel="noopener noreferrer" class="text-blue-500 hover:underline inline-flex items-center text-sm">@visulima/error</a>.',`"${e}"`].join("</br></br>");const r=j("LINKS","ENDLINKS",e),o=r?r.split(`
33
+ `).map(a=>a.trim()).filter(Boolean).map(a=>{try{return JSON.parse(a)}catch{return}}).filter(a=>a!==void 0):[],n=o.length>0?`
34
+
35
+ ## Links
36
+
37
+ ${o.map(a=>`- <a href="${a.url}" target="_blank" rel="noopener noreferrer">${a.title}</a>`).join(`
38
+ `)}`:"";return`${t.replaceAll(/"([^"]*)"(?:\s|\.)/g,"<code>$1</code> ")}${n}
39
+
40
+ --------------------
41
+ This solution was generated with the <a href="https://sdk.vercel.ai/" target="_blank" rel="noopener noreferrer">AI SDK</a> and may not be 100% accurate.`},q={handle:e=>e.hint===void 0?Promise.resolve(void 0):typeof e.hint=="string"&&e.hint!==""?Promise.resolve({body:e.hint}):typeof e.hint=="object"&&typeof e.hint.body=="string"?Promise.resolve(e.hint):Array.isArray(e.hint)?Promise.resolve({body:e.hint.join(`
42
+ `)}):Promise.resolve(void 0),name:"errorHint",priority:1},A=e=>`\`\`\`
43
+ ${e.trim()}
44
+ \`\`\``,d=e=>`\`\`\`bash
45
+ ${e.trim()}
46
+ \`\`\``,h=e=>`\`\`\`ts
47
+ ${e.trim()}
48
+ \`\`\``,I=e=>`\`\`\`js
49
+ ${e.trim()}
50
+ \`\`\``,c=(e,...t)=>{const r=e.toLowerCase();return t.some(o=>r.includes(o.toLowerCase()))},T=[{name:"esm-cjs-interop",test:e=>{const{message:t}=e;if(c(t,"err_require_esm","cannot use import statement outside a module","must use import to load es module","require() of es module","does not provide an export named"))return{md:["Your project or a dependency may be mixing CommonJS and ES Modules.","","Try:","- Ensure package.json has the correct `type` (either `module` or `commonjs`).","- Use dynamic `import()` when requiring ESM from CJS.","- Prefer ESM-compatible entrypoints from dependencies.","- In Node, align `module` resolution with your bundler config.","","Check Node resolution:",d(`node -v
51
+ cat package.json | jq .type`),"","Example dynamic import in CJS:",I("(async () => { const mod = await import('some-esm'); mod.default(); })();")].join(`
52
+ `),title:"ESM/CJS interop"}}},{name:"missing-default-export",test:e=>{const{message:t}=e;if(c(t,"default export not found","has no default export","does not provide an export named 'default'","is not exported from"))return{md:["Verify your import/export shapes.","","Default export example:",h(`export default function Component() {}
53
+ // import Component from './file'`),"","Named export example:",h(`export function Component() {}
54
+ // import { Component } from './file'`)].join(`
55
+ `),title:"Export mismatch (default vs named)"}}},{name:"port-in-use",test:e=>{const{message:t}=e;if(c(t,"eaddrinuse","address already in use","listen eaddrinuse"))return{md:["Another process is using the port.","","Change the port or stop the other process.","","On macOS/Linux:",d(`lsof -i :3000
56
+ kill -9 <PID>`),"","On Windows (PowerShell):",d(`netstat -ano | findstr :3000
57
+ taskkill /PID <PID> /F`)].join(`
58
+ `),title:"Port already in use"}}},{name:"file-not-found-or-case",test:(e,t)=>{const{message:r}=e;if(c(r,"enoent","module not found","cannot find module"))return{md:["Check the import path and filename case (Linux/macOS are case-sensitive).","If using TS path aliases, verify `tsconfig.paths` and bundler aliases.","","Current file:",A(`${t.file}:${String(t.line)}`)].join(`
59
+ `),title:"Missing file or path case mismatch"}}},{name:"ts-path-mapping",test:e=>{const{message:t}=e;if(c(t,"ts2307","cannot find module")||t.includes("TS2307"))return{md:["If you use path aliases, align TS `paths` with Vite/Webpack resolve aliases.","Ensure file extensions are correct and included in resolver.","","tsconfig.json excerpt:",h(`{
60
+ "compilerOptions": {
61
+ "baseUrl": ".",
62
+ "paths": { "@/*": ["src/*"] }
63
+ }
64
+ }`)].join(`
65
+ `),title:"TypeScript path mapping / resolution"}}},{name:"network-dns-enotfound",test:e=>{const{message:t}=e;if(c(t,"enotfound","getaddrinfo enotfound","dns","fetch failed","ecconnrefused","econnrefused"))return{md:["The host may be unreachable or misconfigured.","","Try:","- Verify the hostname and protocol (http/https).","- Check VPN/proxy and firewall.","- Confirm the service is running and listening on the expected port.","",d(`ping <host>
66
+ nslookup <host>
67
+ curl -v http://<host>:<port>`)].join(`
68
+ `),title:"Network/DNS connection issue"}}},{name:"undefined-property",test:e=>{const{message:t}=e;if(c(t,"cannot read properties of undefined","reading '"))return{md:["A variable or function returned `undefined`.","","Mitigations:","- Add nullish checks before property access.","- Validate function return values and input props/state.","",h("const value = maybe?.prop; // or: if (maybe) { use(maybe.prop) }")].join(`
69
+ `),title:"Accessing property of undefined"}}}],H={handle:(e,t)=>{try{const r=T.map(n=>({match:n.test(e,t),rule:n})).filter(n=>!!n.match);if(r.length===0)return Promise.resolve(void 0);const o=r.toSorted((n,a)=>(n.match.priority??0)-(a.match.priority??0)).map(n=>`#### ${n.match.title}
70
+
71
+ ${n.match.md}`).join(`
72
+
73
+ ---
74
+
75
+ `);return o===""?Promise.resolve(void 0):Promise.resolve({body:o,header:"### Potential fixes detected"})}catch{return Promise.resolve(void 0)}},name:"ruleBasedHints",priority:0};let p=class extends Error{constructor(t){super(t),this.name="NonError"}};const z=()=>{if(!Error.captureStackTrace)return;const e=new Error;return Error.captureStackTrace(e),e.stack},x=e=>{if(typeof e!="object"||e===null)return!1;const t=Object.getPrototypeOf(e);return t===null||t===Object.prototype||Object.getPrototypeOf(t)===null},_={maxDepth:Number.POSITIVE_INFINITY},$=(e,t,r=0)=>b(e)?v(e,t,r):t.maxDepth!==void 0&&r>=t.maxDepth?new p(JSON.stringify(e)):new p(JSON.stringify(e)),C=(e,t,r,o,n)=>{const a=t.map(i=>l(i,o,n+1));return new e(a,r)},v=(e,t,r)=>{if(t.maxDepth!==void 0&&r>=t.maxDepth)return new p(JSON.stringify(e));const{cause:o,errors:n,message:a,name:i,stack:s,...m}=e,O=N(i)??Error,u=i==="AggregateError"&&Array.isArray(n)?C(O,n,a,t,r):new O(a);return!u.name&&i&&(u.name=i),a!==void 0&&(u.message=a),s&&(u.stack=s),D(u,m,o,i,t,r),o!==void 0&&(u.cause=l(o,t,r+1)),J(u,e),u},l=(e,t,r)=>{if(x(e)){if(e.__dataType==="Map"&&Array.isArray(e.value))return new Map(e.value.map(([n,a])=>[l(n,t,r+1),l(a,t,r+1)]));if(e.__dataType==="Set"&&Array.isArray(e.value))return new Set(e.value.map(n=>l(n,t,r+1)));if(b(e))return $(e,t,r);const o={};for(const[n,a]of Object.entries(e))n==="__proto__"||n==="constructor"||n==="prototype"||(o[n]=l(a,t,r+1));return o}return Array.isArray(e)?e.map(o=>l(o,t,r)):e},D=(e,t,r,o,n,a)=>{const i=e;for(const[s,m]of Object.entries(t))if(!(s==="__proto__"||s==="constructor"||s==="prototype")){if(s==="cause"&&r!==void 0||s==="errors"&&o==="AggregateError")continue;Object.defineProperty(i,s,{configurable:!0,enumerable:!0,value:l(m,n,a+1),writable:!0})}},J=(e,t)=>{const r=new Set(["message","name","stack"]);for(const o of Object.keys(t))r.add(o);for(const o of r)if(o in e){const n=Object.getOwnPropertyDescriptor(e,o);n&&!n.enumerable&&Object.defineProperty(e,o,{...n,enumerable:!0})}},w=e=>new p(JSON.stringify(e)),F=e=>new p(JSON.stringify(e)),L=(e,t)=>b(e)?v(e,t,0):$(e,t),G=(e,t={})=>{const r={..._,...t};return e instanceof Error?e:e===null?w(null):typeof e=="string"||typeof e=="number"||typeof e=="boolean"?w(e):Array.isArray(e)?F(e):b(e)?v(e,r,0):x(e)?L(e,r):new p(JSON.stringify(e))},M=e=>{const t=e.methodName&&e.methodName!=="<unknown>"?`${e.methodName} `:"",r=e.file??"<unknown>",o=String(e.line??0),n=String(e.column??0);return t.trim()?` at ${t}(${r}:${o}:${n})`:` at ${r}:${o}:${n}`},Q=(e,t)=>{const r=[];if(t?.header&&(t.header.name||t.header.message)){const o=t.header.name??"Error",n=t.header.message??"";r.push(`${o}${n?": ":""}${n}`)}for(const o of e)r.push(M(o));return r.join(`
76
+ `)},R=Object.create({},{cause:{enumerable:!1,value:void 0,writable:!0},code:{enumerable:!0,value:void 0,writable:!0},errors:{enumerable:!1,value:void 0,writable:!0},message:{enumerable:!1,value:void 0,writable:!0},name:{enumerable:!1,value:void 0,writable:!0},stack:{enumerable:!1,value:void 0,writable:!0}}),U=e=>{if(typeof e!="object"||e===null)return!1;const t=Object.getPrototypeOf(e);return t===null||t===Object.prototype||Object.getPrototypeOf(t)===null},g=new WeakSet,k=e=>{const t=Object.getOwnPropertyNames(e);for(const r of t){const o=Object.getOwnPropertyDescriptor(e,r);o&&(o.enumerable||Object.defineProperty(e,r,{...o,enumerable:!0}),o.value&&typeof o.value=="object"&&!Array.isArray(o.value)&&(Object.getPrototypeOf(o.value)===Object.prototype||Object.getPrototypeOf(o.value)===null)&&k(o.value))}},V=e=>{g.add(e);const t=e.toJSON();return g.delete(e),Object.isExtensible(t)&&k(t),t},f=(e,t,r,o,n=new Set)=>{if(e&&e instanceof Uint8Array&&e.constructor.name==="Buffer")return"[object Buffer]";if(e!==null&&typeof e=="object"&&"pipe"in e&&typeof e.pipe=="function")return"[object Stream]";if(e instanceof Error)return t.has(e)?"[Circular]":(r+=1,y(e,o,t,r));if(o.useToJSON&&e!==null&&typeof e=="object"&&"toJSON"in e&&typeof e.toJSON=="function")return e.toJSON();if(e instanceof Date)return e.toISOString();if(e instanceof RegExp)return e.toString();if(typeof URL<"u"&&e instanceof URL)return e.href;if(e instanceof Map){const a=[];for(const[i,s]of e.entries())a.push([f(i,t,r,o,n),f(s,t,r,o,n)]);return{__dataType:"Map",value:a}}if(e instanceof Set){const a=[];for(const i of e.values())a.push(f(i,t,r,o,n));return{__dataType:"Set",value:a}}if(typeof e=="function")return`[Function: ${e.name||"anonymous"}]`;if(typeof e=="bigint")return`${String(e)}n`;if(U(e)){if(n.has(e))return"[Circular]";if(o.maxDepth!==void 0&&o.maxDepth!==Number.POSITIVE_INFINITY&&r+1>=o.maxDepth)return{};r+=1,n.add(e);const a={};for(const i in e)a[i]=f(e[i],t,r,o,n);return n.delete(e),a}try{return e}catch{return"[Not Available]"}},y=(e,t,r,o)=>{if(r.add(e),t.maxDepth===0)return{};if(t.useToJSON&&typeof e.toJSON=="function"&&!g.has(e))return V(e);const n=Object.create(R);if(Object.defineProperty(n,"name",{configurable:!0,enumerable:!0,value:Object.prototype.toString.call(e.constructor)==="[object Function]"?e.constructor.name:e.name,writable:!0}),Object.defineProperty(n,"message",{configurable:!0,enumerable:!0,value:e.message,writable:!0}),Object.defineProperty(n,"stack",{configurable:!0,enumerable:!0,value:e.stack,writable:!0}),Array.isArray(e.errors)){const i=[];for(const s of e.errors){if(!(s instanceof Error))throw new TypeError("All errors in the 'errors' property must be instances of Error");if(r.has(s))return Object.defineProperty(n,"errors",{configurable:!0,enumerable:!0,value:[],writable:!0}),n;i.push(y(s,t,r,o))}Object.defineProperty(n,"errors",{configurable:!0,enumerable:!0,value:i,writable:!0})}const a=e.cause;if(a!=null)if(a instanceof Error)r.has(a)?Object.defineProperty(n,"cause",{configurable:!0,enumerable:!0,value:"[Circular]",writable:!0}):Object.defineProperty(n,"cause",{configurable:!0,enumerable:!0,value:y(a,t,r,o),writable:!0});else{const i=f(a,r,o,t);Object.defineProperty(n,"cause",{configurable:!0,enumerable:!0,value:i,writable:!0})}for(const i in e){if(i==="name"||i==="message"||i==="stack"||i==="cause"||i==="errors")continue;const s=e[i],m=f(s,r,o,t);Object.defineProperty(n,i,{configurable:!0,enumerable:!0,value:m,writable:!0})}if(Array.isArray(t.exclude)&&t.exclude.length>0)for(const i of t.exclude)try{delete n[i]}catch{}return n},Z=(e,t={})=>y(e,{exclude:t.exclude??[],maxDepth:t.maxDepth??Number.POSITIVE_INFINITY,useToJSON:t.useToJSON??!1},new Set,0);export{re as CODE_FRAME_POINTER,p as NonError,fe as VisulimaError,ne as addKnownErrorConstructor,B as aiPrompt,X as aiSolutionResponse,z as captureRawStackTrace,oe as codeFrame,ae as composeFilters,G as deserializeError,q as errorHintFinder,M as formatStackFrameLine,Q as formatStacktrace,ie as getErrorCauses,K as indexToLineColumn,b as isErrorLike,pe as isVisulimaError,se as parseStacktrace,ue as renderError,H as ruleBasedFinder,Z as serializeError,le as stackFilters};
@@ -0,0 +1 @@
1
+ import"./renderError-Dqej8k13-BmipVhik.js";import{h as r}from"./VisulimaError-DTMgXonA-CzaryRgZ.js";class n extends r{code;context;constructor(e,t,o){super({message:e,name:"CerebroError"}),this.code=t,this.context=o}}export{n as t};
@@ -1,8 +1,12 @@
1
1
  import { TableOptions } from '@visulima/tabular';
2
2
  /**
3
3
  * Definition for a command-line option.
4
+ *
5
+ * The optional `Name` and `Value` type parameters allow {@link CommandLineOptions}
6
+ * to be inferred from an `as const` array of definitions. They default to the
7
+ * loose runtime shape so plain `OptionDefinition` usage is unaffected.
4
8
  */
5
- interface OptionDefinition$1 {
9
+ interface OptionDefinition$1<Name extends string = string, Value = unknown> {
6
10
  /**
7
11
  * A getopt-style short option name. Can be any single character except a digit or hyphen.
8
12
  */
@@ -15,7 +19,7 @@ interface OptionDefinition$1 {
15
19
  /**
16
20
  * An initial value for the option.
17
21
  */
18
- defaultValue?: any;
22
+ defaultValue?: Value;
19
23
  /**
20
24
  * One or more group names the option belongs to.
21
25
  */
@@ -31,15 +35,19 @@ interface OptionDefinition$1 {
31
35
  /**
32
36
  * The long option name.
33
37
  */
34
- name: string;
38
+ name: Name;
35
39
  /**
36
40
  * A setter function (you receive the output from this) enabling you to be specific about the type and value received. Typical values
37
41
  * are `String` (the default), `Number` and `Boolean` but you can use a custom function. If no option value was set you will receive `null`.
38
42
  */
39
- type?: (input: string) => any;
43
+ type?: (input: string) => Value;
40
44
  }
41
45
  /**
42
- * Error thrown when an option is already set (duplicate assignment).
46
+ * Resolve a single {@link OptionDefinition} to the type of its parsed value,
47
+ * taking `type`, `multiple`/`lazyMultiple` and `defaultValue` into account.
48
+ *
49
+ * Part of the public type surface: re-exported from the package entry and used by
50
+ * {@link InferCommandLineOptions}.
43
51
  */
44
52
  /** A Content section comprises a header and one or more lines of content. */
45
53
  interface Content {
@@ -60,6 +68,217 @@ interface Content {
60
68
  raw?: boolean;
61
69
  }
62
70
  /**
71
+ * Context provided to plugins during initialization
72
+ */
73
+ interface PluginContext<T extends Console = Console> {
74
+ /** The CLI instance */
75
+ cli: Cli<T>;
76
+ /** Current working directory */
77
+ cwd: string;
78
+ /** Logger instance */
79
+ logger: T;
80
+ }
81
+ /**
82
+ * Plugin interface with lifecycle hooks
83
+ */
84
+ interface Plugin<T extends Console = Console> {
85
+ /**
86
+ * Called after command execution completes successfully
87
+ * @param toolbox The command toolbox
88
+ * @param result The result returned by the command
89
+ */
90
+ afterCommand?: (toolbox: Toolbox<T>, result: unknown) => Promise<void> | void;
91
+ /**
92
+ * Called before command execution
93
+ * @param toolbox The command toolbox
94
+ */
95
+ beforeCommand?: (toolbox: Toolbox<T>) => Promise<void> | void;
96
+ /** Plugin dependencies (other plugin names that must be loaded first) */
97
+ dependencies?: string[];
98
+ /** Plugin description */
99
+ description?: string;
100
+ /**
101
+ * Called during command execution (for plugins that extend toolbox functionality)
102
+ * @param toolbox The command toolbox
103
+ */
104
+ execute?: (toolbox: Toolbox<T>) => Promise<void> | void;
105
+ /**
106
+ * Called once during plugin initialization
107
+ * @param context The plugin context
108
+ */
109
+ init?: (context: PluginContext<T>) => Promise<void> | void;
110
+ /** Plugin name (must be unique) */
111
+ name: string;
112
+ /**
113
+ * Called when an error occurs during command execution
114
+ * @param error The error that occurred
115
+ * @param toolbox The command toolbox
116
+ */
117
+ onError?: (error: Error, toolbox: Toolbox<T>) => Promise<void> | void;
118
+ /** Plugin version */
119
+ version?: string;
120
+ }
121
+ type Logger = Console;
122
+ /**
123
+ * Manages plugin lifecycle and execution
124
+ */
125
+ declare class PluginManager<T extends Logger = Logger> {
126
+ private readonly logger;
127
+ private readonly plugins;
128
+ private initialized;
129
+ private cachedDependencyOrder;
130
+ constructor(logger: T);
131
+ /**
132
+ * Checks if any plugins are registered.
133
+ * @returns True if at least one plugin is registered
134
+ */
135
+ hasPlugins(): boolean;
136
+ /**
137
+ * Registers a plugin.
138
+ * @param plugin The plugin to register
139
+ * @throws {Error} If plugin name is already registered or dependencies are invalid
140
+ */
141
+ register(plugin: Plugin<T>): void;
142
+ /**
143
+ * Initializes all registered plugins.
144
+ * @param context The plugin context for initialization
145
+ */
146
+ init(context: PluginContext<T>): Promise<void>;
147
+ /**
148
+ * Executes a specific lifecycle hook for all plugins.
149
+ * @param hook The lifecycle hook name
150
+ * @param toolbox The command toolbox (for command-specific hooks)
151
+ * @param result The command result (for afterCommand hook)
152
+ */
153
+ executeLifecycle(hook: "beforeCommand" | "afterCommand" | "execute", toolbox: Toolbox<T>, result?: unknown): Promise<void>;
154
+ /**
155
+ * Executes error handlers for all plugins.
156
+ * @param error The error that occurred
157
+ * @param toolbox The command toolbox
158
+ */
159
+ executeErrorHandlers(error: Error, toolbox: Toolbox<T>): Promise<void>;
160
+ /**
161
+ * Gets all registered plugins in dependency order.
162
+ * @returns Array of plugins sorted by dependencies
163
+ */
164
+ getDependencyOrder(): Plugin<T>[];
165
+ /**
166
+ * Validates that all plugin dependencies exist.
167
+ * @throws {Error} If any dependencies are missing
168
+ */
169
+ private validateDependencies;
170
+ }
171
+ type CommandSection = {
172
+ footer?: string;
173
+ header?: string;
174
+ };
175
+ type CliRunOptions = {
176
+ [key: string]: unknown;
177
+ /**
178
+ * Whether to automatically dispose/cleanup the CLI instance after execution
179
+ * @default true
180
+ */
181
+ autoDispose?: boolean;
182
+ shouldExitProcess?: boolean;
183
+ };
184
+ type RunCommandOptions = {
185
+ /**
186
+ * Extra options to merge into the command's options.
187
+ * These will be merged with the command's default options and parsed arguments.
188
+ * Use this to override or add additional options programmatically.
189
+ * @default Empty object
190
+ */
191
+ [key: string]: unknown;
192
+ /**
193
+ * Command-line arguments to pass to the command.
194
+ * If not provided, uses the default argv from the CLI instance.
195
+ * These arguments will be parsed and merged with the command's options.
196
+ * @default Empty array
197
+ */
198
+ argv?: string[];
199
+ };
200
+ interface Cli<T extends Console> {
201
+ /**
202
+ * Add an arbitrary command to the CLI.
203
+ * @param command The command to add.
204
+ * @returns self
205
+ */
206
+ addCommand: <OD extends OptionDefinition<unknown> = OptionDefinition<unknown>>(command: Command<OD, T>) => this;
207
+ /**
208
+ * Add a global option available to all commands.
209
+ * Global options are parsed alongside command options and shown in help output.
210
+ * @param option The option definition
211
+ * @returns self
212
+ */
213
+ addGlobalOption: <V = unknown>(option: OptionDefinition<V>) => this;
214
+ /**
215
+ * Add a plugin to extend the CLI functionality
216
+ * @param plugin The plugin to add.
217
+ * @returns self
218
+ */
219
+ addPlugin: (plugin: Plugin<T>) => this;
220
+ /**
221
+ * Disposes the CLI instance and cleans up resources
222
+ * @returns void
223
+ */
224
+ dispose: () => void;
225
+ getCliName: () => string;
226
+ getCommands: () => Map<string, Command<OptionDefinition<unknown>, T>>;
227
+ getCommandSection: () => CommandSection;
228
+ getCwd: () => string;
229
+ /**
230
+ * Gets all global options (built-in + custom).
231
+ */
232
+ getGlobalOptions: () => OptionDefinition<unknown>[];
233
+ getPackageName: () => string | undefined;
234
+ getPackageVersion: () => string | undefined;
235
+ /**
236
+ * Get the plugin manager instance
237
+ * @returns The plugin manager
238
+ */
239
+ getPluginManager: () => PluginManager<T>;
240
+ run: (extraOptions?: CliRunOptions) => Promise<void>;
241
+ /**
242
+ * Runs a command programmatically from within another command.
243
+ * This allows commands to call other commands during execution.
244
+ * @param commandName The name of the command to execute
245
+ * @param options Optional options including argv and other command options
246
+ * @returns A promise that resolves with the command's result (or void if command doesn't return a value)
247
+ * @throws {Error} If the specified command doesn't exist or command arguments are invalid
248
+ * @example
249
+ * ```typescript
250
+ * cli.addCommand({
251
+ * name: 'deploy',
252
+ * execute: async ({ runtime, logger }) => {
253
+ * logger.info('Building...');
254
+ * const buildResult = await runtime.runCommand('build', { argv: ['--production'] });
255
+ * // buildResult is the return value from the build command's execute function
256
+ *
257
+ * logger.info('Testing...');
258
+ * await runtime.runCommand('test', { argv: ['--coverage'] });
259
+ * }
260
+ * });
261
+ * ```
262
+ */
263
+ runCommand: (commandName: string, options?: RunCommandOptions) => Promise<unknown>;
264
+ setCommandSection: (commandSection: CommandSection) => this;
265
+ /**
266
+ * Set a default command, to display a different command if cli is call without command.
267
+ * @param commandName
268
+ * @returns self
269
+ */
270
+ setDefaultCommand: (commandName: string) => this;
271
+ }
272
+ /**
273
+ * Any of the output types [[OUTPUT_NORMAL]], [[OUTPUT_RAW]] and [[OUTPUT_PLAIN]].
274
+ */
275
+ type OutputType = 1 | 2 | 4;
276
+ /**
277
+ * Any of the verbosity types
278
+ * [[VERBOSITY_QUIET]], [[VERBOSITY_NORMAL]], [[VERBOSITY_VERBOSE]] and [[VERBOSITY_DEBUG]].
279
+ */
280
+ type VERBOSITY_LEVEL = 16 | 32 | 64 | 128 | 256;
281
+ /**
63
282
  * A flexible object for the many "options" objects we throw around in cerebro.
64
283
  */
65
284
  type Options = Record<string | symbol, unknown>;
@@ -268,6 +487,17 @@ type MultiplePropertyOptions<T> = T extends ReadonlyArray<unknown> ? {
268
487
  multiple: true;
269
488
  } : unknown;
270
489
  type OptionDefinition<T> = MultiplePropertyOptions<T> & Omit<OptionDefinition$1, "type|defaultValue"> & {
490
+ /**
491
+ * Restricts the accepted values for this option to a fixed set, validated
492
+ * at parse time (like commander's `.choices()` / yargs `choices`). The
493
+ * provided value(s) are compared by string equality; for `multiple`
494
+ * options every provided value must be a member of the set.
495
+ * @example
496
+ * ```typescript
497
+ * { name: "format", type: String, choices: ["json", "yaml", "table"] }
498
+ * ```
499
+ */
500
+ choices?: ReadonlyArray<string>;
271
501
  /**
272
502
  * A string or array of strings indicating the conflicting option(s).
273
503
  * Note: The default value for an option does not cause a conflict.
@@ -406,215 +636,4 @@ interface Command<O extends OptionDefinition<unknown> = OptionDefinition<unknown
406
636
  options?: (O | OptionDefinition<boolean[]> | OptionDefinition<boolean> | OptionDefinition<number[]> | OptionDefinition<number> | OptionDefinition<string[]> | OptionDefinition<string>)[];
407
637
  usage?: Content[];
408
638
  }
409
- type CommandSection = {
410
- footer?: string;
411
- header?: string;
412
- };
413
- type CliRunOptions = {
414
- [key: string]: unknown;
415
- /**
416
- * Whether to automatically dispose/cleanup the CLI instance after execution
417
- * @default true
418
- */
419
- autoDispose?: boolean;
420
- shouldExitProcess?: boolean;
421
- };
422
- type RunCommandOptions = {
423
- /**
424
- * Extra options to merge into the command's options.
425
- * These will be merged with the command's default options and parsed arguments.
426
- * Use this to override or add additional options programmatically.
427
- * @default Empty object
428
- */
429
- [key: string]: unknown;
430
- /**
431
- * Command-line arguments to pass to the command.
432
- * If not provided, uses the default argv from the CLI instance.
433
- * These arguments will be parsed and merged with the command's options.
434
- * @default Empty array
435
- */
436
- argv?: string[];
437
- };
438
- interface Cli<T extends Console> {
439
- /**
440
- * Add an arbitrary command to the CLI.
441
- * @param command The command to add.
442
- * @returns self
443
- */
444
- addCommand: <OD extends OptionDefinition<unknown> = OptionDefinition<unknown>>(command: Command<OD, T>) => this;
445
- /**
446
- * Add a global option available to all commands.
447
- * Global options are parsed alongside command options and shown in help output.
448
- * @param option The option definition
449
- * @returns self
450
- */
451
- addGlobalOption: <V = unknown>(option: OptionDefinition<V>) => this;
452
- /**
453
- * Add a plugin to extend the CLI functionality
454
- * @param plugin The plugin to add.
455
- * @returns self
456
- */
457
- addPlugin: (plugin: Plugin<T>) => this;
458
- /**
459
- * Disposes the CLI instance and cleans up resources
460
- * @returns void
461
- */
462
- dispose: () => void;
463
- getCliName: () => string;
464
- getCommands: () => Map<string, Command<OptionDefinition<unknown>, T>>;
465
- getCommandSection: () => CommandSection;
466
- getCwd: () => string;
467
- /**
468
- * Gets all global options (built-in + custom).
469
- */
470
- getGlobalOptions: () => OptionDefinition<unknown>[];
471
- getPackageName: () => string | undefined;
472
- getPackageVersion: () => string | undefined;
473
- /**
474
- * Get the plugin manager instance
475
- * @returns The plugin manager
476
- */
477
- getPluginManager: () => PluginManager<T>;
478
- run: (extraOptions?: CliRunOptions) => Promise<void>;
479
- /**
480
- * Runs a command programmatically from within another command.
481
- * This allows commands to call other commands during execution.
482
- * @param commandName The name of the command to execute
483
- * @param options Optional options including argv and other command options
484
- * @returns A promise that resolves with the command's result (or void if command doesn't return a value)
485
- * @throws {Error} If the specified command doesn't exist or command arguments are invalid
486
- * @example
487
- * ```typescript
488
- * cli.addCommand({
489
- * name: 'deploy',
490
- * execute: async ({ runtime, logger }) => {
491
- * logger.info('Building...');
492
- * const buildResult = await runtime.runCommand('build', { argv: ['--production'] });
493
- * // buildResult is the return value from the build command's execute function
494
- *
495
- * logger.info('Testing...');
496
- * await runtime.runCommand('test', { argv: ['--coverage'] });
497
- * }
498
- * });
499
- * ```
500
- */
501
- runCommand: (commandName: string, options?: RunCommandOptions) => Promise<unknown>;
502
- setCommandSection: (commandSection: CommandSection) => this;
503
- /**
504
- * Set a default command, to display a different command if cli is call without command.
505
- * @param commandName
506
- * @returns self
507
- */
508
- setDefaultCommand: (commandName: string) => this;
509
- }
510
- /**
511
- * Any of the output types [[OUTPUT_NORMAL]], [[OUTPUT_RAW]] and [[OUTPUT_PLAIN]].
512
- */
513
- type OutputType = 1 | 2 | 4;
514
- /**
515
- * Any of the verbosity types
516
- * [[VERBOSITY_QUIET]], [[VERBOSITY_NORMAL]], [[VERBOSITY_VERBOSE]] and [[VERBOSITY_DEBUG]].
517
- */
518
- type VERBOSITY_LEVEL = 16 | 32 | 64 | 128 | 256;
519
- /**
520
- * Context provided to plugins during initialization
521
- */
522
- interface PluginContext<T extends Console = Console> {
523
- /** The CLI instance */
524
- cli: Cli<T>;
525
- /** Current working directory */
526
- cwd: string;
527
- /** Logger instance */
528
- logger: T;
529
- }
530
- /**
531
- * Plugin interface with lifecycle hooks
532
- */
533
- interface Plugin<T extends Console = Console> {
534
- /**
535
- * Called after command execution completes successfully
536
- * @param toolbox The command toolbox
537
- * @param result The result returned by the command
538
- */
539
- afterCommand?: (toolbox: Toolbox<T>, result: unknown) => Promise<void> | void;
540
- /**
541
- * Called before command execution
542
- * @param toolbox The command toolbox
543
- */
544
- beforeCommand?: (toolbox: Toolbox<T>) => Promise<void> | void;
545
- /** Plugin dependencies (other plugin names that must be loaded first) */
546
- dependencies?: string[];
547
- /** Plugin description */
548
- description?: string;
549
- /**
550
- * Called during command execution (for plugins that extend toolbox functionality)
551
- * @param toolbox The command toolbox
552
- */
553
- execute?: (toolbox: Toolbox<T>) => Promise<void> | void;
554
- /**
555
- * Called once during plugin initialization
556
- * @param context The plugin context
557
- */
558
- init?: (context: PluginContext<T>) => Promise<void> | void;
559
- /** Plugin name (must be unique) */
560
- name: string;
561
- /**
562
- * Called when an error occurs during command execution
563
- * @param error The error that occurred
564
- * @param toolbox The command toolbox
565
- */
566
- onError?: (error: Error, toolbox: Toolbox<T>) => Promise<void> | void;
567
- /** Plugin version */
568
- version?: string;
569
- }
570
- type Logger = Console;
571
- /**
572
- * Manages plugin lifecycle and execution
573
- */
574
- declare class PluginManager<T extends Logger = Logger> {
575
- private readonly logger;
576
- private readonly plugins;
577
- private initialized;
578
- private cachedDependencyOrder;
579
- constructor(logger: T);
580
- /**
581
- * Checks if any plugins are registered.
582
- * @returns True if at least one plugin is registered
583
- */
584
- hasPlugins(): boolean;
585
- /**
586
- * Registers a plugin.
587
- * @param plugin The plugin to register
588
- * @throws {Error} If plugin name is already registered or dependencies are invalid
589
- */
590
- register(plugin: Plugin<T>): void;
591
- /**
592
- * Initializes all registered plugins.
593
- * @param context The plugin context for initialization
594
- */
595
- init(context: PluginContext<T>): Promise<void>;
596
- /**
597
- * Executes a specific lifecycle hook for all plugins.
598
- * @param hook The lifecycle hook name
599
- * @param toolbox The command toolbox (for command-specific hooks)
600
- * @param result The command result (for afterCommand hook)
601
- */
602
- executeLifecycle(hook: "beforeCommand" | "afterCommand" | "execute", toolbox: Toolbox<T>, result?: unknown): Promise<void>;
603
- /**
604
- * Executes error handlers for all plugins.
605
- * @param error The error that occurred
606
- * @param toolbox The command toolbox
607
- */
608
- executeErrorHandlers(error: Error, toolbox: Toolbox<T>): Promise<void>;
609
- /**
610
- * Gets all registered plugins in dependency order.
611
- * @returns Array of plugins sorted by dependencies
612
- */
613
- getDependencyOrder(): Plugin<T>[];
614
- /**
615
- * Validates that all plugin dependencies exist.
616
- * @throws {Error} If any dependencies are missing
617
- */
618
- private validateDependencies;
619
- }
620
639
  export { ArgumentDefinition as A, Command as C, EnvDefinition as E, LazyCommandModule as L, OptionDefinition as O, Plugin as P, RunCommandOptions as R, Toolbox as T, VERBOSITY_LEVEL as V, CerebroFs as a, CommandSection as b, PluginManager as c, CliRunOptions as d, CommandExecute as e, Cli as f, CerebroProcess as g, OutputType as h, PluginContext as i };