plugin-updater 1.4.1 → 1.4.2

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.js CHANGED
@@ -4,7 +4,7 @@ process.env.PLUGIN_UPDATER_CLI = "1";
4
4
  import fs from "fs";
5
5
  import path from "path";
6
6
  import os from "os";
7
- import { resolveOpencodeConfigPath, insertPluginIntoJsonc, resolveInitApps } from "./init.js";
7
+ import { resolveOpencodeConfigPath, insertPluginIntoJsonc, resolveInitApps, cwdApp } from "./init.js";
8
8
  function parseArgs(argv) {
9
9
  const parsed = { command: argv[0] ?? "", urls: [] };
10
10
  for (let i = 1; i < argv.length; i++) {
@@ -124,34 +124,31 @@ function presentApps() {
124
124
  || binaryExists("opencode");
125
125
  return { claude, opencode };
126
126
  }
127
- // infer the app from the current directory (the prompt's default suggestion)
128
- function cwdApp() {
129
- const cwd = process.cwd().replace(/\\/g, "/");
130
- if (/(^|\/)\.claude(\/|$)/.test(cwd))
131
- return "claude";
132
- if (/(^|\/)\.opencode(\/|$)/.test(cwd) || /(^|\/)\.config\/opencode(\/|$)/.test(cwd))
133
- return "opencode";
134
- return null;
135
- }
136
- // interactive picker shown when both/neither app is detected and no --app was passed
127
+ // interactive picker shown when both/neither app is detected and no --app was passed.
128
+ // defaultApp (cwd-inferred) may be null — then there is no default and an empty answer
129
+ // re-asks rather than guessing.
137
130
  async function promptInitApps(_present, defaultApp) {
138
131
  const readline = await import("readline/promises");
139
132
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
140
133
  try {
141
- const menu = [
134
+ console.log([
142
135
  "Initialize plugins for which app?",
143
136
  ` [1] opencode${defaultApp === "opencode" ? " (default)" : ""}`,
144
137
  ` [2] claude${defaultApp === "claude" ? " (default)" : ""}`,
145
138
  " [3] both",
146
- ].join("\n");
147
- const ans = (await rl.question(`${menu}\n> [${defaultApp}] `)).trim().toLowerCase();
148
- if (ans === "3" || ans === "both")
149
- return ["opencode", "claude"];
150
- if (ans === "1" || ans === "opencode")
151
- return ["opencode"];
152
- if (ans === "2" || ans === "claude")
153
- return ["claude"];
154
- return [defaultApp];
139
+ ].join("\n"));
140
+ for (;;) {
141
+ const ans = (await rl.question(`> ${defaultApp ? `[${defaultApp}] ` : "1/2/3 "}`)).trim().toLowerCase();
142
+ if (ans === "1" || ans === "opencode")
143
+ return ["opencode"];
144
+ if (ans === "2" || ans === "claude")
145
+ return ["claude"];
146
+ if (ans === "3" || ans === "both")
147
+ return ["opencode", "claude"];
148
+ if (ans === "" && defaultApp)
149
+ return [defaultApp];
150
+ // empty with no default, or unrecognized → re-ask
151
+ }
155
152
  }
156
153
  finally {
157
154
  rl.close();
package/dist/init.d.ts CHANGED
@@ -4,10 +4,11 @@ export interface PresentApps {
4
4
  claude: boolean;
5
5
  opencode: boolean;
6
6
  }
7
+ export declare function cwdApp(cwd?: string): string | null;
7
8
  export interface InitAppDeps {
8
9
  present: () => PresentApps;
9
10
  isTTY: boolean;
10
11
  cwdApp: () => string | null;
11
- prompt: (present: PresentApps, defaultApp: string) => Promise<string[]>;
12
+ prompt: (present: PresentApps, defaultApp: string | null) => Promise<string[]>;
12
13
  }
13
14
  export declare function resolveInitApps(explicit: string | undefined, deps: InitAppDeps): Promise<string[]>;
package/dist/init.js CHANGED
@@ -45,10 +45,22 @@ export function insertPluginIntoJsonc(raw, pluginName, hasPluginKey) {
45
45
  }
46
46
  return raw.slice(0, brace + 1) + `\n "plugin": [${entry}],` + afterBrace;
47
47
  }
48
+ // Infer the app ONLY from the current directory actually being an app's config dir
49
+ // (~/.claude or ~/.config/opencode|~/.opencode). Returns null otherwise — e.g. /workspace
50
+ // — so the prompt offers no default rather than silently assuming opencode.
51
+ export function cwdApp(cwd = process.cwd()) {
52
+ const c = cwd.replace(/\\/g, "/");
53
+ if (/(^|\/)\.claude(\/|$)/.test(c))
54
+ return "claude";
55
+ if (/(^|\/)\.opencode(\/|$)/.test(c) || /(^|\/)\.config\/opencode(\/|$)/.test(c))
56
+ return "opencode";
57
+ return null;
58
+ }
48
59
  // Decide which app(s) `init` targets. Explicit --app always wins. A single detected
49
60
  // app is used directly. When both or neither are detected we PROMPT (if interactive)
50
61
  // so the user can pick one or both; non-interactively we keep the hard error rather
51
- // than guess.
62
+ // than guess. The prompt default is the cwd-inferred app, or null (no default) when
63
+ // the cwd gives no signal.
52
64
  export async function resolveInitApps(explicit, deps) {
53
65
  if (explicit === "claude" || explicit === "opencode")
54
66
  return [explicit];
@@ -60,6 +72,5 @@ export async function resolveInitApps(explicit, deps) {
60
72
  if (!deps.isTTY) {
61
73
  throw new Error("Both apps (or neither) found - pass --app claude or --app opencode");
62
74
  }
63
- const defaultApp = deps.cwdApp() ?? "opencode";
64
- return deps.prompt(p, defaultApp);
75
+ return deps.prompt(p, deps.cwdApp());
65
76
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plugin-updater",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "description": "Plugin lifecycle manager for OpenCode and Claude Code launchers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",