poe-code 3.0.69-beta.1 → 3.0.69-beta.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/index.js CHANGED
@@ -2032,170 +2032,9 @@ var init_context = __esm({
2032
2032
  }
2033
2033
  });
2034
2034
 
2035
- // src/services/credentials.ts
2036
- import path4 from "node:path";
2037
- async function saveCredentials(options) {
2038
- const { fs: fs3, filePath, apiKey } = options;
2039
- const document = await readCredentialsDocument(fs3, filePath);
2040
- document.apiKey = apiKey;
2041
- await writeCredentialsDocument(fs3, filePath, document);
2042
- }
2043
- async function loadCredentials(options) {
2044
- const { fs: fs3, filePath } = options;
2045
- const document = await readCredentialsDocument(fs3, filePath);
2046
- return typeof document.apiKey === "string" && document.apiKey.length > 0 ? document.apiKey : null;
2047
- }
2048
- async function deleteCredentials(options) {
2049
- const { fs: fs3, filePath } = options;
2050
- try {
2051
- await fs3.unlink(filePath);
2052
- return true;
2053
- } catch (error2) {
2054
- if (isNotFound(error2)) {
2055
- return false;
2056
- }
2057
- throw error2;
2058
- }
2059
- }
2060
- async function loadConfiguredServices(options) {
2061
- const { fs: fs3, filePath } = options;
2062
- const document = await readCredentialsDocument(fs3, filePath);
2063
- return { ...document.configured_services ?? {} };
2064
- }
2065
- async function saveConfiguredService(options) {
2066
- const { fs: fs3, filePath, service, metadata } = options;
2067
- const document = await readCredentialsDocument(fs3, filePath);
2068
- const normalized = normalizeConfiguredServiceMetadata(metadata);
2069
- document.configured_services = {
2070
- ...document.configured_services ?? {},
2071
- [service]: normalized
2072
- };
2073
- await writeCredentialsDocument(fs3, filePath, document);
2074
- }
2075
- async function unconfigureService(options) {
2076
- const { fs: fs3, filePath, service } = options;
2077
- const document = await readCredentialsDocument(fs3, filePath);
2078
- const services = document.configured_services;
2079
- if (!services || !(service in services)) {
2080
- return false;
2081
- }
2082
- delete services[service];
2083
- if (Object.keys(services).length === 0) {
2084
- delete document.configured_services;
2085
- }
2086
- await writeCredentialsDocument(fs3, filePath, document);
2087
- return true;
2088
- }
2089
- function normalizeConfiguredServiceMetadata(metadata) {
2090
- const seen = /* @__PURE__ */ new Set();
2091
- const files = [];
2092
- for (const entry of metadata.files ?? []) {
2093
- if (typeof entry !== "string" || entry.length === 0) {
2094
- continue;
2095
- }
2096
- if (!seen.has(entry)) {
2097
- files.push(entry);
2098
- seen.add(entry);
2099
- }
2100
- }
2101
- return {
2102
- files
2103
- };
2104
- }
2105
- async function readCredentialsDocument(fs3, filePath) {
2106
- try {
2107
- const raw = await fs3.readFile(filePath, "utf8");
2108
- return await parseCredentialsDocument(fs3, filePath, raw);
2109
- } catch (error2) {
2110
- if (isNotFound(error2)) {
2111
- return {};
2112
- }
2113
- throw error2;
2114
- }
2115
- }
2116
- async function parseCredentialsDocument(fs3, filePath, raw) {
2117
- try {
2118
- const parsed = JSON.parse(raw);
2119
- return normalizeCredentialsDocument(parsed);
2120
- } catch (error2) {
2121
- if (error2 instanceof SyntaxError) {
2122
- await recoverInvalidCredentials(fs3, filePath, raw);
2123
- return {};
2124
- }
2125
- throw error2;
2126
- }
2127
- }
2128
- function normalizeCredentialsDocument(value) {
2129
- if (!isRecord3(value)) {
2130
- return {};
2131
- }
2132
- const document = {};
2133
- if (typeof value.apiKey === "string" && value.apiKey.length > 0) {
2134
- document.apiKey = value.apiKey;
2135
- }
2136
- const services = normalizeConfiguredServices(value.configured_services);
2137
- if (Object.keys(services).length > 0) {
2138
- document.configured_services = services;
2139
- }
2140
- return document;
2141
- }
2142
- function normalizeConfiguredServices(value) {
2143
- if (!isRecord3(value)) {
2144
- return {};
2145
- }
2146
- const entries = {};
2147
- for (const [key, entry] of Object.entries(value)) {
2148
- if (!isRecord3(entry)) {
2149
- continue;
2150
- }
2151
- const normalized = normalizeConfiguredServiceMetadata({
2152
- files: Array.isArray(entry.files) ? entry.files : []
2153
- });
2154
- entries[key] = normalized;
2155
- }
2156
- return entries;
2157
- }
2158
- async function writeCredentialsDocument(fs3, filePath, document) {
2159
- await fs3.mkdir(path4.dirname(filePath), { recursive: true });
2160
- const payload = {};
2161
- if (document.apiKey) {
2162
- payload.apiKey = document.apiKey;
2163
- }
2164
- if (document.configured_services) {
2165
- payload.configured_services = document.configured_services;
2166
- }
2167
- await fs3.writeFile(filePath, `${JSON.stringify(payload, null, 2)}
2168
- `, {
2169
- encoding: "utf8"
2170
- });
2171
- }
2172
- async function recoverInvalidCredentials(fs3, filePath, content) {
2173
- const backupPath = createInvalidBackupPath(filePath);
2174
- await fs3.writeFile(backupPath, content, { encoding: "utf8" });
2175
- await fs3.writeFile(filePath, EMPTY_DOCUMENT, { encoding: "utf8" });
2176
- }
2177
- function createInvalidBackupPath(filePath) {
2178
- const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
2179
- const dir = path4.dirname(filePath);
2180
- const base = path4.basename(filePath);
2181
- return path4.join(dir, `${base}.invalid-${timestamp}.json`);
2182
- }
2183
- function isRecord3(value) {
2184
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
2185
- }
2186
- var EMPTY_DOCUMENT;
2187
- var init_credentials2 = __esm({
2188
- "src/services/credentials.ts"() {
2189
- "use strict";
2190
- init_src2();
2191
- EMPTY_DOCUMENT = `${JSON.stringify({}, null, 2)}
2192
- `;
2193
- }
2194
- });
2195
-
2196
2035
  // src/cli/isolated-env.ts
2197
- import path5 from "node:path";
2198
- async function resolveIsolatedEnvDetails(env, isolated, providerName, fs3) {
2036
+ import path4 from "node:path";
2037
+ async function resolveIsolatedEnvDetails(env, isolated, providerName, readApiKey) {
2199
2038
  if (!providerName) {
2200
2039
  throw new Error("resolveIsolatedEnvDetails requires providerName.");
2201
2040
  }
@@ -2208,7 +2047,7 @@ async function resolveIsolatedEnvDetails(env, isolated, providerName, fs3) {
2208
2047
  }
2209
2048
  return {
2210
2049
  agentBinary: isolated.agentBinary,
2211
- env: await resolveIsolatedEnvVars(env, baseDir, isolated.env, fs3),
2050
+ env: await resolveIsolatedEnvVars(env, baseDir, isolated.env, readApiKey),
2212
2051
  configProbePath: isolated.configProbe ? resolveIsolatedEnvPath(env, baseDir, isolated.configProbe) : void 0
2213
2052
  };
2214
2053
  }
@@ -2216,7 +2055,7 @@ function resolveIsolatedTargetDirectory(input) {
2216
2055
  const expanded = expandHomeShortcut(input.env, input.targetDirectory);
2217
2056
  const baseDir = resolveIsolatedBaseDir(input.env, input.providerName);
2218
2057
  const homeDir = input.env.homeDir;
2219
- const homeDirWithSep = `${homeDir}${path5.sep}`;
2058
+ const homeDirWithSep = `${homeDir}${path4.sep}`;
2220
2059
  if (expanded !== homeDir && !expanded.startsWith(homeDirWithSep)) {
2221
2060
  throw new Error(
2222
2061
  `Isolated config targets must live under the user's home directory (received "${input.targetDirectory}").`
@@ -2231,20 +2070,20 @@ function resolveIsolatedTargetDirectory(input) {
2231
2070
  if (!expanded.startsWith(homeDirWithSep)) {
2232
2071
  return expanded;
2233
2072
  }
2234
- const mapped = path5.join(baseDir, expanded.slice(homeDirWithSep.length));
2073
+ const mapped = path4.join(baseDir, expanded.slice(homeDirWithSep.length));
2235
2074
  return stripAgentHome(mapped, baseDir, input.isolated.agentBinary);
2236
2075
  }
2237
2076
  function resolveIsolatedBaseDir(env, providerName) {
2238
2077
  return env.resolveHomePath(".poe-code", providerName);
2239
2078
  }
2240
- async function resolveIsolatedEnvVars(env, baseDir, vars, fs3) {
2079
+ async function resolveIsolatedEnvVars(env, baseDir, vars, readApiKey) {
2241
2080
  const out = {};
2242
2081
  for (const [key, value] of Object.entries(vars)) {
2243
- out[key] = await resolveIsolatedEnvValue(env, baseDir, value, fs3);
2082
+ out[key] = await resolveIsolatedEnvValue(env, baseDir, value, readApiKey);
2244
2083
  }
2245
2084
  return out;
2246
2085
  }
2247
- async function resolveIsolatedEnvValue(env, baseDir, value, fs3) {
2086
+ async function resolveIsolatedEnvValue(env, baseDir, value, readApiKey) {
2248
2087
  if (typeof value === "string") {
2249
2088
  return expandHomeShortcut(env, value);
2250
2089
  }
@@ -2262,12 +2101,12 @@ async function resolveIsolatedEnvValue(env, baseDir, value, fs3) {
2262
2101
  if (typeof resolved === "string" && resolved.trim().length > 0) {
2263
2102
  return resolved;
2264
2103
  }
2265
- if (!fs3) {
2104
+ if (!readApiKey) {
2266
2105
  throw new Error(
2267
2106
  'Missing Poe API key for isolated wrapper. Set "POE_API_KEY" or run "poe-code login".'
2268
2107
  );
2269
2108
  }
2270
- return await resolvePoeApiKeyFromCredentials({ fs: fs3, env });
2109
+ return await resolvePoeApiKeyFromAuthStore(readApiKey);
2271
2110
  }
2272
2111
  if (isPoeBaseUrlReference(value)) {
2273
2112
  return env.poeBaseUrl;
@@ -2280,9 +2119,9 @@ async function resolveIsolatedEnvValue(env, baseDir, value, fs3) {
2280
2119
  function resolveIsolatedEnvPath(env, baseDir, value) {
2281
2120
  switch (value.kind) {
2282
2121
  case "isolatedDir":
2283
- return value.relativePath ? path5.join(baseDir, value.relativePath) : baseDir;
2122
+ return value.relativePath ? path4.join(baseDir, value.relativePath) : baseDir;
2284
2123
  case "isolatedFile":
2285
- return path5.join(baseDir, value.relativePath);
2124
+ return path4.join(baseDir, value.relativePath);
2286
2125
  }
2287
2126
  }
2288
2127
  function isEnvVarReference(value) {
@@ -2294,8 +2133,8 @@ function isPoeApiKeyReference(value) {
2294
2133
  function isPoeBaseUrlReference(value) {
2295
2134
  return typeof value === "object" && value.kind === "poeBaseUrl";
2296
2135
  }
2297
- async function resolvePoeApiKeyFromCredentials(input) {
2298
- const stored = await loadCredentials({ fs: input.fs, filePath: input.env.credentialsPath }) ?? void 0;
2136
+ async function resolvePoeApiKeyFromAuthStore(readApiKey) {
2137
+ const stored = await readApiKey();
2299
2138
  if (typeof stored !== "string" || stored.trim().length === 0) {
2300
2139
  throw new Error(
2301
2140
  'Missing Poe API key for isolated wrapper. Set "POE_API_KEY" or run "poe-code login".'
@@ -2324,10 +2163,10 @@ async function applyIsolatedEnvRepairs(input) {
2324
2163
  if (repair.kind !== "chmod") {
2325
2164
  continue;
2326
2165
  }
2327
- if (path5.isAbsolute(repair.relativePath)) {
2166
+ if (path4.isAbsolute(repair.relativePath)) {
2328
2167
  continue;
2329
2168
  }
2330
- const repairPath = path5.join(baseDir, repair.relativePath);
2169
+ const repairPath = path4.join(baseDir, repair.relativePath);
2331
2170
  try {
2332
2171
  await input.fs.chmod(repairPath, repair.mode);
2333
2172
  } catch (error2) {
@@ -2338,11 +2177,11 @@ async function applyIsolatedEnvRepairs(input) {
2338
2177
  }
2339
2178
  }
2340
2179
  }
2341
- async function resolveCliSettings(cliSettings, env, fs3) {
2180
+ async function resolveCliSettings(cliSettings, env, readApiKey) {
2342
2181
  const result = { ...cliSettings.values };
2343
2182
  if (cliSettings.resolved) {
2344
2183
  for (const [key, value] of Object.entries(cliSettings.resolved)) {
2345
- result[key] = await resolveCliSettingValue(value, env, fs3);
2184
+ result[key] = await resolveCliSettingValue(value, env, readApiKey);
2346
2185
  }
2347
2186
  }
2348
2187
  if (cliSettings.env) {
@@ -2351,21 +2190,21 @@ async function resolveCliSettings(cliSettings, env, fs3) {
2351
2190
  if (typeof value === "string") {
2352
2191
  resolvedEnv[key] = value;
2353
2192
  } else {
2354
- resolvedEnv[key] = await resolveCliSettingValue(value, env, fs3);
2193
+ resolvedEnv[key] = await resolveCliSettingValue(value, env, readApiKey);
2355
2194
  }
2356
2195
  }
2357
2196
  result.env = resolvedEnv;
2358
2197
  }
2359
2198
  return result;
2360
2199
  }
2361
- async function resolveCliSettingValue(value, env, fs3) {
2200
+ async function resolveCliSettingValue(value, env, readApiKey) {
2362
2201
  if (isPoeApiKeyReference(value)) {
2363
2202
  const resolved = env.getVariable("POE_API_KEY");
2364
2203
  if (typeof resolved === "string" && resolved.trim().length > 0) {
2365
2204
  return resolved;
2366
2205
  }
2367
- if (fs3) {
2368
- return await resolvePoeApiKeyFromCredentials({ fs: fs3, env });
2206
+ if (readApiKey) {
2207
+ return await resolvePoeApiKeyFromAuthStore(readApiKey);
2369
2208
  }
2370
2209
  throw new Error(
2371
2210
  'Missing Poe API key for CLI settings. Set "POE_API_KEY" or run "poe-code login".'
@@ -2378,13 +2217,13 @@ async function resolveCliSettingValue(value, env, fs3) {
2378
2217
  }
2379
2218
  function stripAgentHome(mapped, baseDir, agentBinary) {
2380
2219
  const agentDir = `.${agentBinary}`;
2381
- const prefix = path5.join(baseDir, agentDir);
2220
+ const prefix = path4.join(baseDir, agentDir);
2382
2221
  if (mapped === prefix) {
2383
2222
  return baseDir;
2384
2223
  }
2385
- const withSep = `${prefix}${path5.sep}`;
2224
+ const withSep = `${prefix}${path4.sep}`;
2386
2225
  if (mapped.startsWith(withSep)) {
2387
- return path5.join(baseDir, mapped.slice(withSep.length));
2226
+ return path4.join(baseDir, mapped.slice(withSep.length));
2388
2227
  }
2389
2228
  return mapped;
2390
2229
  }
@@ -2395,11 +2234,11 @@ function expandHomeShortcut(env, input) {
2395
2234
  if (input === "~") {
2396
2235
  return env.homeDir;
2397
2236
  }
2398
- if (input.startsWith("~/") || input.startsWith(`~${path5.sep}`)) {
2399
- return path5.join(env.homeDir, input.slice(2));
2237
+ if (input.startsWith("~/") || input.startsWith(`~${path4.sep}`)) {
2238
+ return path4.join(env.homeDir, input.slice(2));
2400
2239
  }
2401
- if (input.startsWith("~./") || input.startsWith(`~.${path5.sep}`)) {
2402
- return path5.join(env.homeDir, `.${input.slice(3)}`);
2240
+ if (input.startsWith("~./") || input.startsWith(`~.${path4.sep}`)) {
2241
+ return path4.join(env.homeDir, `.${input.slice(3)}`);
2403
2242
  }
2404
2243
  return input;
2405
2244
  }
@@ -2407,7 +2246,6 @@ var init_isolated_env = __esm({
2407
2246
  "src/cli/isolated-env.ts"() {
2408
2247
  "use strict";
2409
2248
  init_src2();
2410
- init_credentials2();
2411
2249
  }
2412
2250
  });
2413
2251
 
@@ -4389,7 +4227,7 @@ var init_src5 = __esm({
4389
4227
  });
4390
4228
 
4391
4229
  // src/cli/commands/shared.ts
4392
- import path6 from "node:path";
4230
+ import path5 from "node:path";
4393
4231
  function resolveCommandFlags(program) {
4394
4232
  const opts = program.optsWithGlobals();
4395
4233
  return {
@@ -4462,7 +4300,7 @@ function buildResumeCommand(canonicalService, threadId, cwd) {
4462
4300
  if (!binaryName) {
4463
4301
  return void 0;
4464
4302
  }
4465
- const resumeCwd = path6.resolve(cwd);
4303
+ const resumeCwd = path5.resolve(cwd);
4466
4304
  const args = spawnConfig.resumeCommand(threadId, resumeCwd);
4467
4305
  const agentCommand = [binaryName, ...args.map(shlexQuote)].join(" ");
4468
4306
  const needsCdPrefix = !args.includes(resumeCwd);
@@ -4559,7 +4397,7 @@ var init_shared = __esm({
4559
4397
  });
4560
4398
 
4561
4399
  // src/sdk/spawn-core.ts
4562
- import path7 from "node:path";
4400
+ import path6 from "node:path";
4563
4401
  import chalk10 from "chalk";
4564
4402
  async function spawnCore(container, service, options, flags = { dryRun: false, verbose: false }) {
4565
4403
  const cwdOverride = resolveSpawnWorkingDirectory(
@@ -4657,10 +4495,10 @@ function resolveSpawnWorkingDirectory(baseDir, candidate) {
4657
4495
  if (!candidate || candidate.trim().length === 0) {
4658
4496
  return void 0;
4659
4497
  }
4660
- if (path7.isAbsolute(candidate)) {
4498
+ if (path6.isAbsolute(candidate)) {
4661
4499
  return candidate;
4662
4500
  }
4663
- return path7.resolve(baseDir, candidate);
4501
+ return path6.resolve(baseDir, candidate);
4664
4502
  }
4665
4503
  var init_spawn_core = __esm({
4666
4504
  "src/sdk/spawn-core.ts"() {
@@ -4670,14 +4508,14 @@ var init_spawn_core = __esm({
4670
4508
  });
4671
4509
 
4672
4510
  // src/cli/environment.ts
4673
- import path8 from "node:path";
4511
+ import path7 from "node:path";
4674
4512
  function createCliEnvironment(init) {
4675
4513
  const platform = init.platform ?? process.platform;
4676
4514
  const variables = init.variables ?? process.env;
4677
4515
  const credentialsPath = resolveCredentialsPath(init.homeDir);
4678
4516
  const logDir = resolveLogDir(init.homeDir);
4679
4517
  const { poeApiBaseUrl, poeBaseUrl } = resolvePoeBaseUrls(variables);
4680
- const resolveHomePath = (...segments) => path8.join(init.homeDir, ...segments);
4518
+ const resolveHomePath = (...segments) => path7.join(init.homeDir, ...segments);
4681
4519
  const getVariable = (name) => variables[name];
4682
4520
  return {
4683
4521
  cwd: init.cwd,
@@ -4693,10 +4531,10 @@ function createCliEnvironment(init) {
4693
4531
  };
4694
4532
  }
4695
4533
  function resolveCredentialsPath(homeDir) {
4696
- return path8.join(homeDir, ".poe-code", "credentials.json");
4534
+ return path7.join(homeDir, ".poe-code", "credentials.json");
4697
4535
  }
4698
4536
  function resolveLogDir(homeDir) {
4699
- return path8.join(homeDir, ".poe-code", "logs");
4537
+ return path7.join(homeDir, ".poe-code", "logs");
4700
4538
  }
4701
4539
  function resolvePoeBaseUrls(variables) {
4702
4540
  const raw = variables.POE_BASE_URL;
@@ -5233,7 +5071,7 @@ var init_logger2 = __esm({
5233
5071
  });
5234
5072
 
5235
5073
  // src/cli/error-logger.ts
5236
- import path9 from "node:path";
5074
+ import path8 from "node:path";
5237
5075
  var DEFAULT_MAX_SIZE, DEFAULT_MAX_BACKUPS, ErrorLogger;
5238
5076
  var init_error_logger = __esm({
5239
5077
  "src/cli/error-logger.ts"() {
@@ -5250,7 +5088,7 @@ var init_error_logger = __esm({
5250
5088
  fileLoggingAvailable;
5251
5089
  constructor(options) {
5252
5090
  this.fs = options.fs;
5253
- this.logFilePath = path9.join(options.logDir, "errors.log");
5091
+ this.logFilePath = path8.join(options.logDir, "errors.log");
5254
5092
  this.logToStderr = options.logToStderr ?? true;
5255
5093
  this.maxSize = options.maxSize ?? DEFAULT_MAX_SIZE;
5256
5094
  this.maxBackups = options.maxBackups ?? DEFAULT_MAX_BACKUPS;
@@ -5369,7 +5207,7 @@ ${entry.stack}`);
5369
5207
  return `${this.logFilePath}.${index}`;
5370
5208
  }
5371
5209
  ensureLogDirectory() {
5372
- const directory = path9.dirname(this.logFilePath);
5210
+ const directory = path8.dirname(this.logFilePath);
5373
5211
  try {
5374
5212
  if (!this.fs.existsSync(directory)) {
5375
5213
  this.fs.mkdirSync(directory, { recursive: true });
@@ -5387,7 +5225,7 @@ ${entry.stack}`);
5387
5225
  });
5388
5226
 
5389
5227
  // src/providers/index.ts
5390
- import path10 from "node:path";
5228
+ import path9 from "node:path";
5391
5229
  import { readdir } from "node:fs/promises";
5392
5230
  import { fileURLToPath, pathToFileURL } from "node:url";
5393
5231
  function isProviderModule(filename) {
@@ -5414,7 +5252,7 @@ async function loadProviders() {
5414
5252
  for (const entry of entries) {
5415
5253
  if (!entry.isFile()) continue;
5416
5254
  if (!isProviderModule(entry.name)) continue;
5417
- const moduleUrl = pathToFileURL(path10.join(currentDir, entry.name)).href;
5255
+ const moduleUrl = pathToFileURL(path9.join(currentDir, entry.name)).href;
5418
5256
  const moduleExports = await import(moduleUrl);
5419
5257
  if (!moduleExports.provider) {
5420
5258
  throw new Error(`Provider module "${entry.name}" must export "provider".`);
@@ -5430,8 +5268,8 @@ var moduleDir, currentDir, defaultProviders;
5430
5268
  var init_providers = __esm({
5431
5269
  async "src/providers/index.ts"() {
5432
5270
  "use strict";
5433
- moduleDir = path10.dirname(fileURLToPath(import.meta.url));
5434
- currentDir = path10.basename(moduleDir) === "providers" ? moduleDir : path10.join(moduleDir, "providers");
5271
+ moduleDir = path9.dirname(fileURLToPath(import.meta.url));
5272
+ currentDir = path9.basename(moduleDir) === "providers" ? moduleDir : path9.join(moduleDir, "providers");
5435
5273
  defaultProviders = await loadProviders();
5436
5274
  }
5437
5275
  });
@@ -5613,7 +5451,7 @@ async function ensureIsolatedConfigForService(input) {
5613
5451
  container.env,
5614
5452
  isolated,
5615
5453
  adapter.name,
5616
- container.fs
5454
+ container.readApiKey
5617
5455
  );
5618
5456
  const hasConfig = await isolatedConfigExists(
5619
5457
  container.fs,
@@ -5688,7 +5526,7 @@ function createPoeCodeCommandRunner(input) {
5688
5526
  container.env,
5689
5527
  adapter.isolatedEnv,
5690
5528
  adapter.name,
5691
- container.fs
5529
+ container.readApiKey
5692
5530
  );
5693
5531
  if (adapter.isolatedEnv.requiresConfig !== false) {
5694
5532
  const hasConfig = await isolatedConfigExists(
@@ -5719,7 +5557,7 @@ function createPoeCodeCommandRunner(input) {
5719
5557
  const resolvedSettings = await resolveCliSettings(
5720
5558
  adapter.isolatedEnv.cliSettings,
5721
5559
  container.env,
5722
- container.fs
5560
+ container.readApiKey
5723
5561
  );
5724
5562
  forwarded = buildArgsWithMergedSettings(forwarded, resolvedSettings);
5725
5563
  }
@@ -5864,7 +5702,9 @@ function createSdkContainer(options) {
5864
5702
  platform: process.platform,
5865
5703
  variables
5866
5704
  }
5867
- }
5705
+ },
5706
+ readApiKey,
5707
+ writeApiKey
5868
5708
  };
5869
5709
  return container;
5870
5710
  }
@@ -6037,6 +5877,161 @@ var init_errors = __esm({
6037
5877
  }
6038
5878
  });
6039
5879
 
5880
+ // src/services/credentials.ts
5881
+ import path10 from "node:path";
5882
+ async function loadCredentials(options) {
5883
+ const { fs: fs3, filePath } = options;
5884
+ const document = await readCredentialsDocument(fs3, filePath);
5885
+ return typeof document.apiKey === "string" && document.apiKey.length > 0 ? document.apiKey : null;
5886
+ }
5887
+ async function deleteCredentials(options) {
5888
+ const { fs: fs3, filePath } = options;
5889
+ try {
5890
+ await fs3.unlink(filePath);
5891
+ return true;
5892
+ } catch (error2) {
5893
+ if (isNotFound(error2)) {
5894
+ return false;
5895
+ }
5896
+ throw error2;
5897
+ }
5898
+ }
5899
+ async function loadConfiguredServices(options) {
5900
+ const { fs: fs3, filePath } = options;
5901
+ const document = await readCredentialsDocument(fs3, filePath);
5902
+ return { ...document.configured_services ?? {} };
5903
+ }
5904
+ async function saveConfiguredService(options) {
5905
+ const { fs: fs3, filePath, service, metadata } = options;
5906
+ const document = await readCredentialsDocument(fs3, filePath);
5907
+ const normalized = normalizeConfiguredServiceMetadata(metadata);
5908
+ document.configured_services = {
5909
+ ...document.configured_services ?? {},
5910
+ [service]: normalized
5911
+ };
5912
+ await writeCredentialsDocument(fs3, filePath, document);
5913
+ }
5914
+ async function unconfigureService(options) {
5915
+ const { fs: fs3, filePath, service } = options;
5916
+ const document = await readCredentialsDocument(fs3, filePath);
5917
+ const services = document.configured_services;
5918
+ if (!services || !(service in services)) {
5919
+ return false;
5920
+ }
5921
+ delete services[service];
5922
+ if (Object.keys(services).length === 0) {
5923
+ delete document.configured_services;
5924
+ }
5925
+ await writeCredentialsDocument(fs3, filePath, document);
5926
+ return true;
5927
+ }
5928
+ function normalizeConfiguredServiceMetadata(metadata) {
5929
+ const seen = /* @__PURE__ */ new Set();
5930
+ const files = [];
5931
+ for (const entry of metadata.files ?? []) {
5932
+ if (typeof entry !== "string" || entry.length === 0) {
5933
+ continue;
5934
+ }
5935
+ if (!seen.has(entry)) {
5936
+ files.push(entry);
5937
+ seen.add(entry);
5938
+ }
5939
+ }
5940
+ return {
5941
+ files
5942
+ };
5943
+ }
5944
+ async function readCredentialsDocument(fs3, filePath) {
5945
+ try {
5946
+ const raw = await fs3.readFile(filePath, "utf8");
5947
+ return await parseCredentialsDocument(fs3, filePath, raw);
5948
+ } catch (error2) {
5949
+ if (isNotFound(error2)) {
5950
+ return {};
5951
+ }
5952
+ throw error2;
5953
+ }
5954
+ }
5955
+ async function parseCredentialsDocument(fs3, filePath, raw) {
5956
+ try {
5957
+ const parsed = JSON.parse(raw);
5958
+ return normalizeCredentialsDocument(parsed);
5959
+ } catch (error2) {
5960
+ if (error2 instanceof SyntaxError) {
5961
+ await recoverInvalidCredentials(fs3, filePath, raw);
5962
+ return {};
5963
+ }
5964
+ throw error2;
5965
+ }
5966
+ }
5967
+ function normalizeCredentialsDocument(value) {
5968
+ if (!isRecord3(value)) {
5969
+ return {};
5970
+ }
5971
+ const document = {};
5972
+ if (typeof value.apiKey === "string" && value.apiKey.length > 0) {
5973
+ document.apiKey = value.apiKey;
5974
+ }
5975
+ const services = normalizeConfiguredServices(value.configured_services);
5976
+ if (Object.keys(services).length > 0) {
5977
+ document.configured_services = services;
5978
+ }
5979
+ return document;
5980
+ }
5981
+ function normalizeConfiguredServices(value) {
5982
+ if (!isRecord3(value)) {
5983
+ return {};
5984
+ }
5985
+ const entries = {};
5986
+ for (const [key, entry] of Object.entries(value)) {
5987
+ if (!isRecord3(entry)) {
5988
+ continue;
5989
+ }
5990
+ const normalized = normalizeConfiguredServiceMetadata({
5991
+ files: Array.isArray(entry.files) ? entry.files : []
5992
+ });
5993
+ entries[key] = normalized;
5994
+ }
5995
+ return entries;
5996
+ }
5997
+ async function writeCredentialsDocument(fs3, filePath, document) {
5998
+ await fs3.mkdir(path10.dirname(filePath), { recursive: true });
5999
+ const payload = {};
6000
+ if (document.apiKey) {
6001
+ payload.apiKey = document.apiKey;
6002
+ }
6003
+ if (document.configured_services) {
6004
+ payload.configured_services = document.configured_services;
6005
+ }
6006
+ await fs3.writeFile(filePath, `${JSON.stringify(payload, null, 2)}
6007
+ `, {
6008
+ encoding: "utf8"
6009
+ });
6010
+ }
6011
+ async function recoverInvalidCredentials(fs3, filePath, content) {
6012
+ const backupPath = createInvalidBackupPath(filePath);
6013
+ await fs3.writeFile(backupPath, content, { encoding: "utf8" });
6014
+ await fs3.writeFile(filePath, EMPTY_DOCUMENT, { encoding: "utf8" });
6015
+ }
6016
+ function createInvalidBackupPath(filePath) {
6017
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
6018
+ const dir = path10.dirname(filePath);
6019
+ const base = path10.basename(filePath);
6020
+ return path10.join(dir, `${base}.invalid-${timestamp}.json`);
6021
+ }
6022
+ function isRecord3(value) {
6023
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
6024
+ }
6025
+ var EMPTY_DOCUMENT;
6026
+ var init_credentials2 = __esm({
6027
+ "src/services/credentials.ts"() {
6028
+ "use strict";
6029
+ init_src2();
6030
+ EMPTY_DOCUMENT = `${JSON.stringify({}, null, 2)}
6031
+ `;
6032
+ }
6033
+ });
6034
+
6040
6035
  // src/services/llm-client.ts
6041
6036
  function createPoeClient(options) {
6042
6037
  const httpClient = options.httpClient ?? createDefaultHttpClient();
@@ -6242,19 +6237,33 @@ function createCliContainer(dependencies) {
6242
6237
  });
6243
6238
  const commandRunner = dependencies.commandRunner ?? runCommand;
6244
6239
  const promptLibrary = createPromptLibrary();
6240
+ const authFs = {
6241
+ readFile: (filePath, encoding) => dependencies.fs.readFile(filePath, encoding),
6242
+ writeFile: (filePath, data, opts) => dependencies.fs.writeFile(filePath, data, opts),
6243
+ mkdir: (directoryPath, opts) => dependencies.fs.mkdir(directoryPath, opts).then(() => void 0),
6244
+ unlink: (filePath) => dependencies.fs.unlink(filePath),
6245
+ chmod: (filePath, mode) => dependencies.fs.chmod ? dependencies.fs.chmod(filePath, mode) : Promise.resolve()
6246
+ };
6247
+ const { store: authStore } = createAuthStore({
6248
+ env: dependencies.env.variables,
6249
+ platform: dependencies.env.platform,
6250
+ fileStore: {
6251
+ fs: authFs,
6252
+ getHomeDirectory: () => dependencies.env.homeDir
6253
+ },
6254
+ legacyCredentials: {
6255
+ fs: authFs,
6256
+ getHomeDirectory: () => dependencies.env.homeDir
6257
+ }
6258
+ });
6259
+ const readApiKey = authStore.getApiKey.bind(authStore);
6260
+ const writeApiKey = authStore.setApiKey.bind(authStore);
6245
6261
  const options = createOptionResolvers({
6246
6262
  prompts: dependencies.prompts,
6247
6263
  promptLibrary,
6248
6264
  apiKeyStore: {
6249
- read: () => loadCredentials({
6250
- fs: dependencies.fs,
6251
- filePath: environment.credentialsPath
6252
- }),
6253
- write: (value) => saveCredentials({
6254
- fs: dependencies.fs,
6255
- filePath: environment.credentialsPath,
6256
- apiKey: value
6257
- })
6265
+ read: readApiKey,
6266
+ write: writeApiKey
6258
6267
  }
6259
6268
  });
6260
6269
  const registry2 = createServiceRegistry();
@@ -6282,14 +6291,16 @@ function createCliContainer(dependencies) {
6282
6291
  httpClient,
6283
6292
  commandRunner: wrappedRunner,
6284
6293
  providers,
6285
- dependencies
6294
+ dependencies,
6295
+ readApiKey,
6296
+ writeApiKey
6286
6297
  };
6287
6298
  return container;
6288
6299
  }
6289
6300
  var init_container2 = __esm({
6290
6301
  async "src/cli/container.ts"() {
6291
6302
  "use strict";
6292
- init_credentials2();
6303
+ init_src();
6293
6304
  init_environment();
6294
6305
  init_service_registry();
6295
6306
  init_context();
@@ -7193,7 +7204,7 @@ async function isolatedEnvRunner(input) {
7193
7204
  input.env,
7194
7205
  input.isolated,
7195
7206
  input.providerName,
7196
- input.fs
7207
+ input.readApiKey
7197
7208
  );
7198
7209
  let args = input.argv.slice(2);
7199
7210
  if (input.isolated.requiresConfig !== false) {
@@ -7208,7 +7219,7 @@ async function isolatedEnvRunner(input) {
7208
7219
  const resolvedSettings = await resolveCliSettings(
7209
7220
  input.isolated.cliSettings,
7210
7221
  input.env,
7211
- input.fs
7222
+ input.readApiKey
7212
7223
  );
7213
7224
  args = buildArgsWithMergedSettings(args, resolvedSettings);
7214
7225
  }
@@ -7295,6 +7306,7 @@ function registerWrapCommand(program, container) {
7295
7306
  await isolatedEnvRunner({
7296
7307
  env: container.env,
7297
7308
  fs: container.fs,
7309
+ readApiKey: container.readApiKey,
7298
7310
  providerName: adapter.name,
7299
7311
  isolated,
7300
7312
  argv: ["node", "poe-code", ...forwarded]
@@ -7328,11 +7340,9 @@ function registerLoginCommand(program, container) {
7328
7340
  fs: container.fs,
7329
7341
  filePath: container.env.credentialsPath
7330
7342
  });
7331
- await saveCredentials({
7332
- fs: resources.context.fs,
7333
- filePath: container.env.credentialsPath,
7334
- apiKey: normalized
7335
- });
7343
+ if (!flags.dryRun) {
7344
+ await container.writeApiKey(normalized);
7345
+ }
7336
7346
  await reconfigureServices({
7337
7347
  program,
7338
7348
  container,
@@ -7702,7 +7712,7 @@ async function executeTest(program, container, service, options = {}) {
7702
7712
  container.env,
7703
7713
  adapter.isolatedEnv,
7704
7714
  adapter.name,
7705
- container.fs
7715
+ container.readApiKey
7706
7716
  ) : null;
7707
7717
  if (options.isolated && adapter.isolatedEnv) {
7708
7718
  const { ensureIsolatedConfigForService: ensureIsolatedConfigForService2 } = await Promise.resolve().then(() => (init_ensure_isolated_config(), ensure_isolated_config_exports));
@@ -35428,10 +35438,7 @@ function registerMcpCommand(program, container) {
35428
35438
  mcp.command("configure [agent]").description("Configure MCP client to use poe-code").option("-y, --yes", "Skip prompt, use claude-code").action(async (agentArg, options) => {
35429
35439
  const flags = resolveCommandFlags(program);
35430
35440
  const resources = createExecutionResources(container, flags, "mcp");
35431
- const existingKey = await loadCredentials({
35432
- fs: container.fs,
35433
- filePath: container.env.credentialsPath
35434
- });
35441
+ const existingKey = await container.readApiKey();
35435
35442
  if (!existingKey) {
35436
35443
  resources.logger.intro("login");
35437
35444
  await container.options.resolveApiKey({ dryRun: flags.dryRun });
@@ -35531,10 +35538,7 @@ async function runMcpServer(container, options) {
35531
35538
  const outputFormatPreferences = parseMcpOutputFormatPreferences(
35532
35539
  options.outputFormat
35533
35540
  );
35534
- const apiKey = await loadCredentials({
35535
- fs: container.fs,
35536
- filePath: container.env.credentialsPath
35537
- });
35541
+ const apiKey = await container.readApiKey();
35538
35542
  if (!apiKey) {
35539
35543
  process.stderr.write("No credentials found. Run 'poe-code login' first.\n");
35540
35544
  process.exit(1);
@@ -35552,7 +35556,6 @@ var init_mcp = __esm({
35552
35556
  "src/cli/commands/mcp.ts"() {
35553
35557
  "use strict";
35554
35558
  init_src4();
35555
- init_credentials2();
35556
35559
  init_client_instance();
35557
35560
  init_mcp_server();
35558
35561
  init_shared();
@@ -38691,10 +38694,7 @@ function registerModelsCommand(program, container) {
38691
38694
  const commandOptions = this.opts();
38692
38695
  resources.logger.intro("models");
38693
38696
  try {
38694
- const apiKey = await loadCredentials({
38695
- fs: container.fs,
38696
- filePath: container.env.credentialsPath
38697
- });
38697
+ const apiKey = await container.readApiKey();
38698
38698
  if (flags.dryRun) {
38699
38699
  resources.logger.dryRun(
38700
38700
  "Dry run: would fetch models from Poe API."
@@ -38882,7 +38882,6 @@ var init_models = __esm({
38882
38882
  "src/cli/commands/models.ts"() {
38883
38883
  "use strict";
38884
38884
  init_shared();
38885
- init_credentials2();
38886
38885
  init_errors();
38887
38886
  init_src4();
38888
38887
  MAX_VALUES_LENGTH = 105;
@@ -38896,7 +38895,7 @@ var init_package = __esm({
38896
38895
  "package.json"() {
38897
38896
  package_default = {
38898
38897
  name: "poe-code",
38899
- version: "3.0.69-beta.1",
38898
+ version: "3.0.69-beta.2",
38900
38899
  description: "CLI tool to configure Poe API for developer workflows.",
38901
38900
  type: "module",
38902
38901
  main: "./dist/index.js",