@a5c-ai/babysitter-sdk 0.0.177-staging.a86ad18c → 0.0.177-staging.ec3ce00a

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.
@@ -2,9 +2,9 @@
2
2
  * plugin:* commands — Manage plugins and marketplaces.
3
3
  *
4
4
  * Marketplace commands:
5
- * plugin:add-marketplace --marketplace-url <url> --scope global|project [--json]
6
- * plugin:update-marketplace --marketplace-name <name> --scope global|project [--json]
7
- * plugin:list-plugins --marketplace-name <name> --scope global|project [--json]
5
+ * plugin:add-marketplace --marketplace-url <url> [--global|--project] [--json]
6
+ * plugin:update-marketplace --marketplace-name <name> [--global|--project] [--json]
7
+ * plugin:list-plugins --marketplace-name <name> [--global|--project] [--json]
8
8
  *
9
9
  * Plugin commands:
10
10
  * plugin:install, plugin:uninstall, plugin:update, plugin:configure,
@@ -22,6 +22,7 @@ export interface PluginCommandArgs {
22
22
  json: boolean;
23
23
  verbose?: boolean;
24
24
  runsDir?: string;
25
+ force?: boolean;
25
26
  }
26
27
  export declare function validateScope(scope: string | undefined): scope is PluginScope;
27
28
  export declare function requireArg(value: string | undefined, name: string, command: string, json: boolean): string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA6BH,OAAO,KAAK,EACV,WAAW,EAGZ,MAAM,qBAAqB,CAAC;AAM7B,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,KAAK,IAAI,WAAW,CAEtB;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,OAAO,GACZ,MAAM,GAAG,IAAI,CAWf;AAuBD;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAgDjB;AAED;;;;GAIG;AACH,wBAAsB,6BAA6B,CACjD,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CA+CjB;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CA8EjB;AAMD,2CAA2C;AAC3C,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAgGjB;AAED,+CAA+C;AAC/C,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAoFjB;AAED,qDAAqD;AACrD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAwIjB;AAED,qCAAqC;AACrC,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAgFjB;AAED,oDAAoD;AACpD,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAsEjB;AAED,qDAAqD;AACrD,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAiFjB;AAED,+CAA+C;AAC/C,wBAAsB,8BAA8B,CAClD,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CA0CjB"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA8BH,OAAO,KAAK,EACV,WAAW,EAGZ,MAAM,qBAAqB,CAAC;AAM7B,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAMD,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,KAAK,IAAI,WAAW,CAEtB;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,OAAO,GACZ,MAAM,GAAG,IAAI,CAWf;AAuCD;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAgDjB;AAED;;;;GAIG;AACH,wBAAsB,6BAA6B,CACjD,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAiDjB;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAoFjB;AAMD,2CAA2C;AAC3C,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAsGjB;AAED,+CAA+C;AAC/C,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAoFjB;AAED,qDAAqD;AACrD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CA8IjB;AAED,qCAAqC;AACrC,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAsFjB;AAED,oDAAoD;AACpD,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAsEjB;AAED,qDAAqD;AACrD,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAsFjB;AAED,+CAA+C;AAC/C,wBAAsB,8BAA8B,CAClD,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CA0CjB"}
@@ -3,9 +3,9 @@
3
3
  * plugin:* commands — Manage plugins and marketplaces.
4
4
  *
5
5
  * Marketplace commands:
6
- * plugin:add-marketplace --marketplace-url <url> --scope global|project [--json]
7
- * plugin:update-marketplace --marketplace-name <name> --scope global|project [--json]
8
- * plugin:list-plugins --marketplace-name <name> --scope global|project [--json]
6
+ * plugin:add-marketplace --marketplace-url <url> [--global|--project] [--json]
7
+ * plugin:update-marketplace --marketplace-name <name> [--global|--project] [--json]
8
+ * plugin:list-plugins --marketplace-name <name> [--global|--project] [--json]
9
9
  *
10
10
  * Plugin commands:
11
11
  * plugin:install, plugin:uninstall, plugin:update, plugin:configure,
@@ -54,7 +54,7 @@ function requireArg(value, name, command, json) {
54
54
  }
55
55
  function requireScope(scope, command, json) {
56
56
  if (!validateScope(scope)) {
57
- const msg = `[${command}] --scope (global|project) is required`;
57
+ const msg = `[${command}] --global or --project is required`;
58
58
  if (json) {
59
59
  console.log(JSON.stringify({ error: "missing_argument", message: msg }));
60
60
  }
@@ -65,6 +65,18 @@ function requireScope(scope, command, json) {
65
65
  }
66
66
  return true;
67
67
  }
68
+ /**
69
+ * Resolves the marketplace name when not explicitly provided.
70
+ * If only one marketplace is cloned for the given scope, returns its name.
71
+ * Otherwise returns null (caller should require the flag).
72
+ */
73
+ async function autoResolveMarketplace(scope, projectDir) {
74
+ const marketplaces = await (0, marketplace_1.listMarketplaces)(scope, projectDir);
75
+ if (marketplaces.length === 1) {
76
+ return marketplaces[0];
77
+ }
78
+ return null;
79
+ }
68
80
  // ============================================================================
69
81
  // Marketplace Handlers
70
82
  // ============================================================================
@@ -74,7 +86,7 @@ function requireScope(scope, command, json) {
74
86
  * Requires: marketplaceUrl, scope
75
87
  */
76
88
  async function handlePluginAddMarketplace(args) {
77
- const { marketplaceUrl, marketplacePath, marketplaceBranch, scope, json } = args;
89
+ const { marketplaceUrl, marketplacePath, marketplaceBranch, scope, json, force } = args;
78
90
  const url = requireArg(marketplaceUrl, "--marketplace-url", "plugin:add-marketplace", json);
79
91
  if (!url)
80
92
  return 1;
@@ -82,7 +94,7 @@ async function handlePluginAddMarketplace(args) {
82
94
  return 1;
83
95
  const projectDir = scope === "project" ? process.cwd() : undefined;
84
96
  try {
85
- const targetDir = await (0, marketplace_1.cloneMarketplace)(marketplaceUrl, scope, projectDir, marketplacePath, marketplaceBranch);
97
+ const targetDir = await (0, marketplace_1.cloneMarketplace)(marketplaceUrl, scope, projectDir, marketplacePath, marketplaceBranch, force);
86
98
  if (json) {
87
99
  console.log(JSON.stringify({
88
100
  success: true,
@@ -113,7 +125,7 @@ async function handlePluginAddMarketplace(args) {
113
125
  * Requires: marketplaceName, scope
114
126
  */
115
127
  async function handlePluginUpdateMarketplace(args) {
116
- const { marketplaceName, scope, json } = args;
128
+ const { marketplaceName, marketplaceBranch, scope, json } = args;
117
129
  const name = requireArg(marketplaceName, "--marketplace-name", "plugin:update-marketplace", json);
118
130
  if (!name)
119
131
  return 1;
@@ -121,16 +133,18 @@ async function handlePluginUpdateMarketplace(args) {
121
133
  return 1;
122
134
  const projectDir = scope === "project" ? process.cwd() : undefined;
123
135
  try {
124
- await (0, marketplace_1.updateMarketplace)(marketplaceName, scope, projectDir);
136
+ await (0, marketplace_1.updateMarketplace)(marketplaceName, scope, projectDir, marketplaceBranch);
125
137
  if (json) {
126
138
  console.log(JSON.stringify({
127
139
  success: true,
128
140
  marketplace: marketplaceName,
129
141
  scope,
142
+ ...(marketplaceBranch ? { branch: marketplaceBranch } : {}),
130
143
  }, null, 2));
131
144
  }
132
145
  else {
133
- console.log(`Marketplace "${marketplaceName}" updated successfully (scope: ${scope}).`);
146
+ const branchInfo = marketplaceBranch ? ` (branch: ${marketplaceBranch})` : "";
147
+ console.log(`Marketplace "${marketplaceName}" updated successfully${branchInfo} (scope: ${scope}).`);
134
148
  }
135
149
  return 0;
136
150
  }
@@ -151,13 +165,18 @@ async function handlePluginUpdateMarketplace(args) {
151
165
  * Requires: marketplaceName, scope
152
166
  */
153
167
  async function handlePluginListPlugins(args) {
154
- const { marketplaceName, scope, json } = args;
155
- const name = requireArg(marketplaceName, "--marketplace-name", "plugin:list-plugins", json);
156
- if (!name)
157
- return 1;
168
+ const { scope, json } = args;
169
+ let { marketplaceName } = args;
158
170
  if (!requireScope(scope, "plugin:list-plugins", json))
159
171
  return 1;
160
172
  const projectDir = scope === "project" ? process.cwd() : undefined;
173
+ // Auto-resolve marketplace when not provided and only one exists
174
+ if (!marketplaceName) {
175
+ marketplaceName = await autoResolveMarketplace(scope, projectDir) ?? undefined;
176
+ }
177
+ const name = requireArg(marketplaceName, "--marketplace-name", "plugin:list-plugins", json);
178
+ if (!name)
179
+ return 1;
161
180
  try {
162
181
  const plugins = await (0, marketplace_1.listMarketplacePlugins)(marketplaceName, scope, projectDir);
163
182
  if (json) {
@@ -202,19 +221,24 @@ async function handlePluginListPlugins(args) {
202
221
  // ============================================================================
203
222
  /** Install a plugin from a marketplace. */
204
223
  async function handlePluginInstall(args) {
205
- const { pluginName, marketplaceName, scope, pluginVersion, json } = args;
224
+ const { pluginName, marketplaceBranch, scope, pluginVersion, json } = args;
225
+ let { marketplaceName } = args;
206
226
  const plugin = requireArg(pluginName, "--plugin-name", "plugin:install", json);
207
227
  if (!plugin)
208
228
  return 1;
209
- const marketplace = requireArg(marketplaceName, "--marketplace-name", "plugin:install", json);
210
- if (!marketplace)
211
- return 1;
212
229
  if (!requireScope(scope, "plugin:install", json))
213
230
  return 1;
214
231
  const projectDir = scope === "project" ? process.cwd() : undefined;
232
+ // Auto-resolve marketplace when not provided and only one exists
233
+ if (!marketplaceName) {
234
+ marketplaceName = await autoResolveMarketplace(scope, projectDir) ?? undefined;
235
+ }
236
+ const marketplace = requireArg(marketplaceName, "--marketplace-name", "plugin:install", json);
237
+ if (!marketplace)
238
+ return 1;
215
239
  try {
216
- // Update marketplace to ensure latest
217
- await (0, marketplace_1.updateMarketplace)(marketplaceName, scope, projectDir);
240
+ // Update marketplace to ensure latest (and optionally switch branch)
241
+ await (0, marketplace_1.updateMarketplace)(marketplaceName, scope, projectDir, marketplaceBranch);
218
242
  // Determine version: use provided or read latestVersion from manifest
219
243
  let version = pluginVersion;
220
244
  if (!version) {
@@ -348,16 +372,21 @@ async function handlePluginUninstall(args) {
348
372
  }
349
373
  /** Update an installed plugin to a newer version. */
350
374
  async function handlePluginUpdate(args) {
351
- const { pluginName, marketplaceName, scope, pluginVersion, json } = args;
375
+ const { pluginName, marketplaceBranch, scope, pluginVersion, json } = args;
376
+ let { marketplaceName } = args;
352
377
  const plugin = requireArg(pluginName, "--plugin-name", "plugin:update", json);
353
378
  if (!plugin)
354
379
  return 1;
355
- const marketplace = requireArg(marketplaceName, "--marketplace-name", "plugin:update", json);
356
- if (!marketplace)
357
- return 1;
358
380
  if (!requireScope(scope, "plugin:update", json))
359
381
  return 1;
360
382
  const projectDir = scope === "project" ? process.cwd() : undefined;
383
+ // Auto-resolve marketplace when not provided and only one exists
384
+ if (!marketplaceName) {
385
+ marketplaceName = await autoResolveMarketplace(scope, projectDir) ?? undefined;
386
+ }
387
+ const marketplace = requireArg(marketplaceName, "--marketplace-name", "plugin:update", json);
388
+ if (!marketplace)
389
+ return 1;
361
390
  try {
362
391
  // Read registry to get currently installed version
363
392
  const registry = await (0, registry_1.readPluginRegistry)(scope, projectDir);
@@ -366,8 +395,8 @@ async function handlePluginUpdate(args) {
366
395
  throw new Error(`Plugin "${pluginName}" is not installed in the ${scope} registry`);
367
396
  }
368
397
  const installedVersion = entry.version;
369
- // Update marketplace to get latest
370
- await (0, marketplace_1.updateMarketplace)(marketplaceName, scope, projectDir);
398
+ // Update marketplace to get latest (and optionally switch branch)
399
+ await (0, marketplace_1.updateMarketplace)(marketplaceName, scope, projectDir, marketplaceBranch);
371
400
  // Determine target version
372
401
  let targetVersion = pluginVersion;
373
402
  if (!targetVersion) {
@@ -448,16 +477,21 @@ async function handlePluginUpdate(args) {
448
477
  }
449
478
  /** Configure an installed plugin. */
450
479
  async function handlePluginConfigure(args) {
451
- const { pluginName, marketplaceName, scope, json } = args;
480
+ const { pluginName, scope, json } = args;
481
+ let { marketplaceName } = args;
452
482
  const plugin = requireArg(pluginName, "--plugin-name", "plugin:configure", json);
453
483
  if (!plugin)
454
484
  return 1;
455
- const marketplace = requireArg(marketplaceName, "--marketplace-name", "plugin:configure", json);
456
- if (!marketplace)
457
- return 1;
458
485
  if (!requireScope(scope, "plugin:configure", json))
459
486
  return 1;
460
487
  const projectDir = scope === "project" ? process.cwd() : undefined;
488
+ // Auto-resolve marketplace when not provided and only one exists
489
+ if (!marketplaceName) {
490
+ marketplaceName = await autoResolveMarketplace(scope, projectDir) ?? undefined;
491
+ }
492
+ const marketplace = requireArg(marketplaceName, "--marketplace-name", "plugin:configure", json);
493
+ if (!marketplace)
494
+ return 1;
461
495
  try {
462
496
  // Resolve plugin package path
463
497
  const packagePath = await (0, marketplace_1.resolvePluginPackagePath)(marketplaceName, pluginName, scope, projectDir);
@@ -575,8 +609,14 @@ async function handlePluginUpdateRegistry(args) {
575
609
  const projectDir = scope === "project" ? process.cwd() : undefined;
576
610
  try {
577
611
  const registry = await (0, registry_1.readPluginRegistry)(scope, projectDir);
578
- // Resolve the plugin package path for the registry entry
579
- const packagePath = await (0, marketplace_1.resolvePluginPackagePath)(marketplaceName, pluginName, scope, projectDir);
612
+ // Try to resolve the plugin package path, but don't fail if marketplace is unavailable
613
+ let packagePath = "";
614
+ try {
615
+ packagePath = await (0, marketplace_1.resolvePluginPackagePath)(marketplaceName, pluginName, scope, projectDir);
616
+ }
617
+ catch {
618
+ // Marketplace may not exist or plugin may not be listed yet — that's OK
619
+ }
580
620
  const now = new Date().toISOString();
581
621
  const existingEntry = (0, registry_1.getPluginEntry)(registry, pluginName);
582
622
  const entry = {
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AAKA,OAAO,EAAE,sBAAsB,IAAI,6BAA6B,EAAoB,MAAM,oBAAoB,CAAC;AAwhB/G;;;;;;;;;GASG;AACH,iBAAS,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CA8BlE;AAOD,2EAA2E;AAC3E,QAAA,MAAM,sBAAsB,sCAAgC,CAAC;AAy+C7D,OAAO,EAAE,aAAa,IAAI,cAAc,EAAE,sBAAsB,IAAI,uBAAuB,EAAE,CAAC;AAE9F,wBAAgB,mBAAmB;eAEf,MAAM,EAAE,GAA2B,OAAO,CAAC,MAAM,CAAC;kBAgQpD,MAAM;EAIvB"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AAKA,OAAO,EAAE,sBAAsB,IAAI,6BAA6B,EAAoB,MAAM,oBAAoB,CAAC;AAmiB/G;;;;;;;;;GASG;AACH,iBAAS,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CA8BlE;AAOD,2EAA2E;AAC3E,QAAA,MAAM,sBAAsB,sCAAgC,CAAC;AAy+C7D,OAAO,EAAE,aAAa,IAAI,cAAc,EAAE,sBAAsB,IAAI,uBAAuB,EAAE,CAAC;AAE9F,wBAAgB,mBAAmB;eAEf,MAAM,EAAE,GAA2B,OAAO,CAAC,MAAM,CAAC;kBA6QpD,MAAM;EAIvB"}
package/dist/cli/main.js CHANGED
@@ -85,7 +85,7 @@ const USAGE = `Usage:
85
85
  babysitter session:iteration-message --iteration <n> [--run-id <id>] [--runs-dir <dir>] [--plugin-root <dir>] [--json]
86
86
  babysitter skill:discover --plugin-root <dir> [--run-id <id>] [--cache-ttl <seconds>] [--runs-dir <dir>] [--include-remote] [--summary-only] [--process-path <path>] [--json]
87
87
  babysitter hook:log --hook-type <type> --log-file <path> [--json]
88
- babysitter hook:run --hook-type <stop|session-start> [--harness <claude-code>] [--plugin-root <dir>] [--state-dir <dir>] [--runs-dir <dir>] [--json] [--verbose]
88
+ babysitter hook:run --hook-type <stop|session-start> [--harness <claude-code|codex|gemini-cli>] [--plugin-root <dir>] [--state-dir <dir>] [--runs-dir <dir>] [--json] [--verbose]
89
89
  babysitter skill:fetch-remote --source-type <github|well-known> --url <url> [--json]
90
90
  babysitter profile:read --user|--project [--dir <dir>] [--json]
91
91
  babysitter profile:write --user|--project --input <file> [--dir <dir>] [--json]
@@ -97,8 +97,8 @@ const USAGE = `Usage:
97
97
  babysitter plugin:configure [<pluginName>] [--plugin-name <name>] [--global|--project] [--json] [--verbose]
98
98
  babysitter plugin:list-installed [--global|--project] [--json] [--verbose]
99
99
  babysitter plugin:list-plugins --marketplace-name <name> [--global|--project] [--json] [--verbose]
100
- babysitter plugin:add-marketplace --marketplace-url <url> [--marketplace-path <path>] [--marketplace-branch <ref>] [--global|--project] [--json] [--verbose]
101
- babysitter plugin:update-marketplace --marketplace-name <name> [--global|--project] [--json] [--verbose]
100
+ babysitter plugin:add-marketplace --marketplace-url <url> [--marketplace-path <path>] [--marketplace-branch <ref>] [--force] [--global|--project] [--json] [--verbose]
101
+ babysitter plugin:update-marketplace --marketplace-name <name> [--marketplace-branch <ref>] [--global|--project] [--json] [--verbose]
102
102
  babysitter plugin:update-registry [<pluginName>] [--plugin-name <name>] [--plugin-version <ver>] [--global|--project] [--json] [--verbose]
103
103
  babysitter plugin:remove-from-registry [<pluginName>] [--plugin-name <name>] [--global|--project] [--json] [--verbose]
104
104
  babysitter health [--json] [--verbose]
@@ -275,7 +275,13 @@ function parseArgs(argv) {
275
275
  }
276
276
  // Session command flags
277
277
  if (arg === "--session-id") {
278
- parsed.sessionId = expectFlagValue(rest, ++i, "--session-id");
278
+ // Tolerate empty/missing value — the harness adapter can auto-detect
279
+ // session ID from CLAUDE_ENV_FILE or CLAUDE_SESSION_ID env var.
280
+ const next = rest[i + 1];
281
+ if (next && !next.startsWith("-")) {
282
+ parsed.sessionId = next;
283
+ i++;
284
+ }
279
285
  continue;
280
286
  }
281
287
  if (arg === "--state-dir") {
@@ -407,6 +413,10 @@ function parseArgs(argv) {
407
413
  parsed.marketplaceBranch = expectFlagValue(rest, ++i, "--marketplace-branch");
408
414
  continue;
409
415
  }
416
+ if (arg === "--force") {
417
+ parsed.pluginForce = true;
418
+ continue;
419
+ }
410
420
  if (arg === "--global") {
411
421
  parsed.pluginScope = "global";
412
422
  continue;
@@ -1935,7 +1945,19 @@ function createBabysitterCli() {
1935
1945
  if (parsed.command === "task:show") {
1936
1946
  return await handleTaskShow(parsed);
1937
1947
  }
1938
- // Session commands
1948
+ // Session commands — auto-resolve sessionId via harness adapter if not
1949
+ // explicitly provided (e.g. from CLAUDE_ENV_FILE written by session-start hook).
1950
+ if (!parsed.sessionId && parsed.command?.startsWith("session:")) {
1951
+ const sessionAdapter = parsed.harness
1952
+ ? (0, harness_1.getAdapterByName)(parsed.harness)
1953
+ : (0, harness_1.getAdapter)();
1954
+ if (sessionAdapter) {
1955
+ const resolved = sessionAdapter.resolveSessionId(parsed);
1956
+ if (resolved) {
1957
+ parsed.sessionId = resolved;
1958
+ }
1959
+ }
1960
+ }
1939
1961
  if (parsed.command === "session:init") {
1940
1962
  return await (0, session_1.handleSessionInit)({
1941
1963
  sessionId: parsed.sessionId,
@@ -2074,6 +2096,7 @@ function createBabysitterCli() {
2074
2096
  marketplaceBranch: parsed.marketplaceBranch,
2075
2097
  pluginVersion: parsed.pluginVersion,
2076
2098
  scope: parsed.pluginScope,
2099
+ force: parsed.pluginForce,
2077
2100
  json: parsed.json,
2078
2101
  verbose: parsed.verbose,
2079
2102
  runsDir: parsed.runsDir,
@@ -1 +1 @@
1
- {"version":3,"file":"resolveInputPath.d.ts","sourceRoot":"","sources":["../../src/cli/resolveInputPath.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CASxD;AA4DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAgC1D"}
1
+ {"version":3,"file":"resolveInputPath.d.ts","sourceRoot":"","sources":["../../src/cli/resolveInputPath.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAiBxD;AA4DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAgC1D"}
@@ -57,12 +57,17 @@ const node_fs_1 = require("node:fs");
57
57
  * // => "C:\\project\\.a5c\\runs\\01RUN"
58
58
  */
59
59
  function collapseDoubledA5cRuns(p) {
60
- // Match both forward and back-slash variants
61
- const pattern = /([/\\]?\.a5c[/\\]runs)[/\\]\.a5c[/\\]runs([/\\]|$)/;
62
60
  let result = p;
63
- // Collapse repeatedly in case of triple+ duplication
64
- while (pattern.test(result)) {
65
- result = result.replace(pattern, "$1$2");
61
+ // Collapse .a5c/runs/.a5c/runs/ → .a5c/runs/
62
+ const runsPattern = /([/\\]?\.a5c[/\\]runs)[/\\]\.a5c[/\\]runs([/\\]|$)/;
63
+ while (runsPattern.test(result)) {
64
+ result = result.replace(runsPattern, "$1$2");
65
+ }
66
+ // Collapse .a5c/.a5c/ → .a5c/ (e.g. when CLI runs from .a5c/ with relative
67
+ // --runs-dir .a5c/runs, producing /project/.a5c/.a5c/runs/)
68
+ const a5cPattern = /([/\\]\.a5c)[/\\]\.a5c([/\\])/;
69
+ while (a5cPattern.test(result)) {
70
+ result = result.replace(a5cPattern, "$1$2");
66
71
  }
67
72
  return result;
68
73
  }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Codex harness adapter.
3
+ *
4
+ * Extends the SDK harness layer with "codex" support while reusing the
5
+ * mature Claude stop/session-start hook handlers. The Codex adapter maps
6
+ * Codex-specific environment conventions to the generic adapter interface.
7
+ */
8
+ import type { HarnessAdapter } from "./types";
9
+ export declare function createCodexAdapter(): HarnessAdapter;
10
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/harness/codex.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EACV,cAAc,EAIf,MAAM,SAAS,CAAC;AA+CjB,wBAAgB,kBAAkB,IAAI,cAAc,CAgFnD"}
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ /**
3
+ * Codex harness adapter.
4
+ *
5
+ * Extends the SDK harness layer with "codex" support while reusing the
6
+ * mature Claude stop/session-start hook handlers. The Codex adapter maps
7
+ * Codex-specific environment conventions to the generic adapter interface.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.createCodexAdapter = createCodexAdapter;
44
+ const path = __importStar(require("node:path"));
45
+ const node_fs_1 = require("node:fs");
46
+ const claudeCode_1 = require("./claudeCode");
47
+ function resolveCodexPluginRoot(args = {}) {
48
+ const root = args.pluginRoot || process.env.CODEX_PLUGIN_ROOT;
49
+ return root ? path.resolve(root) : undefined;
50
+ }
51
+ function resolveCodexStateDir(args) {
52
+ if (args.stateDir)
53
+ return path.resolve(args.stateDir);
54
+ if (process.env.BABYSITTER_STATE_DIR) {
55
+ return path.resolve(process.env.BABYSITTER_STATE_DIR);
56
+ }
57
+ const pluginRoot = resolveCodexPluginRoot(args);
58
+ if (pluginRoot) {
59
+ // Codex plugins conventionally live under ".codex", while state is in ".a5c".
60
+ return path.resolve(pluginRoot, "..", ".a5c");
61
+ }
62
+ return path.resolve(".a5c");
63
+ }
64
+ function resolveCodexSessionId(parsed) {
65
+ if (parsed.sessionId)
66
+ return parsed.sessionId;
67
+ // Codex injects CODEX_THREAD_ID; keep CODEX_SESSION_ID as legacy fallback.
68
+ if (process.env.CODEX_THREAD_ID)
69
+ return process.env.CODEX_THREAD_ID;
70
+ if (process.env.CODEX_SESSION_ID)
71
+ return process.env.CODEX_SESSION_ID;
72
+ const envFile = process.env.CODEX_ENV_FILE;
73
+ if (!envFile)
74
+ return undefined;
75
+ try {
76
+ const content = (0, node_fs_1.readFileSync)(envFile, "utf-8");
77
+ const match = content.match(/(?:^|\n)\s*(?:export\s+)?(?:CODEX_THREAD_ID|CODEX_SESSION_ID)="([^"]+)"/);
78
+ return match?.[1] || undefined;
79
+ }
80
+ catch {
81
+ return undefined;
82
+ }
83
+ }
84
+ function createCodexAdapter() {
85
+ const claude = (0, claudeCode_1.createClaudeCodeAdapter)();
86
+ return {
87
+ name: "codex",
88
+ isActive() {
89
+ return !!(process.env.CODEX_THREAD_ID ||
90
+ process.env.CODEX_SESSION_ID ||
91
+ process.env.CODEX_ENV_FILE ||
92
+ process.env.CODEX_PLUGIN_ROOT);
93
+ },
94
+ resolveSessionId(parsed) {
95
+ return resolveCodexSessionId(parsed);
96
+ },
97
+ resolveStateDir(args) {
98
+ return resolveCodexStateDir(args);
99
+ },
100
+ resolvePluginRoot(args) {
101
+ return resolveCodexPluginRoot(args);
102
+ },
103
+ bindSession(opts) {
104
+ const stateDir = resolveCodexStateDir({
105
+ stateDir: opts.stateDir,
106
+ pluginRoot: opts.pluginRoot,
107
+ });
108
+ return claude.bindSession({
109
+ ...opts,
110
+ stateDir,
111
+ });
112
+ },
113
+ handleStopHook(args) {
114
+ const pluginRoot = resolveCodexPluginRoot(args);
115
+ const stateDir = resolveCodexStateDir({
116
+ stateDir: args.stateDir,
117
+ pluginRoot,
118
+ });
119
+ return claude.handleStopHook({
120
+ ...args,
121
+ pluginRoot,
122
+ stateDir,
123
+ });
124
+ },
125
+ handleSessionStartHook(args) {
126
+ const pluginRoot = resolveCodexPluginRoot(args);
127
+ const stateDir = resolveCodexStateDir({
128
+ stateDir: args.stateDir,
129
+ pluginRoot,
130
+ });
131
+ return claude.handleSessionStartHook({
132
+ ...args,
133
+ pluginRoot,
134
+ stateDir,
135
+ });
136
+ },
137
+ findHookDispatcherPath(startCwd) {
138
+ const pluginRoot = resolveCodexPluginRoot();
139
+ if (pluginRoot) {
140
+ const candidate = path.join(pluginRoot, "hooks", "hook-dispatcher.sh");
141
+ if ((0, node_fs_1.existsSync)(candidate))
142
+ return candidate;
143
+ }
144
+ const local = path.join(path.resolve(startCwd), ".codex", "hooks", "hook-dispatcher.sh");
145
+ if ((0, node_fs_1.existsSync)(local))
146
+ return local;
147
+ return null;
148
+ },
149
+ };
150
+ }
@@ -1,5 +1,6 @@
1
1
  export type { HarnessAdapter, SessionBindOptions, SessionBindResult, HookHandlerArgs, } from "./types";
2
2
  export { createClaudeCodeAdapter } from "./claudeCode";
3
+ export { createCodexAdapter } from "./codex";
3
4
  export { createGeminiCliAdapter } from "./geminiCli";
4
5
  export { createNullAdapter } from "./nullAdapter";
5
6
  export { detectAdapter, getAdapterByName, listSupportedHarnesses, getAdapter, setAdapter, resetAdapter, } from "./registry";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,GAChB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,UAAU,EACV,YAAY,GACb,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,GAChB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,UAAU,EACV,YAAY,GACb,MAAM,YAAY,CAAC"}
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resetAdapter = exports.setAdapter = exports.getAdapter = exports.listSupportedHarnesses = exports.getAdapterByName = exports.detectAdapter = exports.createNullAdapter = exports.createGeminiCliAdapter = exports.createClaudeCodeAdapter = void 0;
3
+ exports.resetAdapter = exports.setAdapter = exports.getAdapter = exports.listSupportedHarnesses = exports.getAdapterByName = exports.detectAdapter = exports.createNullAdapter = exports.createGeminiCliAdapter = exports.createCodexAdapter = exports.createClaudeCodeAdapter = void 0;
4
4
  var claudeCode_1 = require("./claudeCode");
5
5
  Object.defineProperty(exports, "createClaudeCodeAdapter", { enumerable: true, get: function () { return claudeCode_1.createClaudeCodeAdapter; } });
6
+ var codex_1 = require("./codex");
7
+ Object.defineProperty(exports, "createCodexAdapter", { enumerable: true, get: function () { return codex_1.createCodexAdapter; } });
6
8
  var geminiCli_1 = require("./geminiCli");
7
9
  Object.defineProperty(exports, "createGeminiCliAdapter", { enumerable: true, get: function () { return geminiCli_1.createGeminiCliAdapter; } });
8
10
  var nullAdapter_1 = require("./nullAdapter");
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/harness/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAkB9C;;;GAGG;AACH,wBAAgB,aAAa,IAAI,cAAc,CAK9C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAKpE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD;AAQD;;GAEG;AACH,wBAAgB,UAAU,IAAI,cAAc,CAK3C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAExD;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAEnC"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/harness/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAoB9C;;;GAGG;AACH,wBAAgB,aAAa,IAAI,cAAc,CAK9C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAKpE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD;AAQD;;GAEG;AACH,wBAAgB,UAAU,IAAI,cAAc,CAK3C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAExD;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAEnC"}
@@ -14,12 +14,14 @@ exports.getAdapter = getAdapter;
14
14
  exports.setAdapter = setAdapter;
15
15
  exports.resetAdapter = resetAdapter;
16
16
  const claudeCode_1 = require("./claudeCode");
17
+ const codex_1 = require("./codex");
17
18
  const geminiCli_1 = require("./geminiCli");
18
19
  const nullAdapter_1 = require("./nullAdapter");
19
20
  // ---------------------------------------------------------------------------
20
21
  // Registry of known adapters (ordered by priority)
21
22
  // ---------------------------------------------------------------------------
22
23
  const knownAdapters = [
24
+ (0, codex_1.createCodexAdapter)(),
23
25
  (0, claudeCode_1.createClaudeCodeAdapter)(),
24
26
  (0, geminiCli_1.createGeminiCliAdapter)(),
25
27
  ];
@@ -24,17 +24,21 @@ export declare function deriveMarketplaceName(url: string): string;
24
24
  * @param projectDir - Required when scope is 'project'
25
25
  * @param manifestPath - Optional relative path to marketplace.json within the repo
26
26
  * @param branch - Optional git branch/tag/ref to clone (defaults to the repo's default branch)
27
+ * @param force - If true, removes existing clone and re-clones
27
28
  * @returns The directory the marketplace was cloned into
28
29
  */
29
- export declare function cloneMarketplace(url: string, scope: PluginScope, projectDir?: string, manifestPath?: string, branch?: string): Promise<string>;
30
+ export declare function cloneMarketplace(url: string, scope: PluginScope, projectDir?: string, manifestPath?: string, branch?: string, force?: boolean): Promise<string>;
30
31
  /**
31
32
  * Updates a previously cloned marketplace by pulling latest changes.
33
+ * When a branch is specified, switches to that branch first (fetching it
34
+ * even in shallow clones).
32
35
  *
33
36
  * @param marketplaceName - Name of the marketplace directory
34
37
  * @param scope - Whether to look in global or project marketplaces dir
35
38
  * @param projectDir - Required when scope is 'project'
39
+ * @param branch - Optional branch/tag/ref to switch to before pulling
36
40
  */
37
- export declare function updateMarketplace(marketplaceName: string, scope: PluginScope, projectDir?: string): Promise<void>;
41
+ export declare function updateMarketplace(marketplaceName: string, scope: PluginScope, projectDir?: string, branch?: string): Promise<void>;
38
42
  /**
39
43
  * Reads and parses the marketplace manifest from a cloned marketplace.
40
44
  *
@@ -1 +1 @@
1
- {"version":3,"file":"marketplace.d.ts","sourceRoot":"","sources":["../../src/plugins/marketplace.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,WAAW,EAIZ,MAAM,SAAS,CAAC;AAIjB;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAazD;AAED;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,WAAW,EAClB,UAAU,CAAC,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CA6CjB;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,WAAW,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAmBf;AA+JD;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC3C,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,WAAW,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAO9B;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,WAAW,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,sBAAsB,EAAE,CAAC,CASnC;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,wBAAwB,CAC5C,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,WAAW,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CAejB;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,WAAW,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,EAAE,CAAC,CAcnB"}
1
+ {"version":3,"file":"marketplace.d.ts","sourceRoot":"","sources":["../../src/plugins/marketplace.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,WAAW,EAIZ,MAAM,SAAS,CAAC;AAIjB;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAazD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,WAAW,EAClB,UAAU,CAAC,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,OAAO,GACd,OAAO,CAAC,MAAM,CAAC,CAiDjB;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CACrC,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,WAAW,EAClB,UAAU,CAAC,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAoCf;AA+JD;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC3C,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,WAAW,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAO9B;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,WAAW,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,sBAAsB,EAAE,CAAC,CASnC;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,wBAAwB,CAC5C,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,WAAW,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CAejB;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,WAAW,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,EAAE,CAAC,CAcnB"}
@@ -53,9 +53,10 @@ function deriveMarketplaceName(url) {
53
53
  * @param projectDir - Required when scope is 'project'
54
54
  * @param manifestPath - Optional relative path to marketplace.json within the repo
55
55
  * @param branch - Optional git branch/tag/ref to clone (defaults to the repo's default branch)
56
+ * @param force - If true, removes existing clone and re-clones
56
57
  * @returns The directory the marketplace was cloned into
57
58
  */
58
- async function cloneMarketplace(url, scope, projectDir, manifestPath, branch) {
59
+ async function cloneMarketplace(url, scope, projectDir, manifestPath, branch, force) {
59
60
  const name = deriveMarketplaceName(url);
60
61
  const marketplacesDir = (0, paths_1.getMarketplacesDir)(scope, projectDir);
61
62
  const targetDir = node_path_1.default.join(marketplacesDir, name);
@@ -64,7 +65,12 @@ async function cloneMarketplace(url, scope, projectDir, manifestPath, branch) {
64
65
  // Check if already cloned
65
66
  try {
66
67
  await node_fs_1.promises.access(targetDir);
67
- throw new Error(`Marketplace "${name}" already exists at ${targetDir}. Use updateMarketplace() to refresh.`);
68
+ if (force) {
69
+ await node_fs_1.promises.rm(targetDir, { recursive: true, force: true });
70
+ }
71
+ else {
72
+ throw new Error(`Marketplace "${name}" already exists at ${targetDir}. Use --force to replace or plugin:update-marketplace to refresh.`);
73
+ }
68
74
  }
69
75
  catch (error) {
70
76
  if (!(0, types_1.isNodeError)(error) || error.code !== "ENOENT") {
@@ -92,12 +98,15 @@ async function cloneMarketplace(url, scope, projectDir, manifestPath, branch) {
92
98
  }
93
99
  /**
94
100
  * Updates a previously cloned marketplace by pulling latest changes.
101
+ * When a branch is specified, switches to that branch first (fetching it
102
+ * even in shallow clones).
95
103
  *
96
104
  * @param marketplaceName - Name of the marketplace directory
97
105
  * @param scope - Whether to look in global or project marketplaces dir
98
106
  * @param projectDir - Required when scope is 'project'
107
+ * @param branch - Optional branch/tag/ref to switch to before pulling
99
108
  */
100
- async function updateMarketplace(marketplaceName, scope, projectDir) {
109
+ async function updateMarketplace(marketplaceName, scope, projectDir, branch) {
101
110
  const dir = (0, paths_1.getMarketplaceDir)(marketplaceName, scope, projectDir);
102
111
  try {
103
112
  await node_fs_1.promises.access(dir);
@@ -106,6 +115,25 @@ async function updateMarketplace(marketplaceName, scope, projectDir) {
106
115
  throw new Error(`Marketplace "${marketplaceName}" not found at ${dir}. Clone it first.`);
107
116
  }
108
117
  try {
118
+ if (branch) {
119
+ // Fetch the specific branch (works with shallow clones)
120
+ await execFile("git", ["-C", dir, "fetch", "--depth", "1", "origin", branch]);
121
+ // Switch to the branch, creating it locally if needed
122
+ try {
123
+ await execFile("git", ["-C", dir, "checkout", branch]);
124
+ }
125
+ catch {
126
+ // Branch doesn't exist locally — create from FETCH_HEAD
127
+ // Stash any local changes first (e.g. .babysitter-manifest-path)
128
+ try {
129
+ await execFile("git", ["-C", dir, "stash"]);
130
+ }
131
+ catch {
132
+ // Nothing to stash
133
+ }
134
+ await execFile("git", ["-C", dir, "checkout", "-B", branch, "FETCH_HEAD"]);
135
+ }
136
+ }
109
137
  await execFile("git", ["-C", dir, "pull", "--ff-only"]);
110
138
  }
111
139
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a5c-ai/babysitter-sdk",
3
- "version": "0.0.177-staging.a86ad18c",
3
+ "version": "0.0.177-staging.ec3ce00a",
4
4
  "description": "Storage and run-registry primitives for event-sourced babysitter workflows.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "commonjs",