poe-code 3.0.70 → 3.0.71-beta.1

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.
Files changed (61) hide show
  1. package/dist/cli/commands/auth.d.ts +3 -0
  2. package/dist/cli/commands/auth.js +102 -0
  3. package/dist/cli/commands/auth.js.map +1 -0
  4. package/dist/cli/commands/configure.js +2 -2
  5. package/dist/cli/commands/configure.js.map +1 -1
  6. package/dist/cli/commands/ensure-isolated-config.js +1 -1
  7. package/dist/cli/commands/ensure-isolated-config.js.map +1 -1
  8. package/dist/cli/commands/generate.js +5 -2
  9. package/dist/cli/commands/generate.js.map +1 -1
  10. package/dist/cli/commands/login.d.ts +1 -0
  11. package/dist/cli/commands/login.js +57 -36
  12. package/dist/cli/commands/login.js.map +1 -1
  13. package/dist/cli/commands/logout.d.ts +1 -0
  14. package/dist/cli/commands/logout.js +32 -29
  15. package/dist/cli/commands/logout.js.map +1 -1
  16. package/dist/cli/commands/mcp.js +4 -12
  17. package/dist/cli/commands/mcp.js.map +1 -1
  18. package/dist/cli/commands/models.js +1 -5
  19. package/dist/cli/commands/models.js.map +1 -1
  20. package/dist/cli/commands/research.js +2 -2
  21. package/dist/cli/commands/research.js.map +1 -1
  22. package/dist/cli/commands/spawn.js +2 -2
  23. package/dist/cli/commands/spawn.js.map +1 -1
  24. package/dist/cli/commands/test.js +1 -1
  25. package/dist/cli/commands/test.js.map +1 -1
  26. package/dist/cli/commands/unconfigure.js +2 -2
  27. package/dist/cli/commands/unconfigure.js.map +1 -1
  28. package/dist/cli/commands/wrap.js +1 -0
  29. package/dist/cli/commands/wrap.js.map +1 -1
  30. package/dist/cli/container.d.ts +2 -0
  31. package/dist/cli/container.js +29 -11
  32. package/dist/cli/container.js.map +1 -1
  33. package/dist/cli/environment.d.ts +2 -2
  34. package/dist/cli/environment.js +4 -4
  35. package/dist/cli/environment.js.map +1 -1
  36. package/dist/cli/isolated-env-runner.d.ts +1 -0
  37. package/dist/cli/isolated-env-runner.js +2 -2
  38. package/dist/cli/isolated-env-runner.js.map +1 -1
  39. package/dist/cli/isolated-env.d.ts +2 -2
  40. package/dist/cli/isolated-env.js +15 -17
  41. package/dist/cli/isolated-env.js.map +1 -1
  42. package/dist/cli/poe-code-command-runner.js +2 -2
  43. package/dist/cli/poe-code-command-runner.js.map +1 -1
  44. package/dist/cli/program.js +13 -6
  45. package/dist/cli/program.js.map +1 -1
  46. package/dist/index.js +1187 -611
  47. package/dist/index.js.map +4 -4
  48. package/dist/sdk/container.js +27 -11
  49. package/dist/sdk/container.js.map +1 -1
  50. package/dist/sdk/credentials.d.ts +1 -1
  51. package/dist/sdk/credentials.js +6 -19
  52. package/dist/sdk/credentials.js.map +1 -1
  53. package/dist/services/client-instance.d.ts +1 -3
  54. package/dist/services/client-instance.js +1 -11
  55. package/dist/services/client-instance.js.map +1 -1
  56. package/dist/services/config.d.ts +24 -0
  57. package/dist/services/{credentials.js → config.js} +34 -21
  58. package/dist/services/config.js.map +1 -0
  59. package/package.json +2 -1
  60. package/dist/services/credentials.d.ts +0 -24
  61. package/dist/services/credentials.js.map +0 -1
package/dist/index.js CHANGED
@@ -31,34 +31,469 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  mod
32
32
  ));
33
33
 
34
+ // packages/auth/src/encrypted-file-auth-store.ts
35
+ import { createCipheriv, createDecipheriv, randomBytes, scrypt } from "node:crypto";
36
+ import { promises as fs } from "node:fs";
37
+ import { homedir, hostname, userInfo } from "node:os";
38
+ import path from "node:path";
39
+ function defaultMachineIdentity() {
40
+ return {
41
+ hostname: hostname(),
42
+ username: userInfo().username
43
+ };
44
+ }
45
+ async function deriveEncryptionKey(getMachineIdentity) {
46
+ const machineIdentity = await getMachineIdentity();
47
+ const secret = `${machineIdentity.hostname}:${machineIdentity.username}`;
48
+ return await new Promise((resolve, reject) => {
49
+ scrypt(secret, ENCRYPTION_SALT, ENCRYPTION_KEY_BYTES, (error2, derivedKey) => {
50
+ if (error2) {
51
+ reject(error2);
52
+ return;
53
+ }
54
+ resolve(Buffer.from(derivedKey));
55
+ });
56
+ });
57
+ }
58
+ function parseEncryptedDocument(raw) {
59
+ try {
60
+ const parsed = JSON.parse(raw);
61
+ if (!isRecord(parsed)) {
62
+ return null;
63
+ }
64
+ if (parsed.version !== ENCRYPTION_VERSION) {
65
+ return null;
66
+ }
67
+ if (typeof parsed.iv !== "string" || typeof parsed.authTag !== "string" || typeof parsed.ciphertext !== "string") {
68
+ return null;
69
+ }
70
+ return {
71
+ version: parsed.version,
72
+ iv: parsed.iv,
73
+ authTag: parsed.authTag,
74
+ ciphertext: parsed.ciphertext
75
+ };
76
+ } catch {
77
+ return null;
78
+ }
79
+ }
80
+ function isRecord(value) {
81
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
82
+ }
83
+ function isNotFoundError(error2) {
84
+ return Boolean(
85
+ error2 && typeof error2 === "object" && "code" in error2 && error2.code === "ENOENT"
86
+ );
87
+ }
88
+ var ENCRYPTION_ALGORITHM, ENCRYPTION_VERSION, ENCRYPTION_KEY_BYTES, ENCRYPTION_IV_BYTES, ENCRYPTION_AUTH_TAG_BYTES, ENCRYPTION_SALT, ENCRYPTION_FILE_MODE, EncryptedFileAuthStore;
89
+ var init_encrypted_file_auth_store = __esm({
90
+ "packages/auth/src/encrypted-file-auth-store.ts"() {
91
+ "use strict";
92
+ ENCRYPTION_ALGORITHM = "aes-256-gcm";
93
+ ENCRYPTION_VERSION = 1;
94
+ ENCRYPTION_KEY_BYTES = 32;
95
+ ENCRYPTION_IV_BYTES = 12;
96
+ ENCRYPTION_AUTH_TAG_BYTES = 16;
97
+ ENCRYPTION_SALT = "poe-code:encrypted-file-auth-store:v1";
98
+ ENCRYPTION_FILE_MODE = 384;
99
+ EncryptedFileAuthStore = class {
100
+ fs;
101
+ filePath;
102
+ getMachineIdentity;
103
+ getRandomBytes;
104
+ keyPromise = null;
105
+ constructor(input = {}) {
106
+ this.fs = input.fs ?? fs;
107
+ this.filePath = input.filePath ?? path.join(
108
+ (input.getHomeDirectory ?? homedir)(),
109
+ ".poe-code",
110
+ "credentials.enc"
111
+ );
112
+ this.getMachineIdentity = input.getMachineIdentity ?? defaultMachineIdentity;
113
+ this.getRandomBytes = input.getRandomBytes ?? randomBytes;
114
+ }
115
+ async getApiKey() {
116
+ let rawDocument;
117
+ try {
118
+ rawDocument = await this.fs.readFile(this.filePath, "utf8");
119
+ } catch (error2) {
120
+ if (isNotFoundError(error2)) {
121
+ return null;
122
+ }
123
+ throw error2;
124
+ }
125
+ const document = parseEncryptedDocument(rawDocument);
126
+ if (!document) {
127
+ return null;
128
+ }
129
+ const key = await this.getEncryptionKey();
130
+ try {
131
+ const iv = Buffer.from(document.iv, "base64");
132
+ const authTag = Buffer.from(document.authTag, "base64");
133
+ const ciphertext = Buffer.from(document.ciphertext, "base64");
134
+ if (iv.byteLength !== ENCRYPTION_IV_BYTES || authTag.byteLength !== ENCRYPTION_AUTH_TAG_BYTES) {
135
+ return null;
136
+ }
137
+ const decipher = createDecipheriv(ENCRYPTION_ALGORITHM, key, iv);
138
+ decipher.setAuthTag(authTag);
139
+ const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
140
+ return plaintext.toString("utf8");
141
+ } catch {
142
+ return null;
143
+ }
144
+ }
145
+ async setApiKey(apiKey) {
146
+ const key = await this.getEncryptionKey();
147
+ const iv = this.getRandomBytes(ENCRYPTION_IV_BYTES);
148
+ const cipher = createCipheriv(ENCRYPTION_ALGORITHM, key, iv);
149
+ const ciphertext = Buffer.concat([
150
+ cipher.update(apiKey, "utf8"),
151
+ cipher.final()
152
+ ]);
153
+ const authTag = cipher.getAuthTag();
154
+ const document = {
155
+ version: ENCRYPTION_VERSION,
156
+ iv: iv.toString("base64"),
157
+ authTag: authTag.toString("base64"),
158
+ ciphertext: ciphertext.toString("base64")
159
+ };
160
+ await this.fs.mkdir(path.dirname(this.filePath), { recursive: true });
161
+ await this.fs.writeFile(this.filePath, JSON.stringify(document), {
162
+ encoding: "utf8"
163
+ });
164
+ await this.fs.chmod(this.filePath, ENCRYPTION_FILE_MODE);
165
+ }
166
+ async deleteApiKey() {
167
+ try {
168
+ await this.fs.unlink(this.filePath);
169
+ } catch (error2) {
170
+ if (!isNotFoundError(error2)) {
171
+ throw error2;
172
+ }
173
+ }
174
+ }
175
+ getEncryptionKey() {
176
+ if (!this.keyPromise) {
177
+ this.keyPromise = deriveEncryptionKey(this.getMachineIdentity);
178
+ }
179
+ return this.keyPromise;
180
+ }
181
+ };
182
+ }
183
+ });
184
+
185
+ // packages/auth/src/keychain-auth-store.ts
186
+ import { spawn } from "node:child_process";
187
+ function runSecurityCommand(command, args) {
188
+ return new Promise((resolve) => {
189
+ const child = spawn(command, args, {
190
+ stdio: ["ignore", "pipe", "pipe"]
191
+ });
192
+ let stdout = "";
193
+ let stderr = "";
194
+ child.stdout?.setEncoding("utf8");
195
+ child.stdout?.on("data", (chunk) => {
196
+ stdout += chunk.toString();
197
+ });
198
+ child.stderr?.setEncoding("utf8");
199
+ child.stderr?.on("data", (chunk) => {
200
+ stderr += chunk.toString();
201
+ });
202
+ child.on("error", (error2) => {
203
+ const message = error2 instanceof Error ? error2.message : String(error2 ?? "Unknown error");
204
+ resolve({
205
+ stdout,
206
+ stderr: stderr ? `${stderr}${message}` : message,
207
+ exitCode: 127
208
+ });
209
+ });
210
+ child.on("close", (code) => {
211
+ resolve({
212
+ stdout,
213
+ stderr,
214
+ exitCode: code ?? 0
215
+ });
216
+ });
217
+ });
218
+ }
219
+ function stripTrailingLineBreak(value) {
220
+ if (value.endsWith("\r\n")) {
221
+ return value.slice(0, -2);
222
+ }
223
+ if (value.endsWith("\n") || value.endsWith("\r")) {
224
+ return value.slice(0, -1);
225
+ }
226
+ return value;
227
+ }
228
+ function isKeychainEntryNotFound(result) {
229
+ if (result.exitCode === KEYCHAIN_ITEM_NOT_FOUND_EXIT_CODE) {
230
+ return true;
231
+ }
232
+ const output = `${result.stderr}
233
+ ${result.stdout}`.toLowerCase();
234
+ return output.includes("could not be found") || output.includes("item not found") || output.includes("errsecitemnotfound");
235
+ }
236
+ function createSecurityCliFailure(operation, result) {
237
+ const details = result.stderr.trim() || result.stdout.trim();
238
+ if (details) {
239
+ return new Error(
240
+ `Failed to ${operation}: security exited with code ${result.exitCode}: ${details}`
241
+ );
242
+ }
243
+ return new Error(`Failed to ${operation}: security exited with code ${result.exitCode}`);
244
+ }
245
+ var SECURITY_CLI, KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT, KEYCHAIN_ITEM_NOT_FOUND_EXIT_CODE, KeychainAuthStore;
246
+ var init_keychain_auth_store = __esm({
247
+ "packages/auth/src/keychain-auth-store.ts"() {
248
+ "use strict";
249
+ SECURITY_CLI = "security";
250
+ KEYCHAIN_SERVICE = "poe-code";
251
+ KEYCHAIN_ACCOUNT = "api-key";
252
+ KEYCHAIN_ITEM_NOT_FOUND_EXIT_CODE = 44;
253
+ KeychainAuthStore = class {
254
+ runCommand;
255
+ service;
256
+ account;
257
+ constructor(input = {}) {
258
+ this.runCommand = input.runCommand ?? runSecurityCommand;
259
+ this.service = input.service ?? KEYCHAIN_SERVICE;
260
+ this.account = input.account ?? KEYCHAIN_ACCOUNT;
261
+ }
262
+ async getApiKey() {
263
+ const result = await this.executeSecurityCommand(
264
+ ["find-generic-password", "-s", this.service, "-a", this.account, "-w"],
265
+ "read API key from macOS Keychain"
266
+ );
267
+ if (result.exitCode === 0) {
268
+ return stripTrailingLineBreak(result.stdout);
269
+ }
270
+ if (isKeychainEntryNotFound(result)) {
271
+ return null;
272
+ }
273
+ throw createSecurityCliFailure("read API key from macOS Keychain", result);
274
+ }
275
+ async setApiKey(apiKey) {
276
+ const result = await this.executeSecurityCommand(
277
+ [
278
+ "add-generic-password",
279
+ "-s",
280
+ this.service,
281
+ "-a",
282
+ this.account,
283
+ "-w",
284
+ apiKey,
285
+ "-U"
286
+ ],
287
+ "store API key in macOS Keychain"
288
+ );
289
+ if (result.exitCode !== 0) {
290
+ throw createSecurityCliFailure("store API key in macOS Keychain", result);
291
+ }
292
+ }
293
+ async deleteApiKey() {
294
+ const result = await this.executeSecurityCommand(
295
+ ["delete-generic-password", "-s", this.service, "-a", this.account],
296
+ "delete API key from macOS Keychain"
297
+ );
298
+ if (result.exitCode === 0 || isKeychainEntryNotFound(result)) {
299
+ return;
300
+ }
301
+ throw createSecurityCliFailure("delete API key from macOS Keychain", result);
302
+ }
303
+ async executeSecurityCommand(args, operation) {
304
+ try {
305
+ return await this.runCommand(SECURITY_CLI, args);
306
+ } catch (error2) {
307
+ const message = error2 instanceof Error ? error2.message : String(error2);
308
+ throw new Error(`Failed to ${operation}: ${message}`);
309
+ }
310
+ }
311
+ };
312
+ }
313
+ });
314
+
315
+ // packages/auth/src/create-auth-store.ts
316
+ import { promises as nodeFs } from "node:fs";
317
+ import { homedir as homedir2 } from "node:os";
318
+ import path2 from "node:path";
319
+ function createAuthStore(input = {}) {
320
+ const backend = resolveBackend(input);
321
+ const platform = input.platform ?? process.platform;
322
+ if (backend === "keychain" && platform !== MACOS_PLATFORM) {
323
+ throw new Error(
324
+ `POE_AUTH_BACKEND=keychain is only supported on macOS. Current platform: ${platform}`
325
+ );
326
+ }
327
+ const store = authStoreFactories[backend](input);
328
+ return {
329
+ backend,
330
+ store: enableLegacyCredentialsMigration(store, input)
331
+ };
332
+ }
333
+ function resolveBackend(input) {
334
+ const configuredBackend = input.backend ?? input.env?.[AUTH_BACKEND_ENV_VAR] ?? process.env[AUTH_BACKEND_ENV_VAR];
335
+ if (configuredBackend === "keychain") {
336
+ return "keychain";
337
+ }
338
+ return "file";
339
+ }
340
+ function enableLegacyCredentialsMigration(store, input) {
341
+ const migrationContext = createLegacyMigrationContext(input);
342
+ const readApiKeyFromStore = store.getApiKey.bind(store);
343
+ let hasCheckedLegacyCredentials = false;
344
+ let legacyMigrationPromise = null;
345
+ store.getApiKey = async () => {
346
+ const storedApiKey = await readApiKeyFromStore();
347
+ if (isNonEmptyString(storedApiKey)) {
348
+ return storedApiKey;
349
+ }
350
+ if (hasCheckedLegacyCredentials) {
351
+ return null;
352
+ }
353
+ if (!legacyMigrationPromise) {
354
+ legacyMigrationPromise = migrateLegacyApiKey(store, migrationContext).finally(() => {
355
+ hasCheckedLegacyCredentials = true;
356
+ legacyMigrationPromise = null;
357
+ });
358
+ }
359
+ return legacyMigrationPromise;
360
+ };
361
+ return store;
362
+ }
363
+ async function migrateLegacyApiKey(store, migrationContext) {
364
+ const legacyCredentials = await loadLegacyCredentials(
365
+ migrationContext.fs,
366
+ migrationContext.filePath
367
+ );
368
+ if (!legacyCredentials || !isNonEmptyString(legacyCredentials.apiKey)) {
369
+ return null;
370
+ }
371
+ const plaintextApiKey = legacyCredentials.apiKey;
372
+ try {
373
+ await store.setApiKey(plaintextApiKey);
374
+ delete legacyCredentials.apiKey;
375
+ await saveLegacyCredentials(
376
+ migrationContext.fs,
377
+ migrationContext.filePath,
378
+ legacyCredentials
379
+ );
380
+ } catch (error2) {
381
+ migrationContext.logWarning(
382
+ `Failed to migrate plaintext API key from ${migrationContext.filePath}.`,
383
+ error2
384
+ );
385
+ }
386
+ return plaintextApiKey;
387
+ }
388
+ function createLegacyMigrationContext(input) {
389
+ const legacyCredentialsInput = input.legacyCredentials;
390
+ const getHomeDirectory = legacyCredentialsInput?.getHomeDirectory ?? homedir2;
391
+ return {
392
+ fs: legacyCredentialsInput?.fs ?? input.fileStore?.fs ?? nodeFs,
393
+ filePath: legacyCredentialsInput?.filePath ?? path2.join(
394
+ getHomeDirectory(),
395
+ LEGACY_CREDENTIALS_RELATIVE_PATH
396
+ ),
397
+ logWarning: legacyCredentialsInput?.logWarning ?? defaultMigrationWarning
398
+ };
399
+ }
400
+ async function loadLegacyCredentials(fs3, filePath) {
401
+ let raw;
402
+ try {
403
+ raw = await fs3.readFile(filePath, "utf8");
404
+ } catch (error2) {
405
+ if (isNotFoundError2(error2)) {
406
+ return null;
407
+ }
408
+ return null;
409
+ }
410
+ try {
411
+ const parsed = JSON.parse(raw);
412
+ if (!isRecord2(parsed)) {
413
+ return null;
414
+ }
415
+ return parsed;
416
+ } catch {
417
+ return null;
418
+ }
419
+ }
420
+ async function saveLegacyCredentials(fs3, filePath, document) {
421
+ await fs3.mkdir(path2.dirname(filePath), { recursive: true });
422
+ await fs3.writeFile(filePath, `${JSON.stringify(document, null, 2)}
423
+ `, {
424
+ encoding: "utf8"
425
+ });
426
+ }
427
+ function defaultMigrationWarning(message, error2) {
428
+ const details = toErrorDetails(error2);
429
+ if (details.length > 0) {
430
+ console.warn(`${message} ${details}`);
431
+ return;
432
+ }
433
+ console.warn(message);
434
+ }
435
+ function toErrorDetails(error2) {
436
+ if (error2 instanceof Error) {
437
+ return error2.message;
438
+ }
439
+ return typeof error2 === "string" ? error2 : "";
440
+ }
441
+ function isNonEmptyString(value) {
442
+ return typeof value === "string" && value.length > 0;
443
+ }
444
+ function isRecord2(value) {
445
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
446
+ }
447
+ function isNotFoundError2(error2) {
448
+ return Boolean(
449
+ error2 && typeof error2 === "object" && "code" in error2 && error2.code === "ENOENT"
450
+ );
451
+ }
452
+ var AUTH_BACKEND_ENV_VAR, MACOS_PLATFORM, LEGACY_CREDENTIALS_RELATIVE_PATH, authStoreFactories;
453
+ var init_create_auth_store = __esm({
454
+ "packages/auth/src/create-auth-store.ts"() {
455
+ "use strict";
456
+ init_encrypted_file_auth_store();
457
+ init_keychain_auth_store();
458
+ AUTH_BACKEND_ENV_VAR = "POE_AUTH_BACKEND";
459
+ MACOS_PLATFORM = "darwin";
460
+ LEGACY_CREDENTIALS_RELATIVE_PATH = ".poe-code/credentials.json";
461
+ authStoreFactories = {
462
+ file: (input) => new EncryptedFileAuthStore(input.fileStore),
463
+ keychain: (input) => new KeychainAuthStore(input.keychainStore)
464
+ };
465
+ }
466
+ });
467
+
468
+ // packages/auth/src/index.ts
469
+ var init_src = __esm({
470
+ "packages/auth/src/index.ts"() {
471
+ "use strict";
472
+ init_create_auth_store();
473
+ init_encrypted_file_auth_store();
474
+ init_keychain_auth_store();
475
+ }
476
+ });
477
+
34
478
  // src/sdk/credentials.ts
35
- import * as fs from "node:fs/promises";
36
- import * as os from "node:os";
37
- import * as path from "node:path";
38
479
  async function getPoeApiKey() {
39
480
  const envKey = process.env.POE_API_KEY;
40
481
  if (typeof envKey === "string" && envKey.trim().length > 0) {
41
482
  return envKey.trim();
42
483
  }
43
- const homeDir = os.homedir();
44
- const credentialsPath = path.join(homeDir, CREDENTIALS_RELATIVE_PATH);
45
- try {
46
- const content = await fs.readFile(credentialsPath, "utf8");
47
- const parsed = JSON.parse(content);
48
- if (typeof parsed === "object" && parsed !== null && typeof parsed.apiKey === "string" && parsed.apiKey.length > 0) {
49
- return parsed.apiKey;
50
- }
51
- } catch {
484
+ const { store } = createAuthStore();
485
+ const storedKey = await store.getApiKey();
486
+ if (typeof storedKey === "string" && storedKey.trim().length > 0) {
487
+ return storedKey.trim();
52
488
  }
53
489
  throw new Error(
54
490
  "No API key found. Set POE_API_KEY or run 'poe-code login'."
55
491
  );
56
492
  }
57
- var CREDENTIALS_RELATIVE_PATH;
58
493
  var init_credentials = __esm({
59
494
  "src/sdk/credentials.ts"() {
60
495
  "use strict";
61
- CREDENTIALS_RELATIVE_PATH = ".poe-code/credentials.json";
496
+ init_src();
62
497
  }
63
498
  });
64
499
 
@@ -383,16 +818,16 @@ function getConfigFormat(pathOrFormat) {
383
818
  }
384
819
  return formatRegistry[formatName];
385
820
  }
386
- function detectFormat(path20) {
387
- const ext = getExtension(path20);
821
+ function detectFormat(path21) {
822
+ const ext = getExtension(path21);
388
823
  return extensionMap[ext];
389
824
  }
390
- function getExtension(path20) {
391
- const lastDot = path20.lastIndexOf(".");
825
+ function getExtension(path21) {
826
+ const lastDot = path21.lastIndexOf(".");
392
827
  if (lastDot === -1) {
393
828
  return "";
394
829
  }
395
- return path20.slice(lastDot).toLowerCase();
830
+ return path21.slice(lastDot).toLowerCase();
396
831
  }
397
832
  var formatRegistry, extensionMap;
398
833
  var init_formats = __esm({
@@ -414,7 +849,7 @@ var init_formats = __esm({
414
849
  });
415
850
 
416
851
  // packages/config-mutations/src/execution/path-utils.ts
417
- import path2 from "node:path";
852
+ import path3 from "node:path";
418
853
  function expandHome(targetPath, homeDir) {
419
854
  if (!targetPath?.startsWith("~")) {
420
855
  return targetPath;
@@ -431,7 +866,7 @@ function expandHome(targetPath, homeDir) {
431
866
  remainder = remainder.slice(1);
432
867
  }
433
868
  }
434
- return remainder.length === 0 ? homeDir : path2.join(homeDir, remainder);
869
+ return remainder.length === 0 ? homeDir : path3.join(homeDir, remainder);
435
870
  }
436
871
  function validateHomePath(targetPath) {
437
872
  if (typeof targetPath !== "string" || targetPath.length === 0) {
@@ -449,12 +884,12 @@ function resolvePath(rawPath, homeDir, pathMapper) {
449
884
  if (!pathMapper) {
450
885
  return expanded;
451
886
  }
452
- const rawDirectory = path2.dirname(expanded);
887
+ const rawDirectory = path3.dirname(expanded);
453
888
  const mappedDirectory = pathMapper.mapTargetDirectory({
454
889
  targetDirectory: rawDirectory
455
890
  });
456
- const filename = path2.basename(expanded);
457
- return filename.length === 0 ? mappedDirectory : path2.join(mappedDirectory, filename);
891
+ const filename = path3.basename(expanded);
892
+ return filename.length === 0 ? mappedDirectory : path3.join(mappedDirectory, filename);
458
893
  }
459
894
  var init_path_utils = __esm({
460
895
  "packages/config-mutations/src/execution/path-utils.ts"() {
@@ -1115,7 +1550,7 @@ var init_types = __esm({
1115
1550
  });
1116
1551
 
1117
1552
  // packages/config-mutations/src/index.ts
1118
- var init_src = __esm({
1553
+ var init_src2 = __esm({
1119
1554
  "packages/config-mutations/src/index.ts"() {
1120
1555
  "use strict";
1121
1556
  init_config_mutation();
@@ -1135,38 +1570,38 @@ import { createTwoFilesPatch } from "diff";
1135
1570
  import chalk from "chalk";
1136
1571
  function createDryRunFileSystem(base, recorder) {
1137
1572
  const proxy = {
1138
- async readFile(path20, encoding) {
1573
+ async readFile(path21, encoding) {
1139
1574
  if (encoding) {
1140
- return base.readFile(path20, encoding);
1575
+ return base.readFile(path21, encoding);
1141
1576
  }
1142
- return base.readFile(path20);
1577
+ return base.readFile(path21);
1143
1578
  },
1144
- async writeFile(path20, data, options) {
1145
- const previousContent = await tryReadText(base, path20);
1579
+ async writeFile(path21, data, options) {
1580
+ const previousContent = await tryReadText(base, path21);
1146
1581
  const nextContent = formatData(data, options?.encoding);
1147
1582
  recorder.record({
1148
1583
  type: "writeFile",
1149
- path: path20,
1584
+ path: path21,
1150
1585
  nextContent,
1151
1586
  previousContent
1152
1587
  });
1153
1588
  },
1154
- async mkdir(path20, options) {
1155
- recorder.record({ type: "mkdir", path: path20, options });
1589
+ async mkdir(path21, options) {
1590
+ recorder.record({ type: "mkdir", path: path21, options });
1156
1591
  },
1157
- async stat(path20) {
1158
- return base.stat(path20);
1592
+ async stat(path21) {
1593
+ return base.stat(path21);
1159
1594
  },
1160
- async unlink(path20) {
1161
- recorder.record({ type: "unlink", path: path20 });
1595
+ async unlink(path21) {
1596
+ recorder.record({ type: "unlink", path: path21 });
1162
1597
  },
1163
- async readdir(path20) {
1164
- return base.readdir(path20);
1598
+ async readdir(path21) {
1599
+ return base.readdir(path21);
1165
1600
  }
1166
1601
  };
1167
1602
  if (typeof base.rm === "function") {
1168
- proxy.rm = async (path20, options) => {
1169
- recorder.record({ type: "rm", path: path20, options });
1603
+ proxy.rm = async (path21, options) => {
1604
+ recorder.record({ type: "rm", path: path21, options });
1170
1605
  };
1171
1606
  }
1172
1607
  if (typeof base.copyFile === "function") {
@@ -1256,8 +1691,8 @@ function describeWriteChange(previous, next) {
1256
1691
  }
1257
1692
  return "update";
1258
1693
  }
1259
- function renderWriteCommand(path20, change) {
1260
- const command = `cat > ${path20}`;
1694
+ function renderWriteCommand(path21, change) {
1695
+ const command = `cat > ${path21}`;
1261
1696
  if (change === "create") {
1262
1697
  return renderOperationCommand(command, chalk.green, "# create");
1263
1698
  }
@@ -1419,9 +1854,9 @@ function redactTomlLine(line) {
1419
1854
  }
1420
1855
  return line;
1421
1856
  }
1422
- async function tryReadText(base, path20) {
1857
+ async function tryReadText(base, path21) {
1423
1858
  try {
1424
- return await base.readFile(path20, "utf8");
1859
+ return await base.readFile(path21, "utf8");
1425
1860
  } catch (error2) {
1426
1861
  if (isNotFound(error2)) {
1427
1862
  return null;
@@ -1447,7 +1882,7 @@ var REDACTED_PLACEHOLDER, JSON_SENSITIVE_KEYS, AUTH_SENSITIVE_KEYS, TOML_SENSITI
1447
1882
  var init_dry_run = __esm({
1448
1883
  "src/utils/dry-run.ts"() {
1449
1884
  "use strict";
1450
- init_src();
1885
+ init_src2();
1451
1886
  REDACTED_PLACEHOLDER = "<redacted>";
1452
1887
  JSON_SENSITIVE_KEYS = ["apiKey", "api_key", "apiKeyHelper"];
1453
1888
  AUTH_SENSITIVE_KEYS = ["key"];
@@ -1597,170 +2032,9 @@ var init_context = __esm({
1597
2032
  }
1598
2033
  });
1599
2034
 
1600
- // src/services/credentials.ts
1601
- import path3 from "node:path";
1602
- async function saveCredentials(options) {
1603
- const { fs: fs3, filePath, apiKey } = options;
1604
- const document = await readCredentialsDocument(fs3, filePath);
1605
- document.apiKey = apiKey;
1606
- await writeCredentialsDocument(fs3, filePath, document);
1607
- }
1608
- async function loadCredentials(options) {
1609
- const { fs: fs3, filePath } = options;
1610
- const document = await readCredentialsDocument(fs3, filePath);
1611
- return typeof document.apiKey === "string" && document.apiKey.length > 0 ? document.apiKey : null;
1612
- }
1613
- async function deleteCredentials(options) {
1614
- const { fs: fs3, filePath } = options;
1615
- try {
1616
- await fs3.unlink(filePath);
1617
- return true;
1618
- } catch (error2) {
1619
- if (isNotFound(error2)) {
1620
- return false;
1621
- }
1622
- throw error2;
1623
- }
1624
- }
1625
- async function loadConfiguredServices(options) {
1626
- const { fs: fs3, filePath } = options;
1627
- const document = await readCredentialsDocument(fs3, filePath);
1628
- return { ...document.configured_services ?? {} };
1629
- }
1630
- async function saveConfiguredService(options) {
1631
- const { fs: fs3, filePath, service, metadata } = options;
1632
- const document = await readCredentialsDocument(fs3, filePath);
1633
- const normalized = normalizeConfiguredServiceMetadata(metadata);
1634
- document.configured_services = {
1635
- ...document.configured_services ?? {},
1636
- [service]: normalized
1637
- };
1638
- await writeCredentialsDocument(fs3, filePath, document);
1639
- }
1640
- async function unconfigureService(options) {
1641
- const { fs: fs3, filePath, service } = options;
1642
- const document = await readCredentialsDocument(fs3, filePath);
1643
- const services = document.configured_services;
1644
- if (!services || !(service in services)) {
1645
- return false;
1646
- }
1647
- delete services[service];
1648
- if (Object.keys(services).length === 0) {
1649
- delete document.configured_services;
1650
- }
1651
- await writeCredentialsDocument(fs3, filePath, document);
1652
- return true;
1653
- }
1654
- function normalizeConfiguredServiceMetadata(metadata) {
1655
- const seen = /* @__PURE__ */ new Set();
1656
- const files = [];
1657
- for (const entry of metadata.files ?? []) {
1658
- if (typeof entry !== "string" || entry.length === 0) {
1659
- continue;
1660
- }
1661
- if (!seen.has(entry)) {
1662
- files.push(entry);
1663
- seen.add(entry);
1664
- }
1665
- }
1666
- return {
1667
- files
1668
- };
1669
- }
1670
- async function readCredentialsDocument(fs3, filePath) {
1671
- try {
1672
- const raw = await fs3.readFile(filePath, "utf8");
1673
- return await parseCredentialsDocument(fs3, filePath, raw);
1674
- } catch (error2) {
1675
- if (isNotFound(error2)) {
1676
- return {};
1677
- }
1678
- throw error2;
1679
- }
1680
- }
1681
- async function parseCredentialsDocument(fs3, filePath, raw) {
1682
- try {
1683
- const parsed = JSON.parse(raw);
1684
- return normalizeCredentialsDocument(parsed);
1685
- } catch (error2) {
1686
- if (error2 instanceof SyntaxError) {
1687
- await recoverInvalidCredentials(fs3, filePath, raw);
1688
- return {};
1689
- }
1690
- throw error2;
1691
- }
1692
- }
1693
- function normalizeCredentialsDocument(value) {
1694
- if (!isRecord(value)) {
1695
- return {};
1696
- }
1697
- const document = {};
1698
- if (typeof value.apiKey === "string" && value.apiKey.length > 0) {
1699
- document.apiKey = value.apiKey;
1700
- }
1701
- const services = normalizeConfiguredServices(value.configured_services);
1702
- if (Object.keys(services).length > 0) {
1703
- document.configured_services = services;
1704
- }
1705
- return document;
1706
- }
1707
- function normalizeConfiguredServices(value) {
1708
- if (!isRecord(value)) {
1709
- return {};
1710
- }
1711
- const entries = {};
1712
- for (const [key, entry] of Object.entries(value)) {
1713
- if (!isRecord(entry)) {
1714
- continue;
1715
- }
1716
- const normalized = normalizeConfiguredServiceMetadata({
1717
- files: Array.isArray(entry.files) ? entry.files : []
1718
- });
1719
- entries[key] = normalized;
1720
- }
1721
- return entries;
1722
- }
1723
- async function writeCredentialsDocument(fs3, filePath, document) {
1724
- await fs3.mkdir(path3.dirname(filePath), { recursive: true });
1725
- const payload = {};
1726
- if (document.apiKey) {
1727
- payload.apiKey = document.apiKey;
1728
- }
1729
- if (document.configured_services) {
1730
- payload.configured_services = document.configured_services;
1731
- }
1732
- await fs3.writeFile(filePath, `${JSON.stringify(payload, null, 2)}
1733
- `, {
1734
- encoding: "utf8"
1735
- });
1736
- }
1737
- async function recoverInvalidCredentials(fs3, filePath, content) {
1738
- const backupPath = createInvalidBackupPath(filePath);
1739
- await fs3.writeFile(backupPath, content, { encoding: "utf8" });
1740
- await fs3.writeFile(filePath, EMPTY_DOCUMENT, { encoding: "utf8" });
1741
- }
1742
- function createInvalidBackupPath(filePath) {
1743
- const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
1744
- const dir = path3.dirname(filePath);
1745
- const base = path3.basename(filePath);
1746
- return path3.join(dir, `${base}.invalid-${timestamp}.json`);
1747
- }
1748
- function isRecord(value) {
1749
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
1750
- }
1751
- var EMPTY_DOCUMENT;
1752
- var init_credentials2 = __esm({
1753
- "src/services/credentials.ts"() {
1754
- "use strict";
1755
- init_src();
1756
- EMPTY_DOCUMENT = `${JSON.stringify({}, null, 2)}
1757
- `;
1758
- }
1759
- });
1760
-
1761
2035
  // src/cli/isolated-env.ts
1762
2036
  import path4 from "node:path";
1763
- async function resolveIsolatedEnvDetails(env, isolated, providerName, fs3) {
2037
+ async function resolveIsolatedEnvDetails(env, isolated, providerName, readApiKey) {
1764
2038
  if (!providerName) {
1765
2039
  throw new Error("resolveIsolatedEnvDetails requires providerName.");
1766
2040
  }
@@ -1773,7 +2047,7 @@ async function resolveIsolatedEnvDetails(env, isolated, providerName, fs3) {
1773
2047
  }
1774
2048
  return {
1775
2049
  agentBinary: isolated.agentBinary,
1776
- env: await resolveIsolatedEnvVars(env, baseDir, isolated.env, fs3),
2050
+ env: await resolveIsolatedEnvVars(env, baseDir, isolated.env, readApiKey),
1777
2051
  configProbePath: isolated.configProbe ? resolveIsolatedEnvPath(env, baseDir, isolated.configProbe) : void 0
1778
2052
  };
1779
2053
  }
@@ -1802,14 +2076,14 @@ function resolveIsolatedTargetDirectory(input) {
1802
2076
  function resolveIsolatedBaseDir(env, providerName) {
1803
2077
  return env.resolveHomePath(".poe-code", providerName);
1804
2078
  }
1805
- async function resolveIsolatedEnvVars(env, baseDir, vars, fs3) {
2079
+ async function resolveIsolatedEnvVars(env, baseDir, vars, readApiKey) {
1806
2080
  const out = {};
1807
2081
  for (const [key, value] of Object.entries(vars)) {
1808
- out[key] = await resolveIsolatedEnvValue(env, baseDir, value, fs3);
2082
+ out[key] = await resolveIsolatedEnvValue(env, baseDir, value, readApiKey);
1809
2083
  }
1810
2084
  return out;
1811
2085
  }
1812
- async function resolveIsolatedEnvValue(env, baseDir, value, fs3) {
2086
+ async function resolveIsolatedEnvValue(env, baseDir, value, readApiKey) {
1813
2087
  if (typeof value === "string") {
1814
2088
  return expandHomeShortcut(env, value);
1815
2089
  }
@@ -1827,12 +2101,12 @@ async function resolveIsolatedEnvValue(env, baseDir, value, fs3) {
1827
2101
  if (typeof resolved === "string" && resolved.trim().length > 0) {
1828
2102
  return resolved;
1829
2103
  }
1830
- if (!fs3) {
2104
+ if (!readApiKey) {
1831
2105
  throw new Error(
1832
2106
  'Missing Poe API key for isolated wrapper. Set "POE_API_KEY" or run "poe-code login".'
1833
2107
  );
1834
2108
  }
1835
- return await resolvePoeApiKeyFromCredentials({ fs: fs3, env });
2109
+ return await resolvePoeApiKeyFromAuthStore(readApiKey);
1836
2110
  }
1837
2111
  if (isPoeBaseUrlReference(value)) {
1838
2112
  return env.poeBaseUrl;
@@ -1859,8 +2133,8 @@ function isPoeApiKeyReference(value) {
1859
2133
  function isPoeBaseUrlReference(value) {
1860
2134
  return typeof value === "object" && value.kind === "poeBaseUrl";
1861
2135
  }
1862
- async function resolvePoeApiKeyFromCredentials(input) {
1863
- const stored = await loadCredentials({ fs: input.fs, filePath: input.env.credentialsPath }) ?? void 0;
2136
+ async function resolvePoeApiKeyFromAuthStore(readApiKey) {
2137
+ const stored = await readApiKey();
1864
2138
  if (typeof stored !== "string" || stored.trim().length === 0) {
1865
2139
  throw new Error(
1866
2140
  'Missing Poe API key for isolated wrapper. Set "POE_API_KEY" or run "poe-code login".'
@@ -1903,11 +2177,11 @@ async function applyIsolatedEnvRepairs(input) {
1903
2177
  }
1904
2178
  }
1905
2179
  }
1906
- async function resolveCliSettings(cliSettings, env, fs3) {
2180
+ async function resolveCliSettings(cliSettings, env, readApiKey) {
1907
2181
  const result = { ...cliSettings.values };
1908
2182
  if (cliSettings.resolved) {
1909
2183
  for (const [key, value] of Object.entries(cliSettings.resolved)) {
1910
- result[key] = await resolveCliSettingValue(value, env, fs3);
2184
+ result[key] = await resolveCliSettingValue(value, env, readApiKey);
1911
2185
  }
1912
2186
  }
1913
2187
  if (cliSettings.env) {
@@ -1916,21 +2190,21 @@ async function resolveCliSettings(cliSettings, env, fs3) {
1916
2190
  if (typeof value === "string") {
1917
2191
  resolvedEnv[key] = value;
1918
2192
  } else {
1919
- resolvedEnv[key] = await resolveCliSettingValue(value, env, fs3);
2193
+ resolvedEnv[key] = await resolveCliSettingValue(value, env, readApiKey);
1920
2194
  }
1921
2195
  }
1922
2196
  result.env = resolvedEnv;
1923
2197
  }
1924
2198
  return result;
1925
2199
  }
1926
- async function resolveCliSettingValue(value, env, fs3) {
2200
+ async function resolveCliSettingValue(value, env, readApiKey) {
1927
2201
  if (isPoeApiKeyReference(value)) {
1928
2202
  const resolved = env.getVariable("POE_API_KEY");
1929
2203
  if (typeof resolved === "string" && resolved.trim().length > 0) {
1930
2204
  return resolved;
1931
2205
  }
1932
- if (fs3) {
1933
- return await resolvePoeApiKeyFromCredentials({ fs: fs3, env });
2206
+ if (readApiKey) {
2207
+ return await resolvePoeApiKeyFromAuthStore(readApiKey);
1934
2208
  }
1935
2209
  throw new Error(
1936
2210
  'Missing Poe API key for CLI settings. Set "POE_API_KEY" or run "poe-code login".'
@@ -1971,17 +2245,16 @@ function expandHomeShortcut(env, input) {
1971
2245
  var init_isolated_env = __esm({
1972
2246
  "src/cli/isolated-env.ts"() {
1973
2247
  "use strict";
1974
- init_src();
1975
- init_credentials2();
2248
+ init_src2();
1976
2249
  }
1977
2250
  });
1978
2251
 
1979
2252
  // packages/agent-spawn/src/run-command.ts
1980
- import { spawn } from "node:child_process";
2253
+ import { spawn as spawn2 } from "node:child_process";
1981
2254
  function runCommand(command, args, options) {
1982
2255
  return new Promise((resolve) => {
1983
2256
  const hasStdin = options?.stdin != null;
1984
- const child = spawn(command, args, {
2257
+ const child = spawn2(command, args, {
1985
2258
  stdio: [hasStdin ? "pipe" : "ignore", "pipe", "pipe"],
1986
2259
  cwd: options?.cwd,
1987
2260
  env: options?.env ? {
@@ -2184,7 +2457,7 @@ var init_registry = __esm({
2184
2457
  });
2185
2458
 
2186
2459
  // packages/agent-defs/src/index.ts
2187
- var init_src2 = __esm({
2460
+ var init_src3 = __esm({
2188
2461
  "packages/agent-defs/src/index.ts"() {
2189
2462
  "use strict";
2190
2463
  init_agents();
@@ -2409,7 +2682,7 @@ var allSpawnConfigs, lookup2;
2409
2682
  var init_configs = __esm({
2410
2683
  "packages/agent-spawn/src/configs/index.ts"() {
2411
2684
  "use strict";
2412
- init_src2();
2685
+ init_src3();
2413
2686
  init_claude_code2();
2414
2687
  init_codex2();
2415
2688
  init_opencode2();
@@ -2444,7 +2717,7 @@ function resolveConfig(agentId) {
2444
2717
  var init_resolve_config = __esm({
2445
2718
  "packages/agent-spawn/src/configs/resolve-config.ts"() {
2446
2719
  "use strict";
2447
- init_src2();
2720
+ init_src3();
2448
2721
  init_configs();
2449
2722
  }
2450
2723
  });
@@ -2527,7 +2800,7 @@ function buildCliArgs(config2, options, stdinMode) {
2527
2800
  }
2528
2801
  return args;
2529
2802
  }
2530
- async function spawn2(agentId, options, context) {
2803
+ async function spawn3(agentId, options, context) {
2531
2804
  const { agentId: resolvedId, binaryName, spawnConfig } = resolveCliConfig(agentId);
2532
2805
  const stdinMode = options.useStdin && spawnConfig.stdinMode ? spawnConfig.stdinMode : void 0;
2533
2806
  const spawnArgs = buildCliArgs(spawnConfig, options, stdinMode);
@@ -3340,7 +3613,7 @@ var init_static = __esm({
3340
3613
  });
3341
3614
 
3342
3615
  // packages/design-system/src/index.ts
3343
- var init_src3 = __esm({
3616
+ var init_src4 = __esm({
3344
3617
  "packages/design-system/src/index.ts"() {
3345
3618
  "use strict";
3346
3619
  init_tokens();
@@ -3433,7 +3706,7 @@ async function renderAcpStream(events) {
3433
3706
  var init_renderer = __esm({
3434
3707
  "packages/agent-spawn/src/acp/renderer.ts"() {
3435
3708
  "use strict";
3436
- init_src3();
3709
+ init_src4();
3437
3710
  }
3438
3711
  });
3439
3712
 
@@ -3443,13 +3716,13 @@ function truncate2(text4, maxLength) {
3443
3716
  if (maxLength <= 3) return text4.slice(0, maxLength);
3444
3717
  return `${text4.slice(0, maxLength - 3)}...`;
3445
3718
  }
3446
- function isNonEmptyString(value) {
3719
+ function isNonEmptyString2(value) {
3447
3720
  return typeof value === "string" && value.length > 0;
3448
3721
  }
3449
3722
  function extractThreadId(value) {
3450
3723
  if (!value || typeof value !== "object") return;
3451
3724
  const obj = value;
3452
- const maybeThreadId = isNonEmptyString(obj.thread_id) && obj.thread_id || isNonEmptyString(obj.threadId) && obj.threadId || isNonEmptyString(obj.threadID) && obj.threadID || isNonEmptyString(obj.session_id) && obj.session_id || isNonEmptyString(obj.sessionId) && obj.sessionId || isNonEmptyString(obj.sessionID) && obj.sessionID;
3725
+ const maybeThreadId = isNonEmptyString2(obj.thread_id) && obj.thread_id || isNonEmptyString2(obj.threadId) && obj.threadId || isNonEmptyString2(obj.threadID) && obj.threadID || isNonEmptyString2(obj.session_id) && obj.session_id || isNonEmptyString2(obj.sessionId) && obj.sessionId || isNonEmptyString2(obj.sessionID) && obj.sessionID;
3453
3726
  return maybeThreadId || void 0;
3454
3727
  }
3455
3728
  var init_utils = __esm({
@@ -3495,7 +3768,7 @@ async function* adaptClaude(lines) {
3495
3768
  continue;
3496
3769
  }
3497
3770
  const eventType = event.type;
3498
- if (!isNonEmptyString(eventType)) continue;
3771
+ if (!isNonEmptyString2(eventType)) continue;
3499
3772
  if (!emittedSessionStart) {
3500
3773
  const threadId = extractThreadId(event);
3501
3774
  emittedSessionStart = true;
@@ -3518,16 +3791,16 @@ async function* adaptClaude(lines) {
3518
3791
  const item = block;
3519
3792
  if (!item || typeof item !== "object") continue;
3520
3793
  const blockType = item.type;
3521
- if (!isNonEmptyString(blockType)) continue;
3794
+ if (!isNonEmptyString2(blockType)) continue;
3522
3795
  if (eventType === "assistant") {
3523
- if (blockType === "text" && isNonEmptyString(item.text)) {
3796
+ if (blockType === "text" && isNonEmptyString2(item.text)) {
3524
3797
  yield {
3525
3798
  event: "agent_message",
3526
3799
  text: item.text
3527
3800
  };
3528
3801
  continue;
3529
3802
  }
3530
- if (blockType === "tool_use" && isNonEmptyString(item.id) && isNonEmptyString(item.name)) {
3803
+ if (blockType === "tool_use" && isNonEmptyString2(item.id) && isNonEmptyString2(item.name)) {
3531
3804
  const kind = TOOL_KIND_MAP[item.name] ?? "other";
3532
3805
  toolKindsById.set(item.id, kind);
3533
3806
  yield {
@@ -3541,25 +3814,25 @@ async function* adaptClaude(lines) {
3541
3814
  continue;
3542
3815
  }
3543
3816
  if (eventType === "user") {
3544
- if (!isNonEmptyString(item.tool_use_id)) continue;
3817
+ if (!isNonEmptyString2(item.tool_use_id)) continue;
3545
3818
  if (blockType !== "tool_result") continue;
3546
3819
  const kind = toolKindsById.get(item.tool_use_id);
3547
3820
  toolKindsById.delete(item.tool_use_id);
3548
- let path20;
3821
+ let path21;
3549
3822
  if (typeof item.content === "string") {
3550
- path20 = item.content;
3823
+ path21 = item.content;
3551
3824
  } else {
3552
3825
  try {
3553
- path20 = JSON.stringify(item.content);
3826
+ path21 = JSON.stringify(item.content);
3554
3827
  } catch {
3555
- path20 = String(item.content);
3828
+ path21 = String(item.content);
3556
3829
  }
3557
3830
  }
3558
3831
  yield {
3559
3832
  event: "tool_complete",
3560
3833
  id: item.tool_use_id,
3561
3834
  kind,
3562
- path: path20
3835
+ path: path21
3563
3836
  };
3564
3837
  }
3565
3838
  }
@@ -3613,7 +3886,7 @@ async function* adaptCodex(lines) {
3613
3886
  continue;
3614
3887
  }
3615
3888
  const eventType = event.type;
3616
- if (!isNonEmptyString(eventType)) continue;
3889
+ if (!isNonEmptyString2(eventType)) continue;
3617
3890
  if (eventType === "thread.started") {
3618
3891
  const maybeThreadId = extractThreadId(event);
3619
3892
  yield { event: "session_start", threadId: maybeThreadId };
@@ -3637,23 +3910,23 @@ async function* adaptCodex(lines) {
3637
3910
  const item = event.item ?? null;
3638
3911
  if (!item || typeof item !== "object") continue;
3639
3912
  const itemType = item.type;
3640
- if (!isNonEmptyString(itemType)) continue;
3913
+ if (!isNonEmptyString2(itemType)) continue;
3641
3914
  if (eventType === "item.started") {
3642
- if (!isNonEmptyString(item.id)) continue;
3915
+ if (!isNonEmptyString2(item.id)) continue;
3643
3916
  let kind;
3644
3917
  let title;
3645
3918
  if (itemType === "command_execution") {
3646
3919
  kind = "exec";
3647
- title = truncate2(isNonEmptyString(item.command) ? item.command : "", 80);
3920
+ title = truncate2(isNonEmptyString2(item.command) ? item.command : "", 80);
3648
3921
  } else if (itemType === "file_edit") {
3649
3922
  kind = "edit";
3650
- title = isNonEmptyString(item.path) ? item.path : "";
3923
+ title = isNonEmptyString2(item.path) ? item.path : "";
3651
3924
  } else if (itemType === "thinking") {
3652
3925
  kind = "think";
3653
3926
  title = "thinking...";
3654
3927
  } else if (itemType === "mcp_tool_call") {
3655
- const server = isNonEmptyString(item.server) ? item.server : "unknown";
3656
- const tool = isNonEmptyString(item.tool) ? item.tool : "unknown";
3928
+ const server = isNonEmptyString2(item.server) ? item.server : "unknown";
3929
+ const tool = isNonEmptyString2(item.tool) ? item.tool : "unknown";
3657
3930
  kind = "other";
3658
3931
  title = `${server}.${tool}`;
3659
3932
  }
@@ -3666,25 +3939,25 @@ async function* adaptCodex(lines) {
3666
3939
  }
3667
3940
  if (eventType === "item.completed") {
3668
3941
  if (itemType === "agent_message") {
3669
- if (!isNonEmptyString(item.text)) continue;
3942
+ if (!isNonEmptyString2(item.text)) continue;
3670
3943
  yield { event: "agent_message", text: item.text };
3671
3944
  continue;
3672
3945
  }
3673
3946
  if (itemType === "reasoning") {
3674
- const text4 = isNonEmptyString(item.text) ? item.text : isNonEmptyString(item.content) ? item.content : isNonEmptyString(item.summary) ? item.summary : void 0;
3947
+ const text4 = isNonEmptyString2(item.text) ? item.text : isNonEmptyString2(item.content) ? item.content : isNonEmptyString2(item.summary) ? item.summary : void 0;
3675
3948
  if (!text4) continue;
3676
3949
  yield { event: "reasoning", text: text4 };
3677
3950
  continue;
3678
3951
  }
3679
- if (!isNonEmptyString(item.id)) continue;
3952
+ if (!isNonEmptyString2(item.id)) continue;
3680
3953
  if (itemType === "command_execution" || itemType === "file_edit" || itemType === "mcp_tool_call") {
3681
3954
  const kindFromStart = toolKindById.get(item.id);
3682
3955
  const kind = kindFromStart ?? (itemType === "command_execution" ? "exec" : itemType === "file_edit" ? "edit" : "other");
3683
- const titleFromEvent = isNonEmptyString(item.path) ? item.path : itemType === "mcp_tool_call" ? `${isNonEmptyString(item.server) ? item.server : "unknown"}.${isNonEmptyString(item.tool) ? item.tool : "unknown"}` : void 0;
3684
- const path20 = titleFromEvent ?? toolTitleById.get(item.id) ?? "";
3956
+ const titleFromEvent = isNonEmptyString2(item.path) ? item.path : itemType === "mcp_tool_call" ? `${isNonEmptyString2(item.server) ? item.server : "unknown"}.${isNonEmptyString2(item.tool) ? item.tool : "unknown"}` : void 0;
3957
+ const path21 = titleFromEvent ?? toolTitleById.get(item.id) ?? "";
3685
3958
  toolTitleById.delete(item.id);
3686
3959
  toolKindById.delete(item.id);
3687
- yield { event: "tool_complete", id: item.id, kind, path: path20 };
3960
+ yield { event: "tool_complete", id: item.id, kind, path: path21 };
3688
3961
  }
3689
3962
  }
3690
3963
  }
@@ -3723,9 +3996,9 @@ async function* adaptKimi(lines) {
3723
3996
  }
3724
3997
  }
3725
3998
  const role = event.role;
3726
- if (!isNonEmptyString(role) || role !== "assistant") continue;
3999
+ if (!isNonEmptyString2(role) || role !== "assistant") continue;
3727
4000
  const content = event.content;
3728
- if (!isNonEmptyString(content)) continue;
4001
+ if (!isNonEmptyString2(content)) continue;
3729
4002
  yield { event: "agent_message", text: content };
3730
4003
  }
3731
4004
  }
@@ -3754,7 +4027,7 @@ async function* adaptNative(lines) {
3754
4027
  continue;
3755
4028
  }
3756
4029
  const maybeEventType = event?.event;
3757
- if (!isNonEmptyString(maybeEventType)) {
4030
+ if (!isNonEmptyString2(maybeEventType)) {
3758
4031
  yield {
3759
4032
  event: "error",
3760
4033
  message: `[adaptNative] Line missing string "event" field: ${truncate2(line, 200)}`
@@ -3813,23 +4086,23 @@ async function* adaptOpenCode(lines) {
3813
4086
  }
3814
4087
  if (!event || typeof event !== "object") continue;
3815
4088
  const sessionID = extractThreadId(event);
3816
- if (!emittedSessionStart && isNonEmptyString(sessionID)) {
4089
+ if (!emittedSessionStart && isNonEmptyString2(sessionID)) {
3817
4090
  emittedSessionStart = true;
3818
4091
  yield { event: "session_start", threadId: sessionID };
3819
4092
  }
3820
4093
  const eventType = event.type;
3821
- if (!isNonEmptyString(eventType)) continue;
4094
+ if (!isNonEmptyString2(eventType)) continue;
3822
4095
  if (eventType === "text") {
3823
4096
  const part = event.part ?? null;
3824
4097
  if (!part || typeof part !== "object") continue;
3825
- if (!isNonEmptyString(part.text)) continue;
4098
+ if (!isNonEmptyString2(part.text)) continue;
3826
4099
  yield { event: "agent_message", text: part.text };
3827
4100
  continue;
3828
4101
  }
3829
4102
  if (eventType === "tool_use") {
3830
4103
  const part = event.part ?? null;
3831
4104
  if (!part || typeof part !== "object") continue;
3832
- if (!isNonEmptyString(part.callID) || !isNonEmptyString(part.tool)) continue;
4105
+ if (!isNonEmptyString2(part.callID) || !isNonEmptyString2(part.tool)) continue;
3833
4106
  const state = part.state ?? null;
3834
4107
  if (!state || typeof state !== "object") continue;
3835
4108
  const kind = guessToolKind(part.tool);
@@ -3841,7 +4114,7 @@ async function* adaptOpenCode(lines) {
3841
4114
  const maybeInput = state.input;
3842
4115
  if (kind === "exec" && maybeInput && typeof maybeInput === "object") {
3843
4116
  const command = maybeInput.command;
3844
- if (isNonEmptyString(command)) {
4117
+ if (isNonEmptyString2(command)) {
3845
4118
  title = truncate2(command, 80);
3846
4119
  }
3847
4120
  }
@@ -4045,7 +4318,7 @@ var init_spawn2 = __esm({
4045
4318
  });
4046
4319
 
4047
4320
  // packages/agent-spawn/src/index.ts
4048
- var init_src4 = __esm({
4321
+ var init_src5 = __esm({
4049
4322
  "packages/agent-spawn/src/index.ts"() {
4050
4323
  "use strict";
4051
4324
  init_run_command();
@@ -4225,8 +4498,8 @@ var init_shared = __esm({
4225
4498
  "use strict";
4226
4499
  init_context();
4227
4500
  init_isolated_env();
4228
- init_src4();
4229
- init_src2();
4501
+ init_src5();
4502
+ init_src3();
4230
4503
  }
4231
4504
  });
4232
4505
 
@@ -4347,7 +4620,7 @@ import path7 from "node:path";
4347
4620
  function createCliEnvironment(init) {
4348
4621
  const platform = init.platform ?? process.platform;
4349
4622
  const variables = init.variables ?? process.env;
4350
- const credentialsPath = resolveCredentialsPath(init.homeDir);
4623
+ const configPath = resolveConfigPath(init.homeDir);
4351
4624
  const logDir = resolveLogDir(init.homeDir);
4352
4625
  const { poeApiBaseUrl, poeBaseUrl } = resolvePoeBaseUrls(variables);
4353
4626
  const resolveHomePath = (...segments) => path7.join(init.homeDir, ...segments);
@@ -4356,7 +4629,7 @@ function createCliEnvironment(init) {
4356
4629
  cwd: init.cwd,
4357
4630
  homeDir: init.homeDir,
4358
4631
  platform,
4359
- credentialsPath,
4632
+ configPath,
4360
4633
  logDir,
4361
4634
  poeApiBaseUrl,
4362
4635
  poeBaseUrl,
@@ -4365,8 +4638,8 @@ function createCliEnvironment(init) {
4365
4638
  getVariable
4366
4639
  };
4367
4640
  }
4368
- function resolveCredentialsPath(homeDir) {
4369
- return path7.join(homeDir, ".poe-code", "credentials.json");
4641
+ function resolveConfigPath(homeDir) {
4642
+ return path7.join(homeDir, ".poe-code", "config.json");
4370
4643
  }
4371
4644
  function resolveLogDir(homeDir) {
4372
4645
  return path7.join(homeDir, ".poe-code", "logs");
@@ -4537,7 +4810,7 @@ function createServiceRegistry() {
4537
4810
  var init_service_registry = __esm({
4538
4811
  "src/cli/service-registry.ts"() {
4539
4812
  "use strict";
4540
- init_src2();
4813
+ init_src3();
4541
4814
  }
4542
4815
  });
4543
4816
 
@@ -4805,7 +5078,7 @@ function isSilentError(error2) {
4805
5078
  }
4806
5079
  return error2.name === "SilentError" || error2.name === "OperationCancelledError";
4807
5080
  }
4808
- var CliError, SilentError, ApiError, ValidationError, AuthenticationError, OperationCancelledError;
5081
+ var CliError, SilentError, ApiError, ValidationError, OperationCancelledError;
4809
5082
  var init_errors = __esm({
4810
5083
  "src/cli/errors.ts"() {
4811
5084
  "use strict";
@@ -4845,11 +5118,6 @@ var init_errors = __esm({
4845
5118
  super(message, context, { isUserError: true });
4846
5119
  }
4847
5120
  };
4848
- AuthenticationError = class extends CliError {
4849
- constructor(message, context) {
4850
- super(message, context, { isUserError: true });
4851
- }
4852
- };
4853
5121
  OperationCancelledError = class extends SilentError {
4854
5122
  constructor(message = "Operation cancelled.") {
4855
5123
  super(message, { isUserError: true });
@@ -5058,7 +5326,7 @@ function createLoggerFactory(emitter, theme) {
5058
5326
  var init_logger2 = __esm({
5059
5327
  "src/cli/logger.ts"() {
5060
5328
  "use strict";
5061
- init_src3();
5329
+ init_src4();
5062
5330
  init_errors();
5063
5331
  }
5064
5332
  });
@@ -5446,7 +5714,7 @@ async function ensureIsolatedConfigForService(input) {
5446
5714
  container.env,
5447
5715
  isolated,
5448
5716
  adapter.name,
5449
- container.fs
5717
+ container.readApiKey
5450
5718
  );
5451
5719
  const hasConfig = await isolatedConfigExists(
5452
5720
  container.fs,
@@ -5521,7 +5789,7 @@ function createPoeCodeCommandRunner(input) {
5521
5789
  container.env,
5522
5790
  adapter.isolatedEnv,
5523
5791
  adapter.name,
5524
- container.fs
5792
+ container.readApiKey
5525
5793
  );
5526
5794
  if (adapter.isolatedEnv.requiresConfig !== false) {
5527
5795
  const hasConfig = await isolatedConfigExists(
@@ -5552,7 +5820,7 @@ function createPoeCodeCommandRunner(input) {
5552
5820
  const resolvedSettings = await resolveCliSettings(
5553
5821
  adapter.isolatedEnv.cliSettings,
5554
5822
  container.env,
5555
- container.fs
5823
+ container.readApiKey
5556
5824
  );
5557
5825
  forwarded = buildArgsWithMergedSettings(forwarded, resolvedSettings);
5558
5826
  }
@@ -5581,11 +5849,11 @@ var init_poe_code_command_runner = __esm({
5581
5849
 
5582
5850
  // src/sdk/container.ts
5583
5851
  import * as fs2 from "node:fs/promises";
5584
- import * as os2 from "node:os";
5852
+ import * as os from "node:os";
5585
5853
  import * as nodeFsSync from "node:fs";
5586
5854
  function createSdkContainer(options) {
5587
5855
  const cwd = options?.cwd ?? process.cwd();
5588
- const homeDir = options?.homeDir ?? os2.homedir();
5856
+ const homeDir = options?.homeDir ?? os.homedir();
5589
5857
  const variables = options?.variables ?? process.env;
5590
5858
  const verbose = options?.verbose ?? false;
5591
5859
  const environment = createCliEnvironment({
@@ -5604,23 +5872,44 @@ function createSdkContainer(options) {
5604
5872
  });
5605
5873
  loggerFactory.setErrorLogger(errorLogger);
5606
5874
  const asyncFs = {
5607
- readFile: ((path20, encoding) => {
5875
+ readFile: ((path21, encoding) => {
5608
5876
  if (encoding) {
5609
- return fs2.readFile(path20, encoding);
5877
+ return fs2.readFile(path21, encoding);
5610
5878
  }
5611
- return fs2.readFile(path20);
5879
+ return fs2.readFile(path21);
5612
5880
  }),
5613
- writeFile: (path20, data, opts) => fs2.writeFile(path20, data, opts),
5614
- mkdir: (path20, opts) => fs2.mkdir(path20, opts).then(() => {
5881
+ writeFile: (path21, data, opts) => fs2.writeFile(path21, data, opts),
5882
+ mkdir: (path21, opts) => fs2.mkdir(path21, opts).then(() => {
5615
5883
  }),
5616
- stat: (path20) => fs2.stat(path20),
5617
- rm: (path20, opts) => fs2.rm(path20, opts),
5618
- unlink: (path20) => fs2.unlink(path20),
5619
- readdir: (path20) => fs2.readdir(path20),
5884
+ stat: (path21) => fs2.stat(path21),
5885
+ rm: (path21, opts) => fs2.rm(path21, opts),
5886
+ unlink: (path21) => fs2.unlink(path21),
5887
+ readdir: (path21) => fs2.readdir(path21),
5620
5888
  copyFile: (src, dest) => fs2.copyFile(src, dest),
5621
- chmod: (path20, mode) => fs2.chmod(path20, mode)
5889
+ chmod: (path21, mode) => fs2.chmod(path21, mode)
5622
5890
  };
5623
5891
  const contextFactory = createCommandContextFactory({ fs: asyncFs });
5892
+ const authFs = {
5893
+ readFile: (filePath, encoding) => fs2.readFile(filePath, encoding),
5894
+ writeFile: (filePath, data, options2) => fs2.writeFile(filePath, data, options2),
5895
+ mkdir: (directoryPath, options2) => fs2.mkdir(directoryPath, options2).then(() => void 0),
5896
+ unlink: (filePath) => fs2.unlink(filePath),
5897
+ chmod: (filePath, mode) => fs2.chmod(filePath, mode)
5898
+ };
5899
+ const { store: authStore } = createAuthStore({
5900
+ env: variables,
5901
+ platform: process.platform,
5902
+ fileStore: {
5903
+ fs: authFs,
5904
+ getHomeDirectory: () => homeDir
5905
+ },
5906
+ legacyCredentials: {
5907
+ fs: authFs,
5908
+ getHomeDirectory: () => homeDir
5909
+ }
5910
+ });
5911
+ const readApiKey = authStore.getApiKey.bind(authStore);
5912
+ const writeApiKey = authStore.setApiKey.bind(authStore);
5624
5913
  const noopPrompts = async () => {
5625
5914
  throw new Error("SDK does not support interactive prompts");
5626
5915
  };
@@ -5629,15 +5918,8 @@ function createSdkContainer(options) {
5629
5918
  prompts: noopPrompts,
5630
5919
  promptLibrary,
5631
5920
  apiKeyStore: {
5632
- read: () => loadCredentials({
5633
- fs: asyncFs,
5634
- filePath: environment.credentialsPath
5635
- }),
5636
- write: (value) => saveCredentials({
5637
- fs: asyncFs,
5638
- filePath: environment.credentialsPath,
5639
- apiKey: value
5640
- })
5921
+ read: readApiKey,
5922
+ write: writeApiKey
5641
5923
  },
5642
5924
  confirm: async () => true
5643
5925
  });
@@ -5684,7 +5966,9 @@ function createSdkContainer(options) {
5684
5966
  platform: process.platform,
5685
5967
  variables
5686
5968
  }
5687
- }
5969
+ },
5970
+ readApiKey,
5971
+ writeApiKey
5688
5972
  };
5689
5973
  return container;
5690
5974
  }
@@ -5698,15 +5982,15 @@ var init_container = __esm({
5698
5982
  init_options();
5699
5983
  init_logger2();
5700
5984
  init_error_logger();
5701
- init_src4();
5985
+ init_src5();
5702
5986
  await init_providers();
5703
5987
  init_poe_code_command_runner();
5704
- init_credentials2();
5988
+ init_src();
5705
5989
  }
5706
5990
  });
5707
5991
 
5708
5992
  // src/sdk/spawn.ts
5709
- function spawn3(service, promptOrOptions, maybeOptions) {
5993
+ function spawn4(service, promptOrOptions, maybeOptions) {
5710
5994
  const options = typeof promptOrOptions === "string" ? { ...maybeOptions, prompt: promptOrOptions } : promptOrOptions;
5711
5995
  const emptyEvents = (async function* () {
5712
5996
  })();
@@ -5769,7 +6053,7 @@ function spawn3(service, promptOrOptions, maybeOptions) {
5769
6053
  }
5770
6054
  if (spawnConfig && spawnConfig.kind === "cli") {
5771
6055
  resolveEventsOnce(emptyEvents);
5772
- return spawn2(service, {
6056
+ return spawn3(service, {
5773
6057
  prompt: options.prompt,
5774
6058
  cwd: options.cwd,
5775
6059
  model: options.model,
@@ -5803,9 +6087,9 @@ var init_spawn3 = __esm({
5803
6087
  init_credentials();
5804
6088
  init_spawn_core();
5805
6089
  await init_container();
5806
- init_src4();
5807
- spawn3.pretty = async function pretty(service, promptOrOptions, maybeOptions) {
5808
- const { events, result } = spawn3(service, promptOrOptions, maybeOptions);
6090
+ init_src5();
6091
+ spawn4.pretty = async function pretty(service, promptOrOptions, maybeOptions) {
6092
+ const { events, result } = spawn4(service, promptOrOptions, maybeOptions);
5809
6093
  await renderAcpStream(events);
5810
6094
  return result;
5811
6095
  };
@@ -5876,13 +6160,13 @@ async function readErrorBody(response) {
5876
6160
  }
5877
6161
  }
5878
6162
  function extractTextContent(data) {
5879
- if (!isRecord2(data)) return void 0;
6163
+ if (!isRecord3(data)) return void 0;
5880
6164
  const choices = data.choices;
5881
6165
  if (!Array.isArray(choices) || choices.length === 0) return void 0;
5882
6166
  const first = choices[0];
5883
- if (!isRecord2(first)) return void 0;
6167
+ if (!isRecord3(first)) return void 0;
5884
6168
  const message = first.message;
5885
- if (!isRecord2(message)) return void 0;
6169
+ if (!isRecord3(message)) return void 0;
5886
6170
  return typeof message.content === "string" ? message.content : void 0;
5887
6171
  }
5888
6172
  function extractMediaFromCompletion(data) {
@@ -5890,14 +6174,14 @@ function extractMediaFromCompletion(data) {
5890
6174
  if (!content) return {};
5891
6175
  try {
5892
6176
  const parsed = JSON.parse(content);
5893
- if (isRecord2(parsed) && typeof parsed.url === "string") {
6177
+ if (isRecord3(parsed) && typeof parsed.url === "string") {
5894
6178
  return {
5895
6179
  url: parsed.url,
5896
6180
  mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0,
5897
6181
  data: typeof parsed.data === "string" ? parsed.data : void 0
5898
6182
  };
5899
6183
  }
5900
- if (isRecord2(parsed) && typeof parsed.data === "string") {
6184
+ if (isRecord3(parsed) && typeof parsed.data === "string") {
5901
6185
  return {
5902
6186
  data: parsed.data,
5903
6187
  mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0
@@ -5931,7 +6215,7 @@ function isValidUrl(value) {
5931
6215
  return false;
5932
6216
  }
5933
6217
  }
5934
- function isRecord2(value) {
6218
+ function isRecord3(value) {
5935
6219
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
5936
6220
  }
5937
6221
  var init_llm_client = __esm({
@@ -5955,17 +6239,8 @@ async function initializeClient(options) {
5955
6239
  if (globalClient !== null) {
5956
6240
  return;
5957
6241
  }
5958
- const apiKey = await loadCredentials({
5959
- fs: options.fs,
5960
- filePath: options.credentialsPath
5961
- });
5962
- if (!apiKey) {
5963
- throw new AuthenticationError(
5964
- "Poe API key not found. Run 'poe-code login' first."
5965
- );
5966
- }
5967
6242
  const client = createPoeClient({
5968
- apiKey,
6243
+ apiKey: options.apiKey,
5969
6244
  baseUrl: options.baseUrl,
5970
6245
  httpClient: options.httpClient
5971
6246
  });
@@ -5975,8 +6250,6 @@ var globalClient;
5975
6250
  var init_client_instance = __esm({
5976
6251
  "src/services/client-instance.ts"() {
5977
6252
  "use strict";
5978
- init_errors();
5979
- init_credentials2();
5980
6253
  init_llm_client();
5981
6254
  globalClient = null;
5982
6255
  }
@@ -6017,19 +6290,33 @@ function createCliContainer(dependencies) {
6017
6290
  });
6018
6291
  const commandRunner = dependencies.commandRunner ?? runCommand;
6019
6292
  const promptLibrary = createPromptLibrary();
6293
+ const authFs = {
6294
+ readFile: (filePath, encoding) => dependencies.fs.readFile(filePath, encoding),
6295
+ writeFile: (filePath, data, opts) => dependencies.fs.writeFile(filePath, data, opts),
6296
+ mkdir: (directoryPath, opts) => dependencies.fs.mkdir(directoryPath, opts).then(() => void 0),
6297
+ unlink: (filePath) => dependencies.fs.unlink(filePath),
6298
+ chmod: (filePath, mode) => dependencies.fs.chmod ? dependencies.fs.chmod(filePath, mode) : Promise.resolve()
6299
+ };
6300
+ const { store: authStore } = createAuthStore({
6301
+ env: dependencies.env.variables,
6302
+ platform: dependencies.env.platform,
6303
+ fileStore: {
6304
+ fs: authFs,
6305
+ getHomeDirectory: () => dependencies.env.homeDir
6306
+ },
6307
+ legacyCredentials: {
6308
+ fs: authFs,
6309
+ getHomeDirectory: () => dependencies.env.homeDir
6310
+ }
6311
+ });
6312
+ const readApiKey = authStore.getApiKey.bind(authStore);
6313
+ const writeApiKey = authStore.setApiKey.bind(authStore);
6020
6314
  const options = createOptionResolvers({
6021
6315
  prompts: dependencies.prompts,
6022
6316
  promptLibrary,
6023
6317
  apiKeyStore: {
6024
- read: () => loadCredentials({
6025
- fs: dependencies.fs,
6026
- filePath: environment.credentialsPath
6027
- }),
6028
- write: (value) => saveCredentials({
6029
- fs: dependencies.fs,
6030
- filePath: environment.credentialsPath,
6031
- apiKey: value
6032
- })
6318
+ read: readApiKey,
6319
+ write: writeApiKey
6033
6320
  },
6034
6321
  confirm: async (message) => {
6035
6322
  const result = await confirm2({ message });
@@ -6065,14 +6352,16 @@ function createCliContainer(dependencies) {
6065
6352
  httpClient,
6066
6353
  commandRunner: wrappedRunner,
6067
6354
  providers,
6068
- dependencies
6355
+ dependencies,
6356
+ readApiKey,
6357
+ writeApiKey
6069
6358
  };
6070
6359
  return container;
6071
6360
  }
6072
6361
  var init_container2 = __esm({
6073
6362
  async "src/cli/container.ts"() {
6074
6363
  "use strict";
6075
- init_credentials2();
6364
+ init_src();
6076
6365
  init_environment();
6077
6366
  init_service_registry();
6078
6367
  init_context();
@@ -6080,14 +6369,176 @@ var init_container2 = __esm({
6080
6369
  init_options();
6081
6370
  init_logger2();
6082
6371
  init_error_logger();
6372
+ init_src5();
6083
6373
  init_src4();
6084
- init_src3();
6085
6374
  await init_providers();
6086
6375
  init_poe_code_command_runner();
6087
6376
  init_errors();
6088
6377
  }
6089
6378
  });
6090
6379
 
6380
+ // src/services/config.ts
6381
+ import path10 from "node:path";
6382
+ async function deleteConfig(options) {
6383
+ const { fs: fs3, filePath } = options;
6384
+ try {
6385
+ await fs3.unlink(filePath);
6386
+ return true;
6387
+ } catch (error2) {
6388
+ if (isNotFound(error2)) {
6389
+ return false;
6390
+ }
6391
+ throw error2;
6392
+ }
6393
+ }
6394
+ async function loadConfiguredServices(options) {
6395
+ const { fs: fs3, filePath } = options;
6396
+ const document = await readConfigDocument(fs3, filePath);
6397
+ return { ...document.configured_services ?? {} };
6398
+ }
6399
+ async function saveConfiguredService(options) {
6400
+ const { fs: fs3, filePath, service, metadata } = options;
6401
+ const document = await readConfigDocument(fs3, filePath);
6402
+ const normalized = normalizeConfiguredServiceMetadata(metadata);
6403
+ document.configured_services = {
6404
+ ...document.configured_services ?? {},
6405
+ [service]: normalized
6406
+ };
6407
+ await writeConfigDocument(fs3, filePath, document);
6408
+ }
6409
+ async function unconfigureService(options) {
6410
+ const { fs: fs3, filePath, service } = options;
6411
+ const document = await readConfigDocument(fs3, filePath);
6412
+ const services = document.configured_services;
6413
+ if (!services || !(service in services)) {
6414
+ return false;
6415
+ }
6416
+ delete services[service];
6417
+ if (Object.keys(services).length === 0) {
6418
+ delete document.configured_services;
6419
+ }
6420
+ await writeConfigDocument(fs3, filePath, document);
6421
+ return true;
6422
+ }
6423
+ function normalizeConfiguredServiceMetadata(metadata) {
6424
+ const seen = /* @__PURE__ */ new Set();
6425
+ const files = [];
6426
+ for (const entry of metadata.files ?? []) {
6427
+ if (typeof entry !== "string" || entry.length === 0) {
6428
+ continue;
6429
+ }
6430
+ if (!seen.has(entry)) {
6431
+ files.push(entry);
6432
+ seen.add(entry);
6433
+ }
6434
+ }
6435
+ return {
6436
+ files
6437
+ };
6438
+ }
6439
+ async function readConfigDocument(fs3, filePath) {
6440
+ try {
6441
+ const raw = await fs3.readFile(filePath, "utf8");
6442
+ return await parseConfigDocument(fs3, filePath, raw);
6443
+ } catch (error2) {
6444
+ if (isNotFound(error2)) {
6445
+ return migrateLegacyCredentialsFile(fs3, filePath);
6446
+ }
6447
+ throw error2;
6448
+ }
6449
+ }
6450
+ async function migrateLegacyCredentialsFile(fs3, configPath) {
6451
+ const legacyPath = path10.join(path10.dirname(configPath), "credentials.json");
6452
+ try {
6453
+ const raw = await fs3.readFile(legacyPath, "utf8");
6454
+ const document = await parseConfigDocument(fs3, legacyPath, raw);
6455
+ await writeConfigDocument(fs3, configPath, document);
6456
+ await fs3.unlink(legacyPath);
6457
+ return document;
6458
+ } catch {
6459
+ return {};
6460
+ }
6461
+ }
6462
+ async function parseConfigDocument(fs3, filePath, raw) {
6463
+ try {
6464
+ const parsed = JSON.parse(raw);
6465
+ return normalizeConfigDocument(parsed);
6466
+ } catch (error2) {
6467
+ if (error2 instanceof SyntaxError) {
6468
+ await recoverInvalidConfig(fs3, filePath, raw);
6469
+ return {};
6470
+ }
6471
+ throw error2;
6472
+ }
6473
+ }
6474
+ function normalizeConfigDocument(value) {
6475
+ if (!isRecord4(value)) {
6476
+ return {};
6477
+ }
6478
+ const document = {};
6479
+ if (typeof value.apiKey === "string" && value.apiKey.length > 0) {
6480
+ document.apiKey = value.apiKey;
6481
+ }
6482
+ const services = normalizeConfiguredServices(value.configured_services);
6483
+ if (Object.keys(services).length > 0) {
6484
+ document.configured_services = services;
6485
+ }
6486
+ return document;
6487
+ }
6488
+ function normalizeConfiguredServices(value) {
6489
+ if (!isRecord4(value)) {
6490
+ return {};
6491
+ }
6492
+ const entries = {};
6493
+ for (const [key, entry] of Object.entries(value)) {
6494
+ if (!isRecord4(entry)) {
6495
+ continue;
6496
+ }
6497
+ const normalized = normalizeConfiguredServiceMetadata({
6498
+ files: Array.isArray(entry.files) ? entry.files : []
6499
+ });
6500
+ entries[key] = normalized;
6501
+ }
6502
+ return entries;
6503
+ }
6504
+ async function writeConfigDocument(fs3, filePath, document) {
6505
+ await fs3.mkdir(path10.dirname(filePath), { recursive: true });
6506
+ const payload = {};
6507
+ if (document.apiKey) {
6508
+ payload.apiKey = document.apiKey;
6509
+ }
6510
+ if (document.configured_services) {
6511
+ payload.configured_services = document.configured_services;
6512
+ }
6513
+ await fs3.writeFile(filePath, `${JSON.stringify(payload, null, 2)}
6514
+ `, {
6515
+ encoding: "utf8"
6516
+ });
6517
+ }
6518
+ async function recoverInvalidConfig(fs3, filePath, content) {
6519
+ const backupPath = createInvalidBackupPath(filePath);
6520
+ await fs3.writeFile(backupPath, content, { encoding: "utf8" });
6521
+ await fs3.writeFile(filePath, EMPTY_DOCUMENT, { encoding: "utf8" });
6522
+ }
6523
+ function createInvalidBackupPath(filePath) {
6524
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
6525
+ const dir = path10.dirname(filePath);
6526
+ const base = path10.basename(filePath);
6527
+ return path10.join(dir, `${base}.invalid-${timestamp}.json`);
6528
+ }
6529
+ function isRecord4(value) {
6530
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
6531
+ }
6532
+ var EMPTY_DOCUMENT;
6533
+ var init_config = __esm({
6534
+ "src/services/config.ts"() {
6535
+ "use strict";
6536
+ init_src2();
6537
+ EMPTY_DOCUMENT = `${JSON.stringify({}, null, 2)}
6538
+ `;
6539
+ }
6540
+ });
6541
+
6091
6542
  // src/cli/commands/configure.ts
6092
6543
  function registerConfigureCommand(program, container) {
6093
6544
  const serviceNames = container.registry.list().map((service) => service.name);
@@ -6152,7 +6603,7 @@ async function executeConfigure(program, container, service, options) {
6152
6603
  if (!flags.dryRun) {
6153
6604
  await saveConfiguredService({
6154
6605
  fs: container.fs,
6155
- filePath: providerContext.env.credentialsPath,
6606
+ filePath: providerContext.env.configPath,
6156
6607
  service: canonicalService,
6157
6608
  metadata: {
6158
6609
  files: tracker.files()
@@ -6252,7 +6703,7 @@ var init_configure = __esm({
6252
6703
  "use strict";
6253
6704
  init_shared();
6254
6705
  init_errors();
6255
- init_credentials2();
6706
+ init_config();
6256
6707
  init_mutation_events();
6257
6708
  init_configure_payload();
6258
6709
  serviceSelectionPrompt = (action) => `Pick an agent to ${action}:`;
@@ -6260,7 +6711,7 @@ var init_configure = __esm({
6260
6711
  });
6261
6712
 
6262
6713
  // src/cli/commands/spawn.ts
6263
- import path10 from "node:path";
6714
+ import path11 from "node:path";
6264
6715
  function registerSpawnCommand(program, container, options = {}) {
6265
6716
  const spawnServices = container.registry.list().filter((service) => typeof service.spawn === "function" || getSpawnConfig(service.name)).map((service) => service.name);
6266
6717
  const extraServices = options.extraServices ?? [];
@@ -6392,7 +6843,7 @@ function registerSpawnCommand(program, container, options = {}) {
6392
6843
  if (!proceed) {
6393
6844
  return;
6394
6845
  }
6395
- const { events, result } = spawn3(canonicalService, {
6846
+ const { events, result } = spawn4(canonicalService, {
6396
6847
  prompt: spawnOptions.prompt,
6397
6848
  args: spawnOptions.args,
6398
6849
  model: spawnOptions.model,
@@ -6439,7 +6890,7 @@ Resume: ${resumeCommand}`));
6439
6890
  async function confirmUnconfiguredService(container, service, label, flags) {
6440
6891
  const configuredServices = await loadConfiguredServices({
6441
6892
  fs: container.fs,
6442
- filePath: container.env.credentialsPath
6893
+ filePath: container.env.configPath
6443
6894
  });
6444
6895
  if (service in configuredServices) {
6445
6896
  return true;
@@ -6459,10 +6910,10 @@ function resolveSpawnWorkingDirectory2(baseDir, candidate) {
6459
6910
  if (!candidate || candidate.trim().length === 0) {
6460
6911
  return void 0;
6461
6912
  }
6462
- if (path10.isAbsolute(candidate)) {
6913
+ if (path11.isAbsolute(candidate)) {
6463
6914
  return candidate;
6464
6915
  }
6465
- return path10.resolve(baseDir, candidate);
6916
+ return path11.resolve(baseDir, candidate);
6466
6917
  }
6467
6918
  function parseMcpSpawnConfig(input) {
6468
6919
  if (!input) {
@@ -6555,9 +7006,9 @@ function isObjectRecord(value) {
6555
7006
  var init_spawn4 = __esm({
6556
7007
  async "src/cli/commands/spawn.ts"() {
6557
7008
  "use strict";
7009
+ init_src5();
6558
7010
  init_src4();
6559
- init_src3();
6560
- init_credentials2();
7011
+ init_config();
6561
7012
  init_shared();
6562
7013
  init_spawn_core();
6563
7014
  await init_spawn3();
@@ -6566,7 +7017,7 @@ var init_spawn4 = __esm({
6566
7017
  });
6567
7018
 
6568
7019
  // src/sdk/research.ts
6569
- import path11 from "node:path";
7020
+ import path12 from "node:path";
6570
7021
  async function research(container, options) {
6571
7022
  const logger2 = options.logger;
6572
7023
  const source = await resolveSource({
@@ -6576,7 +7027,7 @@ async function research(container, options) {
6576
7027
  });
6577
7028
  const researchPrompt = buildResearchPrompt(options.prompt);
6578
7029
  const mode = options.mode ?? "read";
6579
- const { events, result } = spawn3(options.agent, {
7030
+ const { events, result } = spawn4(options.agent, {
6580
7031
  prompt: researchPrompt,
6581
7032
  args: options.args ?? [],
6582
7033
  model: options.model,
@@ -6601,7 +7052,7 @@ async function research(container, options) {
6601
7052
  markdown: markdownOutput
6602
7053
  });
6603
7054
  outputPath = buildOutputPath(container.env.homeDir, options.prompt);
6604
- await ensureDirectory2(container.fs, path11.dirname(outputPath));
7055
+ await ensureDirectory2(container.fs, path12.dirname(outputPath));
6605
7056
  await container.fs.writeFile(outputPath, document, {
6606
7057
  encoding: "utf8"
6607
7058
  });
@@ -6676,7 +7127,7 @@ function buildResearchDocument(input) {
6676
7127
  }
6677
7128
  function buildClonePath(homeDir, github) {
6678
7129
  const slug = extractRepoSlug(github);
6679
- return path11.join(homeDir, ".poe-code", "repos", slug);
7130
+ return path12.join(homeDir, ".poe-code", "repos", slug);
6680
7131
  }
6681
7132
  function extractRepoSlug(value) {
6682
7133
  const trimmed = value.trim();
@@ -6714,7 +7165,7 @@ function extractRepoSlug(value) {
6714
7165
  function buildOutputPath(homeDir, prompt, now = /* @__PURE__ */ new Date()) {
6715
7166
  const timestamp = formatTimestamp(now);
6716
7167
  const slug = buildSlug(prompt);
6717
- return path11.join(
7168
+ return path12.join(
6718
7169
  homeDir,
6719
7170
  ".poe-code",
6720
7171
  "research",
@@ -6735,7 +7186,7 @@ async function resolveSource(input) {
6735
7186
  if (options.github) {
6736
7187
  const cloneUrl = resolveGithubCloneUrl(options.github);
6737
7188
  const clonePath = buildClonePath(container.env.homeDir, options.github);
6738
- await ensureDirectory2(container.fs, path11.dirname(clonePath));
7189
+ await ensureDirectory2(container.fs, path12.dirname(clonePath));
6739
7190
  const exists = await pathExists2(container.fs, clonePath);
6740
7191
  if (!exists) {
6741
7192
  const cloneResult = await container.commandRunner(
@@ -6833,10 +7284,10 @@ function formatYamlString(value) {
6833
7284
  return JSON.stringify(value);
6834
7285
  }
6835
7286
  function resolvePath2(baseDir, candidate) {
6836
- if (path11.isAbsolute(candidate)) {
7287
+ if (path12.isAbsolute(candidate)) {
6837
7288
  return candidate;
6838
7289
  }
6839
- return path11.resolve(baseDir, candidate);
7290
+ return path12.resolve(baseDir, candidate);
6840
7291
  }
6841
7292
  function teeAcpStream(events) {
6842
7293
  const chunks = [];
@@ -6896,7 +7347,7 @@ async function removePathFallback(fs3, target) {
6896
7347
  if (stats && typeof stats.isDirectory === "function" && stats.isDirectory()) {
6897
7348
  const entries = await fs3.readdir(target);
6898
7349
  for (const entry of entries) {
6899
- await removePathFallback(fs3, path11.join(target, entry));
7350
+ await removePathFallback(fs3, path12.join(target, entry));
6900
7351
  }
6901
7352
  }
6902
7353
  try {
@@ -7000,7 +7451,7 @@ async function resolveResearchAgent(input) {
7000
7451
  if (input.flags.assumeYes) {
7001
7452
  const configured = await loadConfiguredServices({
7002
7453
  fs: input.container.fs,
7003
- filePath: input.container.env.credentialsPath
7454
+ filePath: input.container.env.configPath
7004
7455
  });
7005
7456
  const configuredService = spawnable.find(
7006
7457
  (service) => service.name in configured
@@ -7062,8 +7513,8 @@ async function resolveResearchModel(input) {
7062
7513
  var init_research2 = __esm({
7063
7514
  async "src/cli/commands/research.ts"() {
7064
7515
  "use strict";
7065
- init_src4();
7066
- init_credentials2();
7516
+ init_src5();
7517
+ init_config();
7067
7518
  await init_research();
7068
7519
  init_errors();
7069
7520
  init_shared();
@@ -7071,13 +7522,13 @@ var init_research2 = __esm({
7071
7522
  });
7072
7523
 
7073
7524
  // src/cli/isolated-env-runner.ts
7074
- import { spawn as spawn4 } from "node:child_process";
7525
+ import { spawn as spawn5 } from "node:child_process";
7075
7526
  async function isolatedEnvRunner(input) {
7076
7527
  const details = await resolveIsolatedEnvDetails(
7077
7528
  input.env,
7078
7529
  input.isolated,
7079
7530
  input.providerName,
7080
- input.fs
7531
+ input.readApiKey
7081
7532
  );
7082
7533
  let args = input.argv.slice(2);
7083
7534
  if (input.isolated.requiresConfig !== false) {
@@ -7092,11 +7543,11 @@ async function isolatedEnvRunner(input) {
7092
7543
  const resolvedSettings = await resolveCliSettings(
7093
7544
  input.isolated.cliSettings,
7094
7545
  input.env,
7095
- input.fs
7546
+ input.readApiKey
7096
7547
  );
7097
7548
  args = buildArgsWithMergedSettings(args, resolvedSettings);
7098
7549
  }
7099
- const child = spawn4(details.agentBinary, args, {
7550
+ const child = spawn5(details.agentBinary, args, {
7100
7551
  stdio: "inherit",
7101
7552
  env: {
7102
7553
  ...process.env,
@@ -7129,7 +7580,7 @@ async function configExists(fs3, filePath) {
7129
7580
  var init_isolated_env_runner = __esm({
7130
7581
  "src/cli/isolated-env-runner.ts"() {
7131
7582
  "use strict";
7132
- init_src();
7583
+ init_src2();
7133
7584
  init_isolated_env();
7134
7585
  init_cli_settings_merge();
7135
7586
  }
@@ -7179,6 +7630,7 @@ function registerWrapCommand(program, container) {
7179
7630
  await isolatedEnvRunner({
7180
7631
  env: container.env,
7181
7632
  fs: container.fs,
7633
+ readApiKey: container.readApiKey,
7182
7634
  providerName: adapter.name,
7183
7635
  isolated,
7184
7636
  argv: ["node", "poe-code", ...forwarded]
@@ -7198,46 +7650,66 @@ var init_wrap = __esm({
7198
7650
  // src/cli/commands/login.ts
7199
7651
  function registerLoginCommand(program, container) {
7200
7652
  program.command("login").description("Store a Poe API key for reuse across commands.").option("--api-key <key>", "Poe API key").action(async (options) => {
7201
- const flags = resolveCommandFlags(program);
7202
- const resources = createExecutionResources(
7653
+ await executeLogin(program, container, options);
7654
+ });
7655
+ }
7656
+ async function executeLogin(program, container, options) {
7657
+ const flags = resolveCommandFlags(program);
7658
+ const resources = createExecutionResources(
7659
+ container,
7660
+ flags,
7661
+ "login"
7662
+ );
7663
+ resources.logger.intro("login");
7664
+ try {
7665
+ const input = await resolveApiKeyInput(container, options);
7666
+ const normalized = container.options.normalizeApiKey(input);
7667
+ const configuredServices = await loadConfiguredServices({
7668
+ fs: container.fs,
7669
+ filePath: container.env.configPath
7670
+ });
7671
+ if (!flags.dryRun) {
7672
+ await container.writeApiKey(normalized);
7673
+ }
7674
+ await reconfigureServices({
7675
+ program,
7203
7676
  container,
7204
- flags,
7205
- "login"
7206
- );
7207
- resources.logger.intro("login");
7208
- try {
7209
- const configuredServices = await loadConfiguredServices({
7210
- fs: container.fs,
7211
- filePath: container.env.credentialsPath
7212
- });
7213
- const apiKey = await container.options.resolveApiKey({
7214
- value: options.apiKey,
7215
- envValue: container.env.getVariable("POE_API_KEY"),
7216
- dryRun: flags.dryRun,
7217
- assumeYes: flags.assumeYes,
7218
- allowStored: false
7219
- });
7220
- await reconfigureServices({
7221
- program,
7222
- container,
7223
- apiKey,
7224
- configuredServices
7225
- });
7226
- resources.context.complete({
7227
- success: "Logged in.",
7228
- dry: "Dry run: would save API key."
7677
+ apiKey: normalized,
7678
+ configuredServices
7679
+ });
7680
+ resources.context.complete({
7681
+ success: "Logged in.",
7682
+ dry: "Dry run: would save API key."
7683
+ });
7684
+ resources.context.finalize();
7685
+ } catch (error2) {
7686
+ if (error2 instanceof Error) {
7687
+ resources.logger.logException(error2, "login command", {
7688
+ operation: "login",
7689
+ configPath: container.env.configPath
7229
7690
  });
7230
- resources.context.finalize();
7231
- } catch (error2) {
7232
- if (error2 instanceof Error) {
7233
- resources.logger.logException(error2, "login command", {
7234
- operation: "login",
7235
- credentialsPath: container.env.credentialsPath
7236
- });
7237
- }
7238
- throw error2;
7239
7691
  }
7240
- });
7692
+ throw error2;
7693
+ }
7694
+ }
7695
+ async function resolveApiKeyInput(container, options) {
7696
+ if (options.apiKey) {
7697
+ return options.apiKey;
7698
+ }
7699
+ const envKey = container.env.getVariable("POE_API_KEY");
7700
+ if (envKey && envKey.trim().length > 0) {
7701
+ return envKey;
7702
+ }
7703
+ const descriptor = container.promptLibrary.loginApiKey();
7704
+ const response = await container.prompts(descriptor);
7705
+ const value = response[descriptor.name];
7706
+ if (typeof value !== "string" || value.trim() === "") {
7707
+ throw new ValidationError("POE API key is required.", {
7708
+ operation: "login",
7709
+ field: "apiKey"
7710
+ });
7711
+ }
7712
+ return value;
7241
7713
  }
7242
7714
  async function reconfigureServices(input) {
7243
7715
  const { program, container, apiKey, configuredServices } = input;
@@ -7291,7 +7763,8 @@ var init_login = __esm({
7291
7763
  "src/cli/commands/login.ts"() {
7292
7764
  "use strict";
7293
7765
  init_shared();
7294
- init_credentials2();
7766
+ init_config();
7767
+ init_errors();
7295
7768
  init_mutation_events();
7296
7769
  }
7297
7770
  });
@@ -7371,7 +7844,7 @@ async function executeUnconfigure(program, container, service, options) {
7371
7844
  if (!flags.dryRun) {
7372
7845
  await unconfigureService({
7373
7846
  fs: container.fs,
7374
- filePath: providerContext.env.credentialsPath,
7847
+ filePath: providerContext.env.configPath,
7375
7848
  service: canonicalService
7376
7849
  });
7377
7850
  }
@@ -7416,7 +7889,7 @@ function formatUnconfigureMessages(service, label, unconfigured, _payload) {
7416
7889
  var init_unconfigure = __esm({
7417
7890
  "src/cli/commands/unconfigure.ts"() {
7418
7891
  "use strict";
7419
- init_credentials2();
7892
+ init_config();
7420
7893
  init_mutation_events();
7421
7894
  init_isolated_env();
7422
7895
  init_shared();
@@ -7425,53 +7898,157 @@ var init_unconfigure = __esm({
7425
7898
 
7426
7899
  // src/cli/commands/logout.ts
7427
7900
  function registerLogoutCommand(program, container) {
7428
- program.command("logout").description("Remove all Poe API configuration and stored credentials.").action(async () => {
7429
- const flags = resolveCommandFlags(program);
7430
- const resources = createExecutionResources(
7431
- container,
7432
- flags,
7433
- "logout"
7434
- );
7435
- resources.logger.intro("logout");
7436
- const configuredServices = await loadConfiguredServices({
7437
- fs: container.fs,
7438
- filePath: container.env.credentialsPath
7439
- });
7440
- for (const serviceName of Object.keys(configuredServices)) {
7441
- const adapter = container.registry.get(serviceName);
7442
- if (!adapter) {
7443
- continue;
7444
- }
7445
- await executeUnconfigure(program, container, serviceName, {});
7446
- }
7447
- if (flags.dryRun) {
7448
- resources.context.complete({
7449
- success: "Logged out.",
7450
- dry: `Dry run: would delete credentials at ${container.env.credentialsPath}.`
7451
- });
7452
- resources.context.finalize();
7453
- return;
7901
+ program.command("logout").description("Remove all Poe API configuration.").action(async () => {
7902
+ await executeLogout(program, container);
7903
+ });
7904
+ }
7905
+ async function executeLogout(program, container) {
7906
+ const flags = resolveCommandFlags(program);
7907
+ const resources = createExecutionResources(
7908
+ container,
7909
+ flags,
7910
+ "logout"
7911
+ );
7912
+ resources.logger.intro("logout");
7913
+ const configuredServices = await loadConfiguredServices({
7914
+ fs: container.fs,
7915
+ filePath: container.env.configPath
7916
+ });
7917
+ for (const serviceName of Object.keys(configuredServices)) {
7918
+ const adapter = container.registry.get(serviceName);
7919
+ if (!adapter) {
7920
+ continue;
7454
7921
  }
7455
- const deleted = await deleteCredentials({
7456
- fs: container.fs,
7457
- filePath: container.env.credentialsPath
7458
- });
7922
+ await executeUnconfigure(program, container, serviceName, {});
7923
+ }
7924
+ if (flags.dryRun) {
7459
7925
  resources.context.complete({
7460
- success: deleted ? "Logged out." : "Already logged out.",
7461
- dry: `Dry run: would delete credentials at ${container.env.credentialsPath}.`
7926
+ success: "Logged out.",
7927
+ dry: `Dry run: would delete config at ${container.env.configPath}.`
7462
7928
  });
7463
7929
  resources.context.finalize();
7930
+ return;
7931
+ }
7932
+ const deleted = await deleteConfig({
7933
+ fs: container.fs,
7934
+ filePath: container.env.configPath
7935
+ });
7936
+ resources.context.complete({
7937
+ success: deleted ? "Logged out." : "Already logged out.",
7938
+ dry: `Dry run: would delete config at ${container.env.configPath}.`
7464
7939
  });
7940
+ resources.context.finalize();
7465
7941
  }
7466
7942
  var init_logout = __esm({
7467
7943
  "src/cli/commands/logout.ts"() {
7468
7944
  "use strict";
7469
- init_credentials2();
7945
+ init_config();
7470
7946
  init_shared();
7471
7947
  init_unconfigure();
7472
7948
  }
7473
7949
  });
7474
7950
 
7951
+ // src/cli/commands/auth.ts
7952
+ function registerAuthCommand(program, container) {
7953
+ const auth = program.command("auth").description("Authentication and account commands.").action(async () => {
7954
+ await executeStatus(program, container);
7955
+ });
7956
+ auth.command("status").description("Show login, balance, and configuration status.").action(async () => {
7957
+ await executeStatus(program, container);
7958
+ });
7959
+ auth.command("api_key").description("Display stored API key.").action(async () => {
7960
+ await executeApiKey(program, container);
7961
+ });
7962
+ auth.command("login").description("Store a Poe API key.").option("--api-key <key>", "Poe API key").action(async (options) => {
7963
+ await executeLogin(program, container, options);
7964
+ });
7965
+ auth.command("logout").description("Remove all configuration and credentials.").action(async () => {
7966
+ await executeLogout(program, container);
7967
+ });
7968
+ }
7969
+ async function executeStatus(program, container) {
7970
+ const flags = resolveCommandFlags(program);
7971
+ const resources = createExecutionResources(container, flags, "auth:status");
7972
+ resources.logger.intro("auth status");
7973
+ try {
7974
+ const apiKey = await container.readApiKey();
7975
+ const loggedIn = Boolean(apiKey);
7976
+ resources.logger.info(loggedIn ? "Logged in" : "Not logged in");
7977
+ if (loggedIn) {
7978
+ if (flags.dryRun) {
7979
+ resources.logger.dryRun(
7980
+ "Dry run: would fetch usage balance from Poe API."
7981
+ );
7982
+ } else {
7983
+ const response = await container.httpClient(
7984
+ `${container.env.poeBaseUrl}/usage/current_balance`,
7985
+ {
7986
+ method: "GET",
7987
+ headers: {
7988
+ Authorization: `Bearer ${apiKey}`
7989
+ }
7990
+ }
7991
+ );
7992
+ if (!response.ok) {
7993
+ throw new ApiError(
7994
+ `Failed to fetch usage balance (HTTP ${response.status})`,
7995
+ {
7996
+ httpStatus: response.status,
7997
+ endpoint: "/usage/current_balance"
7998
+ }
7999
+ );
8000
+ }
8001
+ const data = await response.json();
8002
+ const formattedBalance = data.current_point_balance.toLocaleString(
8003
+ "en-US"
8004
+ );
8005
+ resources.logger.info(`Current balance: ${formattedBalance} points`);
8006
+ }
8007
+ }
8008
+ const configuredServices = await loadConfiguredServices({
8009
+ fs: container.fs,
8010
+ filePath: container.env.configPath
8011
+ });
8012
+ const configuredAgentNames = Object.keys(configuredServices).sort();
8013
+ if (configuredAgentNames.length === 0) {
8014
+ resources.logger.info("No agents configured.");
8015
+ } else {
8016
+ resources.logger.info(
8017
+ `Configured agents: ${configuredAgentNames.join(", ")}`
8018
+ );
8019
+ }
8020
+ resources.context.finalize();
8021
+ } catch (error2) {
8022
+ if (error2 instanceof Error) {
8023
+ resources.logger.logException(error2, "auth status", {
8024
+ operation: "auth-status"
8025
+ });
8026
+ }
8027
+ throw error2;
8028
+ }
8029
+ }
8030
+ async function executeApiKey(program, container) {
8031
+ const flags = resolveCommandFlags(program);
8032
+ const resources = createExecutionResources(container, flags, "auth:api_key");
8033
+ resources.logger.intro("auth api_key");
8034
+ const apiKey = await container.readApiKey();
8035
+ if (!apiKey) {
8036
+ resources.logger.info("No API key stored.");
8037
+ return;
8038
+ }
8039
+ resources.logger.info(`API key: ${apiKey}`);
8040
+ }
8041
+ var init_auth = __esm({
8042
+ "src/cli/commands/auth.ts"() {
8043
+ "use strict";
8044
+ init_errors();
8045
+ init_config();
8046
+ init_shared();
8047
+ init_login();
8048
+ init_logout();
8049
+ }
8050
+ });
8051
+
7475
8052
  // src/cli/commands/install.ts
7476
8053
  function registerInstallCommand(program, container) {
7477
8054
  const serviceNames = container.registry.list().filter((service) => typeof service.install === "function").map((service) => service.name);
@@ -7566,7 +8143,7 @@ async function executeTest(program, container, service, options = {}) {
7566
8143
  container.env,
7567
8144
  adapter.isolatedEnv,
7568
8145
  adapter.name,
7569
- container.fs
8146
+ container.readApiKey
7570
8147
  ) : null;
7571
8148
  if (options.isolated && adapter.isolatedEnv) {
7572
8149
  const { ensureIsolatedConfigForService: ensureIsolatedConfigForService2 } = await Promise.resolve().then(() => (init_ensure_isolated_config(), ensure_isolated_config_exports));
@@ -7615,7 +8192,7 @@ var init_test = __esm({
7615
8192
  init_shared();
7616
8193
  init_configure();
7617
8194
  init_isolated_env();
7618
- init_src3();
8195
+ init_src4();
7619
8196
  }
7620
8197
  });
7621
8198
 
@@ -7668,7 +8245,7 @@ var init_media_download = __esm({
7668
8245
  });
7669
8246
 
7670
8247
  // src/cli/commands/generate.ts
7671
- import path12 from "node:path";
8248
+ import path13 from "node:path";
7672
8249
  function registerGenerateCommand(program, container) {
7673
8250
  const generate2 = program.command("generate").description("Generate content via Poe API").option("--model <model>", `Model identifier (default: ${DEFAULT_TEXT_MODEL})`).option(
7674
8251
  "--param <key=value>",
@@ -7847,10 +8424,13 @@ async function resolveClient2(container) {
7847
8424
  try {
7848
8425
  return getGlobalClient();
7849
8426
  } catch {
8427
+ const apiKey = await container.readApiKey();
8428
+ if (!apiKey) {
8429
+ throw new Error("Poe API key not found. Run 'poe-code login' first.");
8430
+ }
7850
8431
  const apiBaseUrl = resolveApiBaseUrl(container);
7851
8432
  await initializeClient({
7852
- fs: container.fs,
7853
- credentialsPath: container.env.credentialsPath,
8433
+ apiKey,
7854
8434
  baseUrl: apiBaseUrl,
7855
8435
  httpClient: container.httpClient
7856
8436
  });
@@ -7931,11 +8511,11 @@ function getDefaultMimeType(type) {
7931
8511
  return defaults[type];
7932
8512
  }
7933
8513
  function resolveOutputPath(filename, cwd) {
7934
- if (path12.isAbsolute(filename)) {
8514
+ if (path13.isAbsolute(filename)) {
7935
8515
  return { path: filename, label: filename };
7936
8516
  }
7937
8517
  return {
7938
- path: path12.join(cwd, filename),
8518
+ path: path13.join(cwd, filename),
7939
8519
  label: `./${filename}`
7940
8520
  };
7941
8521
  }
@@ -7943,7 +8523,7 @@ var MODEL_ENV_KEYS2, DEFAULT_MODELS2;
7943
8523
  var init_generate = __esm({
7944
8524
  "src/cli/commands/generate.ts"() {
7945
8525
  "use strict";
7946
- init_src3();
8526
+ init_src4();
7947
8527
  init_constants();
7948
8528
  init_shared();
7949
8529
  init_client_instance();
@@ -9039,8 +9619,8 @@ var init_parseUtil = __esm({
9039
9619
  init_errors2();
9040
9620
  init_en();
9041
9621
  makeIssue = (params) => {
9042
- const { data, path: path20, errorMaps, issueData } = params;
9043
- const fullPath = [...path20, ...issueData.path || []];
9622
+ const { data, path: path21, errorMaps, issueData } = params;
9623
+ const fullPath = [...path21, ...issueData.path || []];
9044
9624
  const fullIssue = {
9045
9625
  ...issueData,
9046
9626
  path: fullPath
@@ -9320,11 +9900,11 @@ var init_types3 = __esm({
9320
9900
  init_parseUtil();
9321
9901
  init_util();
9322
9902
  ParseInputLazyPath = class {
9323
- constructor(parent, value, path20, key) {
9903
+ constructor(parent, value, path21, key) {
9324
9904
  this._cachedPath = [];
9325
9905
  this.parent = parent;
9326
9906
  this.data = value;
9327
- this._path = path20;
9907
+ this._path = path21;
9328
9908
  this._key = key;
9329
9909
  }
9330
9910
  get path() {
@@ -12828,10 +13408,10 @@ function mergeDefs(...defs) {
12828
13408
  function cloneDef(schema) {
12829
13409
  return mergeDefs(schema._zod.def);
12830
13410
  }
12831
- function getElementAtPath(obj, path20) {
12832
- if (!path20)
13411
+ function getElementAtPath(obj, path21) {
13412
+ if (!path21)
12833
13413
  return obj;
12834
- return path20.reduce((acc, key) => acc?.[key], obj);
13414
+ return path21.reduce((acc, key) => acc?.[key], obj);
12835
13415
  }
12836
13416
  function promiseAllObject(promisesObj) {
12837
13417
  const keys = Object.keys(promisesObj);
@@ -13143,11 +13723,11 @@ function aborted(x, startIndex = 0) {
13143
13723
  }
13144
13724
  return false;
13145
13725
  }
13146
- function prefixIssues(path20, issues) {
13726
+ function prefixIssues(path21, issues) {
13147
13727
  return issues.map((iss) => {
13148
13728
  var _a2;
13149
13729
  (_a2 = iss).path ?? (_a2.path = []);
13150
- iss.path.unshift(path20);
13730
+ iss.path.unshift(path21);
13151
13731
  return iss;
13152
13732
  });
13153
13733
  }
@@ -13523,7 +14103,7 @@ __export(regexes_exports, {
13523
14103
  extendedDuration: () => extendedDuration,
13524
14104
  guid: () => guid,
13525
14105
  hex: () => hex,
13526
- hostname: () => hostname,
14106
+ hostname: () => hostname2,
13527
14107
  html5Email: () => html5Email,
13528
14108
  idnEmail: () => idnEmail,
13529
14109
  integer: () => integer,
@@ -13590,7 +14170,7 @@ function fixedBase64(bodyLength, padding) {
13590
14170
  function fixedBase64url(length) {
13591
14171
  return new RegExp(`^[A-Za-z0-9_-]{${length}}$`);
13592
14172
  }
13593
- var cuid, cuid2, ulid, xid, ksuid, nanoid, duration, extendedDuration, guid, uuid, uuid4, uuid6, uuid7, email, html5Email, rfc5322Email, unicodeEmail, idnEmail, browserEmail, _emoji, ipv4, ipv6, mac, cidrv4, cidrv6, base64, base64url, hostname, domain, e164, dateSource, date, string, bigint, integer, number, boolean, _null, _undefined, lowercase, uppercase, hex, md5_hex, md5_base64, md5_base64url, sha1_hex, sha1_base64, sha1_base64url, sha256_hex, sha256_base64, sha256_base64url, sha384_hex, sha384_base64, sha384_base64url, sha512_hex, sha512_base64, sha512_base64url;
14173
+ var cuid, cuid2, ulid, xid, ksuid, nanoid, duration, extendedDuration, guid, uuid, uuid4, uuid6, uuid7, email, html5Email, rfc5322Email, unicodeEmail, idnEmail, browserEmail, _emoji, ipv4, ipv6, mac, cidrv4, cidrv6, base64, base64url, hostname2, domain, e164, dateSource, date, string, bigint, integer, number, boolean, _null, _undefined, lowercase, uppercase, hex, md5_hex, md5_base64, md5_base64url, sha1_hex, sha1_base64, sha1_base64url, sha256_hex, sha256_base64, sha256_base64url, sha384_hex, sha384_base64, sha384_base64url, sha512_hex, sha512_base64, sha512_base64url;
13594
14174
  var init_regexes = __esm({
13595
14175
  "node_modules/zod/v4/core/regexes.js"() {
13596
14176
  init_util2();
@@ -13628,7 +14208,7 @@ var init_regexes = __esm({
13628
14208
  cidrv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
13629
14209
  base64 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/;
13630
14210
  base64url = /^[A-Za-z0-9_-]*$/;
13631
- hostname = /^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/;
14211
+ hostname2 = /^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/;
13632
14212
  domain = /^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
13633
14213
  e164 = /^\+[1-9]\d{6,14}$/;
13634
14214
  dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`;
@@ -18834,7 +19414,7 @@ __export(schemas_exports3, {
18834
19414
  guid: () => guid2,
18835
19415
  hash: () => hash,
18836
19416
  hex: () => hex2,
18837
- hostname: () => hostname2,
19417
+ hostname: () => hostname3,
18838
19418
  httpUrl: () => httpUrl,
18839
19419
  instanceof: () => _instanceof,
18840
19420
  int: () => int,
@@ -18981,7 +19561,7 @@ function jwt(params) {
18981
19561
  function stringFormat(format, fnOrRegex, _params = {}) {
18982
19562
  return _stringFormat(ZodCustomStringFormat, format, fnOrRegex, _params);
18983
19563
  }
18984
- function hostname2(_params) {
19564
+ function hostname3(_params) {
18985
19565
  return _stringFormat(ZodCustomStringFormat, "hostname", regexes_exports.hostname, _params);
18986
19566
  }
18987
19567
  function hex2(_params) {
@@ -25105,8 +25685,8 @@ var require_utils = __commonJS({
25105
25685
  }
25106
25686
  return ind;
25107
25687
  }
25108
- function removeDotSegments(path20) {
25109
- let input = path20;
25688
+ function removeDotSegments(path21) {
25689
+ let input = path21;
25110
25690
  const output = [];
25111
25691
  let nextSlash = -1;
25112
25692
  let len = 0;
@@ -25305,8 +25885,8 @@ var require_schemes = __commonJS({
25305
25885
  wsComponent.secure = void 0;
25306
25886
  }
25307
25887
  if (wsComponent.resourceName) {
25308
- const [path20, query] = wsComponent.resourceName.split("?");
25309
- wsComponent.path = path20 && path20 !== "/" ? path20 : void 0;
25888
+ const [path21, query] = wsComponent.resourceName.split("?");
25889
+ wsComponent.path = path21 && path21 !== "/" ? path21 : void 0;
25310
25890
  wsComponent.query = query;
25311
25891
  wsComponent.resourceName = void 0;
25312
25892
  }
@@ -34420,7 +35000,7 @@ var init_content = __esm({
34420
35000
  });
34421
35001
 
34422
35002
  // packages/tiny-stdio-mcp-server/src/index.ts
34423
- var init_src5 = __esm({
35003
+ var init_src6 = __esm({
34424
35004
  "packages/tiny-stdio-mcp-server/src/index.ts"() {
34425
35005
  "use strict";
34426
35006
  init_server();
@@ -34724,7 +35304,7 @@ var generateTextSchema, generateImageSchema, generateVideoSchema, generateAudioS
34724
35304
  var init_mcp_server = __esm({
34725
35305
  "src/cli/mcp-server.ts"() {
34726
35306
  "use strict";
34727
- init_src5();
35307
+ init_src6();
34728
35308
  init_client_instance();
34729
35309
  init_constants();
34730
35310
  generateTextSchema = defineSchema({
@@ -34982,7 +35562,7 @@ ${panel.footer}`);
34982
35562
  var init_command_not_found = __esm({
34983
35563
  "src/cli/command-not-found.ts"() {
34984
35564
  "use strict";
34985
- init_src3();
35565
+ init_src4();
34986
35566
  init_execution_context();
34987
35567
  init_errors();
34988
35568
  }
@@ -35007,7 +35587,7 @@ function getAgentConfig(agentId) {
35007
35587
  const support = resolveAgentSupport(agentId);
35008
35588
  return support.status === "supported" ? support.config : void 0;
35009
35589
  }
35010
- function resolveConfigPath(config2, platform) {
35590
+ function resolveConfigPath2(config2, platform) {
35011
35591
  if (typeof config2.configFile === "function") {
35012
35592
  return config2.configFile(platform);
35013
35593
  }
@@ -35017,7 +35597,7 @@ var agentMcpConfigs, supportedAgents;
35017
35597
  var init_configs2 = __esm({
35018
35598
  "packages/agent-mcp-config/src/configs.ts"() {
35019
35599
  "use strict";
35020
- init_src2();
35600
+ init_src3();
35021
35601
  agentMcpConfigs = {
35022
35602
  "claude-code": {
35023
35603
  configFile: "~/.claude.json",
@@ -35130,9 +35710,9 @@ var init_shapes = __esm({
35130
35710
  });
35131
35711
 
35132
35712
  // packages/agent-mcp-config/src/apply.ts
35133
- import path13 from "node:path";
35713
+ import path14 from "node:path";
35134
35714
  function getConfigDirectory(configPath) {
35135
- return path13.dirname(configPath);
35715
+ return path14.dirname(configPath);
35136
35716
  }
35137
35717
  function isConfigObject5(value) {
35138
35718
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -35149,7 +35729,7 @@ async function configure(agentId, server, options) {
35149
35729
  throw new UnsupportedAgentError(agentId);
35150
35730
  }
35151
35731
  const config2 = getAgentConfig(agentId);
35152
- const configPath = resolveConfigPath(config2, options.platform);
35732
+ const configPath = resolveConfigPath2(config2, options.platform);
35153
35733
  const shapeTransformer = getShapeTransformer(config2.shape);
35154
35734
  const shaped = shapeTransformer(server);
35155
35735
  if (shaped === void 0) {
@@ -35195,7 +35775,7 @@ async function unconfigure(agentId, serverName, options) {
35195
35775
  throw new UnsupportedAgentError(agentId);
35196
35776
  }
35197
35777
  const config2 = getAgentConfig(agentId);
35198
- const configPath = resolveConfigPath(config2, options.platform);
35778
+ const configPath = resolveConfigPath2(config2, options.platform);
35199
35779
  await runMutations(
35200
35780
  [
35201
35781
  configMutation.prune({
@@ -35221,7 +35801,7 @@ var UnsupportedAgentError;
35221
35801
  var init_apply = __esm({
35222
35802
  "packages/agent-mcp-config/src/apply.ts"() {
35223
35803
  "use strict";
35224
- init_src();
35804
+ init_src2();
35225
35805
  init_configs2();
35226
35806
  init_shapes();
35227
35807
  UnsupportedAgentError = class extends Error {
@@ -35234,7 +35814,7 @@ var init_apply = __esm({
35234
35814
  });
35235
35815
 
35236
35816
  // packages/agent-mcp-config/src/index.ts
35237
- var init_src6 = __esm({
35817
+ var init_src7 = __esm({
35238
35818
  "packages/agent-mcp-config/src/index.ts"() {
35239
35819
  "use strict";
35240
35820
  init_configs2();
@@ -35292,10 +35872,7 @@ function registerMcpCommand(program, container) {
35292
35872
  mcp.command("configure [agent]").description("Configure MCP client to use poe-code").option("-y, --yes", "Skip prompt, use claude-code").action(async (agentArg, options) => {
35293
35873
  const flags = resolveCommandFlags(program);
35294
35874
  const resources = createExecutionResources(container, flags, "mcp");
35295
- const existingKey = await loadCredentials({
35296
- fs: container.fs,
35297
- filePath: container.env.credentialsPath
35298
- });
35875
+ const existingKey = await container.readApiKey();
35299
35876
  if (!existingKey) {
35300
35877
  resources.logger.intro("login");
35301
35878
  await container.options.resolveApiKey({ dryRun: flags.dryRun });
@@ -35395,17 +35972,13 @@ async function runMcpServer(container, options) {
35395
35972
  const outputFormatPreferences = parseMcpOutputFormatPreferences(
35396
35973
  options.outputFormat
35397
35974
  );
35398
- const apiKey = await loadCredentials({
35399
- fs: container.fs,
35400
- filePath: container.env.credentialsPath
35401
- });
35975
+ const apiKey = await container.readApiKey();
35402
35976
  if (!apiKey) {
35403
- process.stderr.write("No credentials found. Run 'poe-code login' first.\n");
35977
+ process.stderr.write("No API key found. Run 'poe-code login' first.\n");
35404
35978
  process.exit(1);
35405
35979
  }
35406
35980
  await initializeClient({
35407
- fs: container.fs,
35408
- credentialsPath: container.env.credentialsPath,
35981
+ apiKey,
35409
35982
  baseUrl: container.env.poeApiBaseUrl,
35410
35983
  httpClient: container.httpClient
35411
35984
  });
@@ -35415,22 +35988,21 @@ var DEFAULT_MCP_AGENT;
35415
35988
  var init_mcp2 = __esm({
35416
35989
  "src/cli/commands/mcp.ts"() {
35417
35990
  "use strict";
35418
- init_src3();
35419
- init_credentials2();
35991
+ init_src4();
35420
35992
  init_client_instance();
35421
35993
  init_mcp_server();
35422
35994
  init_shared();
35423
35995
  init_mcp_output_format();
35424
35996
  init_command_not_found();
35425
- init_src6();
35997
+ init_src7();
35426
35998
  init_execution_context();
35427
35999
  DEFAULT_MCP_AGENT = "claude-code";
35428
36000
  }
35429
36001
  });
35430
36002
 
35431
36003
  // packages/agent-skill-config/src/configs.ts
35432
- import os3 from "node:os";
35433
- import path14 from "node:path";
36004
+ import os2 from "node:os";
36005
+ import path15 from "node:path";
35434
36006
  function resolveAgentSupport2(input, registry2 = agentSkillConfigs) {
35435
36007
  const resolvedId = resolveAgentId(input);
35436
36008
  if (!resolvedId) {
@@ -35446,7 +36018,7 @@ var agentSkillConfigs, supportedAgents2;
35446
36018
  var init_configs3 = __esm({
35447
36019
  "packages/agent-skill-config/src/configs.ts"() {
35448
36020
  "use strict";
35449
- init_src2();
36021
+ init_src3();
35450
36022
  agentSkillConfigs = {
35451
36023
  "claude-code": {
35452
36024
  globalSkillDir: "~/.claude/skills",
@@ -35466,7 +36038,7 @@ var init_configs3 = __esm({
35466
36038
  });
35467
36039
 
35468
36040
  // packages/agent-skill-config/src/templates.ts
35469
- import { readFile as readFile3 } from "node:fs/promises";
36041
+ import { readFile as readFile2 } from "node:fs/promises";
35470
36042
  async function getTemplates() {
35471
36043
  if (templatesCache) {
35472
36044
  return templatesCache;
@@ -35475,7 +36047,7 @@ async function getTemplates() {
35475
36047
  "./templates/poe-generate.md",
35476
36048
  import.meta.url
35477
36049
  );
35478
- const poeGenerateTemplate = await readFile3(poeGenerateTemplateUrl, "utf8");
36050
+ const poeGenerateTemplate = await readFile2(poeGenerateTemplateUrl, "utf8");
35479
36051
  templatesCache = {
35480
36052
  "poe-generate.md": poeGenerateTemplate
35481
36053
  };
@@ -35607,7 +36179,7 @@ var UnsupportedAgentError2, bundledSkillTemplateIds, SKILL_TEMPLATE_ID;
35607
36179
  var init_apply2 = __esm({
35608
36180
  "packages/agent-skill-config/src/apply.ts"() {
35609
36181
  "use strict";
35610
- init_src();
36182
+ init_src2();
35611
36183
  init_configs3();
35612
36184
  init_templates();
35613
36185
  UnsupportedAgentError2 = class extends Error {
@@ -35622,7 +36194,7 @@ var init_apply2 = __esm({
35622
36194
  });
35623
36195
 
35624
36196
  // packages/agent-skill-config/src/index.ts
35625
- var init_src7 = __esm({
36197
+ var init_src8 = __esm({
35626
36198
  "packages/agent-skill-config/src/index.ts"() {
35627
36199
  "use strict";
35628
36200
  init_configs3();
@@ -35846,8 +36418,8 @@ var DEFAULT_SKILL_AGENT;
35846
36418
  var init_skill = __esm({
35847
36419
  "src/cli/commands/skill.ts"() {
35848
36420
  "use strict";
35849
- init_src3();
35850
- init_src7();
36421
+ init_src4();
36422
+ init_src8();
35851
36423
  init_shared();
35852
36424
  init_command_not_found();
35853
36425
  DEFAULT_SKILL_AGENT = "claude-code";
@@ -35937,7 +36509,7 @@ async function displayVersion(container, currentVersion) {
35937
36509
  var init_version2 = __esm({
35938
36510
  "src/cli/commands/version.ts"() {
35939
36511
  "use strict";
35940
- init_src3();
36512
+ init_src4();
35941
36513
  init_version();
35942
36514
  init_exit_signals();
35943
36515
  }
@@ -36062,10 +36634,10 @@ var init_registry2 = __esm({
36062
36634
  });
36063
36635
 
36064
36636
  // packages/worktree/src/create.ts
36065
- import { join as join2 } from "node:path";
36637
+ import { join } from "node:path";
36066
36638
  async function createWorktree(opts) {
36067
36639
  const branch = `poe-code/${opts.name}`;
36068
- const worktreePath = join2(opts.worktreeDir, opts.name);
36640
+ const worktreePath = join(opts.worktreeDir, opts.name);
36069
36641
  try {
36070
36642
  await opts.deps.exec(`git worktree remove ${worktreePath} --force`, { cwd: opts.cwd });
36071
36643
  } catch {
@@ -36140,7 +36712,7 @@ var init_list = __esm({
36140
36712
  });
36141
36713
 
36142
36714
  // packages/worktree/src/index.ts
36143
- var init_src8 = __esm({
36715
+ var init_src9 = __esm({
36144
36716
  "packages/worktree/src/index.ts"() {
36145
36717
  "use strict";
36146
36718
  init_create();
@@ -36229,13 +36801,13 @@ function getDirtyFiles(cwd) {
36229
36801
  for (const line of lines) {
36230
36802
  if (!line) continue;
36231
36803
  if (line.length < 4) continue;
36232
- let path20 = line.slice(3).trim();
36804
+ let path21 = line.slice(3).trim();
36233
36805
  const renameArrow = " -> ";
36234
- const arrowIndex = path20.lastIndexOf(renameArrow);
36806
+ const arrowIndex = path21.lastIndexOf(renameArrow);
36235
36807
  if (arrowIndex >= 0) {
36236
- path20 = path20.slice(arrowIndex + renameArrow.length).trim();
36808
+ path21 = path21.slice(arrowIndex + renameArrow.length).trim();
36237
36809
  }
36238
- if (path20) files.push(path20);
36810
+ if (path21) files.push(path21);
36239
36811
  }
36240
36812
  return files;
36241
36813
  }
@@ -36247,7 +36819,7 @@ var init_utils2 = __esm({
36247
36819
 
36248
36820
  // packages/ralph/src/plan/parser.ts
36249
36821
  import { parse as parse7 } from "yaml";
36250
- function isRecord3(value) {
36822
+ function isRecord5(value) {
36251
36823
  return typeof value === "object" && value !== null && !Array.isArray(value);
36252
36824
  }
36253
36825
  function asOptionalString(value, field) {
@@ -36298,7 +36870,7 @@ function normalizeStatus(value) {
36298
36870
  );
36299
36871
  }
36300
36872
  function parseStory(value, index) {
36301
- if (!isRecord3(value)) throw new Error(`Invalid stories[${index}]: expected object`);
36873
+ if (!isRecord5(value)) throw new Error(`Invalid stories[${index}]: expected object`);
36302
36874
  return {
36303
36875
  id: asRequiredString(value.id, `stories[${index}].id`),
36304
36876
  title: asRequiredString(value.title, `stories[${index}].title`),
@@ -36322,7 +36894,7 @@ function parsePlan(yamlContent) {
36322
36894
  const message = error2 instanceof Error ? error2.message : String(error2);
36323
36895
  throw new Error(`Invalid plan YAML: ${message}`, { cause: error2 });
36324
36896
  }
36325
- if (!isRecord3(doc)) {
36897
+ if (!isRecord5(doc)) {
36326
36898
  throw new Error("Invalid plan YAML: expected top-level object");
36327
36899
  }
36328
36900
  const storiesValue = doc.stories;
@@ -36388,17 +36960,17 @@ function serializePlan(prd) {
36388
36960
  return yaml.endsWith("\n") ? yaml : `${yaml}
36389
36961
  `;
36390
36962
  }
36391
- function lockPlanFile(path20) {
36392
- return lockFile(path20, { retries: 20, minTimeout: 25, maxTimeout: 250 });
36963
+ function lockPlanFile(path21) {
36964
+ return lockFile(path21, { retries: 20, minTimeout: 25, maxTimeout: 250 });
36393
36965
  }
36394
- async function writePlan(path20, prd, options = {}) {
36966
+ async function writePlan(path21, prd, options = {}) {
36395
36967
  const fs3 = options.fs ?? fsPromises2;
36396
36968
  const lock = options.lock ?? lockPlanFile;
36397
- await fs3.mkdir(dirname3(path20), { recursive: true });
36398
- const release = await lock(path20);
36969
+ await fs3.mkdir(dirname3(path21), { recursive: true });
36970
+ const release = await lock(path21);
36399
36971
  try {
36400
36972
  const yaml = serializePlan(prd);
36401
- await fs3.writeFile(path20, yaml, { encoding: "utf8" });
36973
+ await fs3.writeFile(path21, yaml, { encoding: "utf8" });
36402
36974
  } finally {
36403
36975
  await release();
36404
36976
  }
@@ -36417,7 +36989,7 @@ function renderPrompt(template, variables) {
36417
36989
  var init_renderer2 = __esm({
36418
36990
  "packages/ralph/src/prompt/renderer.ts"() {
36419
36991
  "use strict";
36420
- init_src();
36992
+ init_src2();
36421
36993
  }
36422
36994
  });
36423
36995
 
@@ -36486,8 +37058,8 @@ var init_selector = __esm({
36486
37058
  // packages/ralph/src/story/updater.ts
36487
37059
  import { dirname as dirname4 } from "node:path";
36488
37060
  import * as fsPromises3 from "node:fs/promises";
36489
- function lockPlanFile2(path20) {
36490
- return lockFile(path20, { retries: 20, minTimeout: 25, maxTimeout: 250 });
37061
+ function lockPlanFile2(path21) {
37062
+ return lockFile(path21, { retries: 20, minTimeout: 25, maxTimeout: 250 });
36491
37063
  }
36492
37064
  function assertStoryStatus(value) {
36493
37065
  if (value === "open") return;
@@ -36568,9 +37140,9 @@ function appendSection(lines, title, items, options) {
36568
37140
  }
36569
37141
  lines.push("");
36570
37142
  }
36571
- async function writeRunMeta(path20, metadata, options = {}) {
37143
+ async function writeRunMeta(path21, metadata, options = {}) {
36572
37144
  const fs3 = options.fs ?? fsPromises4;
36573
- await fs3.mkdir(dirname5(path20), { recursive: true });
37145
+ await fs3.mkdir(dirname5(path21), { recursive: true });
36574
37146
  const lines = [];
36575
37147
  lines.push("# Ralph Run Summary", "");
36576
37148
  lines.push(`- Run ID: ${metadata.runId}`);
@@ -36599,7 +37171,7 @@ async function writeRunMeta(path20, metadata, options = {}) {
36599
37171
  const git = metadata.git ?? null;
36600
37172
  if (!git) {
36601
37173
  lines.push("");
36602
- await fs3.writeFile(path20, lines.join("\n"), { encoding: "utf8" });
37174
+ await fs3.writeFile(path21, lines.join("\n"), { encoding: "utf8" });
36603
37175
  return;
36604
37176
  }
36605
37177
  lines.push("", "## Git");
@@ -36614,7 +37186,7 @@ async function writeRunMeta(path20, metadata, options = {}) {
36614
37186
  lines.push("");
36615
37187
  } else {
36616
37188
  lines.push("");
36617
- await fs3.writeFile(path20, lines.join("\n"), { encoding: "utf8" });
37189
+ await fs3.writeFile(path21, lines.join("\n"), { encoding: "utf8" });
36618
37190
  return;
36619
37191
  }
36620
37192
  if (git.commits !== void 0 && git.commits !== null) {
@@ -36634,7 +37206,7 @@ async function writeRunMeta(path20, metadata, options = {}) {
36634
37206
  appendSection(lines, "### Uncommitted Changes", git.dirtyFiles, {
36635
37207
  emptyLabel: "(none)"
36636
37208
  });
36637
- await fs3.writeFile(path20, lines.join("\n"), { encoding: "utf8" });
37209
+ await fs3.writeFile(path21, lines.join("\n"), { encoding: "utf8" });
36638
37210
  }
36639
37211
  var init_metadata = __esm({
36640
37212
  "packages/ralph/src/run/metadata.ts"() {
@@ -36722,9 +37294,9 @@ async function defaultStreamingSpawn(agentId, options) {
36722
37294
  exitCode: result.exitCode
36723
37295
  };
36724
37296
  }
36725
- function absPath(cwd, path20) {
36726
- if (!path20) return resolvePath3(cwd);
36727
- return path20.startsWith("/") ? path20 : resolvePath3(cwd, path20);
37297
+ function absPath(cwd, path21) {
37298
+ if (!path21) return resolvePath3(cwd);
37299
+ return path21.startsWith("/") ? path21 : resolvePath3(cwd, path21);
36728
37300
  }
36729
37301
  function pad2(value) {
36730
37302
  return value < 10 ? `0${value}` : String(value);
@@ -36774,8 +37346,8 @@ async function appendToErrorsLog(fs3, errorsLogPath, message) {
36774
37346
  await fs3.mkdir(dirname6(errorsLogPath), { recursive: true });
36775
37347
  await fs3.writeFile(errorsLogPath, `${previous}${next}`, { encoding: "utf8" });
36776
37348
  }
36777
- function lockPlanFile3(path20) {
36778
- return lockFile(path20, { retries: 20, minTimeout: 25, maxTimeout: 250 });
37349
+ function lockPlanFile3(path21) {
37350
+ return lockFile(path21, { retries: 20, minTimeout: 25, maxTimeout: 250 });
36779
37351
  }
36780
37352
  function getCurrentBranch(cwd) {
36781
37353
  try {
@@ -36877,7 +37449,7 @@ async function defaultPromptOverbake(args) {
36877
37449
  async function buildLoop(options) {
36878
37450
  const fs3 = options.deps?.fs ?? fsPromises5;
36879
37451
  const lock = options.deps?.lock ?? lockPlanFile3;
36880
- const spawn5 = options.deps?.spawn ?? defaultStreamingSpawn;
37452
+ const spawn6 = options.deps?.spawn ?? defaultStreamingSpawn;
36881
37453
  const git = options.deps?.git ?? {
36882
37454
  getHead,
36883
37455
  getCommitList,
@@ -36931,7 +37503,7 @@ async function buildLoop(options) {
36931
37503
  });
36932
37504
  worktreeBranch = entry.branch;
36933
37505
  const worktreePath = entry.path;
36934
- const symlinkFn = fs3.symlink ?? ((target, path20) => fsPromises5.symlink(target, path20));
37506
+ const symlinkFn = fs3.symlink ?? ((target, path21) => fsPromises5.symlink(target, path21));
36935
37507
  const exec = worktreeDeps.exec;
36936
37508
  const dirsToLink = [".poe-code-ralph", ".agents/poe-code-ralph"];
36937
37509
  for (const dir of dirsToLink) {
@@ -37046,7 +37618,7 @@ async function buildLoop(options) {
37046
37618
  let stderrForErrorsLog;
37047
37619
  let overbakeAction = null;
37048
37620
  try {
37049
- const result = await spawn5(options.agent, {
37621
+ const result = await spawn6(options.agent, {
37050
37622
  prompt,
37051
37623
  cwd,
37052
37624
  model: options.model,
@@ -37219,10 +37791,10 @@ var init_loop = __esm({
37219
37791
  "packages/ralph/src/build/loop.ts"() {
37220
37792
  "use strict";
37221
37793
  init_lock();
37794
+ init_src5();
37222
37795
  init_src4();
37223
- init_src3();
37224
- init_src();
37225
- init_src8();
37796
+ init_src2();
37797
+ init_src9();
37226
37798
  init_detector();
37227
37799
  init_utils2();
37228
37800
  init_parser();
@@ -37236,18 +37808,18 @@ var init_loop = __esm({
37236
37808
  });
37237
37809
 
37238
37810
  // packages/ralph/src/plan/resolver.ts
37239
- import path15 from "node:path";
37811
+ import path16 from "node:path";
37240
37812
  import * as fsPromises6 from "node:fs/promises";
37241
37813
  function isPlanCandidateFile(fileName) {
37242
37814
  const lower = fileName.toLowerCase();
37243
37815
  if (!lower.startsWith("plan")) {
37244
37816
  return false;
37245
37817
  }
37246
- const ext = path15.extname(lower);
37818
+ const ext = path16.extname(lower);
37247
37819
  return ext === ".yml" || ext === ".yaml";
37248
37820
  }
37249
37821
  async function listPlanCandidates(fs3, cwd) {
37250
- const plansDir = path15.join(cwd, ".agents", "poe-code-ralph", "plans");
37822
+ const plansDir = path16.join(cwd, ".agents", "poe-code-ralph", "plans");
37251
37823
  let entries;
37252
37824
  try {
37253
37825
  entries = await fs3.readdir(plansDir);
@@ -37262,12 +37834,12 @@ async function listPlanCandidates(fs3, cwd) {
37262
37834
  if (!isPlanCandidateFile(entry)) {
37263
37835
  continue;
37264
37836
  }
37265
- const absPath2 = path15.join(plansDir, entry);
37837
+ const absPath2 = path16.join(plansDir, entry);
37266
37838
  const stats = await fs3.stat(absPath2);
37267
37839
  if (!stats.isFile()) {
37268
37840
  continue;
37269
37841
  }
37270
- const relativePath = path15.relative(cwd, absPath2);
37842
+ const relativePath = path16.relative(cwd, absPath2);
37271
37843
  const content = await fs3.readFile(absPath2, "utf8");
37272
37844
  const plan = parsePlan(content);
37273
37845
  const done = plan.stories.filter((s) => s.status === "done").length;
@@ -37286,7 +37858,7 @@ async function resolvePlanPath(options) {
37286
37858
  const cwd = options.cwd;
37287
37859
  const provided = options.plan?.trim();
37288
37860
  if (provided) {
37289
- const absPath2 = path15.isAbsolute(provided) ? provided : path15.resolve(cwd, provided);
37861
+ const absPath2 = path16.isAbsolute(provided) ? provided : path16.resolve(cwd, provided);
37290
37862
  try {
37291
37863
  const stats = await fs3.stat(absPath2);
37292
37864
  if (!stats.isFile()) {
@@ -37335,21 +37907,21 @@ async function resolvePlanPath(options) {
37335
37907
  var init_resolver = __esm({
37336
37908
  "packages/ralph/src/plan/resolver.ts"() {
37337
37909
  "use strict";
37338
- init_src3();
37339
- init_src();
37910
+ init_src4();
37911
+ init_src2();
37340
37912
  init_parser();
37341
37913
  }
37342
37914
  });
37343
37915
 
37344
37916
  // packages/ralph/src/plan/generator.ts
37345
- import path16 from "node:path";
37917
+ import path17 from "node:path";
37346
37918
  import * as fsPromises7 from "node:fs/promises";
37347
37919
  var PLAN_PROMPT_TEMPLATE;
37348
37920
  var init_generator = __esm({
37349
37921
  "packages/ralph/src/plan/generator.ts"() {
37350
37922
  "use strict";
37351
- init_src4();
37352
- init_src();
37923
+ init_src5();
37924
+ init_src2();
37353
37925
  init_renderer2();
37354
37926
  PLAN_PROMPT_TEMPLATE = [
37355
37927
  "# Plan",
@@ -37411,27 +37983,27 @@ function formatTimestamp3(date4) {
37411
37983
  const seconds = pad22(date4.getSeconds());
37412
37984
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
37413
37985
  }
37414
- function validateLogPath(path20) {
37415
- if (typeof path20 !== "string" || path20.trim().length === 0) {
37986
+ function validateLogPath(path21) {
37987
+ if (typeof path21 !== "string" || path21.trim().length === 0) {
37416
37988
  throw new Error(
37417
- `Invalid activity log path: expected a non-empty string, got ${String(path20)}`
37989
+ `Invalid activity log path: expected a non-empty string, got ${String(path21)}`
37418
37990
  );
37419
37991
  }
37420
- if (path20.includes("\0")) {
37992
+ if (path21.includes("\0")) {
37421
37993
  throw new Error("Invalid activity log path: contains null byte");
37422
37994
  }
37423
37995
  }
37424
- async function logActivity(path20, message, options = {}) {
37425
- validateLogPath(path20);
37996
+ async function logActivity(path21, message, options = {}) {
37997
+ validateLogPath(path21);
37426
37998
  const fs3 = options.fs ?? fsPromises8;
37427
- const parent = dirname7(path20);
37999
+ const parent = dirname7(path21);
37428
38000
  if (parent && parent !== ".") {
37429
38001
  await fs3.mkdir(parent, { recursive: true });
37430
38002
  }
37431
38003
  const entry = `[${formatTimestamp3(/* @__PURE__ */ new Date())}] ${message}
37432
38004
  `;
37433
38005
  try {
37434
- await fs3.appendFile(path20, entry, { encoding: "utf8" });
38006
+ await fs3.appendFile(path21, entry, { encoding: "utf8" });
37435
38007
  } catch (error2) {
37436
38008
  const detail = error2 instanceof Error ? error2.message : `Unknown error: ${String(error2)}`;
37437
38009
  throw new Error(`Failed to append activity log entry: ${detail}`, { cause: error2 });
@@ -37444,7 +38016,7 @@ var init_activity = __esm({
37444
38016
  });
37445
38017
 
37446
38018
  // packages/ralph/src/config/loader.ts
37447
- import path17 from "node:path";
38019
+ import path18 from "node:path";
37448
38020
  import * as fsPromises9 from "node:fs/promises";
37449
38021
  import YAML from "yaml";
37450
38022
  function isPlainObject2(value) {
@@ -37479,8 +38051,8 @@ function pickOptionalPositiveInt(config2, key, options) {
37479
38051
  return value;
37480
38052
  }
37481
38053
  async function loadSingleConfig(configDir, fs3) {
37482
- const yamlPath = path17.join(configDir, "config.yaml");
37483
- const jsonPath = path17.join(configDir, "config.json");
38054
+ const yamlPath = path18.join(configDir, "config.yaml");
38055
+ const jsonPath = path18.join(configDir, "config.json");
37484
38056
  let raw = null;
37485
38057
  let format = null;
37486
38058
  let sourcePath = null;
@@ -37553,14 +38125,14 @@ async function loadConfig(cwd, deps) {
37553
38125
  const sources = [];
37554
38126
  let merged = {};
37555
38127
  if (deps?.homeDir) {
37556
- const globalDir = path17.join(deps.homeDir, ".poe-code", "ralph");
38128
+ const globalDir = path18.join(deps.homeDir, ".poe-code", "ralph");
37557
38129
  const globalResult = await loadSingleConfig(globalDir, fs3);
37558
38130
  if (globalResult) {
37559
38131
  merged = globalResult.config;
37560
38132
  sources.push({ path: globalResult.sourcePath, scope: "global" });
37561
38133
  }
37562
38134
  }
37563
- const localDir = path17.join(cwd, ".agents", "poe-code-ralph");
38135
+ const localDir = path18.join(cwd, ".agents", "poe-code-ralph");
37564
38136
  const localResult = await loadSingleConfig(localDir, fs3);
37565
38137
  if (localResult) {
37566
38138
  merged = mergeConfigs(merged, localResult.config);
@@ -37571,7 +38143,7 @@ async function loadConfig(cwd, deps) {
37571
38143
  var init_loader = __esm({
37572
38144
  "packages/ralph/src/config/loader.ts"() {
37573
38145
  "use strict";
37574
- init_src();
38146
+ init_src2();
37575
38147
  }
37576
38148
  });
37577
38149
 
@@ -37582,7 +38154,7 @@ async function ralphBuild(options) {
37582
38154
  cwd: options.cwd ?? process.cwd()
37583
38155
  });
37584
38156
  }
37585
- var init_src9 = __esm({
38157
+ var init_src10 = __esm({
37586
38158
  "packages/ralph/src/index.ts"() {
37587
38159
  "use strict";
37588
38160
  init_loop();
@@ -37602,12 +38174,12 @@ var require_PROMPT_worktree_merge = __commonJS({
37602
38174
  });
37603
38175
 
37604
38176
  // src/cli/commands/ralph-worktree.ts
37605
- import path18 from "node:path";
38177
+ import path19 from "node:path";
37606
38178
  import { execSync as execSync3 } from "node:child_process";
37607
38179
  function registerRalphWorktreeCommand(ralph, container) {
37608
38180
  ralph.command("worktree").description("Merge a completed worktree back into the main branch.").argument("<name>", "Name of the worktree to merge").option("--agent <name>", "Agent to use for the merge").action(async function(name) {
37609
38181
  const cwd = container.env.cwd;
37610
- const registryFile = path18.join(cwd, ".poe-code-ralph", "worktrees.yaml");
38182
+ const registryFile = path19.join(cwd, ".poe-code-ralph", "worktrees.yaml");
37611
38183
  const worktrees = await listWorktrees(cwd, registryFile, {
37612
38184
  fs: {
37613
38185
  readFile: (p, enc) => container.fs.readFile(p, enc),
@@ -37670,10 +38242,10 @@ function registerRalphWorktreeCommand(ralph, container) {
37670
38242
  var init_ralph_worktree = __esm({
37671
38243
  "src/cli/commands/ralph-worktree.ts"() {
37672
38244
  "use strict";
37673
- init_src3();
37674
- init_src8();
37675
38245
  init_src4();
37676
- init_src();
38246
+ init_src9();
38247
+ init_src5();
38248
+ init_src2();
37677
38249
  init_errors();
37678
38250
  }
37679
38251
  });
@@ -37749,7 +38321,7 @@ var require_activity = __commonJS({
37749
38321
  });
37750
38322
 
37751
38323
  // src/cli/commands/ralph.ts
37752
- import path19 from "node:path";
38324
+ import path20 from "node:path";
37753
38325
  async function loadRalphTemplates() {
37754
38326
  const [
37755
38327
  promptPartialPlan,
@@ -37834,7 +38406,7 @@ async function writeFileOrSkip(args) {
37834
38406
  args.logger.info(`Skip: ${args.displayPath} (already exists)`);
37835
38407
  return "skipped";
37836
38408
  }
37837
- await args.fs.mkdir(path19.dirname(args.filePath), { recursive: true });
38409
+ await args.fs.mkdir(path20.dirname(args.filePath), { recursive: true });
37838
38410
  await args.fs.writeFile(args.filePath, args.contents, { encoding: "utf8" });
37839
38411
  args.logger.info(`${exists ? "Overwrite" : "Create"}: ${args.displayPath}`);
37840
38412
  return "written";
@@ -37870,22 +38442,22 @@ async function installRalphTemplates(args) {
37870
38442
  const promptPlanContents = templates.promptPlan.replace("{{{PROMPT_PARTIAL_PLAN}}}", templates.promptPartialPlan);
37871
38443
  const templateWrites = [
37872
38444
  {
37873
- targetPath: path19.join(cwd, ".agents", "poe-code-ralph", "PROMPT_plan.md"),
38445
+ targetPath: path20.join(cwd, ".agents", "poe-code-ralph", "PROMPT_plan.md"),
37874
38446
  displayPath: ".agents/poe-code-ralph/PROMPT_plan.md",
37875
38447
  contents: promptPlanContents
37876
38448
  },
37877
38449
  {
37878
- targetPath: path19.join(cwd, ".agents", "poe-code-ralph", "PROMPT_build.md"),
38450
+ targetPath: path20.join(cwd, ".agents", "poe-code-ralph", "PROMPT_build.md"),
37879
38451
  displayPath: ".agents/poe-code-ralph/PROMPT_build.md",
37880
38452
  contents: templates.promptBuild
37881
38453
  },
37882
38454
  {
37883
- targetPath: path19.join(cwd, ".agents", "poe-code-ralph", "references", "GUARDRAILS.md"),
38455
+ targetPath: path20.join(cwd, ".agents", "poe-code-ralph", "references", "GUARDRAILS.md"),
37884
38456
  displayPath: ".agents/poe-code-ralph/references/GUARDRAILS.md",
37885
38457
  contents: templates.refGuardrails
37886
38458
  },
37887
38459
  {
37888
- targetPath: path19.join(cwd, ".agents", "poe-code-ralph", "references", "CONTEXT_ENGINEERING.md"),
38460
+ targetPath: path20.join(cwd, ".agents", "poe-code-ralph", "references", "CONTEXT_ENGINEERING.md"),
37889
38461
  displayPath: ".agents/poe-code-ralph/references/CONTEXT_ENGINEERING.md",
37890
38462
  contents: templates.refContextEngineering
37891
38463
  }
@@ -37903,22 +38475,22 @@ async function installRalphTemplates(args) {
37903
38475
  const stateFiles = [
37904
38476
  {
37905
38477
  contents: templates.stateProgress,
37906
- targetPath: path19.join(cwd, ".poe-code-ralph", "progress.md"),
38478
+ targetPath: path20.join(cwd, ".poe-code-ralph", "progress.md"),
37907
38479
  displayPath: ".poe-code-ralph/progress.md"
37908
38480
  },
37909
38481
  {
37910
38482
  contents: templates.stateGuardrails,
37911
- targetPath: path19.join(cwd, ".poe-code-ralph", "guardrails.md"),
38483
+ targetPath: path20.join(cwd, ".poe-code-ralph", "guardrails.md"),
37912
38484
  displayPath: ".poe-code-ralph/guardrails.md"
37913
38485
  },
37914
38486
  {
37915
38487
  contents: templates.stateErrors,
37916
- targetPath: path19.join(cwd, ".poe-code-ralph", "errors.log"),
38488
+ targetPath: path20.join(cwd, ".poe-code-ralph", "errors.log"),
37917
38489
  displayPath: ".poe-code-ralph/errors.log"
37918
38490
  },
37919
38491
  {
37920
38492
  contents: templates.stateActivity,
37921
- targetPath: path19.join(cwd, ".poe-code-ralph", "activity.log"),
38493
+ targetPath: path20.join(cwd, ".poe-code-ralph", "activity.log"),
37922
38494
  displayPath: ".poe-code-ralph/activity.log"
37923
38495
  }
37924
38496
  ];
@@ -37965,7 +38537,7 @@ function registerRalphCommand(program, container) {
37965
38537
  throw new ValidationError(message2);
37966
38538
  }
37967
38539
  const rawPath = options.activityLog?.trim() || configActivityLogPath || ".poe-code-ralph/activity.log";
37968
- const resolvedPath = path19.isAbsolute(rawPath) ? rawPath : path19.resolve(container.env.cwd, rawPath);
38540
+ const resolvedPath = path20.isAbsolute(rawPath) ? rawPath : path20.resolve(container.env.cwd, rawPath);
37969
38541
  await logActivity(resolvedPath, trimmedMessage, {
37970
38542
  fs: container.fs
37971
38543
  });
@@ -37977,7 +38549,7 @@ function registerRalphCommand(program, container) {
37977
38549
  if (!planPath) {
37978
38550
  throw new ValidationError("--plan <path> is required.");
37979
38551
  }
37980
- const resolvedPath = path19.isAbsolute(planPath) ? planPath : path19.resolve(cwd, planPath);
38552
+ const resolvedPath = path20.isAbsolute(planPath) ? planPath : path20.resolve(cwd, planPath);
37981
38553
  let content;
37982
38554
  try {
37983
38555
  content = await container.fs.readFile(resolvedPath, "utf8");
@@ -38151,7 +38723,7 @@ function registerRalphCommand(program, container) {
38151
38723
  } else {
38152
38724
  try {
38153
38725
  const planContent = await container.fs.readFile(
38154
- path19.resolve(cwd, planPath),
38726
+ path20.resolve(cwd, planPath),
38155
38727
  "utf8"
38156
38728
  );
38157
38729
  const plan = parsePlan(planContent);
@@ -38185,7 +38757,7 @@ function registerRalphCommand(program, container) {
38185
38757
  } else {
38186
38758
  try {
38187
38759
  const planContent = await container.fs.readFile(
38188
- path19.resolve(cwd, planPath),
38760
+ path20.resolve(cwd, planPath),
38189
38761
  "utf8"
38190
38762
  );
38191
38763
  const plan = parsePlan(planContent);
@@ -38241,10 +38813,10 @@ var templateImports, DEFAULT_RALPH_AGENT;
38241
38813
  var init_ralph = __esm({
38242
38814
  "src/cli/commands/ralph.ts"() {
38243
38815
  "use strict";
38244
- init_src3();
38245
- init_src9();
38246
- init_src7();
38247
- init_src();
38816
+ init_src4();
38817
+ init_src10();
38818
+ init_src8();
38819
+ init_src2();
38248
38820
  init_errors();
38249
38821
  init_shared();
38250
38822
  init_ralph_worktree();
@@ -38465,7 +39037,7 @@ var init_usage = __esm({
38465
39037
  "use strict";
38466
39038
  init_shared();
38467
39039
  init_errors();
38468
- init_src3();
39040
+ init_src4();
38469
39041
  }
38470
39042
  });
38471
39043
 
@@ -38558,10 +39130,7 @@ function registerModelsCommand(program, container) {
38558
39130
  const commandOptions = this.opts();
38559
39131
  resources.logger.intro("models");
38560
39132
  try {
38561
- const apiKey = await loadCredentials({
38562
- fs: container.fs,
38563
- filePath: container.env.credentialsPath
38564
- });
39133
+ const apiKey = await container.readApiKey();
38565
39134
  if (flags.dryRun) {
38566
39135
  resources.logger.dryRun(
38567
39136
  "Dry run: would fetch models from Poe API."
@@ -38749,9 +39318,8 @@ var init_models = __esm({
38749
39318
  "src/cli/commands/models.ts"() {
38750
39319
  "use strict";
38751
39320
  init_shared();
38752
- init_credentials2();
38753
39321
  init_errors();
38754
- init_src3();
39322
+ init_src4();
38755
39323
  MAX_VALUES_LENGTH = 105;
38756
39324
  MAX_DEFAULT_LENGTH = 36;
38757
39325
  }
@@ -38763,7 +39331,7 @@ var init_package = __esm({
38763
39331
  "package.json"() {
38764
39332
  package_default = {
38765
39333
  name: "poe-code",
38766
- version: "3.0.70",
39334
+ version: "3.0.71-beta.1",
38767
39335
  description: "CLI tool to configure Poe API for developer workflows.",
38768
39336
  type: "module",
38769
39337
  main: "./dist/index.js",
@@ -38845,6 +39413,7 @@ var init_package = __esm({
38845
39413
  devDependencies: {
38846
39414
  "@eslint/js": "^9.0.0",
38847
39415
  "@modelcontextprotocol/sdk": "^1.26.0",
39416
+ "@poe-code/auth": "*",
38848
39417
  "@poe-code/agent-spawn": "*",
38849
39418
  "@poe-code/config-mutations": "*",
38850
39419
  "@poe-code/design-system": "*",
@@ -38908,21 +39477,26 @@ function formatHelpText(input) {
38908
39477
  args: "<agent>",
38909
39478
  description: "Remove a previously applied configuration"
38910
39479
  },
39480
+ {
39481
+ name: "login",
39482
+ args: "",
39483
+ description: "Store a Poe API key"
39484
+ },
38911
39485
  {
38912
39486
  name: "logout",
38913
39487
  args: "",
38914
- description: "Remove all configuration and stored credentials"
39488
+ description: "Remove all configuration"
39489
+ },
39490
+ {
39491
+ name: "auth status",
39492
+ args: "",
39493
+ description: "Show login, balance, and configuration status"
38915
39494
  },
38916
39495
  {
38917
39496
  name: "spawn",
38918
39497
  args: "<agent> [prompt]",
38919
39498
  description: "Launch a coding agent"
38920
39499
  },
38921
- {
38922
- name: "research",
38923
- args: "<prompt>",
38924
- description: "Research a codebase using a coding agent"
38925
- },
38926
39500
  {
38927
39501
  name: "generate",
38928
39502
  args: "[type]",
@@ -39106,6 +39680,7 @@ function bootstrapProgram(container) {
39106
39680
  registerUnconfigureCommand(program, container);
39107
39681
  registerLoginCommand(program, container);
39108
39682
  registerLogoutCommand(program, container);
39683
+ registerAuthCommand(program, container);
39109
39684
  registerMcpCommand(program, container);
39110
39685
  registerSkillCommand(program, container);
39111
39686
  registerRalphCommand(program, container);
@@ -39147,13 +39722,14 @@ var init_program = __esm({
39147
39722
  async "src/cli/program.ts"() {
39148
39723
  "use strict";
39149
39724
  await init_container2();
39150
- init_src3();
39725
+ init_src4();
39151
39726
  init_configure();
39152
39727
  await init_spawn4();
39153
39728
  await init_research2();
39154
39729
  init_wrap();
39155
39730
  init_login();
39156
39731
  init_logout();
39732
+ init_auth();
39157
39733
  init_install();
39158
39734
  init_unconfigure();
39159
39735
  init_test();
@@ -39244,7 +39820,7 @@ function createPromptRunner(adapter = {
39244
39820
  var init_prompt_runner = __esm({
39245
39821
  "src/cli/prompt-runner.ts"() {
39246
39822
  "use strict";
39247
- init_src3();
39823
+ init_src4();
39248
39824
  init_errors();
39249
39825
  }
39250
39826
  });
@@ -39255,17 +39831,17 @@ __export(bootstrap_exports, {
39255
39831
  createCliMain: () => createCliMain,
39256
39832
  isCliInvocation: () => isCliInvocation
39257
39833
  });
39258
- import * as nodeFs from "node:fs/promises";
39834
+ import * as nodeFs2 from "node:fs/promises";
39259
39835
  import * as nodeFsSync3 from "node:fs";
39260
39836
  import { realpathSync } from "node:fs";
39261
- import { homedir as homedir3 } from "node:os";
39837
+ import { homedir as homedir4 } from "node:os";
39262
39838
  import { pathToFileURL as pathToFileURL2 } from "node:url";
39263
- import { join as join3 } from "node:path";
39839
+ import { join as join2 } from "node:path";
39264
39840
  import chalk13 from "chalk";
39265
39841
  function createCliMain(programFactory) {
39266
39842
  return async function runCli() {
39267
- const homeDir = homedir3();
39268
- const logDir = join3(homeDir, ".poe-code", "logs");
39843
+ const homeDir = homedir4();
39844
+ const logDir = join2(homeDir, ".poe-code", "logs");
39269
39845
  const promptRunner = createPromptRunner();
39270
39846
  const shouldLogToStderr = process.env.POE_CODE_STDERR_LOGS === "1" || process.env.POE_CODE_STDERR_LOGS === "true";
39271
39847
  const errorLogger = new ErrorLogger({
@@ -39300,7 +39876,7 @@ function createCliMain(programFactory) {
39300
39876
  } else {
39301
39877
  log2.error(`Error: ${error2.message}`);
39302
39878
  log2.message(
39303
- `See logs at ${join3(logDir, "errors.log")} for more details.`,
39879
+ `See logs at ${join2(logDir, "errors.log")} for more details.`,
39304
39880
  { symbol: chalk13.magenta("\u25CF") }
39305
39881
  );
39306
39882
  }
@@ -39326,11 +39902,11 @@ var fsAdapter;
39326
39902
  var init_bootstrap = __esm({
39327
39903
  "src/cli/bootstrap.ts"() {
39328
39904
  "use strict";
39329
- init_src3();
39905
+ init_src4();
39330
39906
  init_error_logger();
39331
39907
  init_errors();
39332
39908
  init_prompt_runner();
39333
- fsAdapter = nodeFs;
39909
+ fsAdapter = nodeFs2;
39334
39910
  }
39335
39911
  });
39336
39912
 
@@ -39469,6 +40045,6 @@ export {
39469
40045
  getPoeApiKey,
39470
40046
  isCliInvocation2 as isCliInvocation,
39471
40047
  main,
39472
- spawn3 as spawn
40048
+ spawn4 as spawn
39473
40049
  };
39474
40050
  //# sourceMappingURL=index.js.map