@north-light/cli 0.3.524 → 0.3.526

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 (52) hide show
  1. package/dist/api/command-manifest/result.d.ts +4 -2
  2. package/dist/api/command-manifest/result.js +1 -1
  3. package/dist/api/command-manifest/schema.js +1 -1
  4. package/dist/api/plugin-manifest-schema.d.ts +3 -0
  5. package/dist/builtin-memory/crouter-plugin/deploying.md +2 -2
  6. package/dist/builtin-memory/crouter-plugin/output.md +3 -1
  7. package/dist/clients/attach/chrome/roster.d.ts +1 -1
  8. package/dist/clients/attach/chrome/roster.js +4 -4
  9. package/dist/clients/attach/render/chat-view.d.ts +9 -0
  10. package/dist/clients/attach/render/chat-view.js +3 -3
  11. package/dist/clients/attach/render/page-block.d.ts +2 -0
  12. package/dist/clients/attach/render/page-block.js +1 -1
  13. package/dist/clients/attach/session/connection.d.ts +1 -1
  14. package/dist/clients/attach/session/context.d.ts +1 -1
  15. package/dist/clients/attach/session/profile-files.d.ts +3 -3
  16. package/dist/clients/attach/session/profile-files.js +1 -1
  17. package/dist/clients/attach/viewer.js +633 -756
  18. package/dist/commands/pkg/browse/command-view.js +1 -1
  19. package/dist/core/canvas/db.d.ts +28 -2
  20. package/dist/core/canvas/db.js +2 -2
  21. package/dist/core/canvas/migrations.js +53 -53
  22. package/dist/core/canvas/nav-model.js +1 -1
  23. package/dist/core/canvas/recovery.d.ts +13 -0
  24. package/dist/core/canvas/recovery.js +2 -2
  25. package/dist/core/conversation-store/client.d.ts +2 -2
  26. package/dist/core/conversation-store/index.d.ts +30 -2
  27. package/dist/core/conversation-store/index.js +1 -1
  28. package/dist/core/conversation-store/patch.js +1 -1
  29. package/dist/core/graph/watches.d.ts +2 -0
  30. package/dist/core/graph/watches.js +9 -9
  31. package/dist/core/help.js +7 -7
  32. package/dist/core/llm/run.js +2 -2
  33. package/dist/core/runtime/broker/fault-retry.d.ts +9 -3
  34. package/dist/core/runtime/broker/fault-retry.js +1 -1
  35. package/dist/core/runtime/broker/rebind.d.ts +4 -0
  36. package/dist/core/runtime/broker/rebind.js +1 -1
  37. package/dist/core/runtime/broker/run-turn-queue.d.ts +2 -0
  38. package/dist/core/runtime/broker/run-turn-queue.js +1 -1
  39. package/dist/core/runtime/broker-persona-guidance.d.ts +1 -1
  40. package/dist/core/runtime/broker-persona-guidance.js +3 -3
  41. package/dist/core/runtime/broker.js +1 -1
  42. package/dist/core/runtime/close.d.ts +2 -2
  43. package/dist/core/runtime/close.js +1 -1
  44. package/dist/daemon/crtrd.js +8 -8
  45. package/dist/daemon/reconcilers/broker-supervision.d.ts +6 -2
  46. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  47. package/dist/daemon/runs/observer.js +2 -2
  48. package/docs/plugin/deploying.md +2 -2
  49. package/docs/plugin/output.md +3 -1
  50. package/package.json +2 -2
  51. package/packages/crouter-identity/package.json +1 -1
  52. package/runtime.lock.json +12 -12
@@ -27,7 +27,7 @@ export interface AttachConnection {
27
27
  readonly canvasSource: CanvasSource;
28
28
  /** Viewer-LOCAL concerns only — `cwd` drives theming and this pane's own git
29
29
  * status, and is the CLI's own cwd under `--canvas`. */
30
- readonly meta: Pick<NodeMeta, 'cwd' | 'profile_id'>;
30
+ readonly meta: Pick<NodeMeta, 'cwd' | 'profile_id' | 'grantee'>;
31
31
  /** The attached node's persona/lifecycle, when this canvas can tell us —
32
32
  * `undefined` for a remote attach until the viewer refetches it. */
33
33
  readonly nodeIdentity: Pick<NodeMeta, 'kind' | 'mode' | 'lifecycle' | 'icon'> | undefined;
@@ -46,7 +46,7 @@ export interface AttachSession {
46
46
  /** Viewer-LOCAL concerns only: `cwd` drives theming and this pane's own git
47
47
  * status, and is the CLI's own cwd for a remote attach — never the remote
48
48
  * node's directory. */
49
- readonly meta: Pick<NodeMeta, 'cwd' | 'profile_id'>;
49
+ readonly meta: Pick<NodeMeta, 'cwd' | 'profile_id' | 'grantee'>;
50
50
  /** Canvas read authority for chrome and the graph overlay: an API source
51
51
  * locally, a relayed source under `--canvas`. */
52
52
  readonly canvasSource: CanvasSource;
@@ -2,7 +2,7 @@ import type { NodeRow } from '../../../core/canvas/types.js';
2
2
  interface ProfileFileSearchOptions {
3
3
  cwd: string;
4
4
  nodeDirs: readonly string[];
5
- nodeIds: readonly string[];
5
+ nodes: readonly Pick<NodeRow, 'node_id' | 'grantee'>[];
6
6
  profileId: string | null;
7
7
  fdPath: string | null;
8
8
  onNotice: (message: string) => void;
@@ -11,7 +11,7 @@ interface ProfileFileSearchOptions {
11
11
  * descendant subtree. The `parent` hierarchy, rather than the subscription
12
12
  * graph, is the user-visible child/parent relationship. */
13
13
  export declare function relatedNodeIds(nodes: readonly Pick<NodeRow, 'node_id' | 'parent'>[], nodeId: string): string[];
14
- /** Return the working directories of the same node family. */
15
- export declare function relatedNodeDirs(nodes: readonly Pick<NodeRow, 'node_id' | 'cwd' | 'parent'>[], nodeId: string): string[];
14
+ /** Return the rows of the same node family. */
15
+ export declare function relatedNodes<T extends Pick<NodeRow, 'node_id' | 'parent'>>(nodes: readonly T[], nodeId: string): T[];
16
16
  export declare function launchProfileFileSearch(opts: ProfileFileSearchOptions): void;
17
17
  export {};
@@ -1 +1 @@
1
- var N=Object.defineProperty;var l=(e,t)=>N(e,"name",{value:t,configurable:!0});import{constants as _,accessSync as j,existsSync as P,mkdtempSync as k,readFileSync as E,rmSync as d,statSync as z}from"node:fs";import{tmpdir as C}from"node:os";import{delimiter as F,join as p,resolve as I,sep as $}from"node:path";import{execFile as v,spawnSync as T}from"node:child_process";import{loadProfileManifest as q,profileDir as O}from"../../../core/profiles/manifest.js";import{contextDir as A}from"../../../core/canvas/node-agent-paths.js";import{shellQuote as c}from"../../../core/runtime/placement-tmux.js";import{nvimShellCommand as H}from"../../../core/nvim-launch.js";import{surfaceTmuxStyleArgs as S}from"../../../core/runtime/surface-bg.js";function L(e,t){const n=new Map(e.map(o=>[o.node_id,o])),r=new Set([t]);for(let o=n.get(t);o?.parent!==null&&o?.parent!==void 0;){const f=o.parent;if(r.has(f))break;r.add(f),o=n.get(f)}const s=[t];for(;s.length>0;){const o=s.pop();for(const f of e)f.parent!==o||r.has(f.node_id)||(r.add(f.node_id),s.push(f.node_id))}return e.filter(o=>r.has(o.node_id)).map(o=>o.node_id)}l(L,"relatedNodeIds");function ce(e,t){const n=new Set(L(e,t));return e.filter(r=>n.has(r.node_id)).map(r=>r.cwd)}l(ce,"relatedNodeDirs");function M(e){const t=[];for(const n of e)try{t.push(A(n))}catch{continue}return y(t)}l(M,"familyDocumentDirs");function R(e){try{return z(e).isDirectory()}catch{return!1}}l(R,"isDirectory");function W(e,t){const n=[...t==null?[]:[t],...(process.env.PATH??"").split(F).filter(Boolean).map(r=>p(r,e))];return[...new Set(n)]}l(W,"executableCandidates");function h(e,t){for(const n of W(e,t)){try{j(n,_.X_OK)}catch{continue}if(T(n,["--version"],{stdio:"ignore"}).status===0)return n}return null}l(h,"workingExecutable");function B(e){if(e===null||e==="")return{projects:[],settings:null};try{const{profileId:t,manifest:n}=q(e);return{projects:n.projects.map(r=>r.path),settings:O(t)}}catch{return{projects:[],settings:null}}}l(B,"profileSearchRoots");function y(e){const t=new Set,n=[];for(const r of e){const s=I(r);t.has(s)||!R(s)||(t.add(s),n.push(s))}return n}l(y,"dedupeExistingDirs");function K(e){return e.filter(t=>!e.some(n=>n!==t&&t.startsWith(n+$)))}l(K,"outermostDirs");const Q=20;function X(e){try{const t=E(e);if(t.length===0)return null;const n=t[t.length-1]===0?t.length-1:t.length;return t.subarray(0,n).toString("utf8")||null}catch{return null}}l(X,"selectionPath");function se(e){const t=h("fd",e.fdPath);if(t===null){e.onNotice("fd is required for profile file search");return}const n=h("fzf");if(n===null){e.onNotice("fzf is required for profile file search");return}const r=h("nvim");if(r===null){e.onNotice("Neovim is required for profile file search");return}const s=B(e.profileId),o=y([e.cwd,...e.nodeDirs,...s.projects]);if(o.length===0){e.onNotice("No profile file-search directories exist");return}const f=K(o),w=y([...s.settings===null?[]:[s.settings]]),u=k(p(C(),"crtr-profile-files-")),g=p(u,"selection"),x=p(u,"candidates"),b=M(e.nodeIds).filter(i=>!f.some(a=>i===a||i.startsWith(a+$))),D=`{ ${[...f.map(i=>`${c(t)} --type f --hidden --exclude .git . ${c(i)}`),...b.map(i=>`${c(t)} --type f --hidden --exclude .git --exclude ${c("/jobs")} . ${c(i)}`),...w.map(i=>`${c(t)} --type f --hidden --exclude .git --no-ignore . ${c(i)}`)].map(i=>`${i} &`).join(" ")} wait; } > ${c(x)} && ${c(n)} --print0 --scheme=path --hscroll-off=${Q} --header ${c("fuzzy path \u2022 ctrl-y yank file path")} --bind ${c("ctrl-y:execute-silent(printf '%s' {} | { if command -v pbcopy >/dev/null 2>&1; then pbcopy; elif command -v wl-copy >/dev/null 2>&1; then wl-copy; elif command -v xclip >/dev/null 2>&1; then xclip -selection clipboard; else cat >/dev/null; fi; }; printf '%s' {} | tmux load-buffer -w -)+abort")} --preview ${c("head -100 -- {}")} < ${c(x)} > ${c(g)}`;try{v("tmux",["display-popup","-E","-T"," profile files ","-w","80%","-h","60%",...S(),D],()=>{const i=X(g);if(i===null||!P(i)){d(u,{recursive:!0,force:!0});return}const a=`exec ${H("edit",[i],r)}`;try{v("tmux",["display-popup","-E","-T"," profile file ","-w","90%","-h","90%",...S(),a],()=>d(u,{recursive:!0,force:!0}))}catch(m){d(u,{recursive:!0,force:!0}),e.onNotice(`Could not open profile file: ${m instanceof Error?m.message:String(m)}`)}})}catch(i){d(u,{recursive:!0,force:!0}),e.onNotice(`Could not open profile file search: ${i instanceof Error?i.message:String(i)}`)}}l(se,"launchProfileFileSearch");export{se as launchProfileFileSearch,ce as relatedNodeDirs,L as relatedNodeIds};
1
+ var N=Object.defineProperty;var l=(e,t)=>N(e,"name",{value:t,configurable:!0});import{constants as _,accessSync as j,existsSync as P,mkdtempSync as k,readFileSync as E,rmSync as d,statSync as z}from"node:fs";import{tmpdir as C}from"node:os";import{delimiter as F,join as p,resolve as T,sep as $}from"node:path";import{execFile as v,spawnSync as q}from"node:child_process";import{loadProfileManifest as I,profileDir as O}from"../../../core/profiles/manifest.js";import{contextDir as A}from"../../../core/canvas/paths.js";import{shellQuote as c}from"../../../core/runtime/placement-tmux.js";import{nvimShellCommand as H}from"../../../core/nvim-launch.js";import{surfaceTmuxStyleArgs as S}from"../../../core/runtime/surface-bg.js";function L(e,t){const n=new Map(e.map(i=>[i.node_id,i])),o=new Set([t]);for(let i=n.get(t);i?.parent!==null&&i?.parent!==void 0;){const f=i.parent;if(o.has(f))break;o.add(f),i=n.get(f)}const s=[t];for(;s.length>0;){const i=s.pop();for(const f of e)f.parent!==i||o.has(f.node_id)||(o.add(f.node_id),s.push(f.node_id))}return e.filter(i=>o.has(i.node_id)).map(i=>i.node_id)}l(L,"relatedNodeIds");function ce(e,t){const n=new Set(L(e,t));return e.filter(o=>n.has(o.node_id))}l(ce,"relatedNodes");function M(e){const t=[];for(const n of e)try{t.push(A(n.node_id,n.grantee))}catch{continue}return y(t)}l(M,"familyDocumentDirs");function R(e){try{return z(e).isDirectory()}catch{return!1}}l(R,"isDirectory");function W(e,t){const n=[...t==null?[]:[t],...(process.env.PATH??"").split(F).filter(Boolean).map(o=>p(o,e))];return[...new Set(n)]}l(W,"executableCandidates");function h(e,t){for(const n of W(e,t)){try{j(n,_.X_OK)}catch{continue}if(q(n,["--version"],{stdio:"ignore"}).status===0)return n}return null}l(h,"workingExecutable");function B(e){if(e===null||e==="")return{projects:[],settings:null};try{const{profileId:t,manifest:n}=I(e);return{projects:n.projects.map(o=>o.path),settings:O(t)}}catch{return{projects:[],settings:null}}}l(B,"profileSearchRoots");function y(e){const t=new Set,n=[];for(const o of e){const s=T(o);t.has(s)||!R(s)||(t.add(s),n.push(s))}return n}l(y,"dedupeExistingDirs");function K(e){return e.filter(t=>!e.some(n=>n!==t&&t.startsWith(n+$)))}l(K,"outermostDirs");const Q=20;function X(e){try{const t=E(e);if(t.length===0)return null;const n=t[t.length-1]===0?t.length-1:t.length;return t.subarray(0,n).toString("utf8")||null}catch{return null}}l(X,"selectionPath");function se(e){const t=h("fd",e.fdPath);if(t===null){e.onNotice("fd is required for profile file search");return}const n=h("fzf");if(n===null){e.onNotice("fzf is required for profile file search");return}const o=h("nvim");if(o===null){e.onNotice("Neovim is required for profile file search");return}const s=B(e.profileId),i=y([e.cwd,...e.nodeDirs,...s.projects]);if(i.length===0){e.onNotice("No profile file-search directories exist");return}const f=K(i),b=y([...s.settings===null?[]:[s.settings]]),u=k(p(C(),"crtr-profile-files-")),g=p(u,"selection"),x=p(u,"candidates"),w=M(e.nodes).filter(r=>!f.some(a=>r===a||r.startsWith(a+$))),D=`{ ${[...f.map(r=>`${c(t)} --type f --hidden --exclude .git . ${c(r)}`),...w.map(r=>`${c(t)} --type f --hidden --exclude .git --exclude ${c("/jobs")} . ${c(r)}`),...b.map(r=>`${c(t)} --type f --hidden --exclude .git --no-ignore . ${c(r)}`)].map(r=>`${r} &`).join(" ")} wait; } > ${c(x)} && ${c(n)} --print0 --scheme=path --hscroll-off=${Q} --header ${c("fuzzy path \u2022 ctrl-y yank file path")} --bind ${c("ctrl-y:execute-silent(printf '%s' {} | { if command -v pbcopy >/dev/null 2>&1; then pbcopy; elif command -v wl-copy >/dev/null 2>&1; then wl-copy; elif command -v xclip >/dev/null 2>&1; then xclip -selection clipboard; else cat >/dev/null; fi; }; printf '%s' {} | tmux load-buffer -w -)+abort")} --preview ${c("head -100 -- {}")} < ${c(x)} > ${c(g)}`;try{v("tmux",["display-popup","-E","-T"," profile files ","-w","80%","-h","60%",...S(),D],()=>{const r=X(g);if(r===null||!P(r)){d(u,{recursive:!0,force:!0});return}const a=`exec ${H("edit",[r],o)}`;try{v("tmux",["display-popup","-E","-T"," profile file ","-w","90%","-h","90%",...S(),a],()=>d(u,{recursive:!0,force:!0}))}catch(m){d(u,{recursive:!0,force:!0}),e.onNotice(`Could not open profile file: ${m instanceof Error?m.message:String(m)}`)}})}catch(r){d(u,{recursive:!0,force:!0}),e.onNotice(`Could not open profile file search: ${r instanceof Error?r.message:String(r)}`)}}l(se,"launchProfileFileSearch");export{se as launchProfileFileSearch,L as relatedNodeIds,ce as relatedNodes};