@aerovato/operator-helper 1.2.0 → 1.3.0

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/README.md CHANGED
@@ -21,12 +21,12 @@ bun add --global --minimum-release-age 0 @aerovato/operator-helper@latest
21
21
  Install an adapter:
22
22
 
23
23
  ```sh
24
- # OpenCode
25
- operator-helper install opencode
26
-
27
- # OpenCode V2 beta
24
+ # OpenCode 2
28
25
  operator-helper install opencode-v2
29
26
 
27
+ # OpenCode 1 (legacy)
28
+ operator-helper install opencode
29
+
30
30
  # Pi
31
31
  operator-helper install pi
32
32
 
package/dist/index.js CHANGED
@@ -17998,7 +17998,7 @@ var Uint8Array2 = /* @__PURE__ */ instanceOf(globalThis.Uint8Array, {
17998
17998
  // package.json
17999
17999
  var package_default = {
18000
18000
  name: "@aerovato/operator-helper",
18001
- version: "1.2.0",
18001
+ version: "1.3.0",
18002
18002
  description: "Installation and setup CLI for Operator Memory",
18003
18003
  license: "BSD-3-Clause",
18004
18004
  author: "Aerovato Research",
@@ -19041,16 +19041,82 @@ var inspectMainIndex = fn2("inspectMainIndex")(function* (cwd, partitionRoot) {
19041
19041
 
19042
19042
  // src/commands/install/code-puppy.ts
19043
19043
  import { randomUUID } from "node:crypto";
19044
- import { lstat, mkdir as mkdir2, readFile as readFile3, rename as rename3, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
19044
+ import { mkdir as mkdir2, readFile as readFile4, rename as rename3, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
19045
19045
  import { join as join2 } from "node:path";
19046
19046
  import { fileURLToPath as fileURLToPath2 } from "node:url";
19047
+
19048
+ // src/commands/common.ts
19049
+ import { lstat, readFile as readFile3 } from "node:fs/promises";
19050
+ function fileFailure(error) {
19051
+ return { exitCode: 1, output: fileErrorMessage(error) };
19052
+ }
19053
+ function fileErrorMessage(error) {
19054
+ if (error instanceof PathKindError) {
19055
+ return `✗ ${error.path}: Expected a ${error.expected}, found ${error.actual}`;
19056
+ }
19057
+ const path = error.reason instanceof SystemError ? `${error.reason.pathOrDescriptor}: ` : "";
19058
+ return `✗ ${path}${error.reason.description ?? error.message}`;
19059
+ }
19060
+ function runProcess(executable, arguments_, cwd, environment) {
19061
+ return gen2(function* () {
19062
+ const spawner = yield* ChildProcessSpawner;
19063
+ const command = make11(executable, [...arguments_], {
19064
+ cwd,
19065
+ env: environment ?? undefined,
19066
+ extendEnv: true
19067
+ });
19068
+ const execution = yield* scoped2(gen2(function* () {
19069
+ const handle = yield* spawner.spawn(command);
19070
+ const [stdout, stderr, exitCode] = yield* all2([
19071
+ handle.stdout.pipe(decodeText(), mkString),
19072
+ handle.stderr.pipe(decodeText(), mkString),
19073
+ handle.exitCode
19074
+ ], { concurrency: "unbounded" });
19075
+ return { stdout: stdout.trim(), stderr: stderr.trim(), exitCode: Number(exitCode) };
19076
+ })).pipe(result2);
19077
+ if (isFailure2(execution)) {
19078
+ const error = execution.failure instanceof PlatformError ? execution.failure.reason.description ?? execution.failure.message : getErrorMessage(execution.failure);
19079
+ return { ok: false, error };
19080
+ }
19081
+ return {
19082
+ ok: true,
19083
+ ...execution.success,
19084
+ output: [execution.success.stdout, execution.success.stderr].filter(Boolean).join(`
19085
+ `)
19086
+ };
19087
+ });
19088
+ }
19089
+ async function pathKind(path) {
19090
+ try {
19091
+ const info = await lstat(path);
19092
+ return info.isFile() ? "file" : info.isDirectory() ? "directory" : "other";
19093
+ } catch (error) {
19094
+ if (isNodeError(error) && error.code === "ENOENT")
19095
+ return "missing";
19096
+ throw error;
19097
+ }
19098
+ }
19099
+ async function readOptionalFile(path) {
19100
+ try {
19101
+ return await readFile3(path, "utf8");
19102
+ } catch (error) {
19103
+ if (isNodeError(error) && error.code === "ENOENT")
19104
+ return null;
19105
+ throw error;
19106
+ }
19107
+ }
19108
+ function isNodeError(error) {
19109
+ return error instanceof Error && "code" in error;
19110
+ }
19111
+
19112
+ // src/commands/install/code-puppy.ts
19047
19113
  var CODE_PUPPY_MARKER = `Operator Memory managed Code Puppy plugin.
19048
19114
  `;
19049
19115
  var CODE_PUPPY_MARKER_FILE = ".operator-managed";
19050
19116
  var installCodePuppy = fn2("installCodePuppy")(function* (context) {
19051
19117
  return yield* promise2(async () => {
19052
19118
  try {
19053
- const source = await readFile3(await codePuppyAdapterPath(), "utf8");
19119
+ const source = await readFile4(await codePuppyAdapterPath(), "utf8");
19054
19120
  const plugins = join2(context.home, ".code_puppy", "plugins");
19055
19121
  const target = join2(plugins, "operator");
19056
19122
  const marker = join2(target, CODE_PUPPY_MARKER_FILE);
@@ -19069,13 +19135,13 @@ var installCodePuppy = fn2("installCodePuppy")(function* (context) {
19069
19135
  }
19070
19136
  return { exitCode: 0, output: "✓ Code Puppy plugin installed" };
19071
19137
  }
19072
- if (targetKind !== "directory" || await pathKind(marker) !== "file" || await readOptional(marker) !== CODE_PUPPY_MARKER) {
19138
+ if (targetKind !== "directory" || await pathKind(marker) !== "file" || await readOptionalFile(marker) !== CODE_PUPPY_MARKER) {
19073
19139
  return {
19074
19140
  exitCode: 1,
19075
19141
  output: `✗ Preserved unmanaged Code Puppy plugin at ${target}`
19076
19142
  };
19077
19143
  }
19078
- if (await readOptional(callbacks) === source) {
19144
+ if (await readOptionalFile(callbacks) === source) {
19079
19145
  return { exitCode: 0, output: "✓ Code Puppy plugin is current" };
19080
19146
  }
19081
19147
  const staged = `${callbacks}.tmp-${randomUUID()}`;
@@ -19107,36 +19173,116 @@ async function codePuppyAdapterPath() {
19107
19173
  }
19108
19174
  throw new Error("bundled Code Puppy adapter is missing");
19109
19175
  }
19110
- async function pathKind(path) {
19111
- try {
19112
- const info = await lstat(path);
19113
- return info.isFile() ? "file" : info.isDirectory() ? "directory" : "other";
19114
- } catch (error) {
19115
- if (isNodeError(error) && error.code === "ENOENT") {
19116
- return "missing";
19176
+
19177
+ // src/commands/install/codex.ts
19178
+ import { mkdir as mkdir3, writeFile as writeFile4 } from "node:fs/promises";
19179
+ import { join as join3 } from "node:path";
19180
+ var MARKETPLACE_MARKER = `Operator Memory managed Codex marketplace.
19181
+ `;
19182
+ var MARKETPLACE_NAME = "operator-memory";
19183
+ var PLUGIN_NAME = "aerovato";
19184
+ var PLUGIN_ID = `${PLUGIN_NAME}@${MARKETPLACE_NAME}`;
19185
+ var MARKETPLACE = `${JSON.stringify({
19186
+ name: MARKETPLACE_NAME,
19187
+ plugins: [
19188
+ {
19189
+ name: PLUGIN_NAME,
19190
+ source: {
19191
+ source: "npm",
19192
+ package: "@aerovato/operator-codex",
19193
+ version: "latest"
19194
+ },
19195
+ policy: { installation: "AVAILABLE" }
19117
19196
  }
19118
- throw error;
19197
+ ]
19198
+ }, null, 2)}
19199
+ `;
19200
+ var installCodex = fn2("installCodex")(function* (context) {
19201
+ const marketplace = yield* writeMarketplace(context.home);
19202
+ if (!marketplace.ok)
19203
+ return marketplace.result;
19204
+ const addMarketplace = yield* runProcess("codex", ["plugin", "marketplace", "add", marketplace.path, "--json"], context.cwd, { NPM_CONFIG_MIN_RELEASE_AGE: "0" });
19205
+ const addFailure = commandFailure(addMarketplace, "Codex marketplace installation failed");
19206
+ if (addFailure !== null)
19207
+ return addFailure;
19208
+ const install = yield* runProcess("codex", ["plugin", "add", PLUGIN_ID, "--json"], context.cwd, {
19209
+ NPM_CONFIG_MIN_RELEASE_AGE: "0"
19210
+ });
19211
+ const installFailure = commandFailure(install, "Codex plugin installation failed");
19212
+ if (installFailure !== null)
19213
+ return installFailure;
19214
+ const status = yield* runProcess("codex", ["plugin", "list", "--marketplace", MARKETPLACE_NAME, "--json"], context.cwd, { NPM_CONFIG_MIN_RELEASE_AGE: "0" });
19215
+ const statusFailure = commandFailure(status, "Could not verify Codex plugin installation");
19216
+ if (statusFailure !== null)
19217
+ return statusFailure;
19218
+ if (!(status.ok && isInstalledAndEnabled(status.stdout))) {
19219
+ return {
19220
+ exitCode: 1,
19221
+ output: "✗ Codex plugin installation finished but the plugin is not installed and enabled"
19222
+ };
19119
19223
  }
19224
+ return {
19225
+ exitCode: 0,
19226
+ output: [
19227
+ "✓ Codex plugin installed and enabled",
19228
+ "Start a new Codex session and approve the Operator hooks if prompted."
19229
+ ].join(`
19230
+ `)
19231
+ };
19232
+ });
19233
+ function writeMarketplace(home) {
19234
+ return promise2(async () => {
19235
+ const root = join3(home, ".operator-helper", "codex-marketplace");
19236
+ const marker = join3(root, ".operator-managed");
19237
+ const marketplace = join3(root, ".agents", "plugins", "marketplace.json");
19238
+ try {
19239
+ const kind = await pathKind(root);
19240
+ if (kind !== "missing" && (kind !== "directory" || await readOptionalFile(marker) !== MARKETPLACE_MARKER)) {
19241
+ return {
19242
+ ok: false,
19243
+ result: {
19244
+ exitCode: 1,
19245
+ output: `✗ Preserved unmanaged Codex marketplace at ${root}`
19246
+ }
19247
+ };
19248
+ }
19249
+ await mkdir3(join3(root, ".agents", "plugins"), { recursive: true });
19250
+ await writeFile4(marker, MARKETPLACE_MARKER);
19251
+ await writeFile4(marketplace, MARKETPLACE);
19252
+ return { ok: true, path: root };
19253
+ } catch (error) {
19254
+ return {
19255
+ ok: false,
19256
+ result: {
19257
+ exitCode: 1,
19258
+ output: `✗ Could not prepare Codex marketplace: ${getErrorMessage(error)}`
19259
+ }
19260
+ };
19261
+ }
19262
+ });
19120
19263
  }
19121
- async function readOptional(path) {
19264
+ function isInstalledAndEnabled(output) {
19122
19265
  try {
19123
- return await readFile3(path, "utf8");
19124
- } catch (error) {
19125
- if (isNodeError(error) && error.code === "ENOENT") {
19126
- return null;
19127
- }
19128
- throw error;
19266
+ const value = JSON.parse(output);
19267
+ if (typeof value !== "object" || value === null || !("installed" in value))
19268
+ return false;
19269
+ const installed = value.installed;
19270
+ return Array.isArray(installed) && installed.some((plugin) => typeof plugin === "object" && plugin !== null && ("pluginId" in plugin) && plugin.pluginId === PLUGIN_ID && ("installed" in plugin) && plugin.installed === true && ("enabled" in plugin) && plugin.enabled === true);
19271
+ } catch {
19272
+ return false;
19129
19273
  }
19130
19274
  }
19131
- function isNodeError(error) {
19132
- return error instanceof Error && "code" in error;
19275
+ function commandFailure(result, fallback) {
19276
+ if (!result.ok)
19277
+ return { exitCode: 1, output: `✗ Could not run codex: ${result.error}` };
19278
+ return result.exitCode === 0 ? null : { exitCode: result.exitCode, output: result.output || fallback };
19133
19279
  }
19280
+
19134
19281
  // src/commands/install/opencode.ts
19135
19282
  var OPENCODE_PLUGIN = "@aerovato/operator-opencode@latest";
19136
19283
  var installOpenCode = fn2("installOpenCode")(function* (context) {
19137
19284
  const fileSystem = yield* FileSystem;
19138
19285
  const path = yield* Path;
19139
- const spawner = yield* ChildProcessSpawner;
19140
19286
  const cacheRoot = process.env.XDG_CACHE_HOME || path.join(context.home, ".cache");
19141
19287
  const isCacheRemoved = yield* fileSystem.remove(path.join(cacheRoot, "opencode", "packages", "@aerovato", "operator-opencode@latest"), {
19142
19288
  recursive: true,
@@ -19148,85 +19294,39 @@ var installOpenCode = fn2("installOpenCode")(function* (context) {
19148
19294
  output: `✗ Could not clear the OpenCode plugin cache`
19149
19295
  };
19150
19296
  }
19151
- const command = make11("opencode", ["plugin", OPENCODE_PLUGIN, "--global", "--force"], {
19152
- cwd: context.cwd,
19153
- env: { NPM_CONFIG_MIN_RELEASE_AGE: "0" },
19154
- extendEnv: true
19155
- });
19156
- const execution = yield* scoped2(gen2(function* () {
19157
- const handle = yield* spawner.spawn(command);
19158
- const [stdout, stderr, exitCode] = yield* all2([
19159
- handle.stdout.pipe(decodeText(), mkString),
19160
- handle.stderr.pipe(decodeText(), mkString),
19161
- handle.exitCode
19162
- ], { concurrency: "unbounded" });
19163
- return { stdout, stderr, exitCode: Number(exitCode) };
19164
- })).pipe(result2);
19165
- if (isFailure2(execution)) {
19166
- const message = execution.failure instanceof PlatformError ? execution.failure.reason.description ?? execution.failure.message : getErrorMessage(execution.failure);
19167
- return { exitCode: 1, output: `✗ Could not run opencode: ${message}` };
19297
+ const execution = yield* runProcess("opencode", ["plugin", OPENCODE_PLUGIN, "--global", "--force"], context.cwd, { NPM_CONFIG_MIN_RELEASE_AGE: "0" });
19298
+ if (!execution.ok) {
19299
+ return { exitCode: 1, output: `✗ Could not run opencode: ${execution.error}` };
19168
19300
  }
19169
- const output = [execution.success.stdout.trim(), execution.success.stderr.trim()].filter(Boolean).join(`
19170
- `);
19171
- return execution.success.exitCode === 0 ? { exitCode: 0, output } : {
19172
- exitCode: execution.success.exitCode,
19173
- output: output || "OpenCode plugin installation failed"
19301
+ return execution.exitCode === 0 ? { exitCode: 0, output: execution.output } : {
19302
+ exitCode: execution.exitCode,
19303
+ output: execution.output || "OpenCode plugin installation failed"
19174
19304
  };
19175
19305
  });
19176
19306
 
19177
19307
  // src/commands/install/opencode-v2.ts
19178
19308
  var OPENCODE_V2_PLUGIN = "@aerovato/operator-opencode-v2@latest";
19179
19309
  var installOpenCodeV2 = fn2("installOpenCodeV2")(function* (context) {
19180
- const spawner = yield* ChildProcessSpawner;
19181
- const command = make11("opencode2", ["plugin", "add", OPENCODE_V2_PLUGIN], {
19182
- cwd: context.cwd,
19183
- env: { NPM_CONFIG_MIN_RELEASE_AGE: "0" },
19184
- extendEnv: true
19185
- });
19186
- const execution = yield* scoped2(gen2(function* () {
19187
- const handle = yield* spawner.spawn(command);
19188
- const [stdout, stderr, exitCode] = yield* all2([
19189
- handle.stdout.pipe(decodeText(), mkString),
19190
- handle.stderr.pipe(decodeText(), mkString),
19191
- handle.exitCode
19192
- ], { concurrency: "unbounded" });
19193
- return { stdout, stderr, exitCode: Number(exitCode) };
19194
- })).pipe(result2);
19195
- if (isFailure2(execution)) {
19196
- const message = execution.failure instanceof PlatformError ? execution.failure.reason.description ?? execution.failure.message : getErrorMessage(execution.failure);
19197
- return { exitCode: 1, output: `✗ Could not run opencode2: ${message}` };
19310
+ const execution = yield* runProcess("opencode", ["plugin", "add", OPENCODE_V2_PLUGIN], context.cwd, { NPM_CONFIG_MIN_RELEASE_AGE: "0" });
19311
+ if (!execution.ok) {
19312
+ return { exitCode: 1, output: `✗ Could not run opencode: ${execution.error}` };
19198
19313
  }
19199
- const output = [execution.success.stdout.trim(), execution.success.stderr.trim()].filter(Boolean).join(`
19200
- `);
19201
- return execution.success.exitCode === 0 ? { exitCode: 0, output } : {
19202
- exitCode: execution.success.exitCode,
19203
- output: output || "OpenCode V2 plugin installation failed"
19314
+ return execution.exitCode === 0 ? { exitCode: 0, output: execution.output } : {
19315
+ exitCode: execution.exitCode,
19316
+ output: execution.output || "OpenCode V2 plugin installation failed"
19204
19317
  };
19205
19318
  });
19206
19319
 
19207
19320
  // src/commands/install/pi.ts
19208
19321
  var PI_PLUGIN = "npm:@aerovato/operator-pi";
19209
19322
  var installPi = fn2("installPi")(function* (context) {
19210
- const spawner = yield* ChildProcessSpawner;
19211
- const command = make11("pi", ["install", PI_PLUGIN], { cwd: context.cwd });
19212
- const execution = yield* scoped2(gen2(function* () {
19213
- const handle = yield* spawner.spawn(command);
19214
- const [stdout, stderr, exitCode] = yield* all2([
19215
- handle.stdout.pipe(decodeText(), mkString),
19216
- handle.stderr.pipe(decodeText(), mkString),
19217
- handle.exitCode
19218
- ], { concurrency: "unbounded" });
19219
- return { stdout, stderr, exitCode: Number(exitCode) };
19220
- })).pipe(result2);
19221
- if (isFailure2(execution)) {
19222
- const message = execution.failure instanceof PlatformError ? execution.failure.reason.description ?? execution.failure.message : getErrorMessage(execution.failure);
19223
- return { exitCode: 1, output: `✗ Could not run pi: ${message}` };
19323
+ const execution = yield* runProcess("pi", ["install", PI_PLUGIN], context.cwd, null);
19324
+ if (!execution.ok) {
19325
+ return { exitCode: 1, output: `✗ Could not run pi: ${execution.error}` };
19224
19326
  }
19225
- const output = [execution.success.stdout.trim(), execution.success.stderr.trim()].filter(Boolean).join(`
19226
- `);
19227
- return execution.success.exitCode === 0 ? { exitCode: 0, output } : {
19228
- exitCode: execution.success.exitCode,
19229
- output: output || "Pi plugin installation failed"
19327
+ return execution.exitCode === 0 ? { exitCode: 0, output: execution.output } : {
19328
+ exitCode: execution.exitCode,
19329
+ output: execution.output || "Pi plugin installation failed"
19230
19330
  };
19231
19331
  });
19232
19332
 
@@ -19234,7 +19334,7 @@ var installPi = fn2("installPi")(function* (context) {
19234
19334
  import { resolve as resolve3 } from "node:path";
19235
19335
 
19236
19336
  // ../core/src/memory/project.ts
19237
- import { extname, join as join3, relative, sep } from "node:path";
19337
+ import { extname, join as join4, relative, sep } from "node:path";
19238
19338
 
19239
19339
  // ../core/src/utils.ts
19240
19340
  function success(value) {
@@ -19259,17 +19359,17 @@ function readString(value, key) {
19259
19359
 
19260
19360
  // ../core/src/memory/common.ts
19261
19361
  import { constants as constants2 } from "node:fs";
19262
- import { access as access3, readdir, readFile as readFile4, stat as stat3 } from "node:fs/promises";
19362
+ import { access as access3, readdir, readFile as readFile5, stat as stat3 } from "node:fs/promises";
19263
19363
  async function readOptionalContent(path) {
19264
19364
  try {
19265
- return success(await readFile4(path, "utf8"));
19365
+ return success(await readFile5(path, "utf8"));
19266
19366
  } catch (cause) {
19267
19367
  return hasNodeErrorCode(cause, "ENOENT") ? success(null) : failure({ path, cause });
19268
19368
  }
19269
19369
  }
19270
19370
  async function readContent(path) {
19271
19371
  try {
19272
- return success(await readFile4(path, "utf8"));
19372
+ return success(await readFile5(path, "utf8"));
19273
19373
  } catch (cause) {
19274
19374
  return failure({ path, cause });
19275
19375
  }
@@ -19348,13 +19448,13 @@ async function loadProjectPartition(root, loadFiles) {
19348
19448
  return hasNodeErrorCode(directory.error.cause, "ENOENT") ? success(loadFiles ? { exists: false, operatorInstructions: null, catalog: null, indexes: [] } : { exists: false }) : directory;
19349
19449
  }
19350
19450
  if (!loadFiles) {
19351
- for (const path of [join3(root, "operator.md"), join3(root, "catalog.md")]) {
19451
+ for (const path of [join4(root, "operator.md"), join4(root, "catalog.md")]) {
19352
19452
  const file = await checkOptionalReadableFile(path);
19353
19453
  if (!file.ok) {
19354
19454
  return file;
19355
19455
  }
19356
19456
  }
19357
- const indexRoot = join3(root, "index");
19457
+ const indexRoot = join4(root, "index");
19358
19458
  const indexPaths = await listMarkdownFiles(indexRoot, indexRoot);
19359
19459
  if (!indexPaths.ok) {
19360
19460
  return indexPaths;
@@ -19367,15 +19467,15 @@ async function loadProjectPartition(root, loadFiles) {
19367
19467
  }
19368
19468
  return success({ exists: true });
19369
19469
  }
19370
- const operatorInstructions = await readOptionalContent(join3(root, "operator.md"));
19470
+ const operatorInstructions = await readOptionalContent(join4(root, "operator.md"));
19371
19471
  if (!operatorInstructions.ok) {
19372
19472
  return operatorInstructions;
19373
19473
  }
19374
- const catalog = await readOptionalContent(join3(root, "catalog.md"));
19474
+ const catalog = await readOptionalContent(join4(root, "catalog.md"));
19375
19475
  if (!catalog.ok) {
19376
19476
  return catalog;
19377
19477
  }
19378
- const indexes = await readIndexes(join3(root, "index"));
19478
+ const indexes = await readIndexes(join4(root, "index"));
19379
19479
  if (!indexes.ok) {
19380
19480
  return indexes;
19381
19481
  }
@@ -19413,7 +19513,7 @@ async function listMarkdownFiles(root, directory) {
19413
19513
  }
19414
19514
  const paths = [];
19415
19515
  for (const entry of entries.value) {
19416
- const path = join3(directory, entry.name);
19516
+ const path = join4(directory, entry.name);
19417
19517
  if (entry.isDirectory()) {
19418
19518
  const nestedPaths = await listMarkdownFiles(root, path);
19419
19519
  if (!nestedPaths.ok) {
@@ -19434,14 +19534,14 @@ function compareStrings2(left, right) {
19434
19534
  }
19435
19535
 
19436
19536
  // ../core/src/memory/user.ts
19437
- import { join as join4 } from "node:path";
19537
+ import { join as join5 } from "node:path";
19438
19538
  async function loadUserPartition(root, loadFiles) {
19439
19539
  if (!loadFiles) {
19440
19540
  const directory = await readDirectory2(root);
19441
19541
  if (!directory.ok) {
19442
19542
  return hasNodeErrorCode(directory.error.cause, "ENOENT") ? success({ exists: false }) : directory;
19443
19543
  }
19444
- for (const path of [join4(root, "operator.md"), join4(root, "catalog.md")]) {
19544
+ for (const path of [join5(root, "operator.md"), join5(root, "catalog.md")]) {
19445
19545
  const file = await checkOptionalReadableFile(path);
19446
19546
  if (!file.ok) {
19447
19547
  return file;
@@ -19449,11 +19549,11 @@ async function loadUserPartition(root, loadFiles) {
19449
19549
  }
19450
19550
  return success({ exists: true });
19451
19551
  }
19452
- const operatorInstructions = await readOptionalContent(join4(root, "operator.md"));
19552
+ const operatorInstructions = await readOptionalContent(join5(root, "operator.md"));
19453
19553
  if (!operatorInstructions.ok) {
19454
19554
  return operatorInstructions;
19455
19555
  }
19456
- const catalog = await readOptionalContent(join4(root, "catalog.md"));
19556
+ const catalog = await readOptionalContent(join5(root, "catalog.md"));
19457
19557
  if (!catalog.ok) {
19458
19558
  return catalog;
19459
19559
  }
@@ -19979,18 +20079,6 @@ var hasTrackedPrivateFiles = fn2("hasTrackedPrivateFiles")(function* (cwd) {
19979
20079
  return tracked.trim() !== "";
19980
20080
  });
19981
20081
 
19982
- // src/commands/common.ts
19983
- function fileFailure(error) {
19984
- return { exitCode: 1, output: fileErrorMessage(error) };
19985
- }
19986
- function fileErrorMessage(error) {
19987
- if (error instanceof PathKindError) {
19988
- return `✗ ${error.path}: Expected a ${error.expected}, found ${error.actual}`;
19989
- }
19990
- const path = error.reason instanceof SystemError ? `${error.reason.pathOrDescriptor}: ` : "";
19991
- return `✗ ${path}${error.reason.description ?? error.message}`;
19992
- }
19993
-
19994
20082
  // src/commands/project/common.ts
19995
20083
  var PRIVATE_ROOT2 = ".operator";
19996
20084
  var SHARED_ROOT2 = ".operator-shared";
@@ -20248,6 +20336,7 @@ USER COMMANDS
20248
20336
  ${renderTable([
20249
20337
  ["help", "Show help for operator-helper"],
20250
20338
  ["version", "Show the installed version"],
20339
+ ["operator-helper install codex", "Install or update the Codex plugin"],
20251
20340
  ["operator-helper install opencode", "Install or update the OpenCode plugin"],
20252
20341
  ["operator-helper install opencode-v2", "Install or update the OpenCode V2 plugin"],
20253
20342
  ["operator-helper install pi", "Install or update the Pi plugin"],
@@ -20308,6 +20397,8 @@ function runCli(arguments_, context) {
20308
20397
  return yield* indexLint(context);
20309
20398
  case "memory check":
20310
20399
  return yield* memoryCheck(context);
20400
+ case "install codex":
20401
+ return yield* installCodex(context);
20311
20402
  case "install opencode":
20312
20403
  return yield* installOpenCode(context);
20313
20404
  case "install opencode-v2":
@@ -20363,9 +20454,9 @@ var NpmRegistry;
20363
20454
  })(NpmRegistry ||= {});
20364
20455
 
20365
20456
  // src/update.ts
20366
- import { mkdir as mkdir3, readFile as readFile5, writeFile as writeFile4 } from "node:fs/promises";
20457
+ import { mkdir as mkdir4, readFile as readFile6, writeFile as writeFile5 } from "node:fs/promises";
20367
20458
  import { realpathSync } from "node:fs";
20368
- import { dirname as dirname2, join as join5, sep as sep2 } from "node:path";
20459
+ import { dirname as dirname2, join as join6, sep as sep2 } from "node:path";
20369
20460
  var HELPER_PACKAGE = "@aerovato/operator-helper";
20370
20461
  var UPDATE_TIMEOUT = "60 seconds";
20371
20462
  var SUCCESS_COOLDOWN = 60 * 60 * 1000;
@@ -20381,8 +20472,8 @@ var UpdateCheck = Union2([
20381
20472
  ]);
20382
20473
  var decodeUpdateCheck = decodeUnknownSync(fromJsonString2(UpdateCheck));
20383
20474
  function updateCheckPath(context) {
20384
- const cache = process.env.XDG_CACHE_HOME || join5(context.home, ".cache");
20385
- return join5(cache, "operator", "helper-update.json");
20475
+ const cache = process.env.XDG_CACHE_HOME || join6(context.home, ".cache");
20476
+ return join6(cache, "operator", "helper-update.json");
20386
20477
  }
20387
20478
  var autoUpdate = fn2("autoUpdate")(function* (currentVersion, context) {
20388
20479
  const cached = yield* promise2(() => readUpdateCheck(context));
@@ -20432,7 +20523,7 @@ function isFresh(check) {
20432
20523
  }
20433
20524
  async function readUpdateCheck(context) {
20434
20525
  try {
20435
- return decodeUpdateCheck(await readFile5(updateCheckPath(context), "utf8"));
20526
+ return decodeUpdateCheck(await readFile6(updateCheckPath(context), "utf8"));
20436
20527
  } catch {
20437
20528
  return null;
20438
20529
  }
@@ -20440,8 +20531,8 @@ async function readUpdateCheck(context) {
20440
20531
  async function writeUpdateCheck(context, check) {
20441
20532
  const path = updateCheckPath(context);
20442
20533
  try {
20443
- await mkdir3(dirname2(path), { recursive: true, mode: 448 });
20444
- await writeFile4(path, JSON.stringify(check), { mode: 384 });
20534
+ await mkdir4(dirname2(path), { recursive: true, mode: 448 });
20535
+ await writeFile5(path, JSON.stringify(check), { mode: 384 });
20445
20536
  } catch {}
20446
20537
  }
20447
20538
  function detectInstallationChannel(spawner, cwd, executablePath) {
@@ -20546,4 +20637,4 @@ var main = gen2(function* () {
20546
20637
  }).pipe(provide4(LiveLayers));
20547
20638
  runMain2(main);
20548
20639
 
20549
- //# debugId=179D9D023424381964756E2164756E21
20640
+ //# debugId=EE71A176DAC5289D64756E2164756E21