@songsid/agend 2.1.4-beta.3 → 2.1.4-beta.4

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.
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Installation of shell completion, shared by `agend completion install`,
3
+ * install.sh, quickstart and `agend update`.
4
+ *
5
+ * Policy (one deliberate asymmetry):
6
+ * - bash — write a static file into bash-completion's user (or, for root,
7
+ * system) completions directory. No rc file is touched, the write is
8
+ * naturally idempotent, and the shell pays zero startup cost because
9
+ * bash-completion lazy-loads the file on first <tab>.
10
+ * - zsh — there is no user-level auto-loaded directory: completion needs
11
+ * fpath + compinit, both rc-file territory. Root installs get the system
12
+ * site-functions file (no rc edit); everyone else gets a marker-guarded
13
+ * eval line in ~/.zshrc, and ONLY when explicitly authorized
14
+ * (modifyRc: true) — an rc edit is opt-in, a plain file drop is not.
15
+ *
16
+ * `refresh` mode re-generates artifacts that already exist and never creates
17
+ * new ones: `agend update` must keep completions in sync with the new
18
+ * command set without introducing side effects the user never chose.
19
+ */
20
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, accessSync, constants } from "node:fs";
21
+ import { homedir } from "node:os";
22
+ import { basename, dirname, join } from "node:path";
23
+ export const ZSH_RC_MARKER = "# >>> agend completion >>>";
24
+ const ZSH_RC_BLOCK = `
25
+ ${ZSH_RC_MARKER}
26
+ command -v agend >/dev/null 2>&1 && eval "$(agend completion zsh)"
27
+ # <<< agend completion <<<
28
+ `;
29
+ /** Shells worth installing for: $SHELL first, then rc-file evidence. */
30
+ export function detectShells(env = process.env, home = homedir()) {
31
+ const shells = new Set();
32
+ const login = basename(env.SHELL ?? "");
33
+ if (login === "bash" || login === "zsh")
34
+ shells.add(login);
35
+ if (existsSync(join(home, ".bashrc")) || existsSync(join(home, ".bash_profile")))
36
+ shells.add("bash");
37
+ if (existsSync(join(home, ".zshrc")))
38
+ shells.add("zsh");
39
+ return [...shells];
40
+ }
41
+ function canWrite(dir) {
42
+ try {
43
+ accessSync(dir, constants.W_OK);
44
+ return true;
45
+ }
46
+ catch {
47
+ return false;
48
+ }
49
+ }
50
+ /** Write `content` to `path`, reporting whether anything changed. */
51
+ function writeArtifact(path, content) {
52
+ const existed = existsSync(path);
53
+ if (existed) {
54
+ try {
55
+ if (readFileSync(path, "utf-8") === content)
56
+ return "unchanged";
57
+ }
58
+ catch { /* unreadable — rewrite */ }
59
+ }
60
+ mkdirSync(dirname(path), { recursive: true });
61
+ writeFileSync(path, content);
62
+ return existed ? "updated" : "installed";
63
+ }
64
+ /**
65
+ * bash: a static file in the completions directory. bash-completion ≥ 2.9
66
+ * auto-loads `~/.local/share/bash-completion/completions/<command>` (or
67
+ * $XDG_DATA_HOME); root installs prefer the system directory so every user
68
+ * benefits and no home directory is involved.
69
+ */
70
+ export function installBashCompletion(script, opts = {}) {
71
+ const home = opts.home ?? homedir();
72
+ const isRoot = opts.isRoot ?? (typeof process.getuid === "function" && process.getuid() === 0);
73
+ const systemDir = opts.systemBashDir ?? "/usr/share/bash-completion/completions";
74
+ const target = isRoot && existsSync(systemDir) && canWrite(systemDir)
75
+ ? join(systemDir, "agend")
76
+ : join(process.env.XDG_DATA_HOME || join(home, ".local", "share"), "bash-completion", "completions", "agend");
77
+ if (opts.refresh && !existsSync(target))
78
+ return { shell: "bash", status: "skipped" };
79
+ try {
80
+ const status = writeArtifact(target, script);
81
+ return { shell: "bash", status, path: target };
82
+ }
83
+ catch (err) {
84
+ return {
85
+ shell: "bash",
86
+ status: "hint",
87
+ hint: `Could not write ${target} (${err.message}). Manual: echo 'eval "$(agend completion bash)"' >> ~/.bashrc`,
88
+ };
89
+ }
90
+ }
91
+ /**
92
+ * zsh: root installs write the system site-functions `_agend` (already on
93
+ * fpath, no rc edit). Everyone else needs an rc line, which is only written
94
+ * with explicit authorization; otherwise the caller shows the hint.
95
+ */
96
+ export function installZshCompletion(fpathScript, opts = {}) {
97
+ const home = opts.home ?? homedir();
98
+ const isRoot = opts.isRoot ?? (typeof process.getuid === "function" && process.getuid() === 0);
99
+ const systemDir = opts.systemZshDir ?? "/usr/share/zsh/site-functions";
100
+ if (isRoot && existsSync(systemDir) && canWrite(systemDir)) {
101
+ const target = join(systemDir, "_agend");
102
+ if (opts.refresh && !existsSync(target))
103
+ return { shell: "zsh", status: "skipped" };
104
+ try {
105
+ const status = writeArtifact(target, fpathScript);
106
+ return { shell: "zsh", status, path: target };
107
+ }
108
+ catch { /* fall through to the rc path */ }
109
+ }
110
+ const zshrc = join(home, ".zshrc");
111
+ const hasMarker = existsSync(zshrc) && readFileSync(zshrc, "utf-8").includes(ZSH_RC_MARKER);
112
+ if (hasMarker) {
113
+ // The rc line evals the CURRENT binary's script on every shell start, so
114
+ // there is nothing to refresh — it can never go stale.
115
+ return { shell: "zsh", status: "unchanged", path: zshrc };
116
+ }
117
+ if (opts.refresh)
118
+ return { shell: "zsh", status: "skipped" };
119
+ if (!opts.modifyRc) {
120
+ return {
121
+ shell: "zsh",
122
+ status: "hint",
123
+ hint: `To enable zsh completion: echo 'eval "$(agend completion zsh)"' >> ~/.zshrc (requires compinit), or rerun with --modify-rc`,
124
+ };
125
+ }
126
+ try {
127
+ writeFileSync(zshrc, (existsSync(zshrc) ? readFileSync(zshrc, "utf-8") : "") + ZSH_RC_BLOCK);
128
+ return { shell: "zsh", status: "installed", path: zshrc };
129
+ }
130
+ catch (err) {
131
+ return {
132
+ shell: "zsh",
133
+ status: "hint",
134
+ hint: `Could not write ${zshrc} (${err.message}). Manual: echo 'eval "$(agend completion zsh)"' >> ~/.zshrc`,
135
+ };
136
+ }
137
+ }
138
+ /**
139
+ * The whole policy in one call: install for every detected (or requested)
140
+ * shell. Used by `agend completion install`, install.sh, quickstart and
141
+ * update (`refresh: true`).
142
+ */
143
+ export function installCompletions(scripts, shells, opts = {}) {
144
+ const results = [];
145
+ for (const shell of shells) {
146
+ results.push(shell === "bash"
147
+ ? installBashCompletion(scripts.bash, opts)
148
+ : installZshCompletion(scripts.zshFpath, opts));
149
+ }
150
+ return results;
151
+ }
152
+ //# sourceMappingURL=completion-install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion-install.js","sourceRoot":"","sources":["../src/completion-install.ts"],"names":[],"mappings":"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"}
@@ -23,5 +23,11 @@ export interface CompletionSpec {
23
23
  fleetInstanceCommands: string[];
24
24
  }
25
25
  export declare function bashCompletion(spec: CompletionSpec): string;
26
- export declare function zshCompletion(spec: CompletionSpec): string;
26
+ /**
27
+ * @param variant "eval" is sourced from a live shell (via the rc line) and
28
+ * registers itself with `compdef`; "fpath" is a `_agend` file dropped into
29
+ * a directory on fpath, where the `#compdef` header does the registering
30
+ * and the file body is executed as the completion function itself.
31
+ */
32
+ export declare function zshCompletion(spec: CompletionSpec, variant?: "eval" | "fpath"): string;
27
33
  export declare function completionScript(shell: CompletionShell, spec: CompletionSpec): string;
@@ -72,10 +72,20 @@ _agend_completion() {
72
72
  complete -F _agend_completion agend
73
73
  `;
74
74
  }
75
- export function zshCompletion(spec) {
76
- return `# agend zsh completion eval "$(agend completion zsh)"
75
+ /**
76
+ * @param variant "eval" is sourced from a live shell (via the rc line) and
77
+ * registers itself with `compdef`; "fpath" is a `_agend` file dropped into
78
+ * a directory on fpath, where the `#compdef` header does the registering
79
+ * and the file body is executed as the completion function itself.
80
+ */
81
+ export function zshCompletion(spec, variant = "eval") {
82
+ const header = variant === "fpath"
83
+ ? "#compdef agend\n# agend zsh completion — installed by `agend completion install`"
84
+ : `# agend zsh completion — eval "$(agend completion zsh)"
77
85
  # Requires compinit to have run first (put \`autoload -Uz compinit && compinit\`
78
- # above this line in ~/.zshrc).
86
+ # above this line in ~/.zshrc).`;
87
+ const footer = variant === "fpath" ? `_agend "$@"` : "compdef _agend agend";
88
+ return `${header}
79
89
  #
80
90
  # compadd is used rather than _values/_describe because it is the lowest-level
81
91
  # primitive and filters by the current prefix on its own — fewer moving parts.
@@ -112,7 +122,7 @@ _agend() {
112
122
  (( \${#instances} )) && compadd -a instances
113
123
  fi
114
124
  }
115
- compdef _agend agend
125
+ ${footer}
116
126
  `;
117
127
  }
118
128
  export function completionScript(shell, spec) {
@@ -1 +1 @@
1
- {"version":3,"file":"completion.js","sourceRoot":"","sources":["../src/completion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,KAAK,CAAU,CAAC;AAc1D,8EAA8E;AAC9E,SAAS,KAAK,CAAC,IAAc;IAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAoB;IACjD,OAAO;;;;;;;;;;;;;;;;;;;;+BAoBsB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;;;;;+BAKpB,KAAK,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC;;;;;;iCAM3B,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;;;aAGxC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC;;;;;;;;;;WAUnC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC;;;;;;;;;CAStC,CAAC;AACF,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAoB;IAChD,OAAO;;;;;;;;;;;;;iBAaQ,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;;;;;iBAKpB,KAAK,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC;;;;;;mBAM3B,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;;;oCAGH,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC;;;;;;;kCAOnC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC;;;;;;CAM7D,CAAC;AACF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAsB,EAAE,IAAoB;IAC3E,OAAO,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;AACtE,CAAC"}
1
+ {"version":3,"file":"completion.js","sourceRoot":"","sources":["../src/completion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,KAAK,CAAU,CAAC;AAc1D,8EAA8E;AAC9E,SAAS,KAAK,CAAC,IAAc;IAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAoB;IACjD,OAAO;;;;;;;;;;;;;;;;;;;;+BAoBsB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;;;;;+BAKpB,KAAK,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC;;;;;;iCAM3B,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;;;aAGxC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC;;;;;;;;;;WAUnC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC;;;;;;;;;CAStC,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAoB,EAAE,UAA4B,MAAM;IACpF,MAAM,MAAM,GAAG,OAAO,KAAK,OAAO;QAChC,CAAC,CAAC,kFAAkF;QACpF,CAAC,CAAC;;gCAE0B,CAAC;IAC/B,MAAM,MAAM,GAAG,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,sBAAsB,CAAC;IAC5E,OAAO,GAAG,MAAM;;;;;;;;;;;iBAWD,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;;;;;iBAKpB,KAAK,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC;;;;;;mBAM3B,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;;;oCAGH,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC;;;;;;;kCAOnC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC;;;;;EAK5D,MAAM;CACP,CAAC;AACF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAsB,EAAE,IAAoB;IAC3E,OAAO,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;AACtE,CAAC"}
@@ -6533,13 +6533,11 @@ When users create specialized instances, suggest these configurations:
6533
6533
  }
6534
6534
  catch { /* default restart */ }
6535
6535
  const warn = isModelCompatible(backendName, model) ? "" : `⚠️ "${model}" doesn't match ${backendName}'s usual pattern — passing through anyway.\n`;
6536
- if (strategy === "runtime") {
6537
- if (!this.instanceIpcClients.get(instanceName))
6538
- return `${warn}❌ ${instanceName} is not running.`;
6539
- this.pasteRawToClassicInstance(instanceName, `/model ${model}`);
6540
- return `${warn}✅ Switched ${instanceName} to \`${model}\` (runtime).${this.effortSuffix(instanceName)}`;
6536
+ if (strategy === "runtime" && !this.instanceIpcClients.get(instanceName)) {
6537
+ return `${warn}❌ ${instanceName} is not running.`;
6541
6538
  }
6542
- // restart: persist the model so the respawned CLI launches with it.
6539
+ // Persist either way: a runtime switch must survive the next respawn too,
6540
+ // or the instance silently reverts to the CLI default after a fleet restart.
6543
6541
  let persisted = false;
6544
6542
  if (this.fleetConfig?.instances[instanceName]) {
6545
6543
  this.fleetConfig.instances[instanceName].model = model;
@@ -6551,6 +6549,10 @@ When users create specialized instances, suggest these configurations:
6551
6549
  }
6552
6550
  if (!persisted)
6553
6551
  return `${warn}❌ Could not set model for ${instanceName}.`;
6552
+ if (strategy === "runtime") {
6553
+ this.pasteRawToClassicInstance(instanceName, `/model ${model}`);
6554
+ return `${warn}✅ Switched ${instanceName} to \`${model}\` (runtime).${this.effortSuffix(instanceName)}`;
6555
+ }
6554
6556
  await this.restartSingleInstance(instanceName);
6555
6557
  return `${warn}✅ Set ${instanceName} to \`${model}\` and restarted.${this.effortSuffix(instanceName)}`;
6556
6558
  }