@catladder/cli 0.0.0-new-cli-b2300dd6 → 0.0.0-new-cli-19442092

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/package.json CHANGED
@@ -53,7 +53,7 @@
53
53
  }
54
54
  ],
55
55
  "license": "MIT",
56
- "version": "0.0.0-new-cli-b2300dd6",
56
+ "version": "0.0.0-new-cli-19442092",
57
57
  "scripts": {
58
58
  "lint": "eslint \"src/**/*.ts\"",
59
59
  "lint:fix": "eslint \"src/**/*.ts\" --fix",
package/src/cli.ts CHANGED
@@ -189,24 +189,21 @@ completionCmd
189
189
  .command("zsh")
190
190
  .description("output zsh completion script")
191
191
  .action(() => {
192
- const binaryName = process.argv[1].split("/").pop() ?? "catladder";
193
- console.log(generateZshCompletionScript(binaryName));
192
+ console.log(generateZshCompletionScript());
194
193
  });
195
194
 
196
195
  completionCmd
197
196
  .command("install")
198
197
  .description("install shell completions into your .zshrc")
199
198
  .action(async () => {
200
- const binaryName = process.argv[1].split("/").pop() ?? "catladder";
201
- await installCompletions(binaryName);
199
+ await installCompletions();
202
200
  });
203
201
 
204
202
  completionCmd
205
203
  .command("uninstall")
206
204
  .description("remove shell completions from your .zshrc")
207
205
  .action(async () => {
208
- const binaryName = process.argv[1].split("/").pop() ?? "catladder";
209
- await uninstallCompletions(binaryName);
206
+ await uninstallCompletions();
210
207
  });
211
208
 
212
209
  // Cleanup on exit
package/src/completion.ts CHANGED
@@ -142,69 +142,113 @@ async function resolveChoicesForCompletion(
142
142
 
143
143
  /**
144
144
  * Generate the zsh completion script.
145
- * The user adds `eval "$(catladder completion zsh)"` to their .zshrc.
145
+ * The script discovers the local catladder binary at completion time,
146
+ * so it works without a global install.
146
147
  */
147
- export function generateZshCompletionScript(binaryName: string): string {
148
- const funcName = binaryName.replace(/-/g, "_");
148
+ export function generateZshCompletionScript(): string {
149
149
  return `
150
- ###-begin-${funcName}-completions-###
151
- _${funcName}_completions() {
150
+ ###-begin-catladder-completions-###
151
+ # Find catladder binary by walking up from cwd
152
+ _catladder_find_binary() {
153
+ local dir="$PWD"
154
+ while [[ "$dir" != "/" ]]; do
155
+ if [[ -x "$dir/node_modules/.bin/catladder" ]]; then
156
+ echo "$dir/node_modules/.bin/catladder"
157
+ return
158
+ fi
159
+ dir="\${dir:h}"
160
+ done
161
+ # Fall back to global
162
+ if command -v catladder &>/dev/null; then
163
+ echo "catladder"
164
+ fi
165
+ }
166
+
167
+ # Completion for direct invocation: catladder <TAB>
168
+ _catladder_completions() {
169
+ local catladder_bin=$(_catladder_find_binary)
170
+ [[ -z "$catladder_bin" ]] && return
171
+
152
172
  local -a completions
153
173
  local current_word="\${words[$CURRENT]}"
154
-
155
- # Words after the binary name, excluding the current word being completed
156
174
  local -a cmd_words=(\${words:1:$((CURRENT-2))})
157
175
 
158
- # Call the CLI's __complete command
159
- completions=(\${(f)"$(${binaryName} __complete -- "\${cmd_words[*]}" "$current_word" 2>/dev/null)"})
176
+ completions=(\${(f)"$($catladder_bin __complete -- "\${cmd_words[*]}" "$current_word" 2>/dev/null)"})
177
+
178
+ if [[ \${#completions[@]} -gt 0 ]]; then
179
+ compadd -a completions
180
+ fi
181
+ }
182
+
183
+ # Completion for yarn invocation: yarn catladder <TAB>
184
+ _yarn_catladder_completions() {
185
+ # Only activate when second word is "catladder"
186
+ if [[ $CURRENT -le 2 ]] || [[ "\${words[2]}" != "catladder" ]]; then
187
+ return
188
+ fi
189
+
190
+ local catladder_bin=$(_catladder_find_binary)
191
+ [[ -z "$catladder_bin" ]] && return
192
+
193
+ local -a completions
194
+ local current_word="\${words[$CURRENT]}"
195
+ local -a cmd_words=(\${words:2:$((CURRENT-3))})
196
+
197
+ completions=(\${(f)"$($catladder_bin __complete -- "\${cmd_words[*]}" "$current_word" 2>/dev/null)"})
160
198
 
161
199
  if [[ \${#completions[@]} -gt 0 ]]; then
162
200
  compadd -a completions
163
201
  fi
164
202
  }
165
203
 
166
- compdef _${funcName}_completions ${binaryName}
167
- ###-end-${funcName}-completions-###
204
+ compdef _catladder_completions catladder
205
+ compdef _yarn_catladder_completions yarn
206
+ ###-end-catladder-completions-###
168
207
  `.trim();
169
208
  }
170
209
 
171
- const BEGIN_MARKER = (name: string) =>
172
- `###-begin-${name.replace(/-/g, "_")}-completions-###`;
210
+ const BEGIN_MARKER = "###-begin-catladder-completions-###";
211
+ const END_MARKER = "###-end-catladder-completions-###";
173
212
 
174
213
  function getZshrcPath(): string {
175
214
  return join(homedir(), ".zshrc");
176
215
  }
177
216
 
178
217
  /**
179
- * Install completions by adding an eval line to .zshrc.
218
+ * Install completions by writing the script directly into .zshrc.
180
219
  */
181
- export async function installCompletions(binaryName: string): Promise<void> {
220
+ export async function installCompletions(): Promise<void> {
182
221
  const zshrcPath = getZshrcPath();
183
- const evalLine = `eval "$(${binaryName} completion zsh)"`;
184
- const marker = BEGIN_MARKER(binaryName);
185
222
 
186
223
  let content = "";
187
224
  if (existsSync(zshrcPath)) {
188
225
  content = readFileSync(zshrcPath, "utf-8");
189
226
  }
190
227
 
191
- if (content.includes(marker)) {
192
- console.log(
193
- `Completions for ${binaryName} are already installed in ${zshrcPath}`,
228
+ if (content.includes(BEGIN_MARKER)) {
229
+ // Replace existing
230
+ const startIdx = content.indexOf(BEGIN_MARKER);
231
+ const endIdx = content.indexOf(END_MARKER) + END_MARKER.length;
232
+ content =
233
+ content.slice(0, startIdx) +
234
+ generateZshCompletionScript() +
235
+ content.slice(endIdx);
236
+ writeFileSync(zshrcPath, content);
237
+ console.log(`Updated catladder completions in ${zshrcPath}`);
238
+ } else {
239
+ writeFileSync(
240
+ zshrcPath,
241
+ content + "\n" + generateZshCompletionScript() + "\n",
194
242
  );
195
- return;
243
+ console.log(`Installed catladder completions in ${zshrcPath}`);
196
244
  }
197
-
198
- const addition = `\n# ${binaryName} shell completions\n${evalLine}\n`;
199
- writeFileSync(zshrcPath, content + addition);
200
- console.log(`Installed completions for ${binaryName} in ${zshrcPath}`);
201
245
  console.log(`Restart your shell or run: source ${zshrcPath}`);
202
246
  }
203
247
 
204
248
  /**
205
249
  * Remove completions from .zshrc.
206
250
  */
207
- export async function uninstallCompletions(binaryName: string): Promise<void> {
251
+ export async function uninstallCompletions(): Promise<void> {
208
252
  const zshrcPath = getZshrcPath();
209
253
  if (!existsSync(zshrcPath)) {
210
254
  console.log("No .zshrc found");
@@ -212,31 +256,20 @@ export async function uninstallCompletions(binaryName: string): Promise<void> {
212
256
  }
213
257
 
214
258
  const content = readFileSync(zshrcPath, "utf-8");
215
- const evalLine = `eval "$(${binaryName} completion zsh)"`;
216
- const commentLine = `# ${binaryName} shell completions`;
217
259
 
218
- if (!content.includes(evalLine)) {
219
- console.log(`No completions for ${binaryName} found in ${zshrcPath}`);
260
+ if (!content.includes(BEGIN_MARKER)) {
261
+ console.log("No catladder completions found in " + zshrcPath);
220
262
  return;
221
263
  }
222
264
 
223
- const cleaned = content
224
- .replace(
225
- new RegExp(
226
- `\\n?${commentLine.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\n?`,
227
- "g",
228
- ),
229
- "\n",
230
- )
231
- .replace(
232
- new RegExp(
233
- `\\n?${evalLine.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\n?`,
234
- "g",
235
- ),
236
- "\n",
237
- );
265
+ const startIdx = content.indexOf(BEGIN_MARKER);
266
+ const endIdx = content.indexOf(END_MARKER) + END_MARKER.length;
267
+ const cleaned = (content.slice(0, startIdx) + content.slice(endIdx)).replace(
268
+ /\n{3,}/g,
269
+ "\n\n",
270
+ );
238
271
 
239
272
  writeFileSync(zshrcPath, cleaned);
240
- console.log(`Removed completions for ${binaryName} from ${zshrcPath}`);
273
+ console.log(`Removed catladder completions from ${zshrcPath}`);
241
274
  console.log(`Restart your shell or run: source ${zshrcPath}`);
242
275
  }