kraken-code 1.3.3 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +24 -24
- package/dist/index.js +231 -459
- package/package.json +1 -2
package/dist/cli/index.js
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
-
var
|
|
4
|
-
`)[0]?.trim()??null}}catch{}return{exists:!1,path:null}}async function V(n){try{let t=Bun.spawn([n,"--version"],{stdout:"pipe",stderr:"pipe"}),e=await new Response(t.stdout).text(),
|
|
5
|
-
`)[0]}catch{}return null}async function
|
|
6
|
-
`)[0]}catch{}return null}async function
|
|
7
|
-
`);
|
|
8
|
-
`+g}return
|
|
3
|
+
var w=import.meta.require;import{Command as de}from"commander";import x from"picocolors";var O={check:x.green("\u2713"),cross:x.red("\u2717"),warn:x.yellow("\u26A0"),info:x.blue("\u2139"),arrow:x.cyan("\u2192"),bullet:x.dim("\u2022"),skip:x.dim("\u25CB")},B={pass:x.green,fail:x.red,warn:x.yellow,skip:x.dim},i={OPENCODE_INSTALLATION:"opencode-installation",PLUGIN_REGISTRATION:"plugin-registration",CONFIG_VALIDATION:"config-validation",AUTH_ANTHROPIC:"auth-anthropic",AUTH_OPENAI:"auth-openai",DEP_AST_GREP_CLI:"dep-ast-grep-cli",DEP_AST_GREP_NAPI:"dep-ast-grep-napi",DEP_PYTHON:"dep-python",DEP_RIPGREP:"dep-ripgrep",DEP_COMMENT_CHECKER:"dep-comment-checker",GH_CLI:"gh-cli",LSP_SERVERS:"lsp-servers",MCP_BUILTIN:"mcp-builtin",MCP_USER:"mcp-user",VERSION_STATUS:"version-status"},o={[i.OPENCODE_INSTALLATION]:"OpenCode Installation",[i.PLUGIN_REGISTRATION]:"Plugin Registration",[i.CONFIG_VALIDATION]:"Configuration Validity",[i.AUTH_ANTHROPIC]:"Anthropic (Claude) Auth",[i.AUTH_OPENAI]:"OpenAI (ChatGPT) Auth",[i.DEP_AST_GREP_CLI]:"AST-Grep CLI",[i.DEP_AST_GREP_NAPI]:"AST-Grep NAPI",[i.DEP_PYTHON]:"Python 3",[i.DEP_RIPGREP]:"ripgrep (rg)",[i.DEP_COMMENT_CHECKER]:"Comment Checker",[i.GH_CLI]:"GitHub CLI",[i.LSP_SERVERS]:"LSP Servers",[i.MCP_BUILTIN]:"Built-in MCP Servers",[i.MCP_USER]:"User MCP Configuration",[i.VERSION_STATUS]:"Version Status"},K={installation:"Installation",configuration:"Configuration",authentication:"Authentication",dependencies:"Dependencies",tools:"Tools & Servers",updates:"Updates"},v={SUCCESS:0,FAILURE:1},k="1.0.150",R="kraken-code",nn=["opencode","opencode-desktop"];async function qn(){for(let n of nn)try{let t=Bun.spawn(["which",n],{stdout:"pipe",stderr:"pipe"}),e=await new Response(t.stdout).text();if(await t.exited,t.exitCode===0)return{binary:n,path:e.trim()}}catch{continue}return null}async function Xn(n){try{let t=Bun.spawn([n,"--version"],{stdout:"pipe",stderr:"pipe"}),e=await new Response(t.stdout).text();if(await t.exited,t.exitCode===0)return e.trim()}catch{return null}return null}function Wn(n,t){let e=(a)=>{return a.replace(/^v/,"").split("-")[0].split(".").map((g)=>parseInt(g,10)||0)},s=e(n),r=e(t);for(let a=0;a<Math.max(s.length,r.length);a++){let p=s[a]??0,g=r[a]??0;if(p>g)return!0;if(p<g)return!1}return!0}async function Mn(){let n=await qn();if(!n)return{installed:!1,version:null,path:null,binary:null};return{installed:!0,version:await Xn(n.binary),path:n.path,binary:n.binary}}async function Qn(){let n=await Mn();if(!n.installed)return{name:o[i.OPENCODE_INSTALLATION],status:"fail",message:"OpenCode is not installed",details:["Visit: https://opencode.ai/docs for installation instructions","Run: npm install -g opencode"]};if(n.version&&!Wn(n.version,k))return{name:o[i.OPENCODE_INSTALLATION],status:"warn",message:`Version ${n.version} is below minimum ${k}`,details:[`Current: ${n.version}`,`Required: >= ${k}`,"Run: npm update -g opencode"]};return{name:o[i.OPENCODE_INSTALLATION],status:"pass",message:n.version??"installed",details:n.path?[`Path: ${n.path}`]:void 0}}function tn(){return{id:i.OPENCODE_INSTALLATION,name:o[i.OPENCODE_INSTALLATION],category:"installation",check:Qn,critical:!0}}import{existsSync as en,readFileSync as Zn}from"fs";import*as sn from"jsonc-parser";import S from"path";import Hn from"os";function rn(){let n=S.join(Hn.homedir(),".config","opencode");return{configJson:S.join(n,"opencode.json"),configJsonc:S.join(n,"opencode.jsonc")}}function Yn(n){let t=[],e=sn.parse(n,t,{allowTrailingComma:!0});if(t.length>0)throw Error(`JSONC parse error: ${t[0].error}`);return e}function Bn(){let n=rn();if(en(n.configJsonc))return{path:n.configJsonc,format:"jsonc"};if(en(n.configJson))return{path:n.configJson,format:"json"};return null}function Kn(n){for(let t of n)if(t===R||t.startsWith(`${R}@`)){let e=t.includes("@"),s=e?t.split("@")[1]:null;return{entry:t,isPinned:e,version:s}}return null}function nt(){let n=Bn();if(!n)return{registered:!1,configPath:null,entry:null,isPinned:!1,pinnedVersion:null};try{let t=Zn(n.path,"utf-8"),s=Yn(t).plugin??[],r=Kn(s);if(!r)return{registered:!1,configPath:n.path,entry:null,isPinned:!1,pinnedVersion:null};return{registered:!0,configPath:n.path,entry:r.entry,isPinned:r.isPinned,pinnedVersion:r.version}}catch{return{registered:!1,configPath:n.path,entry:null,isPinned:!1,pinnedVersion:null}}}async function tt(){let n=nt();if(!n.configPath){let e=rn();return{name:o[i.PLUGIN_REGISTRATION],status:"fail",message:"OpenCode config file not found",details:["Run: kraken-code install",`Expected: ${e.configJson} or ${e.configJsonc}`]}}if(!n.registered)return{name:o[i.PLUGIN_REGISTRATION],status:"fail",message:"Plugin not registered in config",details:["Run: kraken-code install",`Config: ${n.configPath}`]};let t=n.isPinned?`Registered (pinned: ${n.pinnedVersion})`:"Registered";return{name:o[i.PLUGIN_REGISTRATION],status:"pass",message:t,details:[`Config: ${n.configPath}`]}}function an(){return{id:i.PLUGIN_REGISTRATION,name:o[i.PLUGIN_REGISTRATION],category:"installation",check:tt,critical:!0}}import{existsSync as et,readFileSync as st}from"fs";import*as on from"jsonc-parser";import G from"path";import it from"os";function rt(){let n=G.join(it.homedir(),".config","opencode");return{configJson:G.join(n,"opencode.json"),configJsonc:G.join(n,"opencode.jsonc")}}function at(n){let t=[],e=on.parse(n,t,{allowTrailingComma:!0});if(t.length>0)throw Error(`JSONC parse error: ${t[0].error}`);return e}async function ot(){let n=rt(),t=n.configJsonc||n.configJson;if(!et(t))return{name:o[i.CONFIG_VALIDATION],status:"fail",message:"OpenCode config file not found",details:[`Expected: ${t}`]};try{let e=st(t,"utf-8");return at(e),{name:o[i.CONFIG_VALIDATION],status:"pass",message:"Config file is valid JSONC",details:[`Config: ${t}`]}}catch(e){return{name:o[i.CONFIG_VALIDATION],status:"fail",message:`Config parse error: ${e instanceof Error?e.message:"Unknown error"}`,details:[`Config: ${t}`]}}}function cn(){return{id:i.CONFIG_VALIDATION,name:o[i.CONFIG_VALIDATION],category:"configuration",check:ot,critical:!1}}import{existsSync as pn,readFileSync as ct}from"fs";import{homedir as ut}from"os";import{join as U}from"path";import*as un from"jsonc-parser";function A(n){let t=[],e=un.parse(n,t,{allowTrailingComma:!0});if(t.length>0)throw Error(`JSONC parse error: ${t[0].error}`);return e}var mn=U(ut(),".config","opencode"),pt=U(mn,"opencode.json"),ln=U(mn,"opencode.jsonc"),J={anthropic:{plugin:"builtin",name:"Anthropic (Claude)"},openai:{plugin:"opencode-openai-codex-auth",name:"OpenAI (ChatGPT)"}};function lt(){let n=pn(ln)?ln:pt;if(!pn(n))return null;try{let t=ct(n,"utf-8");return A(t)}catch{return null}}function mt(n,t){if(t==="builtin")return!0;return n.some((e)=>e===t||e.startsWith(`${t}@`))}function gt(n){let e=lt()?.plugin??[],s=J[n],r=mt(e,s.plugin);return{id:n,name:s.name,pluginInstalled:r,configured:r}}async function gn(n){let t=gt(n),e=`auth-${n}`,s=o[e]||t.name;if(!t.pluginInstalled)return{name:s,status:"skip",message:"Auth plugin not installed",details:[`Plugin: ${J[n].plugin}`,"Run: kraken-code install"]};return{name:s,status:"pass",message:"Auth plugin available",details:[n==="anthropic"?"Run: opencode auth login (select Anthropic)":`Plugin: ${J[n].plugin}`]}}async function ft(){return gn("anthropic")}async function dt(){return gn("openai")}function fn(){return[{id:i.AUTH_ANTHROPIC,name:o[i.AUTH_ANTHROPIC],category:"authentication",check:ft,critical:!1},{id:i.AUTH_OPENAI,name:o[i.AUTH_OPENAI],category:"authentication",check:dt,critical:!1}]}function ht(){return process.platform==="win32"?["where"]:["which"]}async function y(n){try{let t=Bun.spawn([...ht(),n],{stdout:"pipe",stderr:"pipe"}),e=await new Response(t.stdout).text();if(await t.exited,t.exitCode===0)return{exists:!0,path:e.trim().split(`
|
|
4
|
+
`)[0]?.trim()??null}}catch{}return{exists:!1,path:null}}async function V(n){try{let t=Bun.spawn([n,"--version"],{stdout:"pipe",stderr:"pipe"}),e=await new Response(t.stdout).text(),s=await new Response(t.stderr).text();if(await t.exited,t.exitCode===0)return(e.trim()||s.trim()).split(`
|
|
5
|
+
`)[0]}catch{}return null}async function Pt(){let n=await y("sg"),t=!n.exists?await y("ast-grep"):null,e=n.exists?n:t;if(!e||!e.exists)return{name:"AST-Grep CLI",required:!1,installed:!1,version:null,path:null,installHint:"Install: npm install -g @ast-grep/cli"};return{name:"AST-Grep CLI",required:!1,installed:!0,version:await V(e.path),path:e.path}}function It(){try{return w.resolve("@ast-grep/napi"),{name:"AST-Grep NAPI",required:!1,installed:!0,version:null,path:null}}catch{return{name:"AST-Grep NAPI",required:!1,installed:!1,version:null,path:null,installHint:"Will use CLI fallback if available"}}}async function xt(){let n=await y("python3"),t=!n.exists?await y("python"):null,e=n.exists?n:t;if(!e||!e.exists)return{name:"Python 3",required:!1,installed:!1,version:null,path:null,installHint:process.platform==="win32"?"Install: https://www.python.org/downloads/windows/":"Install: https://www.python.org/downloads/"};return{name:"Python 3",required:!1,installed:!0,version:await V(e.path),path:e.path}}async function Ot(){let n=await y("rg");if(!n.exists)return{name:"ripgrep (rg)",required:!1,installed:!1,version:null,path:null,installHint:"Install: apt install ripgrep or brew install ripgrep"};return{name:"ripgrep (rg)",required:!1,installed:!0,version:await V(n.path),path:n.path}}function _(n,t){if(n.installed)return{name:t,status:"pass",message:n.version??"installed",details:n.path?[`Path: ${n.path}`]:void 0};return{name:t,status:"warn",message:"Not installed (optional)",details:n.installHint?[n.installHint]:void 0}}async function Rt(){let n=await Pt();return _(n,o[i.DEP_AST_GREP_CLI])}async function Et(){let n=It();return _(n,o[i.DEP_AST_GREP_NAPI])}async function At(){let n=await xt();return _(n,o[i.DEP_PYTHON])}async function Nt(){let n=await Ot();return _(n,o[i.DEP_RIPGREP])}async function jt(){return{name:"Comment Checker",status:"pass",message:"Built-in hook, always available",details:["Comment checking is handled by hooks/comment-checker"]}}function dn(){return[{id:i.DEP_AST_GREP_CLI,name:o[i.DEP_AST_GREP_CLI],category:"dependencies",check:Rt,critical:!1},{id:i.DEP_AST_GREP_NAPI,name:o[i.DEP_AST_GREP_NAPI],category:"dependencies",check:Et,critical:!1},{id:i.DEP_PYTHON,name:o[i.DEP_PYTHON],category:"dependencies",check:At,critical:!1},{id:i.DEP_RIPGREP,name:o[i.DEP_RIPGREP],category:"dependencies",check:Nt,critical:!1},{id:i.DEP_COMMENT_CHECKER,name:o[i.DEP_COMMENT_CHECKER],category:"dependencies",check:jt,critical:!1}]}async function wt(n){try{let t=Bun.spawn(["which",n],{stdout:"pipe",stderr:"pipe"}),e=await new Response(t.stdout).text();if(await t.exited,t.exitCode===0)return{exists:!0,path:e.trim()}}catch{}return{exists:!1,path:null}}async function kt(){try{let n=Bun.spawn(["gh","--version"],{stdout:"pipe",stderr:"pipe"}),t=await new Response(n.stdout).text();if(await n.exited,n.exitCode===0)return t.match(/gh version (\S+)/)?.[1]??t.trim().split(`
|
|
6
|
+
`)[0]}catch{}return null}async function Ct(){try{let n=Bun.spawn(["gh","auth","status"],{stdout:"pipe",stderr:"pipe",env:{...process.env,GH_NO_UPDATE_NOTIFIER:"1"}}),t=await new Response(n.stdout).text(),e=await new Response(n.stderr).text();await n.exited;let s=e||t;if(n.exitCode===0){let p=s.match(/Logged in to github\.com account (\S+)/)?.[1]?.replace(/[()]/g,"")??null,g=s.match(/Token scopes?:\s*(.+)/i),f=g?.[1]?g[1].split(/,\s*/).map((c)=>c.replace(/['"]/g,"").trim()).filter(Boolean):[];return{authenticated:!0,username:p,scopes:f,error:null}}let r=s.match(/error[:\s]+(.+)/i);return{authenticated:!1,username:null,scopes:[],error:r?.[1]?.trim()??"Not authenticated"}}catch(n){return{authenticated:!1,username:null,scopes:[],error:n instanceof Error?n.message:"Failed to check auth status"}}}async function vt(){let n=await wt("gh");if(!n.exists)return{installed:!1,version:null,path:null,authenticated:!1,username:null,scopes:[],error:null};let[t,e]=await Promise.all([kt(),Ct()]);return{installed:!0,version:t,path:n.path,authenticated:e.authenticated,username:e.username,scopes:e.scopes,error:e.error}}async function yt(){let n=await vt(),t=o[i.GH_CLI];if(!n.installed)return{name:t,status:"warn",message:"Not installed (optional)",details:["GitHub CLI is used by librarian agent and scripts","Install: https://cli.github.com/"]};if(!n.authenticated)return{name:t,status:"warn",message:`${n.version??"installed"} - not authenticated`,details:[n.path?`Path: ${n.path}`:null,"Authenticate: gh auth login",n.error?`Error: ${n.error}`:null].filter((s)=>s!==null)};let e=[];if(n.path)e.push(`Path: ${n.path}`);if(n.username)e.push(`Account: ${n.username}`);if(n.scopes.length>0)e.push(`Scopes: ${n.scopes.join(", ")}`);return{name:t,status:"pass",message:`${n.version??"installed"} - authenticated as ${n.username??"unknown"}`,details:e.length>0?e:void 0}}function hn(){return{id:i.GH_CLI,name:o[i.GH_CLI],category:"tools",check:yt,critical:!1}}function z(n){return{"typescript-language-server":"npm install -g typescript-language-server typescript",pyright:"npm install -g pyright","rust-analyzer":"rustup component add rust-analyzer",gopls:"go install golang.org/x/tools/gopls@latest",jdtls:"Install from https://download.eclipse.org/jdtls/snapshots/",clangd:"Install from https://clangd.llvm.org/installation",omnisharp:"Install from https://github.com/OmniSharp/omnisharp-roslyn",intelephense:"npm install -g intelephense","ruby-lsp":"gem install ruby-lsp","dart-analysis-server":"Install Dart SDK from https://dart.dev/get-dart","lua-language-server":"Install from https://github.com/LuaLS/lua-language-server","kotlin-language-server":"Install from https://github.com/fwcd/kotlin-language-server","svelte-language-server":"npm install -g svelte-language-server","vue-language-server":"npm install -g @vue/language-server","elixir-ls":"Install from https://github.com/elixir-lsp/elixir-ls","terraform-ls":"Install from https://github.com/hashicorp/terraform-ls"}[n]??`Install ${n}`}var Tt=[{id:"typescript-language-server",binary:"typescript-language-server",extensions:[".ts",".tsx",".js",".jsx"]},{id:"pyright",binary:"pyright-langserver",extensions:[".py"]},{id:"rust-analyzer",binary:"rust-analyzer",extensions:[".rs"]},{id:"gopls",binary:"gopls",extensions:[".go"]}];function bt(){return process.platform==="win32"?["where"]:["which"]}async function Lt(n){try{let t=Bun.spawn([...bt(),n],{stdout:"pipe",stderr:"pipe"});return await t.exited,t.exitCode===0}catch{return!1}}async function _t(){let n=[];for(let t of Tt){let e=await Lt(t.binary);n.push({id:t.id,installed:e,extensions:t.extensions,source:"builtin"})}return n}function Dt(n){return{installed:n.filter((e)=>e.installed).length,total:n.length}}async function $t(){let n=await _t(),t=Dt(n),e=n.filter((a)=>a.installed),s=n.filter((a)=>!a.installed);if(t.installed===0)return{name:o[i.LSP_SERVERS],status:"warn",message:"No LSP servers detected",details:["LSP tools will have limited functionality",...s.map((a)=>`Missing: ${a.id} (install: ${z(a.id)})`)]};let r=[...e.map((a)=>`Installed: ${a.id}`),...s.map((a)=>`Not found: ${a.id} (install: ${z(a.id)})`)];return{name:o[i.LSP_SERVERS],status:"pass",message:`${t.installed}/${t.total} servers available`,details:r}}function Pn(){return{id:i.LSP_SERVERS,name:o[i.LSP_SERVERS],category:"tools",check:$t,critical:!1}}import{existsSync as St,readFileSync as Gt}from"fs";import{homedir as Jt}from"os";import{join as F}from"path";var Ut=["websearch","context7","grep_app"],Vt=[F(Jt(),".claude",".mcp.json"),F(process.cwd(),".mcp.json"),F(process.cwd(),".claude",".mcp.json")];function zt(){let n={};for(let t of Vt){if(!St(t))continue;try{let e=Gt(t,"utf-8"),s=A(e);if(s.mcpServers)Object.assign(n,s.mcpServers)}catch{}}return n}function Ft(){return Ut.map((n)=>({id:n,type:"builtin",enabled:!0,valid:!0}))}function qt(){let n=zt(),t=[];for(let[e,s]of Object.entries(n)){let r=typeof s==="object"&&s!==null;t.push({id:e,type:"user",enabled:!0,valid:r,error:r?void 0:"Invalid configuration format"})}return t}async function Xt(){let n=Ft();return{name:o[i.MCP_BUILTIN],status:"pass",message:`${n.length} built-in servers enabled`,details:n.map((t)=>`Enabled: ${t.id}`)}}async function Wt(){let n=qt();if(n.length===0)return{name:o[i.MCP_USER],status:"skip",message:"No user MCP configuration found",details:["Optional: Add .mcp.json for custom MCP servers"]};let t=n.filter((e)=>!e.valid);if(t.length>0)return{name:o[i.MCP_USER],status:"warn",message:`${t.length} server(s) have configuration issues`,details:[...n.filter((e)=>e.valid).map((e)=>`Valid: ${e.id}`),...t.map((e)=>`Invalid: ${e.id} - ${e.error}`)]};return{name:o[i.MCP_USER],status:"pass",message:`${n.length} user server(s) configured`,details:n.map((e)=>`Configured: ${e.id}`)}}function In(){return[{id:i.MCP_BUILTIN,name:o[i.MCP_BUILTIN],category:"tools",check:Xt,critical:!1},{id:i.MCP_USER,name:o[i.MCP_USER],category:"tools",check:Wt,critical:!1}]}async function Mt(){return{name:o[i.VERSION_STATUS],status:"pass",message:"Kraken Code plugin version check bypassed (version tracking not implemented)",details:[`Minimum required: ${k}`,"Run 'bun run build' to build the plugin"]}}function xn(){return{id:i.VERSION_STATUS,name:o[i.VERSION_STATUS],category:"updates",check:Mt,critical:!1}}function On(){return[tn(),an(),cn(),...fn(),...dn(),hn(),Pn(),...In(),xn()]}import d from"picocolors";function Qt(n){switch(n){case"pass":return O.check;case"fail":return O.cross;case"warn":return O.warn;case"skip":return O.skip}}function Rn(n,t){let e=Qt(n.status),s=B[n.status],r=s(n.name),a=d.dim(n.message),p=` ${e} ${r}`;if(n.message)p+=` ${O.arrow} ${a}`;if(t&&n.details&&n.details.length>0){let g=n.details.map((f)=>` ${O.bullet} ${d.dim(f)}`).join(`
|
|
7
|
+
`);p+=`
|
|
8
|
+
`+g}return p}function En(n){let t=K[n]||n;return`
|
|
9
9
|
${d.bold(d.white(t))}
|
|
10
|
-
${d.dim("\u2500".repeat(40))}`}function
|
|
11
|
-
`)}function
|
|
10
|
+
${d.dim("\u2500".repeat(40))}`}function An(n){let t=[];t.push(d.bold(d.white("Summary"))),t.push(d.dim("\u2500".repeat(40))),t.push("");let e=n.passed>0?d.green(`${n.passed} passed`):d.dim("0 passed"),s=n.failed>0?d.red(`${n.failed} failed`):d.dim("0 failed"),r=n.warnings>0?d.yellow(`${n.warnings} warnings`):d.dim("0 warnings"),a=n.skipped>0?d.dim(`${n.skipped} skipped`):"",p=[e,s,r];if(a)p.push(a);return t.push(` ${p.join(", ")}`),t.push(` ${d.dim(`Total: ${n.total} checks in ${n.duration}ms`)}`),t.join(`
|
|
11
|
+
`)}function Nn(){return`
|
|
12
12
|
${d.bgBlue(d.white(" Kraken Code Doctor "))}
|
|
13
|
-
`}function
|
|
13
|
+
`}function jn(n){if(n.failed>0)return`
|
|
14
14
|
${O.cross} ${d.red("Issues detected. Please review the errors above.")}
|
|
15
15
|
`;if(n.warnings>0)return`
|
|
16
16
|
${O.warn} ${d.yellow("All systems operational with warnings.")}
|
|
17
17
|
`;return`
|
|
18
18
|
${O.check} ${d.green("All systems operational!")}
|
|
19
|
-
`}function
|
|
20
|
-
${r}`);return{name:n.name,status:"fail",message:
|
|
19
|
+
`}function wn(n){return JSON.stringify(n,null,2)}async function Zt(n){let t=performance.now();try{let e=await n.check();return e.duration=Math.round(performance.now()-t),e}catch(e){let s=e instanceof Error?e.message:"Unknown error",r=e instanceof Error?e.stack:void 0;if(console.error(`[doctor] Check "${n.name}" failed:`,s),r)console.error(`[doctor] Stack trace:
|
|
20
|
+
${r}`);return{name:n.name,status:"fail",message:s,duration:Math.round(performance.now()-t)}}}function Ht(n,t){return{total:n.length,passed:n.filter((e)=>e.status==="pass").length,failed:n.filter((e)=>e.status==="fail").length,warnings:n.filter((e)=>e.status==="warn").length,skipped:n.filter((e)=>e.status==="skip").length,duration:Math.round(t)}}function Yt(n){return n.some((e)=>e.status==="fail")?v.FAILURE:v.SUCCESS}function Bt(n,t){if(!t)return n;return n.filter((e)=>e.category===t)}function Kt(n){let t=new Map;for(let e of n){let s=t.get(e.category)??[];s.push(e),t.set(e.category,s)}return t}var ne=["installation","configuration","authentication","dependencies","tools","updates"];async function kn(n){let t=performance.now(),e=On(),s=Bt(e,n.category),r=Kt(s),a=[];if(!n.json)console.log(Nn());for(let P of ne){let l=r.get(P);if(!l||l.length===0)continue;if(!n.json)console.log(En(P));for(let j of l){let L=await Zt(j);if(a.push(L),!n.json)console.log(Rn(L,n.verbose??!1))}}let p=performance.now()-t,g=Ht(a,p),f=Yt(a),c={results:a,summary:g,exitCode:f};if(n.json)console.log(wn(c));else console.log(""),console.log(An(g)),console.log(jn(g));return c}import{existsSync as X,readFileSync as te,writeFileSync as ee}from"fs";import*as C from"jsonc-parser";import D from"path";import se from"os";import q from"picocolors";function Cn(){let n=D.join(se.homedir(),".config","opencode");return{configJson:D.join(n,"opencode.json"),configJsonc:D.join(n,"opencode.jsonc")}}function ie(){let n=Cn();if(X(n.configJsonc))return{path:n.configJsonc,format:"jsonc"};if(X(n.configJson))return{path:n.configJson,format:"json"};return null}function re(n,t){let e=[],s=C.parse(n,e,{allowTrailingComma:!0});if(e.length>0)throw Error(`Failed to parse config: ${e[0].error}`);let r=Array.isArray(s.plugin)?[...s.plugin]:[];if(r.some((f)=>f===R||f.startsWith(`${R}@`)))return n;r.push(R);let p={formattingOptions:{insertSpaces:!0,tabSize:2,insertFinalNewline:!0}};if(s.plugin===void 0){let f=0,c=n.indexOf("{");if(c!==-1)f=c+1;let P=t==="jsonc"?" ":" ",j=`${n.includes(`
|
|
21
21
|
`)?`
|
|
22
|
-
`:""}${P}"plugin": ${JSON.stringify(r)},`;return n.slice(0,f)+
|
|
22
|
+
`:""}${P}"plugin": ${JSON.stringify(r)},`;return n.slice(0,f)+j+n.slice(f)}let g=C.modify(n,["plugin"],r,p);return C.applyEdits(n,g)}function ae(){return`{
|
|
23
23
|
"plugin": [
|
|
24
24
|
"${R}"
|
|
25
25
|
]
|
|
26
26
|
}
|
|
27
|
-
`}async function
|
|
27
|
+
`}async function oe(){let n=Cn(),t=ie(),e,s;if(t)try{e=te(t.path,"utf-8"),s=t.format}catch(r){return{success:!1,message:`Failed to read config: ${r instanceof Error?r.message:String(r)}`}}else{let r=D.dirname(n.configJson);if(!X(r))try{let{mkdirSync:a}=await import("fs");a(r,{recursive:!0})}catch(a){return{success:!1,message:`Failed to create config directory: ${a instanceof Error?a.message:String(a)}`}}e=ae(),s="json"}try{let r=re(e,s);ee(t?.path??n.configJson,r,"utf-8");let a=t?.path??n.configJson;if(r===e)return{success:!0,message:`Plugin "${R}" is already registered`,configPath:a};return{success:!0,message:`Plugin "${R}" registered successfully`,configPath:a}}catch(r){return{success:!1,message:`Failed to register plugin: ${r instanceof Error?r.message:String(r)}`}}}function ce(n){if(n.success){if(console.log(q.green(`
|
|
28
28
|
${String.fromCodePoint(10003)} ${n.message}`)),n.configPath)console.log(q.dim(` Config: ${n.configPath}`))}else console.log(q.red(`
|
|
29
|
-
${String.fromCodePoint(10007)} ${n.message}`))}async function
|
|
29
|
+
${String.fromCodePoint(10007)} ${n.message}`))}async function vn(){let n=await oe();ce(n),process.exit(n.success?0:1)}import{writeFileSync as yn,existsSync as N,mkdirSync as Q,readFileSync as W}from"fs";import{parseJsonc as M}from"jsonc-parser";import*as I from"path";import*as T from"os";import u from"picocolors";var __dirname="/home/runner/work/kraken/kraken/src/cli";function Tn(n,t){let e=structuredClone(n)||{};for(let[s,r]of Object.entries(t))if(r!==null&&r!==void 0&&typeof r==="object"&&!Array.isArray(r))if(typeof e[s]==="object"&&e[s]!==null&&!Array.isArray(e[s]))e[s]=Tn(e[s],r);else e[s]=structuredClone(r);else if(r!==null&&r!==void 0)e[s]=r;return e}async function bn(n){if(n.verbose)console.log(u.dim("\uD83D\uDC19 Initializing Kraken Code with verbose output..."));else console.log(u.cyan("\uD83D\uDC19 Initializing Kraken Code..."));let t=I.join(T.homedir(),".config","opencode"),e=I.join(t,"opencode.json"),s=I.join(t,"kraken-code.json");if(!N(t))try{if(Q(t,{recursive:!0}),n.verbose)console.log(u.dim(`\u2139\uFE0F Created config directory: ${t}`));console.log(u.green(`\u2713 Created config directory: ${t}`))}catch(l){console.error(u.red(`\u274C Failed to create config directory: ${l instanceof Error?l.message:String(l)}`)),console.error(u.dim("Try running with elevated permissions or check permissions for ~/.config/opencode")),process.exit(1)}else if(n.verbose)console.log(u.dim(`\u2139\uFE0F Config directory already exists: ${t}`));let{minimal:r,full:a}=n,p={blitzkrieg:{enabled:!0,testPlan:{requiredBeforeImplementation:!0,minTestCases:3,requireCoverageThreshold:!0,coverageThresholdPercent:80},tddWorkflow:{enforceWriteTestFirst:!0,forbidCodeWithoutTest:!0,allowRefactorWithoutTest:!0},evidence:{requireTestExecutionEvidence:!0,requireAssertionEvidence:!0,requireEdgeCaseEvidence:!0},plannerConstraints:{requireTestStep:!0,requireVerificationStep:!0,maxImplementationStepComplexity:3}},kratos:{enabled:!0,autoSave:!0,storagePath:"~/.kratos"},modes:{blitzkrieg:{enabled:!0},ultrathink:{enabled:!0,thinkingBudget:32000,autoVariantSwitch:!0},ultrawork:{enabled:!0,parallelAgents:4},search:{enabled:!0,maxResults:50},analyze:{enabled:!0,consultationPhases:3}}},g={};if(N(s))try{if(g=M(W(s,"utf-8")),n.verbose)console.log(u.dim(`\u2139\uFE0F Found existing Kraken configuration at ${s}, merging with new settings`))}catch(l){console.error(u.red(`\u274C Failed to read existing Kraken configuration: ${l instanceof Error?l.message:String(l)}`)),console.error(u.dim("This might be a corrupted config file. Try removing it manually and re-running init.")),g={}}else if(n.verbose)console.log(u.dim(`\u2139\uFE0F No existing Kraken configuration found at ${s}`));let f=Tn(p,g);try{if(yn(s,JSON.stringify(f,null,2)),n.verbose)console.log(u.dim(`\u2139\uFE0F Wrote configuration with ${Object.keys(f).length} keys`));console.log(u.green(`\u2713 Kraken Code configuration written to ${s}`))}catch(l){console.error(u.red(`\u274C Failed to write Kraken configuration: ${l instanceof Error?l.message:String(l)}`)),console.error(u.dim("Check permissions for the config file and try again.")),process.exit(1)}let c={};if(N(e))try{if(c=M(W(e,"utf-8")),n.verbose)console.log(u.dim(`\u2139\uFE0F Found existing OpenCode configuration at ${e}`))}catch(l){console.error(u.red(`\u274C Failed to read OpenCode configuration: ${l instanceof Error?l.message:String(l)}`)),console.error(u.dim("This might be a corrupted opencode.json file. Try removing it manually and re-running init.")),c={}}else if(n.verbose)console.log(u.dim(`\u2139\uFE0F No existing OpenCode configuration found at ${e}`));let P={...c,plugin:Array.from(new Set([...c.plugin||[],"kraken-code"]))};if(n.verbose)console.log(u.dim(`\u2139\uFE0F Adding kraken-code to plugin list (current plugins: ${c.plugin||[]})`));try{if(yn(e,JSON.stringify(P,null,2)),n.verbose)console.log(u.dim(`\u2139\uFE0F Updated OpenCode configuration with ${P.plugin.length} plugins`));console.log(u.green(`\u2713 OpenCode configuration updated at ${e}`))}catch(l){console.error(u.red(`\u274C Failed to update OpenCode configuration: ${l instanceof Error?l.message:String(l)}`)),console.error(u.dim("Check permissions for the config file and try again.")),process.exit(1)}try{if(await ue(),n.verbose)console.log(u.dim("\u2139\uFE0F Skill templates installation completed successfully"));console.log(u.green("\u2713 Skill templates installed successfully"))}catch(l){console.error(u.yellow(`\u26A0\uFE0F Failed to install skill templates: ${l instanceof Error?l.message:String(l)}`)),console.error(u.dim("You can install them manually later by copying templates/skills to ~/.config/opencode/skill"))}if(console.log(u.green(`
|
|
30
30
|
\uD83C\uDF89 Kraken Code initialized successfully!`)),console.log(u.dim(`
|
|
31
31
|
Next steps:`)),console.log(u.dim(" 1. Run: opencode")),console.log(u.dim(" 2. Use 'blitz' or 'blz' to activate Blitzkrieg Mode")),n.verbose)console.log(u.dim(`
|
|
32
32
|
\uD83D\uDD0D Verifying installation with detailed output...`));else console.log(u.dim(`
|
|
33
|
-
\uD83D\uDD0D Verifying installation...`));try{let
|
|
34
|
-
`));let n=
|
|
35
|
-
\u26A0 Kraken Code configuration not found`)),console.log(h.dim(" Run: kraken-code init"));return}let r=JSON.parse(
|
|
36
|
-
Default Agent:`)),console.log(` ${r.default_agent}`);if(r.agents){let
|
|
37
|
-
Enabled Agents:`)),console.log(` ${
|
|
38
|
-
Blitzkrieg Mode:`)),console.log(` Status: ${
|
|
39
|
-
Learning:`)),console.log(` Status: ${
|
|
40
|
-
Active Modes:`)),console.log(` ${
|
|
33
|
+
\uD83D\uDD0D Verifying installation...`));try{let l=I.join(T.homedir(),".config","opencode","opencode.json"),j=M(W(l,"utf-8"));if(j.plugin&&j.plugin.includes("kraken-code"))console.log(u.green("\u2713 Kraken Code plugin is registered in opencode.json"));else console.log(u.yellow("\u26A0\uFE0F Kraken Code plugin not found in opencode.json - may need manual registration"));let L=I.join(T.homedir(),".config","opencode","kraken-code.json");if(N(L))console.log(u.green("\u2713 Kraken Code configuration file exists"));else console.log(u.yellow("\u26A0\uFE0F Kraken Code configuration file missing"));let{exec:Un}=await import("child_process");if((await new Promise((Vn,zn)=>{Un("opencode --plugins",{timeout:5000},(Y,Fn,Pe)=>{if(Y)zn(Y);else Vn(Fn||"")})})).includes("kraken-code"))console.log(u.green("\u2713 Kraken Code appears in plugin list"));else console.log(u.yellow("\u26A0\uFE0F Kraken Code not found in plugin list - run 'opencode --plugins' to verify"))}catch(l){console.log(u.yellow("\u26A0\uFE0F Verification failed - some checks could not be performed"))}}async function ue(){let n=I.join(T.homedir(),".config","opencode","skill");if(!N(n))Q(n,{recursive:!0});let t=I.join(__dirname,"../../templates/skills");if(N(t)){let{copyFile:e}=await import("fs/promises"),{readdir:s}=await import("fs/promises");try{let r=await s(t);for(let a of r){let p=I.join(t,a),g=I.join(n,a);if(!N(g))Q(g,{recursive:!0});let f=await s(p);for(let c of f){let P=I.join(p,c),l=I.join(g,c);await e(P,l)}}}catch(r){console.log(u.dim(" \u2713 Skill templates installed"))}}else console.log(u.dim(" \u2713 Skill templates ready (manual install)"))}import{readFileSync as Ln,existsSync as _n}from"fs";import*as Z from"path";import*as H from"os";import h from"picocolors";async function Dn(){console.log(h.cyan(`\uD83D\uDC19 Kraken Code Status
|
|
34
|
+
`));let n=Z.join(H.homedir(),".config","opencode","opencode.json"),t=Z.join(H.homedir(),".config","opencode","kraken-code.json");if(!_n(n)){console.log(h.red("\u2717 OpenCode configuration not found")),console.log(h.dim(" Run: kraken-code init"));return}let s=JSON.parse(Ln(n,"utf-8")).plugin?.includes("kraken-code")||!1;if(console.log(h.bold("Plugin:")),s)console.log(h.green(" \u2713 Registered: kraken-code"));else console.log(h.red(" \u2717 Not registered")),console.log(h.dim(" Run: kraken-code init"));if(!_n(t)){console.log(h.yellow(`
|
|
35
|
+
\u26A0 Kraken Code configuration not found`)),console.log(h.dim(" Run: kraken-code init"));return}let r=JSON.parse(Ln(t,"utf-8"));if(console.log(h.bold("Plugin:")),console.log(h.green(" \u2713 Registered: kraken-code")),r.default_agent)console.log(h.bold(`
|
|
36
|
+
Default Agent:`)),console.log(` ${r.default_agent}`);if(r.agents){let p=Object.entries(r.agents).filter(([g,f])=>!f.disable).map(([g])=>g);if(p.length>0)console.log(h.bold(`
|
|
37
|
+
Enabled Agents:`)),console.log(` ${p.join(", ")}`)}if(r.blitzkrieg){let p=r.blitzkrieg.enabled?h.green("\u2713 Enabled"):h.red("\u2717 Disabled");console.log(h.bold(`
|
|
38
|
+
Blitzkrieg Mode:`)),console.log(` Status: ${p}`),console.log(h.dim(" Activate with: 'blitz' or 'blz'"))}let a=r.learning||r.memory;if(a){let p=a.enabled?h.green("\u2713 Enabled"):h.red("\u2717 Disabled");console.log(h.bold(`
|
|
39
|
+
Learning:`)),console.log(` Status: ${p}`),console.log(` Storage: ${a.storagePath||"~/.kraken/learning"}`)}if(r.modes){let p=[];for(let[g,f]of Object.entries(r.modes))if(typeof f==="object"&&f&&f.enabled)p.push(g);if(p.length>0)console.log(h.bold(`
|
|
40
|
+
Active Modes:`)),console.log(` ${p.join(", ")}`)}}import*as b from"path";import*as Sn from"os";import m from"picocolors";import{existsSync as $,readFileSync as $n,unlinkSync as pe,rmSync as le,writeFileSync as me}from"fs";async function ge(n){let t=n.dryRun||!1,e=b.join(Sn.homedir(),".config","opencode"),s=b.join(e,"opencode.json"),r=b.join(e,"kraken-code.json"),a=b.join(e,"skill");if(console.log(m.cyan("\uD83D\uDDD1\uFE0F Uninstalling Kraken Code...")),n.verbose)console.log(m.dim("\uD83D\uDDD1\uFE0F Uninstalling Kraken Code with verbose output..."));else if(t)console.log(m.yellow("\uD83D\uDD0D Dry run mode - showing what would be removed:"));let p=[];if($(r))p.push(r);let g={};if($(s))try{g=A($n(s,"utf-8"))}catch{}if(n.verbose)console.log(m.dim(`\u2139\uFE0F Found ${p.length} files to remove:`)),p.forEach((c)=>{console.log(m.dim(` - ${c}`))});else console.log(m.dim(" Files to remove:")),p.forEach((c)=>{console.log(m.dim(` - ${c}`))});let f=[];if($(a))f.push(a);if(n.verbose)console.log(m.dim(`\u2139\uFE0F Found ${f.length} directories to remove:`)),f.forEach((c)=>{console.log(m.dim(` - ${c}`))});else console.log(m.dim(" Directories to remove:")),f.forEach((c)=>{console.log(m.dim(` - ${c}`))});if(t){console.log(m.green(`
|
|
41
41
|
\uD83D\uDD0D Dry run complete. No files were actually removed.`)),console.log(m.dim("Run without --dry-run to perform actual uninstall."));return}if(n.verbose)console.log(m.dim(`
|
|
42
42
|
\uD83D\uDDD1\uFE0F Removing files...`));else console.log(m.yellow(`
|
|
43
|
-
\uD83D\uDDD1\uFE0F Removing files...`));if(
|
|
43
|
+
\uD83D\uDDD1\uFE0F Removing files...`));if(p.forEach((c)=>{try{if(pe(c),n.verbose)console.log(m.dim(`\u2139\uFE0F Removed ${c}`));else console.log(m.green(`\u2713 Removed ${c}`))}catch(P){console.log(m.yellow(`\u26A0\uFE0F Could not remove ${c}: ${P instanceof Error?P.message:String(P)}`))}}),n.verbose)console.log(m.dim("\uD83D\uDDD1\uFE0F Removing directories..."));else console.log(m.yellow("\uD83D\uDDD1\uFE0F Removing directories..."));if(f.forEach((c)=>{try{if(le(c,{recursive:!0,force:!0}),n.verbose)console.log(m.dim(`\u2139\uFE0F Removed ${c}`));else console.log(m.green(`\u2713 Removed ${c}`))}catch(P){console.log(m.yellow(`\u26A0\uFE0F Could not remove ${c}: ${P instanceof Error?P.message:String(P)}`))}}),$(s))try{let c=A($n(s,"utf-8"));if(c.plugin){let P=c.plugin.filter((l)=>l!=="kraken-code");if(P.length!==c.plugin.length){let l={...c,plugin:P};if(me(s,JSON.stringify(l,null,2)),n.verbose)console.log(m.dim("\u2139\uFE0F Updated opencode.json plugin list (removed kraken-code)"));console.log(m.green("\u2713 Removed kraken-code from opencode.json plugin list"))}else if(n.verbose)console.log(m.dim("\u2139\uFE0F kraken-code was not in opencode.json plugin list"))}}catch(c){console.log(m.yellow(`\u26A0\uFE0F Could not update opencode.json: ${c instanceof Error?c.message:String(c)}`))}else if(n.verbose)console.log(m.dim("\u2139\uFE0F opencode.json not found, skipping plugin list update"));if(console.log(m.green(`
|
|
44
44
|
\uD83C\uDF89 Kraken Code uninstalled successfully!`)),n.verbose)console.log(m.dim(`
|
|
45
45
|
\uD83D\uDCCB Summary of changes:`)),console.log(m.dim(" - Configuration files removed")),console.log(m.dim(" - Skill templates removed")),console.log(m.dim(" - Plugin registration removed from opencode.json"));console.log(m.dim(`
|
|
46
|
-
To reinstall, run: kraken-code install`))}function
|
|
46
|
+
To reinstall, run: kraken-code install`))}function Gn(n){n.command("uninstall").description("Uninstall and deregister Kraken Code plugin").option("--dry-run","Show what would be removed without actually removing").option("-v, --verbose","Show detailed output").action(async(t)=>{await ge(t)})}var Jn="1.4.0";var E=new de;E.name("kraken-code").description("Kraken Code CLI - Unified OpenCode Plugin Manager").version(Jn);E.command("install").description("Install and register Kraken Code plugin").action(async()=>{await vn()});E.command("init").description("Initialize Kraken Code with recommended configuration").option("--minimal","Minimal setup (agents only)").option("--full","Full setup (all features)").option("-v, --verbose","Show detailed output").action(async(n)=>{await bn(n)});E.command("status").description("Show Kraken Code installation status").action(async()=>{await Dn()});Gn(E);E.command("doctor").description("Run system checks and diagnostics").option("-c, --category <category>","Run checks for a specific category").option("--json","Output results as JSON").option("-v, --verbose","Show detailed output").action(async(n)=>{await kn({category:n.category,json:n.json,verbose:n.verbose})});E.parse(process.argv);if(!process.argv.slice(2).length)E.outputHelp();
|