@north-light/crouter 0.3.343 → 0.3.344

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.
@@ -1,9 +1,9 @@
1
- var q=Object.defineProperty;var a=(e,t)=>q(e,"name",{value:t,configurable:!0});import{spawn as W,spawnSync as H}from"node:child_process";import{homedir as g}from"node:os";import{basename as V,dirname as J,join as S,resolve as X}from"node:path";import{isDeepStrictEqual as k}from"node:util";import{BINDING_CATALOG as Q,normalizeGesture as Z,splitGestureExpression as ee,inboxShortcut as te,resolveKeybindings as w}from"../../core/keybindings/index.js";import{builtinPiPackageDir as b}from"../../core/scope.js";import{readJsonIfExists as ne,readJsonOrNull as re}from"../../core/fs-utils.js";import{resolveBundledPiCliPath as ie}from"../../core/runtime/pi-cli.js";import{crtrVersion as se}from"../../shared/crtr-version.js";import{installTmuxBindings as ae}from"../../core/runtime/tmux-chrome.js";import{normalizeTmuxPassthrough as oe}from"../../core/config.js";import{detectNerdFont as ce,nerdFontInstallCommand as ue,createCurlPercentReader as le,NERD_FONT_MANUAL_LINUX_COMMAND as de,NERD_FONT_SELECT_HINT as pe}from"../../core/runtime/nerd-font.js";import{startProgressBar as he}from"../../core/runtime/progress-bar.js";import{ensureRenderer as fe,isRendererReady as A}from"../../core/termrender/termrender.js";import{installFromMarketplace as me}from"../pkg/plugin-manage.js";import{addMarketplace as $}from"../pkg/market-manage.js";import{findPluginByName as ge,findMarketplaceByName as E}from"../../core/resolver.js";import{expandTilde as ke}from"../../core/fs-utils.js";const R="crouter-official-marketplace",D="https://github.com/crouton-labs/crouter-official-marketplace.git",O="main";function T(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}a(T,"isKeybindingsObject");function h(e){return T(e)?Object.fromEntries(Object.entries(e).map(([t,n])=>[t,Array.isArray(n)?[...n]:n])):{}}a(h,"cloneKeybindings");class Je{static{a(this,"SetupKeybindingsDraft")}expected;baseline;current;baselineInvalidRoot;invalidRoot;resolutionCache;expectedPassthrough;baselinePassthrough;currentPassthrough;constructor(t,n=void 0){this.expected=t,this.baseline=h(t),this.current=h(t),this.baselineInvalidRoot=t!==void 0&&!T(t)?t:void 0,this.invalidRoot=this.baselineInvalidRoot,this.expectedPassthrough=n,this.baselinePassthrough=oe(n),this.currentPassthrough=[...this.baselinePassthrough]}get dirty(){return!k(this.current,this.baseline)||!k(this.invalidRoot,this.baselineInvalidRoot)||!k(this.currentPassthrough,this.baselinePassthrough)}overrides(){return h(this.current)}expectedKeybindings(){return this.expected}tmuxPassthrough(){return[...this.currentPassthrough]}expectedTmuxPassthrough(){return this.expectedPassthrough}usesTmuxPassthrough(t){return this.currentPassthrough.includes(t)}toggleTmuxPassthrough(t){this.currentPassthrough=this.currentPassthrough.includes(t)?this.currentPassthrough.filter(n=>n!==t):[...this.currentPassthrough,t]}resolution(){return this.resolutionCache===void 0&&(this.resolutionCache=w(this.invalidRoot===void 0?this.current:this.invalidRoot)),this.resolutionCache}hasInvalidRoot(){return this.invalidRoot!==void 0}expression(t){return this.resolution().gestures(t).join(", ")}edit(t,n){if(this.invalidRoot!==void 0)return{ok:!1,diagnostics:[{severity:"error",code:"invalid-keybindings",offendingValue:this.invalidRoot,message:"Reset all before editing: the saved keybindings root is invalid."}]};const r=Q.find(p=>p.id===t);let o;try{o=n.trim()===""?[]:ee(n).map(p=>Z(p.trim(),r))}catch(p){return{ok:!1,diagnostics:[{severity:"error",code:"invalid-override",bindingId:t,offendingValue:n,message:p instanceof Error?p.message:String(p)}]}}const i=[...new Set(o)],u={...this.current};delete u[t];const c=[...w(u).gestures(t)],l=k(i,c)?u:{...this.current,[t]:i},s=w(l),d=s.diagnostics.filter(p=>p.bindingId===t||p.relatedBindingIds?.includes(t));return d.length>0?{ok:!1,diagnostics:d}:(this.current=l,this.resolutionCache=void 0,{ok:!0,diagnostics:s.diagnostics})}unbind(t){return this.edit(t,"")}resetRow(t){delete this.current[t],this.resolutionCache=void 0}resetAll(){this.current={},this.currentPassthrough=[],this.invalidRoot=void 0,this.resolutionCache=void 0}discard(){this.current=h(this.baseline),this.currentPassthrough=[...this.baselinePassthrough],this.invalidRoot=this.baselineInvalidRoot,this.resolutionCache=void 0}markSaved(t,n=[]){this.expected=Object.keys(t).length===0?void 0:h(t),this.baseline=h(t),this.current=h(t),this.expectedPassthrough=n.length===0?void 0:[...n],this.baselinePassthrough=[...n],this.currentPassthrough=[...n],this.baselineInvalidRoot=void 0,this.invalidRoot=void 0,this.resolutionCache=void 0}}const be={"official-marketplace":{name:R,shortDescription:"the official crtr plugin catalog \u2014 registered as a source so its plugins are installable by ref.",longDescription:"Shallow-clones github.com/crouton-labs/crouter-official-marketplace into the user scope and registers it, which is what makes `crtr pkg plugin install crouter-official-marketplace/<name>` resolve and what fills `crtr pkg market browse`. Registering the source installs no plugin by itself. Uncheck it on a machine that should reach no external catalog \u2014 a plugin selected below still registers the marketplace it comes from, because its ref cannot resolve otherwise."},"crtr-extensions":{name:"pi-crtr-extensions",shortDescription:"crtr companion extensions \u2014 command palette, help gating, subscription/OAuth rotation, nested context.",longDescription:"Bundles the extensions built for crtr: a crtr slash-command palette, crtr/crouter help gating, surfacing of Claude Code marketplace plugin commands, nested AGENTS.md/CLAUDE.md loading, OAuth login + rotation across multiple Claude subscriptions (provider-rotation), and system-prompt trimming. The OAuth/rotation piece is what lets crtr authenticate your Claude account."},"oauth-adapter":{name:"pi-claude-oauth-adapter",shortDescription:"Anthropic OAuth / Claude Code credential compatibility for pi.",longDescription:"Third-party adapter (minzique/dotfiles-agents) letting pi authenticate with Claude using Claude Code OAuth credentials. Installed from npm, pinned to 0.1.2."},"capture-plugin":{name:"capture",shortDescription:"crtr plugin mounting `crtr capture` \u2014 browser automation and UI measurement over CDP.",longDescription:"Installs the `capture` plugin from the official crtr marketplace. It mounts `crtr capture` as a transparent passthrough to the external Capture CLI (`npm install -g @crouton-kit/capture`) for CDP screenshots, rendered-geometry measurement, HAR, accessibility trees, and JS execution against a live page. Uncheck it on a machine where agents never drive a browser \u2014 the command then costs nothing in their root prompt."},"search-plugin":{name:"search",shortDescription:"crtr plugin mounting `crtr search` \u2014 public-web discovery, grounded answers, and content extraction.",longDescription:"Installs the `search` plugin from the official crtr marketplace. It mounts `crtr search` and calls Exa directly, resolving its own API key from EXA_API_KEY or ~/.crouter/exa.key \u2014 crouter never handles that credential. Uncheck it on a machine whose agents get web search from somewhere else, such as a Northlight home where the platform serves `crtr search` from its own plugin."},"dev-plugin":{name:"dev",shortDescription:"crtr plugin mounting the development workflow \u2014 repository setup, worktrees, pull requests, and a dev track in the tutorial.",longDescription:"Installs the dev plugin from the official crtr marketplace. It adds the /dev: workflow commands (init, spec, design, plan, pr-loop), mounts crtr dev for a repository's own lifecycle commands and Grove instances, and contributes the crtr sys tutorial dev track. Uncheck it on a machine whose agents do not work in source repositories."}},y={"official-marketplace":{kind:"marketplace-source",source:D},"crtr-extensions":{kind:"local-path",source:b("pi-crtr-extensions")},"oauth-adapter":{kind:"npm",source:"npm:pi-claude-oauth-adapter@0.1.2"},"capture-plugin":{kind:"marketplace-plugin",source:"crouter-official-marketplace/capture"},"search-plugin":{kind:"marketplace-plugin",source:"crouter-official-marketplace/search"},"dev-plugin":{kind:"marketplace-plugin",source:"crouter-official-marketplace/dev"}},ve={"official-marketplace":[],"crtr-extensions":["pi-crtr-extensions"],"oauth-adapter":[],"capture-plugin":[],"search-plugin":[],"dev-plugin":[]};function P(e=b){return["official-marketplace","crtr-extensions","oauth-adapter","capture-plugin","search-plugin","dev-plugin"].map(t=>{const n=be[t],r=y[t].kind==="local-path"?e(n.name):y[t].source;return{id:t,name:n.name,sourceKind:y[t].kind,installSource:r,shortDescription:n.shortDescription,longDescription:n.longDescription}})}a(P,"buildSetupManifest");function Xe(e){switch(e.sourceKind){case"marketplace-source":return`clone + register ${e.installSource}`;case"marketplace-plugin":return`crtr pkg plugin install ${e.installSource}`;default:return`pi install ${e.installSource}`}}a(Xe,"packagePlanAction");function we(e){if(!e.startsWith("npm:"))return null;const t=e.slice(4),n=t.startsWith("@")?t.indexOf("@",1):t.lastIndexOf("@");return n>0?t.slice(0,n):t}a(we,"npmPackageName");function N(e,t,n){const r=we(e);if(r!==null)return`npm:${r}`;const o=ke(e,n);return X(t,o)}a(N,"normalizePackageIdentity");function I(e){return`package:${e}`}a(I,"packageNameIdentity");function ye(e){return e.startsWith("npm:")?[]:[I(V(e))]}a(ye,"localPackageNameIdentities");function Pe(e,t,n){const r=[N(e.installSource,t,n)];if(e.sourceKind==="local-path"){r.push(I(e.name));for(const o of ve[e.id])r.push(I(o))}return r}a(Pe,"manifestIdentities");function L(e,t=P(),n=S(g(),".pi","agent","settings.json"),r=g()){const o=J(n),i=new Set,u=new Map;for(const l of t)for(const s of Pe(l,o,r))u.set(s,l.id);const c=e&&typeof e=="object"?e.packages:void 0;if(!Array.isArray(c))return i;for(const l of c){const s=typeof l=="string"?l:l&&typeof l=="object"&&typeof l.source=="string"?l.source:null;if(s===null)continue;const d=[N(s,o,r),...ye(s)];for(const p of d){const f=u.get(p);f!==void 0&&i.add(f)}}return i}a(L,"detectInstalledSetupPackageIds");function m(e){return H("sh",["-lc",`command -v ${e} >/dev/null 2>&1`],{stdio:"ignore"}).status===0}a(m,"detectCommandOnPath");function Ie(e=process.platform,t=m){switch(e){case"darwin":return t("brew")?"brew":"manual";case"linux":return t("apt-get")?"apt-get":t("dnf")?"dnf":t("pacman")?"pacman":"manual";default:return"manual"}}a(Ie,"detectPackageManager");function xe(e,t,n=m){if(e==="nerd-font"?ce().installed:n(e))return{tool:e,installed:!0,command:null,hint:"already installed",autoInstall:!1};if(e==="nerd-font"){const i=ue(t);return{tool:e,installed:!1,command:i.command,hint:`${i.hint} \u2014 ${pe}`,autoInstall:i.autoInstall}}const o=e==="nvim"?"neovim":"tmux";switch(t){case"brew":return{tool:e,installed:!1,command:`brew install ${o}`,hint:"Homebrew install",autoInstall:!0};case"apt-get":return{tool:e,installed:!1,command:`sudo apt-get update && sudo apt-get install -y ${o}`,hint:"apt-get install",autoInstall:!0};case"dnf":return{tool:e,installed:!1,command:`sudo dnf install -y ${o}`,hint:"dnf install",autoInstall:!0};case"pacman":return{tool:e,installed:!1,command:`sudo pacman -S --noconfirm ${o}`,hint:"pacman install",autoInstall:!0};default:return{tool:e,installed:!1,command:null,hint:`manual install required for ${e}`,autoInstall:!1}}}a(xe,"buildSystemInstallPlan");function _(e=g()){return S(e,".pi","agent","settings.json")}a(_,"resolveSettingsPath");function Qe(e={}){const t=e.homeDir??g(),n=e.settingsPath??_(t),r=e.manifest??P(b),o=ne(n),i=L(o,r,n,t);for(const s of G(r))i.add(s);const u=e.commandExists??m,c=e.packageManager??Ie(process.platform,u),l=["tmux","nvim","nerd-font"].map(s=>xe(s,c,u));return{manifest:r,installedPackageIds:i,systemPlans:l}}a(Qe,"buildSetupInitialState");function Ze(e){const t=e.manifest.map(r=>{const o=e.installedPackageIds.has(r.id)?"installed":"not installed";return`- ${r.name} \u2014 ${r.shortDescription} (${o})`}),n=e.systemPlans.map(r=>r.installed?`- ${r.tool}: \u2713 installed`:r.command?`- ${r.tool}: ${r.command}`:`- ${r.tool}: ${r.hint}`);return["crtr sys setup (non-interactive)","","Provider login: open the wizard in a TTY and use the Providers tab (same flow as /login) to authenticate a model provider.","","Packages:",...t,"","System deps:",...n,"",`Inbox: the inbox-toggle key (${te()??"disabled"}) is a crouter keybinding \u2014 view or rebind it in \`crtr sys settings\`; it is installed on the same tmux server as every other crouter binding.`,"Run `crtr sys setup` in a TTY to open the wizard."].join(`
1
+ var V=Object.defineProperty;var s=(e,t)=>V(e,"name",{value:t,configurable:!0});import{spawn as X,spawnSync as Q}from"node:child_process";import{homedir as k}from"node:os";import{basename as Z,dirname as R,join as P,relative as ee,resolve as te}from"node:path";import{isDeepStrictEqual as m}from"node:util";import{BINDING_CATALOG as ne,normalizeGesture as re,splitGestureExpression as ie,inboxShortcut as se,resolveKeybindings as I}from"../../core/keybindings/index.js";import{runtimeManifest as ae}from"./shared.js";import{atomicWriteJson as oe,readJsonIfExists as ce,readJsonOrNull as D}from"../../core/fs-utils.js";import{resolveBundledPiCliPath as ue}from"../../core/runtime/pi-cli.js";import{crtrVersion as le}from"../../shared/crtr-version.js";import{installTmuxBindings as de}from"../../core/runtime/tmux-chrome.js";import{normalizeTmuxPassthrough as pe}from"../../core/config.js";import{detectNerdFont as he,nerdFontInstallCommand as fe,createCurlPercentReader as me,NERD_FONT_MANUAL_LINUX_COMMAND as ge,NERD_FONT_SELECT_HINT as ke}from"../../core/runtime/nerd-font.js";import{startProgressBar as be}from"../../core/runtime/progress-bar.js";import{ensureRenderer as ve,isRendererReady as O}from"../../core/termrender/termrender.js";import{installFromMarketplace as we}from"../pkg/plugin-manage.js";import{addMarketplace as T}from"../pkg/market-manage.js";import{findPluginByName as xe,findMarketplaceByName as N}from"../../core/resolver.js";import{expandTilde as ye}from"../../core/fs-utils.js";const L="crouter-official-marketplace",_="https://github.com/crouton-labs/crouter-official-marketplace.git",M="main";function K(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}s(K,"isKeybindingsObject");function f(e){return K(e)?Object.fromEntries(Object.entries(e).map(([t,n])=>[t,Array.isArray(n)?[...n]:n])):{}}s(f,"cloneKeybindings");class tt{static{s(this,"SetupKeybindingsDraft")}expected;baseline;current;baselineInvalidRoot;invalidRoot;resolutionCache;expectedPassthrough;baselinePassthrough;currentPassthrough;constructor(t,n=void 0){this.expected=t,this.baseline=f(t),this.current=f(t),this.baselineInvalidRoot=t!==void 0&&!K(t)?t:void 0,this.invalidRoot=this.baselineInvalidRoot,this.expectedPassthrough=n,this.baselinePassthrough=pe(n),this.currentPassthrough=[...this.baselinePassthrough]}get dirty(){return!m(this.current,this.baseline)||!m(this.invalidRoot,this.baselineInvalidRoot)||!m(this.currentPassthrough,this.baselinePassthrough)}overrides(){return f(this.current)}expectedKeybindings(){return this.expected}tmuxPassthrough(){return[...this.currentPassthrough]}expectedTmuxPassthrough(){return this.expectedPassthrough}usesTmuxPassthrough(t){return this.currentPassthrough.includes(t)}toggleTmuxPassthrough(t){this.currentPassthrough=this.currentPassthrough.includes(t)?this.currentPassthrough.filter(n=>n!==t):[...this.currentPassthrough,t]}resolution(){return this.resolutionCache===void 0&&(this.resolutionCache=I(this.invalidRoot===void 0?this.current:this.invalidRoot)),this.resolutionCache}hasInvalidRoot(){return this.invalidRoot!==void 0}expression(t){return this.resolution().gestures(t).join(", ")}edit(t,n){if(this.invalidRoot!==void 0)return{ok:!1,diagnostics:[{severity:"error",code:"invalid-keybindings",offendingValue:this.invalidRoot,message:"Reset all before editing: the saved keybindings root is invalid."}]};const r=ne.find(p=>p.id===t);let o;try{o=n.trim()===""?[]:ie(n).map(p=>re(p.trim(),r))}catch(p){return{ok:!1,diagnostics:[{severity:"error",code:"invalid-override",bindingId:t,offendingValue:n,message:p instanceof Error?p.message:String(p)}]}}const i=[...new Set(o)],u={...this.current};delete u[t];const c=[...I(u).gestures(t)],l=m(i,c)?u:{...this.current,[t]:i},a=I(l),d=a.diagnostics.filter(p=>p.bindingId===t||p.relatedBindingIds?.includes(t));return d.length>0?{ok:!1,diagnostics:d}:(this.current=l,this.resolutionCache=void 0,{ok:!0,diagnostics:a.diagnostics})}unbind(t){return this.edit(t,"")}resetRow(t){delete this.current[t],this.resolutionCache=void 0}resetAll(){this.current={},this.currentPassthrough=[],this.invalidRoot=void 0,this.resolutionCache=void 0}discard(){this.current=f(this.baseline),this.currentPassthrough=[...this.baselinePassthrough],this.invalidRoot=this.baselineInvalidRoot,this.resolutionCache=void 0}markSaved(t,n=[]){this.expected=Object.keys(t).length===0?void 0:f(t),this.baseline=f(t),this.current=f(t),this.expectedPassthrough=n.length===0?void 0:[...n],this.baselinePassthrough=[...n],this.currentPassthrough=[...n],this.baselineInvalidRoot=void 0,this.invalidRoot=void 0,this.resolutionCache=void 0}}const Pe={"official-marketplace":{name:L,shortDescription:"the official crtr plugin catalog \u2014 registered as a source so its plugins are installable by ref.",longDescription:"Shallow-clones github.com/crouton-labs/crouter-official-marketplace into the user scope and registers it, which is what makes `crtr pkg plugin install crouter-official-marketplace/<name>` resolve and what fills `crtr pkg market browse`. Registering the source installs no plugin by itself. Uncheck it on a machine that should reach no external catalog \u2014 a plugin selected below still registers the marketplace it comes from, because its ref cannot resolve otherwise."},"crtr-extensions":{name:"pi-crtr-extensions",shortDescription:"crtr companion extensions \u2014 command palette, help gating, subscription/OAuth rotation, nested context.",longDescription:"Bundles the extensions built for crtr: a crtr slash-command palette, crtr/crouter help gating, surfacing of Claude Code marketplace plugin commands, nested AGENTS.md/CLAUDE.md loading, OAuth login + rotation across multiple Claude subscriptions (provider-rotation), and system-prompt trimming. The OAuth/rotation piece is what lets crtr authenticate your Claude account."},"oauth-adapter":{name:"pi-claude-oauth-adapter",shortDescription:"Anthropic OAuth / Claude Code credential compatibility for pi.",longDescription:"Third-party adapter (minzique/dotfiles-agents) letting pi authenticate with Claude using Claude Code OAuth credentials. Installed from npm, pinned to 0.1.2."},"capture-plugin":{name:"capture",shortDescription:"crtr plugin mounting `crtr capture` \u2014 browser automation and UI measurement over CDP.",longDescription:"Installs the `capture` plugin from the official crtr marketplace. It mounts `crtr capture` as a transparent passthrough to the external Capture CLI (`npm install -g @crouton-kit/capture`) for CDP screenshots, rendered-geometry measurement, HAR, accessibility trees, and JS execution against a live page. Uncheck it on a machine where agents never drive a browser \u2014 the command then costs nothing in their root prompt."},"search-plugin":{name:"search",shortDescription:"crtr plugin mounting `crtr search` \u2014 public-web discovery, grounded answers, and content extraction.",longDescription:"Installs the `search` plugin from the official crtr marketplace. It mounts `crtr search` and calls Exa directly, resolving its own API key from EXA_API_KEY or ~/.crouter/exa.key \u2014 crouter never handles that credential. Uncheck it on a machine whose agents get web search from somewhere else, such as a Northlight home where the platform serves `crtr search` from its own plugin."},"dev-plugin":{name:"dev",shortDescription:"crtr plugin mounting the development workflow \u2014 repository setup, worktrees, pull requests, and a dev track in the tutorial.",longDescription:"Installs the dev plugin from the official crtr marketplace. It adds the /dev: workflow commands (init, spec, design, plan, pr-loop), mounts crtr dev for a repository's own lifecycle commands and Grove instances, and contributes the crtr sys tutorial dev track. Uncheck it on a machine whose agents do not work in source repositories."}},C={"official-marketplace":{kind:"marketplace-source",source:_},"crtr-extensions":{kind:"local-path",source:F("pi-crtr-extensions")},"oauth-adapter":{kind:"npm",source:"npm:pi-claude-oauth-adapter@0.1.2"},"capture-plugin":{kind:"marketplace-plugin",source:"crouter-official-marketplace/capture"},"search-plugin":{kind:"marketplace-plugin",source:"crouter-official-marketplace/search"},"dev-plugin":{kind:"marketplace-plugin",source:"crouter-official-marketplace/dev"}},j=["extensions/*.ts","extensions/*/index.ts","!extensions/**/*.d.ts"],Ie={"official-marketplace":[],"crtr-extensions":["pi-crtr-extensions"],"oauth-adapter":[],"capture-plugin":[],"search-plugin":[],"dev-plugin":[]};function F(e){return P(ae.runtimeHome(),"selected","dist","builtin-pi-packages",e)}s(F,"selectedPiPackageDir");function S(e=F){return["official-marketplace","crtr-extensions","oauth-adapter","capture-plugin","search-plugin","dev-plugin"].map(t=>{const n=Pe[t],r=C[t].kind==="local-path"?e(n.name):C[t].source;return{id:t,name:n.name,sourceKind:C[t].kind,installSource:r,shortDescription:n.shortDescription,longDescription:n.longDescription}})}s(S,"buildSetupManifest");function nt(e){switch(e.sourceKind){case"marketplace-source":return`clone + register ${e.installSource}`;case"marketplace-plugin":return`crtr pkg plugin install ${e.installSource}`;default:return`pi install ${e.installSource}`}}s(nt,"packagePlanAction");function Ce(e){if(!e.startsWith("npm:"))return null;const t=e.slice(4),n=t.startsWith("@")?t.indexOf("@",1):t.lastIndexOf("@");return n>0?t.slice(0,n):t}s(Ce,"npmPackageName");function b(e,t,n){const r=Ce(e);if(r!==null)return`npm:${r}`;const o=ye(e,n);return te(t,o)}s(b,"normalizePackageIdentity");function v(e){return`package:${e}`}s(v,"packageNameIdentity");function B(e){return e.startsWith("npm:")?[]:[v(Z(e))]}s(B,"localPackageNameIdentities");function Se(e,t,n){const r=[b(e.installSource,t,n)];if(e.sourceKind==="local-path"){r.push(v(e.name));for(const o of Ie[e.id])r.push(v(o))}return r}s(Se,"manifestIdentities");function G(e,t=S(),n=P(k(),".pi","agent","settings.json"),r=k()){const o=R(n),i=new Set,u=new Map;for(const l of t)for(const a of Se(l,o,r))u.set(a,l.id);const c=e&&typeof e=="object"?e.packages:void 0;if(!Array.isArray(c))return i;for(const l of c){const a=typeof l=="string"?l:l&&typeof l=="object"&&typeof l.source=="string"?l.source:null;if(a===null)continue;const d=[b(a,o,r),...B(a)];for(const p of d){const h=u.get(p);if(h==="crtr-extensions"){const x=t.find(y=>y.id===h);if(b(a,o,r)!==b(x.installSource,o,r)||!l||typeof l!="object"||!m(l.extensions,j))continue}h!==void 0&&i.add(h)}}return i}s(G,"detectInstalledSetupPackageIds");function g(e){return Q("sh",["-lc",`command -v ${e} >/dev/null 2>&1`],{stdio:"ignore"}).status===0}s(g,"detectCommandOnPath");function Ae(e=process.platform,t=g){switch(e){case"darwin":return t("brew")?"brew":"manual";case"linux":return t("apt-get")?"apt-get":t("dnf")?"dnf":t("pacman")?"pacman":"manual";default:return"manual"}}s(Ae,"detectPackageManager");function $e(e,t,n=g){if(e==="nerd-font"?he().installed:n(e))return{tool:e,installed:!0,command:null,hint:"already installed",autoInstall:!1};if(e==="nerd-font"){const i=fe(t);return{tool:e,installed:!1,command:i.command,hint:`${i.hint} \u2014 ${ke}`,autoInstall:i.autoInstall}}const o=e==="nvim"?"neovim":"tmux";switch(t){case"brew":return{tool:e,installed:!1,command:`brew install ${o}`,hint:"Homebrew install",autoInstall:!0};case"apt-get":return{tool:e,installed:!1,command:`sudo apt-get update && sudo apt-get install -y ${o}`,hint:"apt-get install",autoInstall:!0};case"dnf":return{tool:e,installed:!1,command:`sudo dnf install -y ${o}`,hint:"dnf install",autoInstall:!0};case"pacman":return{tool:e,installed:!1,command:`sudo pacman -S --noconfirm ${o}`,hint:"pacman install",autoInstall:!0};default:return{tool:e,installed:!1,command:null,hint:`manual install required for ${e}`,autoInstall:!1}}}s($e,"buildSystemInstallPlan");function A(e=k()){return P(e,".pi","agent","settings.json")}s(A,"resolveSettingsPath");function rt(e={}){const t=e.homeDir??k(),n=e.settingsPath??A(t),r=e.manifest??S(),o=ce(n),i=G(o,r,n,t);for(const a of H(r))i.add(a);const u=e.commandExists??g,c=e.packageManager??Ae(process.platform,u),l=["tmux","nvim","nerd-font"].map(a=>$e(a,c,u));return{manifest:r,installedPackageIds:i,systemPlans:l}}s(rt,"buildSetupInitialState");function it(e){const t=e.manifest.map(r=>{const o=e.installedPackageIds.has(r.id)?"installed":"not installed";return`- ${r.name} \u2014 ${r.shortDescription} (${o})`}),n=e.systemPlans.map(r=>r.installed?`- ${r.tool}: \u2713 installed`:r.command?`- ${r.tool}: ${r.command}`:`- ${r.tool}: ${r.hint}`);return["crtr sys setup (non-interactive)","","Provider login: open the wizard in a TTY and use the Providers tab (same flow as /login) to authenticate a model provider.","","Packages:",...t,"","System deps:",...n,"",`Inbox: the inbox-toggle key (${se()??"disabled"}) is a crouter keybinding \u2014 view or rebind it in \`crtr sys settings\`; it is installed on the same tmux server as every other crouter binding.`,"Run `crtr sys setup` in a TTY to open the wizard."].join(`
2
2
  `)+`
3
- `}a(Ze,"renderSetupStaticInstructions");class v extends Error{static{a(this,"SetupCommandError")}output;constructor(t,n){super(t),this.output=n}}function et(e){return`${e.stdout?.toString()??""}${e.stderr?.toString()??""}`}a(et,"commandOutput");function M(e,t,n){return new Promise((r,o)=>{const i=W(e,t,{stdio:["ignore","pipe","pipe"]});let u="";i.stdout.setEncoding("utf8"),i.stderr.setEncoding("utf8"),i.stdout.on("data",c=>{u+=c}),i.stderr.on("data",c=>{u+=c,n?.(c)}),i.on("error",c=>o(new v(`${e} failed: ${c.message}`,u))),i.on("close",c=>{c===0?r():o(new v(`${e} failed with status ${c??"unknown"}`,u))})})}a(M,"runCapturedCommand");function x(e,t){return M("sh",["-lc",e],t)}a(x,"runShellCommand");function Ce(e,t=ie()){return M(process.execPath,[t,"install",e])}a(Ce,"installPiPackage");async function K(){m("capture")||await x("npm install -g @crouton-kit/capture")}a(K,"installCaptureCliIfMissing");function F(e){return e instanceof v?e.output:void 0}a(F,"capturedFailureOutput");function Se(e){const n=F(e)?.split(/\r?\n/).find(r=>r.trim()!=="");return n!==void 0?n.trim():e instanceof Error?e.message:String(e)}a(Se,"firstFailureLine");function Ae(e){const t=F(e);t===void 0||t.length===0||process.stderr.write(t.endsWith(`
3
+ `}s(it,"renderSetupStaticInstructions");class w extends Error{static{s(this,"SetupCommandError")}output;constructor(t,n){super(t),this.output=n}}function st(e){return`${e.stdout?.toString()??""}${e.stderr?.toString()??""}`}s(st,"commandOutput");function U(e,t,n){return new Promise((r,o)=>{const i=X(e,t,{stdio:["ignore","pipe","pipe"]});let u="";i.stdout.setEncoding("utf8"),i.stderr.setEncoding("utf8"),i.stdout.on("data",c=>{u+=c}),i.stderr.on("data",c=>{u+=c,n?.(c)}),i.on("error",c=>o(new w(`${e} failed: ${c.message}`,u))),i.on("close",c=>{c===0?r():o(new w(`${e} failed with status ${c??"unknown"}`,u))})})}s(U,"runCapturedCommand");function $(e,t){return U("sh",["-lc",e],t)}s($,"runShellCommand");function Ee(e,t=ue()){return U(process.execPath,[t,"install",e])}s(Ee,"installPiPackage");async function Y(){g("capture")||await $("npm install -g @crouton-kit/capture")}s(Y,"installCaptureCliIfMissing");function z(e){return e instanceof w?e.output:void 0}s(z,"capturedFailureOutput");function Re(e){const n=z(e)?.split(/\r?\n/).find(r=>r.trim()!=="");return n!==void 0?n.trim():e instanceof Error?e.message:String(e)}s(Re,"firstFailureLine");function De(e){const t=z(e);t===void 0||t.length===0||process.stderr.write(t.endsWith(`
4
4
  `)?t:`${t}
5
- `)}a(Ae,"printCapturedFailure");class $e{static{a(this,"SetupProgress")}interactive;bar=null;constructor(t=!!process.stdout.isTTY){this.interactive=t}start(t){return this.interactive?(this.bar=he(`Installing ${t}\u2026`),this.bar):null}async clear(){await this.bar?.stop(),this.bar=null}async succeed(t){await this.clear(),this.interactive&&process.stdout.write(`\r\x1B[2K\u2713 ${t}
6
- `)}async fail(t,n){await this.clear(),this.interactive&&process.stdout.write(`\r\x1B[2K\u2717 ${t} \u2014 ${Se(n)}
7
- `),Ae(n)}async run(t,n){const r=this.start(t);try{const o=await n(r);return await this.succeed(t),o}catch(o){throw await this.fail(t,o),o}}}function j(e,t){return A()?"current":(e?.(),fe(t),A()?"provisioned":"unavailable")}a(j,"ensureManagedRenderer");async function Ee(){try{ae()}catch{}}a(Ee,"reconcileInboxFrontDoor");function B(e,t){return t.length===0?[`${e}: none`]:[`${e}:`,...t.map(n=>` - ${n}`)]}a(B,"summarySection");function tt(e){return["crtr sys setup complete",...B("installed",e.installed),...B("skipped",e.skipped),"New to crouter? Ask for the tutorial in your first conversation, or run /tutorial any time."].join(`
5
+ `)}s(De,"printCapturedFailure");class Oe{static{s(this,"SetupProgress")}interactive;bar=null;constructor(t=!!process.stdout.isTTY){this.interactive=t}start(t){return this.interactive?(this.bar=be(`Installing ${t}\u2026`),this.bar):null}async clear(){await this.bar?.stop(),this.bar=null}async succeed(t){await this.clear(),this.interactive&&process.stdout.write(`\r\x1B[2K\u2713 ${t}
6
+ `)}async fail(t,n){await this.clear(),this.interactive&&process.stdout.write(`\r\x1B[2K\u2717 ${t} \u2014 ${Re(n)}
7
+ `),De(n)}async run(t,n){const r=this.start(t);try{const o=await n(r);return await this.succeed(t),o}catch(o){throw await this.fail(t,o),o}}}function W(e,t){return O()?"current":(e?.(),ve(t),O()?"provisioned":"unavailable")}s(W,"ensureManagedRenderer");async function Te(){try{de()}catch{}}s(Te,"reconcileInboxFrontDoor");function q(e,t){return t.length===0?[`${e}: none`]:[`${e}:`,...t.map(n=>` - ${n}`)]}s(q,"summarySection");function at(e){return["crtr sys setup complete",...q("installed",e.installed),...q("skipped",e.skipped),"New to crouter? Ask for the tutorial in your first conversation, or run /tutorial any time."].join(`
8
8
  `)+`
9
- `}a(tt,"formatSetupExecutionSummary");function G(e,t){const n=[];for(const r of e)try{r.sourceKind==="marketplace-source"?E(r.name,t)!==null&&n.push(r.id):r.sourceKind==="marketplace-plugin"&&ge(r.name,t)!==null&&n.push(r.id)}catch{}return n}a(G,"detectInstalledMarketplaceEntries");function Re(e,t="user"){if(E(e,t)!==null)return null;if(e!==R)throw new Error(`marketplace not registered: ${e}`);return $({url:D,ref:O,scope:t}),e}a(Re,"ensureMarketplaceRegistered");async function U(e){if(e.sourceKind==="marketplace-source")return $({url:e.installSource,ref:O,scope:"user"}),[e.name];if(e.sourceKind==="marketplace-plugin"){const[t,n]=e.installSource.split("/"),r=Re(t);return await me({marketplace:t,plugin:n},"user"),e.id==="capture-plugin"&&await K(),r===null?[e.name]:[r,e.name]}return await Ce(e.installSource),[e.name]}a(U,"installSetupPackage");async function nt(e){const t=P(b),n=L(re(_()),t);for(const i of G(t,"user"))n.add(i);const r=new Map(t.map(i=>[i.id,i])),o=process.stdin.isTTY&&process.stdout.isTTY?["crtr-extensions","official-marketplace","oauth-adapter","capture-plugin","search-plugin"]:["crtr-extensions","official-marketplace","capture-plugin","search-plugin"];for(const i of o){const u=r.get(i);if(!n.has(i))try{await U(u)}catch(c){e(u.name,c)}}try{j(void 0,()=>{})==="unavailable"&&e("termrender renderer",new Error("unavailable \u2014 install uv"))}catch(i){e("termrender renderer",i)}return se()}a(nt,"reconcileFirstRun");async function rt(e){const t=[],n=[],r=[],o=[],i=new $e;for(const s of e.packages){if(e.installedPackageIds.has(s.id)){if(n.push(`${s.name} (already installed)`),s.id==="capture-plugin"&&!m("capture"))try{await i.run("Capture CLI",()=>K()),t.push("Capture CLI")}catch(d){n.push(`Capture CLI (${d instanceof Error?d.message:String(d)})`)}continue}try{t.push(...await i.run(s.name,()=>U(s)))}catch(d){if(s.sourceKind!=="marketplace-source"&&s.sourceKind!=="marketplace-plugin")throw d;n.push(`${s.name} (${d instanceof Error?d.message:String(d)})`)}}for(const s of e.systemDeps){if(s.installed){o.push(`${s.tool} (already installed)`);continue}if(!s.autoInstall||!s.command){o.push(`${s.tool} (${s.hint})`);continue}const d=s.command,p=d===de;await i.run(s.tool,f=>{if(!p||f===null)return x(d);const Y=le();return x(d,z=>{const C=Y(z);C!==null&&f.setFraction(C/100)})}),r.push(s.tool)}const u=[];let c=!1,l;try{l=j(()=>{c=!0,i.start("termrender renderer")},s=>u.push(s))}catch(s){throw c&&await i.fail("termrender renderer",s),s}switch(l){case"provisioned":c&&await i.succeed("termrender renderer"),t.push("termrender renderer");break;case"current":n.push("termrender renderer (current)");break;case"unavailable":{const s=new v("unavailable \u2014 install uv",u.join(""));c&&await i.fail("termrender renderer",s),n.push("termrender renderer (unavailable \u2014 install uv)");break}}return await Ee(),{installed:[...t,...r],skipped:[...n,...o]}}a(rt,"executeSetupSubmission");export{R as OFFICIAL_MARKETPLACE_NAME,O as OFFICIAL_MARKETPLACE_REF,D as OFFICIAL_MARKETPLACE_URL,Je as SetupKeybindingsDraft,Qe as buildSetupInitialState,P as buildSetupManifest,xe as buildSystemInstallPlan,m as detectCommandOnPath,L as detectInstalledSetupPackageIds,Ie as detectPackageManager,rt as executeSetupSubmission,tt as formatSetupExecutionSummary,N as normalizePackageIdentity,Xe as packagePlanAction,nt as reconcileFirstRun,Ee as reconcileInboxFrontDoor,Ze as renderSetupStaticInstructions,_ as resolveSettingsPath};
9
+ `}s(at,"formatSetupExecutionSummary");function H(e,t){const n=[];for(const r of e)try{r.sourceKind==="marketplace-source"?N(r.name,t)!==null&&n.push(r.id):r.sourceKind==="marketplace-plugin"&&xe(r.name,t)!==null&&n.push(r.id)}catch{}return n}s(H,"detectInstalledMarketplaceEntries");function Ne(e,t="user"){if(N(e,t)!==null)return null;if(e!==L)throw new Error(`marketplace not registered: ${e}`);return T({url:_,ref:M,scope:t}),e}s(Ne,"ensureMarketplaceRegistered");function Le(e){const t=A(),n=D(t);if(!n||typeof n!="object"||Array.isArray(n))throw new Error(`invalid pi settings: ${t}`);const r=n.packages;if(!Array.isArray(r))throw new Error(`invalid pi packages: ${t}`);const o=s(c=>{const l=typeof c=="string"?c:c&&typeof c=="object"?c.source:void 0;return typeof l=="string"&&B(l).includes(v("pi-crtr-extensions"))},"isCrtrExtensions"),i=r.findIndex(o),u=r.filter(c=>!o(c));u.splice(i<0?u.length:i,0,{source:ee(R(t),e),extensions:j}),oe(t,{...n,packages:u})}s(Le,"configureCrtrExtensions");async function J(e){if(e.sourceKind==="marketplace-source")return T({url:e.installSource,ref:M,scope:"user"}),[e.name];if(e.sourceKind==="marketplace-plugin"){const[t,n]=e.installSource.split("/"),r=Ne(t);return await we({marketplace:t,plugin:n},"user"),e.id==="capture-plugin"&&await Y(),r===null?[e.name]:[r,e.name]}return await Ee(e.installSource),e.id==="crtr-extensions"&&Le(e.installSource),[e.name]}s(J,"installSetupPackage");async function ot(e){const t=S(),n=G(D(A()),t);for(const i of H(t,"user"))n.add(i);const r=new Map(t.map(i=>[i.id,i])),o=process.stdin.isTTY&&process.stdout.isTTY?["crtr-extensions","official-marketplace","oauth-adapter","capture-plugin","search-plugin"]:["crtr-extensions","official-marketplace","capture-plugin","search-plugin"];for(const i of o){const u=r.get(i);if(!n.has(i))try{await J(u)}catch(c){e(u.name,c)}}try{W(void 0,()=>{})==="unavailable"&&e("termrender renderer",new Error("unavailable \u2014 install uv"))}catch(i){e("termrender renderer",i)}return le()}s(ot,"reconcileFirstRun");async function ct(e){const t=[],n=[],r=[],o=[],i=new Oe;for(const a of e.packages){if(e.installedPackageIds.has(a.id)){if(n.push(`${a.name} (already installed)`),a.id==="capture-plugin"&&!g("capture"))try{await i.run("Capture CLI",()=>Y()),t.push("Capture CLI")}catch(d){n.push(`Capture CLI (${d instanceof Error?d.message:String(d)})`)}continue}try{t.push(...await i.run(a.name,()=>J(a)))}catch(d){if(a.sourceKind!=="marketplace-source"&&a.sourceKind!=="marketplace-plugin")throw d;n.push(`${a.name} (${d instanceof Error?d.message:String(d)})`)}}for(const a of e.systemDeps){if(a.installed){o.push(`${a.tool} (already installed)`);continue}if(!a.autoInstall||!a.command){o.push(`${a.tool} (${a.hint})`);continue}const d=a.command,p=d===ge;await i.run(a.tool,h=>{if(!p||h===null)return $(d);const x=me();return $(d,y=>{const E=x(y);E!==null&&h.setFraction(E/100)})}),r.push(a.tool)}const u=[];let c=!1,l;try{l=W(()=>{c=!0,i.start("termrender renderer")},a=>u.push(a))}catch(a){throw c&&await i.fail("termrender renderer",a),a}switch(l){case"provisioned":c&&await i.succeed("termrender renderer"),t.push("termrender renderer");break;case"current":n.push("termrender renderer (current)");break;case"unavailable":{const a=new w("unavailable \u2014 install uv",u.join(""));c&&await i.fail("termrender renderer",a),n.push("termrender renderer (unavailable \u2014 install uv)");break}}return await Te(),{installed:[...t,...r],skipped:[...n,...o]}}s(ct,"executeSetupSubmission");export{L as OFFICIAL_MARKETPLACE_NAME,M as OFFICIAL_MARKETPLACE_REF,_ as OFFICIAL_MARKETPLACE_URL,tt as SetupKeybindingsDraft,rt as buildSetupInitialState,S as buildSetupManifest,$e as buildSystemInstallPlan,g as detectCommandOnPath,G as detectInstalledSetupPackageIds,Ae as detectPackageManager,ct as executeSetupSubmission,at as formatSetupExecutionSummary,b as normalizePackageIdentity,nt as packagePlanAction,ot as reconcileFirstRun,Te as reconcileInboxFrontDoor,it as renderSetupStaticInstructions,A as resolveSettingsPath};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.343",
3
+ "version": "0.3.344",
4
4
  "description": "crtr — agent runtime with memory, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/runtime.lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.343",
3
+ "version": "0.3.344",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@north-light/crouter",
9
- "version": "0.3.343",
9
+ "version": "0.3.344",
10
10
  "hasInstallScript": true,
11
11
  "license": "GPL-3.0-only",
12
12
  "workspaces": [
@@ -10859,28 +10859,28 @@
10859
10859
  },
10860
10860
  "packages/crouter-api": {
10861
10861
  "name": "@north-light/crouter-api",
10862
- "version": "0.3.343",
10862
+ "version": "0.3.344",
10863
10863
  "license": "GPL-3.0-only"
10864
10864
  },
10865
10865
  "packages/crouter-env-docker": {
10866
10866
  "name": "@north-light/crouter-env-docker",
10867
- "version": "0.3.343",
10867
+ "version": "0.3.344",
10868
10868
  "license": "GPL-3.0-only"
10869
10869
  },
10870
10870
  "packages/crouter-plugin": {
10871
10871
  "name": "@north-light/crouter-plugin",
10872
- "version": "0.3.343",
10872
+ "version": "0.3.344",
10873
10873
  "license": "GPL-3.0-only",
10874
10874
  "dependencies": {
10875
- "@north-light/crouter-api": "^0.3.343"
10875
+ "@north-light/crouter-api": "^0.3.344"
10876
10876
  }
10877
10877
  },
10878
10878
  "packages/crouter-sdk": {
10879
10879
  "name": "@north-light/crouter-sdk",
10880
- "version": "0.3.343",
10880
+ "version": "0.3.344",
10881
10881
  "license": "GPL-3.0-only",
10882
10882
  "dependencies": {
10883
- "@north-light/crouter-api": "^0.3.343"
10883
+ "@north-light/crouter-api": "^0.3.344"
10884
10884
  }
10885
10885
  }
10886
10886
  }