poe-code 3.0.71 → 3.0.72-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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"];
@@ -1598,170 +2033,9 @@ var init_context = __esm({
1598
2033
  }
1599
2034
  });
1600
2035
 
1601
- // src/services/credentials.ts
1602
- import path3 from "node:path";
1603
- async function saveCredentials(options) {
1604
- const { fs: fs3, filePath, apiKey } = options;
1605
- const document = await readCredentialsDocument(fs3, filePath);
1606
- document.apiKey = apiKey;
1607
- await writeCredentialsDocument(fs3, filePath, document);
1608
- }
1609
- async function loadCredentials(options) {
1610
- const { fs: fs3, filePath } = options;
1611
- const document = await readCredentialsDocument(fs3, filePath);
1612
- return typeof document.apiKey === "string" && document.apiKey.length > 0 ? document.apiKey : null;
1613
- }
1614
- async function deleteCredentials(options) {
1615
- const { fs: fs3, filePath } = options;
1616
- try {
1617
- await fs3.unlink(filePath);
1618
- return true;
1619
- } catch (error2) {
1620
- if (isNotFound(error2)) {
1621
- return false;
1622
- }
1623
- throw error2;
1624
- }
1625
- }
1626
- async function loadConfiguredServices(options) {
1627
- const { fs: fs3, filePath } = options;
1628
- const document = await readCredentialsDocument(fs3, filePath);
1629
- return { ...document.configured_services ?? {} };
1630
- }
1631
- async function saveConfiguredService(options) {
1632
- const { fs: fs3, filePath, service, metadata } = options;
1633
- const document = await readCredentialsDocument(fs3, filePath);
1634
- const normalized = normalizeConfiguredServiceMetadata(metadata);
1635
- document.configured_services = {
1636
- ...document.configured_services ?? {},
1637
- [service]: normalized
1638
- };
1639
- await writeCredentialsDocument(fs3, filePath, document);
1640
- }
1641
- async function unconfigureService(options) {
1642
- const { fs: fs3, filePath, service } = options;
1643
- const document = await readCredentialsDocument(fs3, filePath);
1644
- const services = document.configured_services;
1645
- if (!services || !(service in services)) {
1646
- return false;
1647
- }
1648
- delete services[service];
1649
- if (Object.keys(services).length === 0) {
1650
- delete document.configured_services;
1651
- }
1652
- await writeCredentialsDocument(fs3, filePath, document);
1653
- return true;
1654
- }
1655
- function normalizeConfiguredServiceMetadata(metadata) {
1656
- const seen = /* @__PURE__ */ new Set();
1657
- const files = [];
1658
- for (const entry of metadata.files ?? []) {
1659
- if (typeof entry !== "string" || entry.length === 0) {
1660
- continue;
1661
- }
1662
- if (!seen.has(entry)) {
1663
- files.push(entry);
1664
- seen.add(entry);
1665
- }
1666
- }
1667
- return {
1668
- files
1669
- };
1670
- }
1671
- async function readCredentialsDocument(fs3, filePath) {
1672
- try {
1673
- const raw = await fs3.readFile(filePath, "utf8");
1674
- return await parseCredentialsDocument(fs3, filePath, raw);
1675
- } catch (error2) {
1676
- if (isNotFound(error2)) {
1677
- return {};
1678
- }
1679
- throw error2;
1680
- }
1681
- }
1682
- async function parseCredentialsDocument(fs3, filePath, raw) {
1683
- try {
1684
- const parsed = JSON.parse(raw);
1685
- return normalizeCredentialsDocument(parsed);
1686
- } catch (error2) {
1687
- if (error2 instanceof SyntaxError) {
1688
- await recoverInvalidCredentials(fs3, filePath, raw);
1689
- return {};
1690
- }
1691
- throw error2;
1692
- }
1693
- }
1694
- function normalizeCredentialsDocument(value) {
1695
- if (!isRecord(value)) {
1696
- return {};
1697
- }
1698
- const document = {};
1699
- if (typeof value.apiKey === "string" && value.apiKey.length > 0) {
1700
- document.apiKey = value.apiKey;
1701
- }
1702
- const services = normalizeConfiguredServices(value.configured_services);
1703
- if (Object.keys(services).length > 0) {
1704
- document.configured_services = services;
1705
- }
1706
- return document;
1707
- }
1708
- function normalizeConfiguredServices(value) {
1709
- if (!isRecord(value)) {
1710
- return {};
1711
- }
1712
- const entries = {};
1713
- for (const [key, entry] of Object.entries(value)) {
1714
- if (!isRecord(entry)) {
1715
- continue;
1716
- }
1717
- const normalized = normalizeConfiguredServiceMetadata({
1718
- files: Array.isArray(entry.files) ? entry.files : []
1719
- });
1720
- entries[key] = normalized;
1721
- }
1722
- return entries;
1723
- }
1724
- async function writeCredentialsDocument(fs3, filePath, document) {
1725
- await fs3.mkdir(path3.dirname(filePath), { recursive: true });
1726
- const payload = {};
1727
- if (document.apiKey) {
1728
- payload.apiKey = document.apiKey;
1729
- }
1730
- if (document.configured_services) {
1731
- payload.configured_services = document.configured_services;
1732
- }
1733
- await fs3.writeFile(filePath, `${JSON.stringify(payload, null, 2)}
1734
- `, {
1735
- encoding: "utf8"
1736
- });
1737
- }
1738
- async function recoverInvalidCredentials(fs3, filePath, content) {
1739
- const backupPath = createInvalidBackupPath(filePath);
1740
- await fs3.writeFile(backupPath, content, { encoding: "utf8" });
1741
- await fs3.writeFile(filePath, EMPTY_DOCUMENT, { encoding: "utf8" });
1742
- }
1743
- function createInvalidBackupPath(filePath) {
1744
- const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
1745
- const dir = path3.dirname(filePath);
1746
- const base = path3.basename(filePath);
1747
- return path3.join(dir, `${base}.invalid-${timestamp}.json`);
1748
- }
1749
- function isRecord(value) {
1750
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
1751
- }
1752
- var EMPTY_DOCUMENT;
1753
- var init_credentials2 = __esm({
1754
- "src/services/credentials.ts"() {
1755
- "use strict";
1756
- init_src();
1757
- EMPTY_DOCUMENT = `${JSON.stringify({}, null, 2)}
1758
- `;
1759
- }
1760
- });
1761
-
1762
2036
  // src/cli/isolated-env.ts
1763
2037
  import path4 from "node:path";
1764
- async function resolveIsolatedEnvDetails(env, isolated, providerName, fs3) {
2038
+ async function resolveIsolatedEnvDetails(env, isolated, providerName, readApiKey) {
1765
2039
  if (!providerName) {
1766
2040
  throw new Error("resolveIsolatedEnvDetails requires providerName.");
1767
2041
  }
@@ -1774,7 +2048,7 @@ async function resolveIsolatedEnvDetails(env, isolated, providerName, fs3) {
1774
2048
  }
1775
2049
  return {
1776
2050
  agentBinary: isolated.agentBinary,
1777
- env: await resolveIsolatedEnvVars(env, baseDir, isolated.env, fs3),
2051
+ env: await resolveIsolatedEnvVars(env, baseDir, isolated.env, readApiKey),
1778
2052
  configProbePath: isolated.configProbe ? resolveIsolatedEnvPath(env, baseDir, isolated.configProbe) : void 0
1779
2053
  };
1780
2054
  }
@@ -1803,14 +2077,14 @@ function resolveIsolatedTargetDirectory(input) {
1803
2077
  function resolveIsolatedBaseDir(env, providerName) {
1804
2078
  return env.resolveHomePath(".poe-code", providerName);
1805
2079
  }
1806
- async function resolveIsolatedEnvVars(env, baseDir, vars, fs3) {
2080
+ async function resolveIsolatedEnvVars(env, baseDir, vars, readApiKey) {
1807
2081
  const out = {};
1808
2082
  for (const [key, value] of Object.entries(vars)) {
1809
- out[key] = await resolveIsolatedEnvValue(env, baseDir, value, fs3);
2083
+ out[key] = await resolveIsolatedEnvValue(env, baseDir, value, readApiKey);
1810
2084
  }
1811
2085
  return out;
1812
2086
  }
1813
- async function resolveIsolatedEnvValue(env, baseDir, value, fs3) {
2087
+ async function resolveIsolatedEnvValue(env, baseDir, value, readApiKey) {
1814
2088
  if (typeof value === "string") {
1815
2089
  return expandHomeShortcut(env, value);
1816
2090
  }
@@ -1828,12 +2102,12 @@ async function resolveIsolatedEnvValue(env, baseDir, value, fs3) {
1828
2102
  if (typeof resolved === "string" && resolved.trim().length > 0) {
1829
2103
  return resolved;
1830
2104
  }
1831
- if (!fs3) {
2105
+ if (!readApiKey) {
1832
2106
  throw new Error(
1833
2107
  'Missing Poe API key for isolated wrapper. Set "POE_API_KEY" or run "poe-code login".'
1834
2108
  );
1835
2109
  }
1836
- return await resolvePoeApiKeyFromCredentials({ fs: fs3, env });
2110
+ return await resolvePoeApiKeyFromAuthStore(readApiKey);
1837
2111
  }
1838
2112
  if (isPoeBaseUrlReference(value)) {
1839
2113
  return env.poeBaseUrl;
@@ -1860,8 +2134,8 @@ function isPoeApiKeyReference(value) {
1860
2134
  function isPoeBaseUrlReference(value) {
1861
2135
  return typeof value === "object" && value.kind === "poeBaseUrl";
1862
2136
  }
1863
- async function resolvePoeApiKeyFromCredentials(input) {
1864
- const stored = await loadCredentials({ fs: input.fs, filePath: input.env.credentialsPath }) ?? void 0;
2137
+ async function resolvePoeApiKeyFromAuthStore(readApiKey) {
2138
+ const stored = await readApiKey();
1865
2139
  if (typeof stored !== "string" || stored.trim().length === 0) {
1866
2140
  throw new Error(
1867
2141
  'Missing Poe API key for isolated wrapper. Set "POE_API_KEY" or run "poe-code login".'
@@ -1904,11 +2178,11 @@ async function applyIsolatedEnvRepairs(input) {
1904
2178
  }
1905
2179
  }
1906
2180
  }
1907
- async function resolveCliSettings(cliSettings, env, fs3) {
2181
+ async function resolveCliSettings(cliSettings, env, readApiKey) {
1908
2182
  const result = { ...cliSettings.values };
1909
2183
  if (cliSettings.resolved) {
1910
2184
  for (const [key, value] of Object.entries(cliSettings.resolved)) {
1911
- result[key] = await resolveCliSettingValue(value, env, fs3);
2185
+ result[key] = await resolveCliSettingValue(value, env, readApiKey);
1912
2186
  }
1913
2187
  }
1914
2188
  if (cliSettings.env) {
@@ -1917,21 +2191,21 @@ async function resolveCliSettings(cliSettings, env, fs3) {
1917
2191
  if (typeof value === "string") {
1918
2192
  resolvedEnv[key] = value;
1919
2193
  } else {
1920
- resolvedEnv[key] = await resolveCliSettingValue(value, env, fs3);
2194
+ resolvedEnv[key] = await resolveCliSettingValue(value, env, readApiKey);
1921
2195
  }
1922
2196
  }
1923
2197
  result.env = resolvedEnv;
1924
2198
  }
1925
2199
  return result;
1926
2200
  }
1927
- async function resolveCliSettingValue(value, env, fs3) {
2201
+ async function resolveCliSettingValue(value, env, readApiKey) {
1928
2202
  if (isPoeApiKeyReference(value)) {
1929
2203
  const resolved = env.getVariable("POE_API_KEY");
1930
2204
  if (typeof resolved === "string" && resolved.trim().length > 0) {
1931
2205
  return resolved;
1932
2206
  }
1933
- if (fs3) {
1934
- return await resolvePoeApiKeyFromCredentials({ fs: fs3, env });
2207
+ if (readApiKey) {
2208
+ return await resolvePoeApiKeyFromAuthStore(readApiKey);
1935
2209
  }
1936
2210
  throw new Error(
1937
2211
  'Missing Poe API key for CLI settings. Set "POE_API_KEY" or run "poe-code login".'
@@ -1972,17 +2246,16 @@ function expandHomeShortcut(env, input) {
1972
2246
  var init_isolated_env = __esm({
1973
2247
  "src/cli/isolated-env.ts"() {
1974
2248
  "use strict";
1975
- init_src();
1976
- init_credentials2();
2249
+ init_src2();
1977
2250
  }
1978
2251
  });
1979
2252
 
1980
2253
  // packages/agent-spawn/src/run-command.ts
1981
- import { spawn } from "node:child_process";
2254
+ import { spawn as spawn2 } from "node:child_process";
1982
2255
  function runCommand(command, args, options) {
1983
2256
  return new Promise((resolve) => {
1984
2257
  const hasStdin = options?.stdin != null;
1985
- const child = spawn(command, args, {
2258
+ const child = spawn2(command, args, {
1986
2259
  stdio: [hasStdin ? "pipe" : "ignore", "pipe", "pipe"],
1987
2260
  cwd: options?.cwd,
1988
2261
  env: options?.env ? {
@@ -2185,7 +2458,7 @@ var init_registry = __esm({
2185
2458
  });
2186
2459
 
2187
2460
  // packages/agent-defs/src/index.ts
2188
- var init_src2 = __esm({
2461
+ var init_src3 = __esm({
2189
2462
  "packages/agent-defs/src/index.ts"() {
2190
2463
  "use strict";
2191
2464
  init_agents();
@@ -2410,7 +2683,7 @@ var allSpawnConfigs, lookup2;
2410
2683
  var init_configs = __esm({
2411
2684
  "packages/agent-spawn/src/configs/index.ts"() {
2412
2685
  "use strict";
2413
- init_src2();
2686
+ init_src3();
2414
2687
  init_claude_code2();
2415
2688
  init_codex2();
2416
2689
  init_opencode2();
@@ -2445,7 +2718,7 @@ function resolveConfig(agentId) {
2445
2718
  var init_resolve_config = __esm({
2446
2719
  "packages/agent-spawn/src/configs/resolve-config.ts"() {
2447
2720
  "use strict";
2448
- init_src2();
2721
+ init_src3();
2449
2722
  init_configs();
2450
2723
  }
2451
2724
  });
@@ -2528,7 +2801,7 @@ function buildCliArgs(config2, options, stdinMode) {
2528
2801
  }
2529
2802
  return args;
2530
2803
  }
2531
- async function spawn2(agentId, options, context) {
2804
+ async function spawn3(agentId, options, context) {
2532
2805
  const { agentId: resolvedId, binaryName, spawnConfig } = resolveCliConfig(agentId);
2533
2806
  const stdinMode = options.useStdin && spawnConfig.stdinMode ? spawnConfig.stdinMode : void 0;
2534
2807
  const spawnArgs = buildCliArgs(spawnConfig, options, stdinMode);
@@ -3341,7 +3614,7 @@ var init_static = __esm({
3341
3614
  });
3342
3615
 
3343
3616
  // packages/design-system/src/index.ts
3344
- var init_src3 = __esm({
3617
+ var init_src4 = __esm({
3345
3618
  "packages/design-system/src/index.ts"() {
3346
3619
  "use strict";
3347
3620
  init_tokens();
@@ -3434,7 +3707,7 @@ async function renderAcpStream(events) {
3434
3707
  var init_renderer = __esm({
3435
3708
  "packages/agent-spawn/src/acp/renderer.ts"() {
3436
3709
  "use strict";
3437
- init_src3();
3710
+ init_src4();
3438
3711
  }
3439
3712
  });
3440
3713
 
@@ -3444,13 +3717,13 @@ function truncate2(text4, maxLength) {
3444
3717
  if (maxLength <= 3) return text4.slice(0, maxLength);
3445
3718
  return `${text4.slice(0, maxLength - 3)}...`;
3446
3719
  }
3447
- function isNonEmptyString(value) {
3720
+ function isNonEmptyString2(value) {
3448
3721
  return typeof value === "string" && value.length > 0;
3449
3722
  }
3450
3723
  function extractThreadId(value) {
3451
3724
  if (!value || typeof value !== "object") return;
3452
3725
  const obj = value;
3453
- 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;
3726
+ 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;
3454
3727
  return maybeThreadId || void 0;
3455
3728
  }
3456
3729
  var init_utils = __esm({
@@ -3496,7 +3769,7 @@ async function* adaptClaude(lines) {
3496
3769
  continue;
3497
3770
  }
3498
3771
  const eventType = event.type;
3499
- if (!isNonEmptyString(eventType)) continue;
3772
+ if (!isNonEmptyString2(eventType)) continue;
3500
3773
  if (!emittedSessionStart) {
3501
3774
  const threadId = extractThreadId(event);
3502
3775
  emittedSessionStart = true;
@@ -3519,16 +3792,16 @@ async function* adaptClaude(lines) {
3519
3792
  const item = block;
3520
3793
  if (!item || typeof item !== "object") continue;
3521
3794
  const blockType = item.type;
3522
- if (!isNonEmptyString(blockType)) continue;
3795
+ if (!isNonEmptyString2(blockType)) continue;
3523
3796
  if (eventType === "assistant") {
3524
- if (blockType === "text" && isNonEmptyString(item.text)) {
3797
+ if (blockType === "text" && isNonEmptyString2(item.text)) {
3525
3798
  yield {
3526
3799
  event: "agent_message",
3527
3800
  text: item.text
3528
3801
  };
3529
3802
  continue;
3530
3803
  }
3531
- if (blockType === "tool_use" && isNonEmptyString(item.id) && isNonEmptyString(item.name)) {
3804
+ if (blockType === "tool_use" && isNonEmptyString2(item.id) && isNonEmptyString2(item.name)) {
3532
3805
  const kind = TOOL_KIND_MAP[item.name] ?? "other";
3533
3806
  toolKindsById.set(item.id, kind);
3534
3807
  yield {
@@ -3542,25 +3815,25 @@ async function* adaptClaude(lines) {
3542
3815
  continue;
3543
3816
  }
3544
3817
  if (eventType === "user") {
3545
- if (!isNonEmptyString(item.tool_use_id)) continue;
3818
+ if (!isNonEmptyString2(item.tool_use_id)) continue;
3546
3819
  if (blockType !== "tool_result") continue;
3547
3820
  const kind = toolKindsById.get(item.tool_use_id);
3548
3821
  toolKindsById.delete(item.tool_use_id);
3549
- let path20;
3822
+ let path21;
3550
3823
  if (typeof item.content === "string") {
3551
- path20 = item.content;
3824
+ path21 = item.content;
3552
3825
  } else {
3553
3826
  try {
3554
- path20 = JSON.stringify(item.content);
3827
+ path21 = JSON.stringify(item.content);
3555
3828
  } catch {
3556
- path20 = String(item.content);
3829
+ path21 = String(item.content);
3557
3830
  }
3558
3831
  }
3559
3832
  yield {
3560
3833
  event: "tool_complete",
3561
3834
  id: item.tool_use_id,
3562
3835
  kind,
3563
- path: path20
3836
+ path: path21
3564
3837
  };
3565
3838
  }
3566
3839
  }
@@ -3614,7 +3887,7 @@ async function* adaptCodex(lines) {
3614
3887
  continue;
3615
3888
  }
3616
3889
  const eventType = event.type;
3617
- if (!isNonEmptyString(eventType)) continue;
3890
+ if (!isNonEmptyString2(eventType)) continue;
3618
3891
  if (eventType === "thread.started") {
3619
3892
  const maybeThreadId = extractThreadId(event);
3620
3893
  yield { event: "session_start", threadId: maybeThreadId };
@@ -3638,23 +3911,23 @@ async function* adaptCodex(lines) {
3638
3911
  const item = event.item ?? null;
3639
3912
  if (!item || typeof item !== "object") continue;
3640
3913
  const itemType = item.type;
3641
- if (!isNonEmptyString(itemType)) continue;
3914
+ if (!isNonEmptyString2(itemType)) continue;
3642
3915
  if (eventType === "item.started") {
3643
- if (!isNonEmptyString(item.id)) continue;
3916
+ if (!isNonEmptyString2(item.id)) continue;
3644
3917
  let kind;
3645
3918
  let title;
3646
3919
  if (itemType === "command_execution") {
3647
3920
  kind = "exec";
3648
- title = truncate2(isNonEmptyString(item.command) ? item.command : "", 80);
3921
+ title = truncate2(isNonEmptyString2(item.command) ? item.command : "", 80);
3649
3922
  } else if (itemType === "file_edit") {
3650
3923
  kind = "edit";
3651
- title = isNonEmptyString(item.path) ? item.path : "";
3924
+ title = isNonEmptyString2(item.path) ? item.path : "";
3652
3925
  } else if (itemType === "thinking") {
3653
3926
  kind = "think";
3654
3927
  title = "thinking...";
3655
3928
  } else if (itemType === "mcp_tool_call") {
3656
- const server = isNonEmptyString(item.server) ? item.server : "unknown";
3657
- const tool = isNonEmptyString(item.tool) ? item.tool : "unknown";
3929
+ const server = isNonEmptyString2(item.server) ? item.server : "unknown";
3930
+ const tool = isNonEmptyString2(item.tool) ? item.tool : "unknown";
3658
3931
  kind = "other";
3659
3932
  title = `${server}.${tool}`;
3660
3933
  }
@@ -3667,25 +3940,25 @@ async function* adaptCodex(lines) {
3667
3940
  }
3668
3941
  if (eventType === "item.completed") {
3669
3942
  if (itemType === "agent_message") {
3670
- if (!isNonEmptyString(item.text)) continue;
3943
+ if (!isNonEmptyString2(item.text)) continue;
3671
3944
  yield { event: "agent_message", text: item.text };
3672
3945
  continue;
3673
3946
  }
3674
3947
  if (itemType === "reasoning") {
3675
- const text4 = isNonEmptyString(item.text) ? item.text : isNonEmptyString(item.content) ? item.content : isNonEmptyString(item.summary) ? item.summary : void 0;
3948
+ const text4 = isNonEmptyString2(item.text) ? item.text : isNonEmptyString2(item.content) ? item.content : isNonEmptyString2(item.summary) ? item.summary : void 0;
3676
3949
  if (!text4) continue;
3677
3950
  yield { event: "reasoning", text: text4 };
3678
3951
  continue;
3679
3952
  }
3680
- if (!isNonEmptyString(item.id)) continue;
3953
+ if (!isNonEmptyString2(item.id)) continue;
3681
3954
  if (itemType === "command_execution" || itemType === "file_edit" || itemType === "mcp_tool_call") {
3682
3955
  const kindFromStart = toolKindById.get(item.id);
3683
3956
  const kind = kindFromStart ?? (itemType === "command_execution" ? "exec" : itemType === "file_edit" ? "edit" : "other");
3684
- 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;
3685
- const path20 = titleFromEvent ?? toolTitleById.get(item.id) ?? "";
3957
+ 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;
3958
+ const path21 = titleFromEvent ?? toolTitleById.get(item.id) ?? "";
3686
3959
  toolTitleById.delete(item.id);
3687
3960
  toolKindById.delete(item.id);
3688
- yield { event: "tool_complete", id: item.id, kind, path: path20 };
3961
+ yield { event: "tool_complete", id: item.id, kind, path: path21 };
3689
3962
  }
3690
3963
  }
3691
3964
  }
@@ -3724,9 +3997,9 @@ async function* adaptKimi(lines) {
3724
3997
  }
3725
3998
  }
3726
3999
  const role = event.role;
3727
- if (!isNonEmptyString(role) || role !== "assistant") continue;
4000
+ if (!isNonEmptyString2(role) || role !== "assistant") continue;
3728
4001
  const content = event.content;
3729
- if (!isNonEmptyString(content)) continue;
4002
+ if (!isNonEmptyString2(content)) continue;
3730
4003
  yield { event: "agent_message", text: content };
3731
4004
  }
3732
4005
  }
@@ -3755,7 +4028,7 @@ async function* adaptNative(lines) {
3755
4028
  continue;
3756
4029
  }
3757
4030
  const maybeEventType = event?.event;
3758
- if (!isNonEmptyString(maybeEventType)) {
4031
+ if (!isNonEmptyString2(maybeEventType)) {
3759
4032
  yield {
3760
4033
  event: "error",
3761
4034
  message: `[adaptNative] Line missing string "event" field: ${truncate2(line, 200)}`
@@ -3814,23 +4087,23 @@ async function* adaptOpenCode(lines) {
3814
4087
  }
3815
4088
  if (!event || typeof event !== "object") continue;
3816
4089
  const sessionID = extractThreadId(event);
3817
- if (!emittedSessionStart && isNonEmptyString(sessionID)) {
4090
+ if (!emittedSessionStart && isNonEmptyString2(sessionID)) {
3818
4091
  emittedSessionStart = true;
3819
4092
  yield { event: "session_start", threadId: sessionID };
3820
4093
  }
3821
4094
  const eventType = event.type;
3822
- if (!isNonEmptyString(eventType)) continue;
4095
+ if (!isNonEmptyString2(eventType)) continue;
3823
4096
  if (eventType === "text") {
3824
4097
  const part = event.part ?? null;
3825
4098
  if (!part || typeof part !== "object") continue;
3826
- if (!isNonEmptyString(part.text)) continue;
4099
+ if (!isNonEmptyString2(part.text)) continue;
3827
4100
  yield { event: "agent_message", text: part.text };
3828
4101
  continue;
3829
4102
  }
3830
4103
  if (eventType === "tool_use") {
3831
4104
  const part = event.part ?? null;
3832
4105
  if (!part || typeof part !== "object") continue;
3833
- if (!isNonEmptyString(part.callID) || !isNonEmptyString(part.tool)) continue;
4106
+ if (!isNonEmptyString2(part.callID) || !isNonEmptyString2(part.tool)) continue;
3834
4107
  const state = part.state ?? null;
3835
4108
  if (!state || typeof state !== "object") continue;
3836
4109
  const kind = guessToolKind(part.tool);
@@ -3842,7 +4115,7 @@ async function* adaptOpenCode(lines) {
3842
4115
  const maybeInput = state.input;
3843
4116
  if (kind === "exec" && maybeInput && typeof maybeInput === "object") {
3844
4117
  const command = maybeInput.command;
3845
- if (isNonEmptyString(command)) {
4118
+ if (isNonEmptyString2(command)) {
3846
4119
  title = truncate2(command, 80);
3847
4120
  }
3848
4121
  }
@@ -4046,7 +4319,7 @@ var init_spawn2 = __esm({
4046
4319
  });
4047
4320
 
4048
4321
  // packages/agent-spawn/src/index.ts
4049
- var init_src4 = __esm({
4322
+ var init_src5 = __esm({
4050
4323
  "packages/agent-spawn/src/index.ts"() {
4051
4324
  "use strict";
4052
4325
  init_run_command();
@@ -4226,8 +4499,8 @@ var init_shared = __esm({
4226
4499
  "use strict";
4227
4500
  init_context();
4228
4501
  init_isolated_env();
4229
- init_src4();
4230
- init_src2();
4502
+ init_src5();
4503
+ init_src3();
4231
4504
  }
4232
4505
  });
4233
4506
 
@@ -4348,7 +4621,7 @@ import path7 from "node:path";
4348
4621
  function createCliEnvironment(init) {
4349
4622
  const platform = init.platform ?? process.platform;
4350
4623
  const variables = init.variables ?? process.env;
4351
- const credentialsPath = resolveCredentialsPath(init.homeDir);
4624
+ const configPath = resolveConfigPath(init.homeDir);
4352
4625
  const logDir = resolveLogDir(init.homeDir);
4353
4626
  const { poeApiBaseUrl, poeBaseUrl } = resolvePoeBaseUrls(variables);
4354
4627
  const resolveHomePath = (...segments) => path7.join(init.homeDir, ...segments);
@@ -4357,7 +4630,7 @@ function createCliEnvironment(init) {
4357
4630
  cwd: init.cwd,
4358
4631
  homeDir: init.homeDir,
4359
4632
  platform,
4360
- credentialsPath,
4633
+ configPath,
4361
4634
  logDir,
4362
4635
  poeApiBaseUrl,
4363
4636
  poeBaseUrl,
@@ -4366,8 +4639,8 @@ function createCliEnvironment(init) {
4366
4639
  getVariable
4367
4640
  };
4368
4641
  }
4369
- function resolveCredentialsPath(homeDir) {
4370
- return path7.join(homeDir, ".poe-code", "credentials.json");
4642
+ function resolveConfigPath(homeDir) {
4643
+ return path7.join(homeDir, ".poe-code", "config.json");
4371
4644
  }
4372
4645
  function resolveLogDir(homeDir) {
4373
4646
  return path7.join(homeDir, ".poe-code", "logs");
@@ -4538,7 +4811,7 @@ function createServiceRegistry() {
4538
4811
  var init_service_registry = __esm({
4539
4812
  "src/cli/service-registry.ts"() {
4540
4813
  "use strict";
4541
- init_src2();
4814
+ init_src3();
4542
4815
  }
4543
4816
  });
4544
4817
 
@@ -4806,7 +5079,7 @@ function isSilentError(error2) {
4806
5079
  }
4807
5080
  return error2.name === "SilentError" || error2.name === "OperationCancelledError";
4808
5081
  }
4809
- var CliError, SilentError, ApiError, ValidationError, AuthenticationError, OperationCancelledError;
5082
+ var CliError, SilentError, ApiError, ValidationError, OperationCancelledError;
4810
5083
  var init_errors = __esm({
4811
5084
  "src/cli/errors.ts"() {
4812
5085
  "use strict";
@@ -4846,11 +5119,6 @@ var init_errors = __esm({
4846
5119
  super(message, context, { isUserError: true });
4847
5120
  }
4848
5121
  };
4849
- AuthenticationError = class extends CliError {
4850
- constructor(message, context) {
4851
- super(message, context, { isUserError: true });
4852
- }
4853
- };
4854
5122
  OperationCancelledError = class extends SilentError {
4855
5123
  constructor(message = "Operation cancelled.") {
4856
5124
  super(message, { isUserError: true });
@@ -5059,7 +5327,7 @@ function createLoggerFactory(emitter, theme) {
5059
5327
  var init_logger2 = __esm({
5060
5328
  "src/cli/logger.ts"() {
5061
5329
  "use strict";
5062
- init_src3();
5330
+ init_src4();
5063
5331
  init_errors();
5064
5332
  }
5065
5333
  });
@@ -5447,7 +5715,7 @@ async function ensureIsolatedConfigForService(input) {
5447
5715
  container.env,
5448
5716
  isolated,
5449
5717
  adapter.name,
5450
- container.fs
5718
+ container.readApiKey
5451
5719
  );
5452
5720
  const hasConfig = await isolatedConfigExists(
5453
5721
  container.fs,
@@ -5522,7 +5790,7 @@ function createPoeCodeCommandRunner(input) {
5522
5790
  container.env,
5523
5791
  adapter.isolatedEnv,
5524
5792
  adapter.name,
5525
- container.fs
5793
+ container.readApiKey
5526
5794
  );
5527
5795
  if (adapter.isolatedEnv.requiresConfig !== false) {
5528
5796
  const hasConfig = await isolatedConfigExists(
@@ -5553,7 +5821,7 @@ function createPoeCodeCommandRunner(input) {
5553
5821
  const resolvedSettings = await resolveCliSettings(
5554
5822
  adapter.isolatedEnv.cliSettings,
5555
5823
  container.env,
5556
- container.fs
5824
+ container.readApiKey
5557
5825
  );
5558
5826
  forwarded = buildArgsWithMergedSettings(forwarded, resolvedSettings);
5559
5827
  }
@@ -5582,11 +5850,11 @@ var init_poe_code_command_runner = __esm({
5582
5850
 
5583
5851
  // src/sdk/container.ts
5584
5852
  import * as fs2 from "node:fs/promises";
5585
- import * as os2 from "node:os";
5853
+ import * as os from "node:os";
5586
5854
  import * as nodeFsSync from "node:fs";
5587
5855
  function createSdkContainer(options) {
5588
5856
  const cwd = options?.cwd ?? process.cwd();
5589
- const homeDir = options?.homeDir ?? os2.homedir();
5857
+ const homeDir = options?.homeDir ?? os.homedir();
5590
5858
  const variables = options?.variables ?? process.env;
5591
5859
  const verbose = options?.verbose ?? false;
5592
5860
  const environment = createCliEnvironment({
@@ -5605,23 +5873,44 @@ function createSdkContainer(options) {
5605
5873
  });
5606
5874
  loggerFactory.setErrorLogger(errorLogger);
5607
5875
  const asyncFs = {
5608
- readFile: ((path20, encoding) => {
5876
+ readFile: ((path21, encoding) => {
5609
5877
  if (encoding) {
5610
- return fs2.readFile(path20, encoding);
5878
+ return fs2.readFile(path21, encoding);
5611
5879
  }
5612
- return fs2.readFile(path20);
5880
+ return fs2.readFile(path21);
5613
5881
  }),
5614
- writeFile: (path20, data, opts) => fs2.writeFile(path20, data, opts),
5615
- mkdir: (path20, opts) => fs2.mkdir(path20, opts).then(() => {
5882
+ writeFile: (path21, data, opts) => fs2.writeFile(path21, data, opts),
5883
+ mkdir: (path21, opts) => fs2.mkdir(path21, opts).then(() => {
5616
5884
  }),
5617
- stat: (path20) => fs2.stat(path20),
5618
- rm: (path20, opts) => fs2.rm(path20, opts),
5619
- unlink: (path20) => fs2.unlink(path20),
5620
- readdir: (path20) => fs2.readdir(path20),
5885
+ stat: (path21) => fs2.stat(path21),
5886
+ rm: (path21, opts) => fs2.rm(path21, opts),
5887
+ unlink: (path21) => fs2.unlink(path21),
5888
+ readdir: (path21) => fs2.readdir(path21),
5621
5889
  copyFile: (src, dest) => fs2.copyFile(src, dest),
5622
- chmod: (path20, mode) => fs2.chmod(path20, mode)
5890
+ chmod: (path21, mode) => fs2.chmod(path21, mode)
5623
5891
  };
5624
5892
  const contextFactory = createCommandContextFactory({ fs: asyncFs });
5893
+ const authFs = {
5894
+ readFile: (filePath, encoding) => fs2.readFile(filePath, encoding),
5895
+ writeFile: (filePath, data, options2) => fs2.writeFile(filePath, data, options2),
5896
+ mkdir: (directoryPath, options2) => fs2.mkdir(directoryPath, options2).then(() => void 0),
5897
+ unlink: (filePath) => fs2.unlink(filePath),
5898
+ chmod: (filePath, mode) => fs2.chmod(filePath, mode)
5899
+ };
5900
+ const { store: authStore } = createAuthStore({
5901
+ env: variables,
5902
+ platform: process.platform,
5903
+ fileStore: {
5904
+ fs: authFs,
5905
+ getHomeDirectory: () => homeDir
5906
+ },
5907
+ legacyCredentials: {
5908
+ fs: authFs,
5909
+ getHomeDirectory: () => homeDir
5910
+ }
5911
+ });
5912
+ const readApiKey = authStore.getApiKey.bind(authStore);
5913
+ const writeApiKey = authStore.setApiKey.bind(authStore);
5625
5914
  const noopPrompts = async () => {
5626
5915
  throw new Error("SDK does not support interactive prompts");
5627
5916
  };
@@ -5630,15 +5919,8 @@ function createSdkContainer(options) {
5630
5919
  prompts: noopPrompts,
5631
5920
  promptLibrary,
5632
5921
  apiKeyStore: {
5633
- read: () => loadCredentials({
5634
- fs: asyncFs,
5635
- filePath: environment.credentialsPath
5636
- }),
5637
- write: (value) => saveCredentials({
5638
- fs: asyncFs,
5639
- filePath: environment.credentialsPath,
5640
- apiKey: value
5641
- })
5922
+ read: readApiKey,
5923
+ write: writeApiKey
5642
5924
  },
5643
5925
  confirm: async () => true
5644
5926
  });
@@ -5685,7 +5967,9 @@ function createSdkContainer(options) {
5685
5967
  platform: process.platform,
5686
5968
  variables
5687
5969
  }
5688
- }
5970
+ },
5971
+ readApiKey,
5972
+ writeApiKey
5689
5973
  };
5690
5974
  return container;
5691
5975
  }
@@ -5699,15 +5983,15 @@ var init_container = __esm({
5699
5983
  init_options();
5700
5984
  init_logger2();
5701
5985
  init_error_logger();
5702
- init_src4();
5986
+ init_src5();
5703
5987
  await init_providers();
5704
5988
  init_poe_code_command_runner();
5705
- init_credentials2();
5989
+ init_src();
5706
5990
  }
5707
5991
  });
5708
5992
 
5709
5993
  // src/sdk/spawn.ts
5710
- function spawn3(service, promptOrOptions, maybeOptions) {
5994
+ function spawn4(service, promptOrOptions, maybeOptions) {
5711
5995
  const options = typeof promptOrOptions === "string" ? { ...maybeOptions, prompt: promptOrOptions } : promptOrOptions;
5712
5996
  const emptyEvents = (async function* () {
5713
5997
  })();
@@ -5770,7 +6054,7 @@ function spawn3(service, promptOrOptions, maybeOptions) {
5770
6054
  }
5771
6055
  if (spawnConfig && spawnConfig.kind === "cli") {
5772
6056
  resolveEventsOnce(emptyEvents);
5773
- return spawn2(service, {
6057
+ return spawn3(service, {
5774
6058
  prompt: options.prompt,
5775
6059
  cwd: options.cwd,
5776
6060
  model: options.model,
@@ -5804,9 +6088,9 @@ var init_spawn3 = __esm({
5804
6088
  init_credentials();
5805
6089
  init_spawn_core();
5806
6090
  await init_container();
5807
- init_src4();
5808
- spawn3.pretty = async function pretty(service, promptOrOptions, maybeOptions) {
5809
- const { events, result } = spawn3(service, promptOrOptions, maybeOptions);
6091
+ init_src5();
6092
+ spawn4.pretty = async function pretty(service, promptOrOptions, maybeOptions) {
6093
+ const { events, result } = spawn4(service, promptOrOptions, maybeOptions);
5810
6094
  await renderAcpStream(events);
5811
6095
  return result;
5812
6096
  };
@@ -5877,13 +6161,13 @@ async function readErrorBody(response) {
5877
6161
  }
5878
6162
  }
5879
6163
  function extractTextContent(data) {
5880
- if (!isRecord2(data)) return void 0;
6164
+ if (!isRecord3(data)) return void 0;
5881
6165
  const choices = data.choices;
5882
6166
  if (!Array.isArray(choices) || choices.length === 0) return void 0;
5883
6167
  const first = choices[0];
5884
- if (!isRecord2(first)) return void 0;
6168
+ if (!isRecord3(first)) return void 0;
5885
6169
  const message = first.message;
5886
- if (!isRecord2(message)) return void 0;
6170
+ if (!isRecord3(message)) return void 0;
5887
6171
  return typeof message.content === "string" ? message.content : void 0;
5888
6172
  }
5889
6173
  function extractMediaFromCompletion(data) {
@@ -5891,14 +6175,14 @@ function extractMediaFromCompletion(data) {
5891
6175
  if (!content) return {};
5892
6176
  try {
5893
6177
  const parsed = JSON.parse(content);
5894
- if (isRecord2(parsed) && typeof parsed.url === "string") {
6178
+ if (isRecord3(parsed) && typeof parsed.url === "string") {
5895
6179
  return {
5896
6180
  url: parsed.url,
5897
6181
  mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0,
5898
6182
  data: typeof parsed.data === "string" ? parsed.data : void 0
5899
6183
  };
5900
6184
  }
5901
- if (isRecord2(parsed) && typeof parsed.data === "string") {
6185
+ if (isRecord3(parsed) && typeof parsed.data === "string") {
5902
6186
  return {
5903
6187
  data: parsed.data,
5904
6188
  mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0
@@ -5932,7 +6216,7 @@ function isValidUrl(value) {
5932
6216
  return false;
5933
6217
  }
5934
6218
  }
5935
- function isRecord2(value) {
6219
+ function isRecord3(value) {
5936
6220
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
5937
6221
  }
5938
6222
  var init_llm_client = __esm({
@@ -5956,17 +6240,8 @@ async function initializeClient(options) {
5956
6240
  if (globalClient !== null) {
5957
6241
  return;
5958
6242
  }
5959
- const apiKey = await loadCredentials({
5960
- fs: options.fs,
5961
- filePath: options.credentialsPath
5962
- });
5963
- if (!apiKey) {
5964
- throw new AuthenticationError(
5965
- "Poe API key not found. Run 'poe-code login' first."
5966
- );
5967
- }
5968
6243
  const client = createPoeClient({
5969
- apiKey,
6244
+ apiKey: options.apiKey,
5970
6245
  baseUrl: options.baseUrl,
5971
6246
  httpClient: options.httpClient
5972
6247
  });
@@ -5976,8 +6251,6 @@ var globalClient;
5976
6251
  var init_client_instance = __esm({
5977
6252
  "src/services/client-instance.ts"() {
5978
6253
  "use strict";
5979
- init_errors();
5980
- init_credentials2();
5981
6254
  init_llm_client();
5982
6255
  globalClient = null;
5983
6256
  }
@@ -6018,19 +6291,33 @@ function createCliContainer(dependencies) {
6018
6291
  });
6019
6292
  const commandRunner = dependencies.commandRunner ?? runCommand;
6020
6293
  const promptLibrary = createPromptLibrary();
6294
+ const authFs = {
6295
+ readFile: (filePath, encoding) => dependencies.fs.readFile(filePath, encoding),
6296
+ writeFile: (filePath, data, opts) => dependencies.fs.writeFile(filePath, data, opts),
6297
+ mkdir: (directoryPath, opts) => dependencies.fs.mkdir(directoryPath, opts).then(() => void 0),
6298
+ unlink: (filePath) => dependencies.fs.unlink(filePath),
6299
+ chmod: (filePath, mode) => dependencies.fs.chmod ? dependencies.fs.chmod(filePath, mode) : Promise.resolve()
6300
+ };
6301
+ const { store: authStore } = createAuthStore({
6302
+ env: dependencies.env.variables,
6303
+ platform: dependencies.env.platform,
6304
+ fileStore: {
6305
+ fs: authFs,
6306
+ getHomeDirectory: () => dependencies.env.homeDir
6307
+ },
6308
+ legacyCredentials: {
6309
+ fs: authFs,
6310
+ getHomeDirectory: () => dependencies.env.homeDir
6311
+ }
6312
+ });
6313
+ const readApiKey = authStore.getApiKey.bind(authStore);
6314
+ const writeApiKey = authStore.setApiKey.bind(authStore);
6021
6315
  const options = createOptionResolvers({
6022
6316
  prompts: dependencies.prompts,
6023
6317
  promptLibrary,
6024
6318
  apiKeyStore: {
6025
- read: () => loadCredentials({
6026
- fs: dependencies.fs,
6027
- filePath: environment.credentialsPath
6028
- }),
6029
- write: (value) => saveCredentials({
6030
- fs: dependencies.fs,
6031
- filePath: environment.credentialsPath,
6032
- apiKey: value
6033
- })
6319
+ read: readApiKey,
6320
+ write: writeApiKey
6034
6321
  },
6035
6322
  confirm: async (message) => {
6036
6323
  const result = await confirm2({ message });
@@ -6066,14 +6353,16 @@ function createCliContainer(dependencies) {
6066
6353
  httpClient,
6067
6354
  commandRunner: wrappedRunner,
6068
6355
  providers,
6069
- dependencies
6356
+ dependencies,
6357
+ readApiKey,
6358
+ writeApiKey
6070
6359
  };
6071
6360
  return container;
6072
6361
  }
6073
6362
  var init_container2 = __esm({
6074
6363
  async "src/cli/container.ts"() {
6075
6364
  "use strict";
6076
- init_credentials2();
6365
+ init_src();
6077
6366
  init_environment();
6078
6367
  init_service_registry();
6079
6368
  init_context();
@@ -6081,14 +6370,176 @@ var init_container2 = __esm({
6081
6370
  init_options();
6082
6371
  init_logger2();
6083
6372
  init_error_logger();
6373
+ init_src5();
6084
6374
  init_src4();
6085
- init_src3();
6086
6375
  await init_providers();
6087
6376
  init_poe_code_command_runner();
6088
6377
  init_errors();
6089
6378
  }
6090
6379
  });
6091
6380
 
6381
+ // src/services/config.ts
6382
+ import path10 from "node:path";
6383
+ async function deleteConfig(options) {
6384
+ const { fs: fs3, filePath } = options;
6385
+ try {
6386
+ await fs3.unlink(filePath);
6387
+ return true;
6388
+ } catch (error2) {
6389
+ if (isNotFound(error2)) {
6390
+ return false;
6391
+ }
6392
+ throw error2;
6393
+ }
6394
+ }
6395
+ async function loadConfiguredServices(options) {
6396
+ const { fs: fs3, filePath } = options;
6397
+ const document = await readConfigDocument(fs3, filePath);
6398
+ return { ...document.configured_services ?? {} };
6399
+ }
6400
+ async function saveConfiguredService(options) {
6401
+ const { fs: fs3, filePath, service, metadata } = options;
6402
+ const document = await readConfigDocument(fs3, filePath);
6403
+ const normalized = normalizeConfiguredServiceMetadata(metadata);
6404
+ document.configured_services = {
6405
+ ...document.configured_services ?? {},
6406
+ [service]: normalized
6407
+ };
6408
+ await writeConfigDocument(fs3, filePath, document);
6409
+ }
6410
+ async function unconfigureService(options) {
6411
+ const { fs: fs3, filePath, service } = options;
6412
+ const document = await readConfigDocument(fs3, filePath);
6413
+ const services = document.configured_services;
6414
+ if (!services || !(service in services)) {
6415
+ return false;
6416
+ }
6417
+ delete services[service];
6418
+ if (Object.keys(services).length === 0) {
6419
+ delete document.configured_services;
6420
+ }
6421
+ await writeConfigDocument(fs3, filePath, document);
6422
+ return true;
6423
+ }
6424
+ function normalizeConfiguredServiceMetadata(metadata) {
6425
+ const seen = /* @__PURE__ */ new Set();
6426
+ const files = [];
6427
+ for (const entry of metadata.files ?? []) {
6428
+ if (typeof entry !== "string" || entry.length === 0) {
6429
+ continue;
6430
+ }
6431
+ if (!seen.has(entry)) {
6432
+ files.push(entry);
6433
+ seen.add(entry);
6434
+ }
6435
+ }
6436
+ return {
6437
+ files
6438
+ };
6439
+ }
6440
+ async function readConfigDocument(fs3, filePath) {
6441
+ try {
6442
+ const raw = await fs3.readFile(filePath, "utf8");
6443
+ return await parseConfigDocument(fs3, filePath, raw);
6444
+ } catch (error2) {
6445
+ if (isNotFound(error2)) {
6446
+ return migrateLegacyCredentialsFile(fs3, filePath);
6447
+ }
6448
+ throw error2;
6449
+ }
6450
+ }
6451
+ async function migrateLegacyCredentialsFile(fs3, configPath) {
6452
+ const legacyPath = path10.join(path10.dirname(configPath), "credentials.json");
6453
+ try {
6454
+ const raw = await fs3.readFile(legacyPath, "utf8");
6455
+ const document = await parseConfigDocument(fs3, legacyPath, raw);
6456
+ await writeConfigDocument(fs3, configPath, document);
6457
+ await fs3.unlink(legacyPath);
6458
+ return document;
6459
+ } catch {
6460
+ return {};
6461
+ }
6462
+ }
6463
+ async function parseConfigDocument(fs3, filePath, raw) {
6464
+ try {
6465
+ const parsed = JSON.parse(raw);
6466
+ return normalizeConfigDocument(parsed);
6467
+ } catch (error2) {
6468
+ if (error2 instanceof SyntaxError) {
6469
+ await recoverInvalidConfig(fs3, filePath, raw);
6470
+ return {};
6471
+ }
6472
+ throw error2;
6473
+ }
6474
+ }
6475
+ function normalizeConfigDocument(value) {
6476
+ if (!isRecord4(value)) {
6477
+ return {};
6478
+ }
6479
+ const document = {};
6480
+ if (typeof value.apiKey === "string" && value.apiKey.length > 0) {
6481
+ document.apiKey = value.apiKey;
6482
+ }
6483
+ const services = normalizeConfiguredServices(value.configured_services);
6484
+ if (Object.keys(services).length > 0) {
6485
+ document.configured_services = services;
6486
+ }
6487
+ return document;
6488
+ }
6489
+ function normalizeConfiguredServices(value) {
6490
+ if (!isRecord4(value)) {
6491
+ return {};
6492
+ }
6493
+ const entries = {};
6494
+ for (const [key, entry] of Object.entries(value)) {
6495
+ if (!isRecord4(entry)) {
6496
+ continue;
6497
+ }
6498
+ const normalized = normalizeConfiguredServiceMetadata({
6499
+ files: Array.isArray(entry.files) ? entry.files : []
6500
+ });
6501
+ entries[key] = normalized;
6502
+ }
6503
+ return entries;
6504
+ }
6505
+ async function writeConfigDocument(fs3, filePath, document) {
6506
+ await fs3.mkdir(path10.dirname(filePath), { recursive: true });
6507
+ const payload = {};
6508
+ if (document.apiKey) {
6509
+ payload.apiKey = document.apiKey;
6510
+ }
6511
+ if (document.configured_services) {
6512
+ payload.configured_services = document.configured_services;
6513
+ }
6514
+ await fs3.writeFile(filePath, `${JSON.stringify(payload, null, 2)}
6515
+ `, {
6516
+ encoding: "utf8"
6517
+ });
6518
+ }
6519
+ async function recoverInvalidConfig(fs3, filePath, content) {
6520
+ const backupPath = createInvalidBackupPath(filePath);
6521
+ await fs3.writeFile(backupPath, content, { encoding: "utf8" });
6522
+ await fs3.writeFile(filePath, EMPTY_DOCUMENT, { encoding: "utf8" });
6523
+ }
6524
+ function createInvalidBackupPath(filePath) {
6525
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
6526
+ const dir = path10.dirname(filePath);
6527
+ const base = path10.basename(filePath);
6528
+ return path10.join(dir, `${base}.invalid-${timestamp}.json`);
6529
+ }
6530
+ function isRecord4(value) {
6531
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
6532
+ }
6533
+ var EMPTY_DOCUMENT;
6534
+ var init_config = __esm({
6535
+ "src/services/config.ts"() {
6536
+ "use strict";
6537
+ init_src2();
6538
+ EMPTY_DOCUMENT = `${JSON.stringify({}, null, 2)}
6539
+ `;
6540
+ }
6541
+ });
6542
+
6092
6543
  // src/cli/commands/configure.ts
6093
6544
  function registerConfigureCommand(program, container) {
6094
6545
  const serviceNames = container.registry.list().map((service) => service.name);
@@ -6153,7 +6604,7 @@ async function executeConfigure(program, container, service, options) {
6153
6604
  if (!flags.dryRun) {
6154
6605
  await saveConfiguredService({
6155
6606
  fs: container.fs,
6156
- filePath: providerContext.env.credentialsPath,
6607
+ filePath: providerContext.env.configPath,
6157
6608
  service: canonicalService,
6158
6609
  metadata: {
6159
6610
  files: tracker.files()
@@ -6253,7 +6704,7 @@ var init_configure = __esm({
6253
6704
  "use strict";
6254
6705
  init_shared();
6255
6706
  init_errors();
6256
- init_credentials2();
6707
+ init_config();
6257
6708
  init_mutation_events();
6258
6709
  init_configure_payload();
6259
6710
  serviceSelectionPrompt = (action) => `Pick an agent to ${action}:`;
@@ -6261,7 +6712,7 @@ var init_configure = __esm({
6261
6712
  });
6262
6713
 
6263
6714
  // src/cli/commands/spawn.ts
6264
- import path10 from "node:path";
6715
+ import path11 from "node:path";
6265
6716
  function registerSpawnCommand(program, container, options = {}) {
6266
6717
  const spawnServices = container.registry.list().filter((service) => typeof service.spawn === "function" || getSpawnConfig(service.name)).map((service) => service.name);
6267
6718
  const extraServices = options.extraServices ?? [];
@@ -6393,7 +6844,7 @@ function registerSpawnCommand(program, container, options = {}) {
6393
6844
  if (!proceed) {
6394
6845
  return;
6395
6846
  }
6396
- const { events, result } = spawn3(canonicalService, {
6847
+ const { events, result } = spawn4(canonicalService, {
6397
6848
  prompt: spawnOptions.prompt,
6398
6849
  args: spawnOptions.args,
6399
6850
  model: spawnOptions.model,
@@ -6440,7 +6891,7 @@ Resume: ${resumeCommand}`));
6440
6891
  async function confirmUnconfiguredService(container, service, label, flags) {
6441
6892
  const configuredServices = await loadConfiguredServices({
6442
6893
  fs: container.fs,
6443
- filePath: container.env.credentialsPath
6894
+ filePath: container.env.configPath
6444
6895
  });
6445
6896
  if (service in configuredServices) {
6446
6897
  return true;
@@ -6460,10 +6911,10 @@ function resolveSpawnWorkingDirectory2(baseDir, candidate) {
6460
6911
  if (!candidate || candidate.trim().length === 0) {
6461
6912
  return void 0;
6462
6913
  }
6463
- if (path10.isAbsolute(candidate)) {
6914
+ if (path11.isAbsolute(candidate)) {
6464
6915
  return candidate;
6465
6916
  }
6466
- return path10.resolve(baseDir, candidate);
6917
+ return path11.resolve(baseDir, candidate);
6467
6918
  }
6468
6919
  function parseMcpSpawnConfig(input) {
6469
6920
  if (!input) {
@@ -6556,9 +7007,9 @@ function isObjectRecord(value) {
6556
7007
  var init_spawn4 = __esm({
6557
7008
  async "src/cli/commands/spawn.ts"() {
6558
7009
  "use strict";
7010
+ init_src5();
6559
7011
  init_src4();
6560
- init_src3();
6561
- init_credentials2();
7012
+ init_config();
6562
7013
  init_shared();
6563
7014
  init_spawn_core();
6564
7015
  await init_spawn3();
@@ -6567,7 +7018,7 @@ var init_spawn4 = __esm({
6567
7018
  });
6568
7019
 
6569
7020
  // src/sdk/research.ts
6570
- import path11 from "node:path";
7021
+ import path12 from "node:path";
6571
7022
  async function research(container, options) {
6572
7023
  const logger2 = options.logger;
6573
7024
  const source = await resolveSource({
@@ -6577,7 +7028,7 @@ async function research(container, options) {
6577
7028
  });
6578
7029
  const researchPrompt = buildResearchPrompt(options.prompt);
6579
7030
  const mode = options.mode ?? "read";
6580
- const { events, result } = spawn3(options.agent, {
7031
+ const { events, result } = spawn4(options.agent, {
6581
7032
  prompt: researchPrompt,
6582
7033
  args: options.args ?? [],
6583
7034
  model: options.model,
@@ -6602,7 +7053,7 @@ async function research(container, options) {
6602
7053
  markdown: markdownOutput
6603
7054
  });
6604
7055
  outputPath = buildOutputPath(container.env.homeDir, options.prompt);
6605
- await ensureDirectory2(container.fs, path11.dirname(outputPath));
7056
+ await ensureDirectory2(container.fs, path12.dirname(outputPath));
6606
7057
  await container.fs.writeFile(outputPath, document, {
6607
7058
  encoding: "utf8"
6608
7059
  });
@@ -6677,7 +7128,7 @@ function buildResearchDocument(input) {
6677
7128
  }
6678
7129
  function buildClonePath(homeDir, github) {
6679
7130
  const slug = extractRepoSlug(github);
6680
- return path11.join(homeDir, ".poe-code", "repos", slug);
7131
+ return path12.join(homeDir, ".poe-code", "repos", slug);
6681
7132
  }
6682
7133
  function extractRepoSlug(value) {
6683
7134
  const trimmed = value.trim();
@@ -6715,7 +7166,7 @@ function extractRepoSlug(value) {
6715
7166
  function buildOutputPath(homeDir, prompt, now = /* @__PURE__ */ new Date()) {
6716
7167
  const timestamp = formatTimestamp(now);
6717
7168
  const slug = buildSlug(prompt);
6718
- return path11.join(
7169
+ return path12.join(
6719
7170
  homeDir,
6720
7171
  ".poe-code",
6721
7172
  "research",
@@ -6736,7 +7187,7 @@ async function resolveSource(input) {
6736
7187
  if (options.github) {
6737
7188
  const cloneUrl = resolveGithubCloneUrl(options.github);
6738
7189
  const clonePath = buildClonePath(container.env.homeDir, options.github);
6739
- await ensureDirectory2(container.fs, path11.dirname(clonePath));
7190
+ await ensureDirectory2(container.fs, path12.dirname(clonePath));
6740
7191
  const exists = await pathExists2(container.fs, clonePath);
6741
7192
  if (!exists) {
6742
7193
  const cloneResult = await container.commandRunner(
@@ -6834,10 +7285,10 @@ function formatYamlString(value) {
6834
7285
  return JSON.stringify(value);
6835
7286
  }
6836
7287
  function resolvePath2(baseDir, candidate) {
6837
- if (path11.isAbsolute(candidate)) {
7288
+ if (path12.isAbsolute(candidate)) {
6838
7289
  return candidate;
6839
7290
  }
6840
- return path11.resolve(baseDir, candidate);
7291
+ return path12.resolve(baseDir, candidate);
6841
7292
  }
6842
7293
  function teeAcpStream(events) {
6843
7294
  const chunks = [];
@@ -6897,7 +7348,7 @@ async function removePathFallback(fs3, target) {
6897
7348
  if (stats && typeof stats.isDirectory === "function" && stats.isDirectory()) {
6898
7349
  const entries = await fs3.readdir(target);
6899
7350
  for (const entry of entries) {
6900
- await removePathFallback(fs3, path11.join(target, entry));
7351
+ await removePathFallback(fs3, path12.join(target, entry));
6901
7352
  }
6902
7353
  }
6903
7354
  try {
@@ -7001,7 +7452,7 @@ async function resolveResearchAgent(input) {
7001
7452
  if (input.flags.assumeYes) {
7002
7453
  const configured = await loadConfiguredServices({
7003
7454
  fs: input.container.fs,
7004
- filePath: input.container.env.credentialsPath
7455
+ filePath: input.container.env.configPath
7005
7456
  });
7006
7457
  const configuredService = spawnable.find(
7007
7458
  (service) => service.name in configured
@@ -7063,8 +7514,8 @@ async function resolveResearchModel(input) {
7063
7514
  var init_research2 = __esm({
7064
7515
  async "src/cli/commands/research.ts"() {
7065
7516
  "use strict";
7066
- init_src4();
7067
- init_credentials2();
7517
+ init_src5();
7518
+ init_config();
7068
7519
  await init_research();
7069
7520
  init_errors();
7070
7521
  init_shared();
@@ -7072,13 +7523,13 @@ var init_research2 = __esm({
7072
7523
  });
7073
7524
 
7074
7525
  // src/cli/isolated-env-runner.ts
7075
- import { spawn as spawn4 } from "node:child_process";
7526
+ import { spawn as spawn5 } from "node:child_process";
7076
7527
  async function isolatedEnvRunner(input) {
7077
7528
  const details = await resolveIsolatedEnvDetails(
7078
7529
  input.env,
7079
7530
  input.isolated,
7080
7531
  input.providerName,
7081
- input.fs
7532
+ input.readApiKey
7082
7533
  );
7083
7534
  let args = input.argv.slice(2);
7084
7535
  if (input.isolated.requiresConfig !== false) {
@@ -7093,11 +7544,11 @@ async function isolatedEnvRunner(input) {
7093
7544
  const resolvedSettings = await resolveCliSettings(
7094
7545
  input.isolated.cliSettings,
7095
7546
  input.env,
7096
- input.fs
7547
+ input.readApiKey
7097
7548
  );
7098
7549
  args = buildArgsWithMergedSettings(args, resolvedSettings);
7099
7550
  }
7100
- const child = spawn4(details.agentBinary, args, {
7551
+ const child = spawn5(details.agentBinary, args, {
7101
7552
  stdio: "inherit",
7102
7553
  env: {
7103
7554
  ...process.env,
@@ -7130,7 +7581,7 @@ async function configExists(fs3, filePath) {
7130
7581
  var init_isolated_env_runner = __esm({
7131
7582
  "src/cli/isolated-env-runner.ts"() {
7132
7583
  "use strict";
7133
- init_src();
7584
+ init_src2();
7134
7585
  init_isolated_env();
7135
7586
  init_cli_settings_merge();
7136
7587
  }
@@ -7180,6 +7631,7 @@ function registerWrapCommand(program, container) {
7180
7631
  await isolatedEnvRunner({
7181
7632
  env: container.env,
7182
7633
  fs: container.fs,
7634
+ readApiKey: container.readApiKey,
7183
7635
  providerName: adapter.name,
7184
7636
  isolated,
7185
7637
  argv: ["node", "poe-code", ...forwarded]
@@ -7199,46 +7651,66 @@ var init_wrap = __esm({
7199
7651
  // src/cli/commands/login.ts
7200
7652
  function registerLoginCommand(program, container) {
7201
7653
  program.command("login").description("Store a Poe API key for reuse across commands.").option("--api-key <key>", "Poe API key").action(async (options) => {
7202
- const flags = resolveCommandFlags(program);
7203
- const resources = createExecutionResources(
7654
+ await executeLogin(program, container, options);
7655
+ });
7656
+ }
7657
+ async function executeLogin(program, container, options) {
7658
+ const flags = resolveCommandFlags(program);
7659
+ const resources = createExecutionResources(
7660
+ container,
7661
+ flags,
7662
+ "login"
7663
+ );
7664
+ resources.logger.intro("login");
7665
+ try {
7666
+ const input = await resolveApiKeyInput(container, options);
7667
+ const normalized = container.options.normalizeApiKey(input);
7668
+ const configuredServices = await loadConfiguredServices({
7669
+ fs: container.fs,
7670
+ filePath: container.env.configPath
7671
+ });
7672
+ if (!flags.dryRun) {
7673
+ await container.writeApiKey(normalized);
7674
+ }
7675
+ await reconfigureServices({
7676
+ program,
7204
7677
  container,
7205
- flags,
7206
- "login"
7207
- );
7208
- resources.logger.intro("login");
7209
- try {
7210
- const configuredServices = await loadConfiguredServices({
7211
- fs: container.fs,
7212
- filePath: container.env.credentialsPath
7213
- });
7214
- const apiKey = await container.options.resolveApiKey({
7215
- value: options.apiKey,
7216
- envValue: container.env.getVariable("POE_API_KEY"),
7217
- dryRun: flags.dryRun,
7218
- assumeYes: flags.assumeYes,
7219
- allowStored: false
7220
- });
7221
- await reconfigureServices({
7222
- program,
7223
- container,
7224
- apiKey,
7225
- configuredServices
7226
- });
7227
- resources.context.complete({
7228
- success: "Logged in.",
7229
- dry: "Dry run: would save API key."
7678
+ apiKey: normalized,
7679
+ configuredServices
7680
+ });
7681
+ resources.context.complete({
7682
+ success: "Logged in.",
7683
+ dry: "Dry run: would save API key."
7684
+ });
7685
+ resources.context.finalize();
7686
+ } catch (error2) {
7687
+ if (error2 instanceof Error) {
7688
+ resources.logger.logException(error2, "login command", {
7689
+ operation: "login",
7690
+ configPath: container.env.configPath
7230
7691
  });
7231
- resources.context.finalize();
7232
- } catch (error2) {
7233
- if (error2 instanceof Error) {
7234
- resources.logger.logException(error2, "login command", {
7235
- operation: "login",
7236
- credentialsPath: container.env.credentialsPath
7237
- });
7238
- }
7239
- throw error2;
7240
7692
  }
7241
- });
7693
+ throw error2;
7694
+ }
7695
+ }
7696
+ async function resolveApiKeyInput(container, options) {
7697
+ if (options.apiKey) {
7698
+ return options.apiKey;
7699
+ }
7700
+ const envKey = container.env.getVariable("POE_API_KEY");
7701
+ if (envKey && envKey.trim().length > 0) {
7702
+ return envKey;
7703
+ }
7704
+ const descriptor = container.promptLibrary.loginApiKey();
7705
+ const response = await container.prompts(descriptor);
7706
+ const value = response[descriptor.name];
7707
+ if (typeof value !== "string" || value.trim() === "") {
7708
+ throw new ValidationError("POE API key is required.", {
7709
+ operation: "login",
7710
+ field: "apiKey"
7711
+ });
7712
+ }
7713
+ return value;
7242
7714
  }
7243
7715
  async function reconfigureServices(input) {
7244
7716
  const { program, container, apiKey, configuredServices } = input;
@@ -7292,7 +7764,8 @@ var init_login = __esm({
7292
7764
  "src/cli/commands/login.ts"() {
7293
7765
  "use strict";
7294
7766
  init_shared();
7295
- init_credentials2();
7767
+ init_config();
7768
+ init_errors();
7296
7769
  init_mutation_events();
7297
7770
  }
7298
7771
  });
@@ -7372,7 +7845,7 @@ async function executeUnconfigure(program, container, service, options) {
7372
7845
  if (!flags.dryRun) {
7373
7846
  await unconfigureService({
7374
7847
  fs: container.fs,
7375
- filePath: providerContext.env.credentialsPath,
7848
+ filePath: providerContext.env.configPath,
7376
7849
  service: canonicalService
7377
7850
  });
7378
7851
  }
@@ -7417,7 +7890,7 @@ function formatUnconfigureMessages(service, label, unconfigured, _payload) {
7417
7890
  var init_unconfigure = __esm({
7418
7891
  "src/cli/commands/unconfigure.ts"() {
7419
7892
  "use strict";
7420
- init_credentials2();
7893
+ init_config();
7421
7894
  init_mutation_events();
7422
7895
  init_isolated_env();
7423
7896
  init_shared();
@@ -7426,53 +7899,157 @@ var init_unconfigure = __esm({
7426
7899
 
7427
7900
  // src/cli/commands/logout.ts
7428
7901
  function registerLogoutCommand(program, container) {
7429
- program.command("logout").description("Remove all Poe API configuration and stored credentials.").action(async () => {
7430
- const flags = resolveCommandFlags(program);
7431
- const resources = createExecutionResources(
7432
- container,
7433
- flags,
7434
- "logout"
7435
- );
7436
- resources.logger.intro("logout");
7437
- const configuredServices = await loadConfiguredServices({
7438
- fs: container.fs,
7439
- filePath: container.env.credentialsPath
7440
- });
7441
- for (const serviceName of Object.keys(configuredServices)) {
7442
- const adapter = container.registry.get(serviceName);
7443
- if (!adapter) {
7444
- continue;
7445
- }
7446
- await executeUnconfigure(program, container, serviceName, {});
7447
- }
7448
- if (flags.dryRun) {
7449
- resources.context.complete({
7450
- success: "Logged out.",
7451
- dry: `Dry run: would delete credentials at ${container.env.credentialsPath}.`
7452
- });
7453
- resources.context.finalize();
7454
- return;
7902
+ program.command("logout").description("Remove all Poe API configuration.").action(async () => {
7903
+ await executeLogout(program, container);
7904
+ });
7905
+ }
7906
+ async function executeLogout(program, container) {
7907
+ const flags = resolveCommandFlags(program);
7908
+ const resources = createExecutionResources(
7909
+ container,
7910
+ flags,
7911
+ "logout"
7912
+ );
7913
+ resources.logger.intro("logout");
7914
+ const configuredServices = await loadConfiguredServices({
7915
+ fs: container.fs,
7916
+ filePath: container.env.configPath
7917
+ });
7918
+ for (const serviceName of Object.keys(configuredServices)) {
7919
+ const adapter = container.registry.get(serviceName);
7920
+ if (!adapter) {
7921
+ continue;
7455
7922
  }
7456
- const deleted = await deleteCredentials({
7457
- fs: container.fs,
7458
- filePath: container.env.credentialsPath
7459
- });
7923
+ await executeUnconfigure(program, container, serviceName, {});
7924
+ }
7925
+ if (flags.dryRun) {
7460
7926
  resources.context.complete({
7461
- success: deleted ? "Logged out." : "Already logged out.",
7462
- dry: `Dry run: would delete credentials at ${container.env.credentialsPath}.`
7927
+ success: "Logged out.",
7928
+ dry: `Dry run: would delete config at ${container.env.configPath}.`
7463
7929
  });
7464
7930
  resources.context.finalize();
7931
+ return;
7932
+ }
7933
+ const deleted = await deleteConfig({
7934
+ fs: container.fs,
7935
+ filePath: container.env.configPath
7936
+ });
7937
+ resources.context.complete({
7938
+ success: deleted ? "Logged out." : "Already logged out.",
7939
+ dry: `Dry run: would delete config at ${container.env.configPath}.`
7465
7940
  });
7941
+ resources.context.finalize();
7466
7942
  }
7467
7943
  var init_logout = __esm({
7468
7944
  "src/cli/commands/logout.ts"() {
7469
7945
  "use strict";
7470
- init_credentials2();
7946
+ init_config();
7471
7947
  init_shared();
7472
7948
  init_unconfigure();
7473
7949
  }
7474
7950
  });
7475
7951
 
7952
+ // src/cli/commands/auth.ts
7953
+ function registerAuthCommand(program, container) {
7954
+ const auth = program.command("auth").description("Authentication and account commands.").action(async () => {
7955
+ await executeStatus(program, container);
7956
+ });
7957
+ auth.command("status").description("Show login, balance, and configuration status.").action(async () => {
7958
+ await executeStatus(program, container);
7959
+ });
7960
+ auth.command("api_key").description("Display stored API key.").action(async () => {
7961
+ await executeApiKey(program, container);
7962
+ });
7963
+ auth.command("login").description("Store a Poe API key.").option("--api-key <key>", "Poe API key").action(async (options) => {
7964
+ await executeLogin(program, container, options);
7965
+ });
7966
+ auth.command("logout").description("Remove all configuration and credentials.").action(async () => {
7967
+ await executeLogout(program, container);
7968
+ });
7969
+ }
7970
+ async function executeStatus(program, container) {
7971
+ const flags = resolveCommandFlags(program);
7972
+ const resources = createExecutionResources(container, flags, "auth:status");
7973
+ resources.logger.intro("auth status");
7974
+ try {
7975
+ const apiKey = await container.readApiKey();
7976
+ const loggedIn = Boolean(apiKey);
7977
+ resources.logger.info(loggedIn ? "Logged in" : "Not logged in");
7978
+ if (loggedIn) {
7979
+ if (flags.dryRun) {
7980
+ resources.logger.dryRun(
7981
+ "Dry run: would fetch usage balance from Poe API."
7982
+ );
7983
+ } else {
7984
+ const response = await container.httpClient(
7985
+ `${container.env.poeBaseUrl}/usage/current_balance`,
7986
+ {
7987
+ method: "GET",
7988
+ headers: {
7989
+ Authorization: `Bearer ${apiKey}`
7990
+ }
7991
+ }
7992
+ );
7993
+ if (!response.ok) {
7994
+ throw new ApiError(
7995
+ `Failed to fetch usage balance (HTTP ${response.status})`,
7996
+ {
7997
+ httpStatus: response.status,
7998
+ endpoint: "/usage/current_balance"
7999
+ }
8000
+ );
8001
+ }
8002
+ const data = await response.json();
8003
+ const formattedBalance = data.current_point_balance.toLocaleString(
8004
+ "en-US"
8005
+ );
8006
+ resources.logger.info(`Current balance: ${formattedBalance} points`);
8007
+ }
8008
+ }
8009
+ const configuredServices = await loadConfiguredServices({
8010
+ fs: container.fs,
8011
+ filePath: container.env.configPath
8012
+ });
8013
+ const configuredAgentNames = Object.keys(configuredServices).sort();
8014
+ if (configuredAgentNames.length === 0) {
8015
+ resources.logger.info("No agents configured.");
8016
+ } else {
8017
+ resources.logger.info(
8018
+ `Configured agents: ${configuredAgentNames.join(", ")}`
8019
+ );
8020
+ }
8021
+ resources.context.finalize();
8022
+ } catch (error2) {
8023
+ if (error2 instanceof Error) {
8024
+ resources.logger.logException(error2, "auth status", {
8025
+ operation: "auth-status"
8026
+ });
8027
+ }
8028
+ throw error2;
8029
+ }
8030
+ }
8031
+ async function executeApiKey(program, container) {
8032
+ const flags = resolveCommandFlags(program);
8033
+ const resources = createExecutionResources(container, flags, "auth:api_key");
8034
+ resources.logger.intro("auth api_key");
8035
+ const apiKey = await container.readApiKey();
8036
+ if (!apiKey) {
8037
+ resources.logger.info("No API key stored.");
8038
+ return;
8039
+ }
8040
+ resources.logger.info(`API key: ${apiKey}`);
8041
+ }
8042
+ var init_auth = __esm({
8043
+ "src/cli/commands/auth.ts"() {
8044
+ "use strict";
8045
+ init_errors();
8046
+ init_config();
8047
+ init_shared();
8048
+ init_login();
8049
+ init_logout();
8050
+ }
8051
+ });
8052
+
7476
8053
  // src/cli/commands/install.ts
7477
8054
  function registerInstallCommand(program, container) {
7478
8055
  const serviceNames = container.registry.list().filter((service) => typeof service.install === "function").map((service) => service.name);
@@ -7567,7 +8144,7 @@ async function executeTest(program, container, service, options = {}) {
7567
8144
  container.env,
7568
8145
  adapter.isolatedEnv,
7569
8146
  adapter.name,
7570
- container.fs
8147
+ container.readApiKey
7571
8148
  ) : null;
7572
8149
  if (options.isolated && adapter.isolatedEnv) {
7573
8150
  const { ensureIsolatedConfigForService: ensureIsolatedConfigForService2 } = await Promise.resolve().then(() => (init_ensure_isolated_config(), ensure_isolated_config_exports));
@@ -7616,7 +8193,7 @@ var init_test = __esm({
7616
8193
  init_shared();
7617
8194
  init_configure();
7618
8195
  init_isolated_env();
7619
- init_src3();
8196
+ init_src4();
7620
8197
  }
7621
8198
  });
7622
8199
 
@@ -7669,7 +8246,7 @@ var init_media_download = __esm({
7669
8246
  });
7670
8247
 
7671
8248
  // src/cli/commands/generate.ts
7672
- import path12 from "node:path";
8249
+ import path13 from "node:path";
7673
8250
  function registerGenerateCommand(program, container) {
7674
8251
  const generate2 = program.command("generate").description("Generate content via Poe API").option("--model <model>", `Model identifier (default: ${DEFAULT_TEXT_MODEL})`).option(
7675
8252
  "--param <key=value>",
@@ -7848,10 +8425,13 @@ async function resolveClient2(container) {
7848
8425
  try {
7849
8426
  return getGlobalClient();
7850
8427
  } catch {
8428
+ const apiKey = await container.readApiKey();
8429
+ if (!apiKey) {
8430
+ throw new Error("Poe API key not found. Run 'poe-code login' first.");
8431
+ }
7851
8432
  const apiBaseUrl = resolveApiBaseUrl(container);
7852
8433
  await initializeClient({
7853
- fs: container.fs,
7854
- credentialsPath: container.env.credentialsPath,
8434
+ apiKey,
7855
8435
  baseUrl: apiBaseUrl,
7856
8436
  httpClient: container.httpClient
7857
8437
  });
@@ -7932,11 +8512,11 @@ function getDefaultMimeType(type) {
7932
8512
  return defaults[type];
7933
8513
  }
7934
8514
  function resolveOutputPath(filename, cwd) {
7935
- if (path12.isAbsolute(filename)) {
8515
+ if (path13.isAbsolute(filename)) {
7936
8516
  return { path: filename, label: filename };
7937
8517
  }
7938
8518
  return {
7939
- path: path12.join(cwd, filename),
8519
+ path: path13.join(cwd, filename),
7940
8520
  label: `./${filename}`
7941
8521
  };
7942
8522
  }
@@ -7944,7 +8524,7 @@ var MODEL_ENV_KEYS2, DEFAULT_MODELS2;
7944
8524
  var init_generate = __esm({
7945
8525
  "src/cli/commands/generate.ts"() {
7946
8526
  "use strict";
7947
- init_src3();
8527
+ init_src4();
7948
8528
  init_constants();
7949
8529
  init_shared();
7950
8530
  init_client_instance();
@@ -9040,8 +9620,8 @@ var init_parseUtil = __esm({
9040
9620
  init_errors2();
9041
9621
  init_en();
9042
9622
  makeIssue = (params) => {
9043
- const { data, path: path20, errorMaps, issueData } = params;
9044
- const fullPath = [...path20, ...issueData.path || []];
9623
+ const { data, path: path21, errorMaps, issueData } = params;
9624
+ const fullPath = [...path21, ...issueData.path || []];
9045
9625
  const fullIssue = {
9046
9626
  ...issueData,
9047
9627
  path: fullPath
@@ -9321,11 +9901,11 @@ var init_types3 = __esm({
9321
9901
  init_parseUtil();
9322
9902
  init_util();
9323
9903
  ParseInputLazyPath = class {
9324
- constructor(parent, value, path20, key) {
9904
+ constructor(parent, value, path21, key) {
9325
9905
  this._cachedPath = [];
9326
9906
  this.parent = parent;
9327
9907
  this.data = value;
9328
- this._path = path20;
9908
+ this._path = path21;
9329
9909
  this._key = key;
9330
9910
  }
9331
9911
  get path() {
@@ -12829,10 +13409,10 @@ function mergeDefs(...defs) {
12829
13409
  function cloneDef(schema) {
12830
13410
  return mergeDefs(schema._zod.def);
12831
13411
  }
12832
- function getElementAtPath(obj, path20) {
12833
- if (!path20)
13412
+ function getElementAtPath(obj, path21) {
13413
+ if (!path21)
12834
13414
  return obj;
12835
- return path20.reduce((acc, key) => acc?.[key], obj);
13415
+ return path21.reduce((acc, key) => acc?.[key], obj);
12836
13416
  }
12837
13417
  function promiseAllObject(promisesObj) {
12838
13418
  const keys = Object.keys(promisesObj);
@@ -13144,11 +13724,11 @@ function aborted(x, startIndex = 0) {
13144
13724
  }
13145
13725
  return false;
13146
13726
  }
13147
- function prefixIssues(path20, issues) {
13727
+ function prefixIssues(path21, issues) {
13148
13728
  return issues.map((iss) => {
13149
13729
  var _a2;
13150
13730
  (_a2 = iss).path ?? (_a2.path = []);
13151
- iss.path.unshift(path20);
13731
+ iss.path.unshift(path21);
13152
13732
  return iss;
13153
13733
  });
13154
13734
  }
@@ -13524,7 +14104,7 @@ __export(regexes_exports, {
13524
14104
  extendedDuration: () => extendedDuration,
13525
14105
  guid: () => guid,
13526
14106
  hex: () => hex,
13527
- hostname: () => hostname,
14107
+ hostname: () => hostname2,
13528
14108
  html5Email: () => html5Email,
13529
14109
  idnEmail: () => idnEmail,
13530
14110
  integer: () => integer,
@@ -13591,7 +14171,7 @@ function fixedBase64(bodyLength, padding) {
13591
14171
  function fixedBase64url(length) {
13592
14172
  return new RegExp(`^[A-Za-z0-9_-]{${length}}$`);
13593
14173
  }
13594
- 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;
14174
+ 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;
13595
14175
  var init_regexes = __esm({
13596
14176
  "node_modules/zod/v4/core/regexes.js"() {
13597
14177
  init_util2();
@@ -13629,7 +14209,7 @@ var init_regexes = __esm({
13629
14209
  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])$/;
13630
14210
  base64 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/;
13631
14211
  base64url = /^[A-Za-z0-9_-]*$/;
13632
- 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])?)*\.?$/;
14212
+ 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])?)*\.?$/;
13633
14213
  domain = /^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
13634
14214
  e164 = /^\+[1-9]\d{6,14}$/;
13635
14215
  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])))`;
@@ -18835,7 +19415,7 @@ __export(schemas_exports3, {
18835
19415
  guid: () => guid2,
18836
19416
  hash: () => hash,
18837
19417
  hex: () => hex2,
18838
- hostname: () => hostname2,
19418
+ hostname: () => hostname3,
18839
19419
  httpUrl: () => httpUrl,
18840
19420
  instanceof: () => _instanceof,
18841
19421
  int: () => int,
@@ -18982,7 +19562,7 @@ function jwt(params) {
18982
19562
  function stringFormat(format, fnOrRegex, _params = {}) {
18983
19563
  return _stringFormat(ZodCustomStringFormat, format, fnOrRegex, _params);
18984
19564
  }
18985
- function hostname2(_params) {
19565
+ function hostname3(_params) {
18986
19566
  return _stringFormat(ZodCustomStringFormat, "hostname", regexes_exports.hostname, _params);
18987
19567
  }
18988
19568
  function hex2(_params) {
@@ -25106,8 +25686,8 @@ var require_utils = __commonJS({
25106
25686
  }
25107
25687
  return ind;
25108
25688
  }
25109
- function removeDotSegments(path20) {
25110
- let input = path20;
25689
+ function removeDotSegments(path21) {
25690
+ let input = path21;
25111
25691
  const output = [];
25112
25692
  let nextSlash = -1;
25113
25693
  let len = 0;
@@ -25306,8 +25886,8 @@ var require_schemes = __commonJS({
25306
25886
  wsComponent.secure = void 0;
25307
25887
  }
25308
25888
  if (wsComponent.resourceName) {
25309
- const [path20, query] = wsComponent.resourceName.split("?");
25310
- wsComponent.path = path20 && path20 !== "/" ? path20 : void 0;
25889
+ const [path21, query] = wsComponent.resourceName.split("?");
25890
+ wsComponent.path = path21 && path21 !== "/" ? path21 : void 0;
25311
25891
  wsComponent.query = query;
25312
25892
  wsComponent.resourceName = void 0;
25313
25893
  }
@@ -34421,7 +35001,7 @@ var init_content = __esm({
34421
35001
  });
34422
35002
 
34423
35003
  // packages/tiny-stdio-mcp-server/src/index.ts
34424
- var init_src5 = __esm({
35004
+ var init_src6 = __esm({
34425
35005
  "packages/tiny-stdio-mcp-server/src/index.ts"() {
34426
35006
  "use strict";
34427
35007
  init_server();
@@ -34725,7 +35305,7 @@ var generateTextSchema, generateImageSchema, generateVideoSchema, generateAudioS
34725
35305
  var init_mcp_server = __esm({
34726
35306
  "src/cli/mcp-server.ts"() {
34727
35307
  "use strict";
34728
- init_src5();
35308
+ init_src6();
34729
35309
  init_client_instance();
34730
35310
  init_constants();
34731
35311
  generateTextSchema = defineSchema({
@@ -34983,7 +35563,7 @@ ${panel.footer}`);
34983
35563
  var init_command_not_found = __esm({
34984
35564
  "src/cli/command-not-found.ts"() {
34985
35565
  "use strict";
34986
- init_src3();
35566
+ init_src4();
34987
35567
  init_execution_context();
34988
35568
  init_errors();
34989
35569
  }
@@ -35008,7 +35588,7 @@ function getAgentConfig(agentId) {
35008
35588
  const support = resolveAgentSupport(agentId);
35009
35589
  return support.status === "supported" ? support.config : void 0;
35010
35590
  }
35011
- function resolveConfigPath(config2, platform) {
35591
+ function resolveConfigPath2(config2, platform) {
35012
35592
  if (typeof config2.configFile === "function") {
35013
35593
  return config2.configFile(platform);
35014
35594
  }
@@ -35018,7 +35598,7 @@ var agentMcpConfigs, supportedAgents;
35018
35598
  var init_configs2 = __esm({
35019
35599
  "packages/agent-mcp-config/src/configs.ts"() {
35020
35600
  "use strict";
35021
- init_src2();
35601
+ init_src3();
35022
35602
  agentMcpConfigs = {
35023
35603
  "claude-code": {
35024
35604
  configFile: "~/.claude.json",
@@ -35131,9 +35711,9 @@ var init_shapes = __esm({
35131
35711
  });
35132
35712
 
35133
35713
  // packages/agent-mcp-config/src/apply.ts
35134
- import path13 from "node:path";
35714
+ import path14 from "node:path";
35135
35715
  function getConfigDirectory(configPath) {
35136
- return path13.dirname(configPath);
35716
+ return path14.dirname(configPath);
35137
35717
  }
35138
35718
  function isConfigObject5(value) {
35139
35719
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -35150,7 +35730,7 @@ async function configure(agentId, server, options) {
35150
35730
  throw new UnsupportedAgentError(agentId);
35151
35731
  }
35152
35732
  const config2 = getAgentConfig(agentId);
35153
- const configPath = resolveConfigPath(config2, options.platform);
35733
+ const configPath = resolveConfigPath2(config2, options.platform);
35154
35734
  const shapeTransformer = getShapeTransformer(config2.shape);
35155
35735
  const shaped = shapeTransformer(server);
35156
35736
  if (shaped === void 0) {
@@ -35196,7 +35776,7 @@ async function unconfigure(agentId, serverName, options) {
35196
35776
  throw new UnsupportedAgentError(agentId);
35197
35777
  }
35198
35778
  const config2 = getAgentConfig(agentId);
35199
- const configPath = resolveConfigPath(config2, options.platform);
35779
+ const configPath = resolveConfigPath2(config2, options.platform);
35200
35780
  await runMutations(
35201
35781
  [
35202
35782
  configMutation.prune({
@@ -35222,7 +35802,7 @@ var UnsupportedAgentError;
35222
35802
  var init_apply = __esm({
35223
35803
  "packages/agent-mcp-config/src/apply.ts"() {
35224
35804
  "use strict";
35225
- init_src();
35805
+ init_src2();
35226
35806
  init_configs2();
35227
35807
  init_shapes();
35228
35808
  UnsupportedAgentError = class extends Error {
@@ -35235,7 +35815,7 @@ var init_apply = __esm({
35235
35815
  });
35236
35816
 
35237
35817
  // packages/agent-mcp-config/src/index.ts
35238
- var init_src6 = __esm({
35818
+ var init_src7 = __esm({
35239
35819
  "packages/agent-mcp-config/src/index.ts"() {
35240
35820
  "use strict";
35241
35821
  init_configs2();
@@ -35293,10 +35873,7 @@ function registerMcpCommand(program, container) {
35293
35873
  mcp.command("configure [agent]").description("Configure MCP client to use poe-code").option("-y, --yes", "Skip prompt, use claude-code").action(async (agentArg, options) => {
35294
35874
  const flags = resolveCommandFlags(program);
35295
35875
  const resources = createExecutionResources(container, flags, "mcp");
35296
- const existingKey = await loadCredentials({
35297
- fs: container.fs,
35298
- filePath: container.env.credentialsPath
35299
- });
35876
+ const existingKey = await container.readApiKey();
35300
35877
  if (!existingKey) {
35301
35878
  resources.logger.intro("login");
35302
35879
  await container.options.resolveApiKey({ dryRun: flags.dryRun });
@@ -35396,17 +35973,13 @@ async function runMcpServer(container, options) {
35396
35973
  const outputFormatPreferences = parseMcpOutputFormatPreferences(
35397
35974
  options.outputFormat
35398
35975
  );
35399
- const apiKey = await loadCredentials({
35400
- fs: container.fs,
35401
- filePath: container.env.credentialsPath
35402
- });
35976
+ const apiKey = await container.readApiKey();
35403
35977
  if (!apiKey) {
35404
- process.stderr.write("No credentials found. Run 'poe-code login' first.\n");
35978
+ process.stderr.write("No API key found. Run 'poe-code login' first.\n");
35405
35979
  process.exit(1);
35406
35980
  }
35407
35981
  await initializeClient({
35408
- fs: container.fs,
35409
- credentialsPath: container.env.credentialsPath,
35982
+ apiKey,
35410
35983
  baseUrl: container.env.poeApiBaseUrl,
35411
35984
  httpClient: container.httpClient
35412
35985
  });
@@ -35416,22 +35989,21 @@ var DEFAULT_MCP_AGENT;
35416
35989
  var init_mcp2 = __esm({
35417
35990
  "src/cli/commands/mcp.ts"() {
35418
35991
  "use strict";
35419
- init_src3();
35420
- init_credentials2();
35992
+ init_src4();
35421
35993
  init_client_instance();
35422
35994
  init_mcp_server();
35423
35995
  init_shared();
35424
35996
  init_mcp_output_format();
35425
35997
  init_command_not_found();
35426
- init_src6();
35998
+ init_src7();
35427
35999
  init_execution_context();
35428
36000
  DEFAULT_MCP_AGENT = "claude-code";
35429
36001
  }
35430
36002
  });
35431
36003
 
35432
36004
  // packages/agent-skill-config/src/configs.ts
35433
- import os3 from "node:os";
35434
- import path14 from "node:path";
36005
+ import os2 from "node:os";
36006
+ import path15 from "node:path";
35435
36007
  function resolveAgentSupport2(input, registry2 = agentSkillConfigs) {
35436
36008
  const resolvedId = resolveAgentId(input);
35437
36009
  if (!resolvedId) {
@@ -35447,7 +36019,7 @@ var agentSkillConfigs, supportedAgents2;
35447
36019
  var init_configs3 = __esm({
35448
36020
  "packages/agent-skill-config/src/configs.ts"() {
35449
36021
  "use strict";
35450
- init_src2();
36022
+ init_src3();
35451
36023
  agentSkillConfigs = {
35452
36024
  "claude-code": {
35453
36025
  globalSkillDir: "~/.claude/skills",
@@ -35467,7 +36039,7 @@ var init_configs3 = __esm({
35467
36039
  });
35468
36040
 
35469
36041
  // packages/agent-skill-config/src/templates.ts
35470
- import { readFile as readFile3 } from "node:fs/promises";
36042
+ import { readFile as readFile2 } from "node:fs/promises";
35471
36043
  async function getTemplates() {
35472
36044
  if (templatesCache) {
35473
36045
  return templatesCache;
@@ -35476,7 +36048,7 @@ async function getTemplates() {
35476
36048
  "./templates/poe-generate.md",
35477
36049
  import.meta.url
35478
36050
  );
35479
- const poeGenerateTemplate = await readFile3(poeGenerateTemplateUrl, "utf8");
36051
+ const poeGenerateTemplate = await readFile2(poeGenerateTemplateUrl, "utf8");
35480
36052
  templatesCache = {
35481
36053
  "poe-generate.md": poeGenerateTemplate
35482
36054
  };
@@ -35608,7 +36180,7 @@ var UnsupportedAgentError2, bundledSkillTemplateIds, SKILL_TEMPLATE_ID;
35608
36180
  var init_apply2 = __esm({
35609
36181
  "packages/agent-skill-config/src/apply.ts"() {
35610
36182
  "use strict";
35611
- init_src();
36183
+ init_src2();
35612
36184
  init_configs3();
35613
36185
  init_templates();
35614
36186
  UnsupportedAgentError2 = class extends Error {
@@ -35623,7 +36195,7 @@ var init_apply2 = __esm({
35623
36195
  });
35624
36196
 
35625
36197
  // packages/agent-skill-config/src/index.ts
35626
- var init_src7 = __esm({
36198
+ var init_src8 = __esm({
35627
36199
  "packages/agent-skill-config/src/index.ts"() {
35628
36200
  "use strict";
35629
36201
  init_configs3();
@@ -35847,8 +36419,8 @@ var DEFAULT_SKILL_AGENT;
35847
36419
  var init_skill = __esm({
35848
36420
  "src/cli/commands/skill.ts"() {
35849
36421
  "use strict";
35850
- init_src3();
35851
- init_src7();
36422
+ init_src4();
36423
+ init_src8();
35852
36424
  init_shared();
35853
36425
  init_command_not_found();
35854
36426
  DEFAULT_SKILL_AGENT = "claude-code";
@@ -35938,7 +36510,7 @@ async function displayVersion(container, currentVersion) {
35938
36510
  var init_version2 = __esm({
35939
36511
  "src/cli/commands/version.ts"() {
35940
36512
  "use strict";
35941
- init_src3();
36513
+ init_src4();
35942
36514
  init_version();
35943
36515
  init_exit_signals();
35944
36516
  }
@@ -36063,10 +36635,10 @@ var init_registry2 = __esm({
36063
36635
  });
36064
36636
 
36065
36637
  // packages/worktree/src/create.ts
36066
- import { join as join2 } from "node:path";
36638
+ import { join } from "node:path";
36067
36639
  async function createWorktree(opts) {
36068
36640
  const branch = `poe-code/${opts.name}`;
36069
- const worktreePath = join2(opts.worktreeDir, opts.name);
36641
+ const worktreePath = join(opts.worktreeDir, opts.name);
36070
36642
  try {
36071
36643
  await opts.deps.exec(`git worktree remove ${worktreePath} --force`, { cwd: opts.cwd });
36072
36644
  } catch {
@@ -36141,7 +36713,7 @@ var init_list = __esm({
36141
36713
  });
36142
36714
 
36143
36715
  // packages/worktree/src/index.ts
36144
- var init_src8 = __esm({
36716
+ var init_src9 = __esm({
36145
36717
  "packages/worktree/src/index.ts"() {
36146
36718
  "use strict";
36147
36719
  init_create();
@@ -36230,13 +36802,13 @@ function getDirtyFiles(cwd) {
36230
36802
  for (const line of lines) {
36231
36803
  if (!line) continue;
36232
36804
  if (line.length < 4) continue;
36233
- let path20 = line.slice(3).trim();
36805
+ let path21 = line.slice(3).trim();
36234
36806
  const renameArrow = " -> ";
36235
- const arrowIndex = path20.lastIndexOf(renameArrow);
36807
+ const arrowIndex = path21.lastIndexOf(renameArrow);
36236
36808
  if (arrowIndex >= 0) {
36237
- path20 = path20.slice(arrowIndex + renameArrow.length).trim();
36809
+ path21 = path21.slice(arrowIndex + renameArrow.length).trim();
36238
36810
  }
36239
- if (path20) files.push(path20);
36811
+ if (path21) files.push(path21);
36240
36812
  }
36241
36813
  return files;
36242
36814
  }
@@ -36248,7 +36820,7 @@ var init_utils2 = __esm({
36248
36820
 
36249
36821
  // packages/ralph/src/plan/parser.ts
36250
36822
  import { parse as parse7 } from "yaml";
36251
- function isRecord3(value) {
36823
+ function isRecord5(value) {
36252
36824
  return typeof value === "object" && value !== null && !Array.isArray(value);
36253
36825
  }
36254
36826
  function asOptionalString(value, field) {
@@ -36299,7 +36871,7 @@ function normalizeStatus(value) {
36299
36871
  );
36300
36872
  }
36301
36873
  function parseStory(value, index) {
36302
- if (!isRecord3(value)) throw new Error(`Invalid stories[${index}]: expected object`);
36874
+ if (!isRecord5(value)) throw new Error(`Invalid stories[${index}]: expected object`);
36303
36875
  return {
36304
36876
  id: asRequiredString(value.id, `stories[${index}].id`),
36305
36877
  title: asRequiredString(value.title, `stories[${index}].title`),
@@ -36323,7 +36895,7 @@ function parsePlan(yamlContent) {
36323
36895
  const message = error2 instanceof Error ? error2.message : String(error2);
36324
36896
  throw new Error(`Invalid plan YAML: ${message}`, { cause: error2 });
36325
36897
  }
36326
- if (!isRecord3(doc)) {
36898
+ if (!isRecord5(doc)) {
36327
36899
  throw new Error("Invalid plan YAML: expected top-level object");
36328
36900
  }
36329
36901
  const storiesValue = doc.stories;
@@ -36389,17 +36961,17 @@ function serializePlan(prd) {
36389
36961
  return yaml.endsWith("\n") ? yaml : `${yaml}
36390
36962
  `;
36391
36963
  }
36392
- function lockPlanFile(path20) {
36393
- return lockFile(path20, { retries: 20, minTimeout: 25, maxTimeout: 250 });
36964
+ function lockPlanFile(path21) {
36965
+ return lockFile(path21, { retries: 20, minTimeout: 25, maxTimeout: 250 });
36394
36966
  }
36395
- async function writePlan(path20, prd, options = {}) {
36967
+ async function writePlan(path21, prd, options = {}) {
36396
36968
  const fs3 = options.fs ?? fsPromises2;
36397
36969
  const lock = options.lock ?? lockPlanFile;
36398
- await fs3.mkdir(dirname3(path20), { recursive: true });
36399
- const release = await lock(path20);
36970
+ await fs3.mkdir(dirname3(path21), { recursive: true });
36971
+ const release = await lock(path21);
36400
36972
  try {
36401
36973
  const yaml = serializePlan(prd);
36402
- await fs3.writeFile(path20, yaml, { encoding: "utf8" });
36974
+ await fs3.writeFile(path21, yaml, { encoding: "utf8" });
36403
36975
  } finally {
36404
36976
  await release();
36405
36977
  }
@@ -36418,7 +36990,7 @@ function renderPrompt(template, variables) {
36418
36990
  var init_renderer2 = __esm({
36419
36991
  "packages/ralph/src/prompt/renderer.ts"() {
36420
36992
  "use strict";
36421
- init_src();
36993
+ init_src2();
36422
36994
  }
36423
36995
  });
36424
36996
 
@@ -36487,8 +37059,8 @@ var init_selector = __esm({
36487
37059
  // packages/ralph/src/story/updater.ts
36488
37060
  import { dirname as dirname4 } from "node:path";
36489
37061
  import * as fsPromises3 from "node:fs/promises";
36490
- function lockPlanFile2(path20) {
36491
- return lockFile(path20, { retries: 20, minTimeout: 25, maxTimeout: 250 });
37062
+ function lockPlanFile2(path21) {
37063
+ return lockFile(path21, { retries: 20, minTimeout: 25, maxTimeout: 250 });
36492
37064
  }
36493
37065
  function assertStoryStatus(value) {
36494
37066
  if (value === "open") return;
@@ -36569,9 +37141,9 @@ function appendSection(lines, title, items, options) {
36569
37141
  }
36570
37142
  lines.push("");
36571
37143
  }
36572
- async function writeRunMeta(path20, metadata, options = {}) {
37144
+ async function writeRunMeta(path21, metadata, options = {}) {
36573
37145
  const fs3 = options.fs ?? fsPromises4;
36574
- await fs3.mkdir(dirname5(path20), { recursive: true });
37146
+ await fs3.mkdir(dirname5(path21), { recursive: true });
36575
37147
  const lines = [];
36576
37148
  lines.push("# Ralph Run Summary", "");
36577
37149
  lines.push(`- Run ID: ${metadata.runId}`);
@@ -36600,7 +37172,7 @@ async function writeRunMeta(path20, metadata, options = {}) {
36600
37172
  const git = metadata.git ?? null;
36601
37173
  if (!git) {
36602
37174
  lines.push("");
36603
- await fs3.writeFile(path20, lines.join("\n"), { encoding: "utf8" });
37175
+ await fs3.writeFile(path21, lines.join("\n"), { encoding: "utf8" });
36604
37176
  return;
36605
37177
  }
36606
37178
  lines.push("", "## Git");
@@ -36615,7 +37187,7 @@ async function writeRunMeta(path20, metadata, options = {}) {
36615
37187
  lines.push("");
36616
37188
  } else {
36617
37189
  lines.push("");
36618
- await fs3.writeFile(path20, lines.join("\n"), { encoding: "utf8" });
37190
+ await fs3.writeFile(path21, lines.join("\n"), { encoding: "utf8" });
36619
37191
  return;
36620
37192
  }
36621
37193
  if (git.commits !== void 0 && git.commits !== null) {
@@ -36635,7 +37207,7 @@ async function writeRunMeta(path20, metadata, options = {}) {
36635
37207
  appendSection(lines, "### Uncommitted Changes", git.dirtyFiles, {
36636
37208
  emptyLabel: "(none)"
36637
37209
  });
36638
- await fs3.writeFile(path20, lines.join("\n"), { encoding: "utf8" });
37210
+ await fs3.writeFile(path21, lines.join("\n"), { encoding: "utf8" });
36639
37211
  }
36640
37212
  var init_metadata = __esm({
36641
37213
  "packages/ralph/src/run/metadata.ts"() {
@@ -36723,9 +37295,9 @@ async function defaultStreamingSpawn(agentId, options) {
36723
37295
  exitCode: result.exitCode
36724
37296
  };
36725
37297
  }
36726
- function absPath(cwd, path20) {
36727
- if (!path20) return resolvePath3(cwd);
36728
- return path20.startsWith("/") ? path20 : resolvePath3(cwd, path20);
37298
+ function absPath(cwd, path21) {
37299
+ if (!path21) return resolvePath3(cwd);
37300
+ return path21.startsWith("/") ? path21 : resolvePath3(cwd, path21);
36729
37301
  }
36730
37302
  function pad2(value) {
36731
37303
  return value < 10 ? `0${value}` : String(value);
@@ -36775,8 +37347,8 @@ async function appendToErrorsLog(fs3, errorsLogPath, message) {
36775
37347
  await fs3.mkdir(dirname6(errorsLogPath), { recursive: true });
36776
37348
  await fs3.writeFile(errorsLogPath, `${previous}${next}`, { encoding: "utf8" });
36777
37349
  }
36778
- function lockPlanFile3(path20) {
36779
- return lockFile(path20, { retries: 20, minTimeout: 25, maxTimeout: 250 });
37350
+ function lockPlanFile3(path21) {
37351
+ return lockFile(path21, { retries: 20, minTimeout: 25, maxTimeout: 250 });
36780
37352
  }
36781
37353
  function getCurrentBranch(cwd) {
36782
37354
  try {
@@ -36878,7 +37450,7 @@ async function defaultPromptOverbake(args) {
36878
37450
  async function buildLoop(options) {
36879
37451
  const fs3 = options.deps?.fs ?? fsPromises5;
36880
37452
  const lock = options.deps?.lock ?? lockPlanFile3;
36881
- const spawn5 = options.deps?.spawn ?? defaultStreamingSpawn;
37453
+ const spawn6 = options.deps?.spawn ?? defaultStreamingSpawn;
36882
37454
  const git = options.deps?.git ?? {
36883
37455
  getHead,
36884
37456
  getCommitList,
@@ -36932,7 +37504,7 @@ async function buildLoop(options) {
36932
37504
  });
36933
37505
  worktreeBranch = entry.branch;
36934
37506
  const worktreePath = entry.path;
36935
- const symlinkFn = fs3.symlink ?? ((target, path20) => fsPromises5.symlink(target, path20));
37507
+ const symlinkFn = fs3.symlink ?? ((target, path21) => fsPromises5.symlink(target, path21));
36936
37508
  const exec = worktreeDeps.exec;
36937
37509
  const dirsToLink = [".poe-code-ralph", ".agents/poe-code-ralph"];
36938
37510
  for (const dir of dirsToLink) {
@@ -37047,7 +37619,7 @@ async function buildLoop(options) {
37047
37619
  let stderrForErrorsLog;
37048
37620
  let overbakeAction = null;
37049
37621
  try {
37050
- const result = await spawn5(options.agent, {
37622
+ const result = await spawn6(options.agent, {
37051
37623
  prompt,
37052
37624
  cwd,
37053
37625
  model: options.model,
@@ -37220,10 +37792,10 @@ var init_loop = __esm({
37220
37792
  "packages/ralph/src/build/loop.ts"() {
37221
37793
  "use strict";
37222
37794
  init_lock();
37795
+ init_src5();
37223
37796
  init_src4();
37224
- init_src3();
37225
- init_src();
37226
- init_src8();
37797
+ init_src2();
37798
+ init_src9();
37227
37799
  init_detector();
37228
37800
  init_utils2();
37229
37801
  init_parser();
@@ -37237,18 +37809,18 @@ var init_loop = __esm({
37237
37809
  });
37238
37810
 
37239
37811
  // packages/ralph/src/plan/resolver.ts
37240
- import path15 from "node:path";
37812
+ import path16 from "node:path";
37241
37813
  import * as fsPromises6 from "node:fs/promises";
37242
37814
  function isPlanCandidateFile(fileName) {
37243
37815
  const lower = fileName.toLowerCase();
37244
37816
  if (!lower.startsWith("plan")) {
37245
37817
  return false;
37246
37818
  }
37247
- const ext = path15.extname(lower);
37819
+ const ext = path16.extname(lower);
37248
37820
  return ext === ".yml" || ext === ".yaml";
37249
37821
  }
37250
37822
  async function listPlanCandidates(fs3, cwd) {
37251
- const plansDir = path15.join(cwd, ".agents", "poe-code-ralph", "plans");
37823
+ const plansDir = path16.join(cwd, ".agents", "poe-code-ralph", "plans");
37252
37824
  let entries;
37253
37825
  try {
37254
37826
  entries = await fs3.readdir(plansDir);
@@ -37263,12 +37835,12 @@ async function listPlanCandidates(fs3, cwd) {
37263
37835
  if (!isPlanCandidateFile(entry)) {
37264
37836
  continue;
37265
37837
  }
37266
- const absPath2 = path15.join(plansDir, entry);
37838
+ const absPath2 = path16.join(plansDir, entry);
37267
37839
  const stats = await fs3.stat(absPath2);
37268
37840
  if (!stats.isFile()) {
37269
37841
  continue;
37270
37842
  }
37271
- const relativePath = path15.relative(cwd, absPath2);
37843
+ const relativePath = path16.relative(cwd, absPath2);
37272
37844
  const content = await fs3.readFile(absPath2, "utf8");
37273
37845
  const plan = parsePlan(content);
37274
37846
  const done = plan.stories.filter((s) => s.status === "done").length;
@@ -37287,7 +37859,7 @@ async function resolvePlanPath(options) {
37287
37859
  const cwd = options.cwd;
37288
37860
  const provided = options.plan?.trim();
37289
37861
  if (provided) {
37290
- const absPath2 = path15.isAbsolute(provided) ? provided : path15.resolve(cwd, provided);
37862
+ const absPath2 = path16.isAbsolute(provided) ? provided : path16.resolve(cwd, provided);
37291
37863
  try {
37292
37864
  const stats = await fs3.stat(absPath2);
37293
37865
  if (!stats.isFile()) {
@@ -37336,21 +37908,21 @@ async function resolvePlanPath(options) {
37336
37908
  var init_resolver = __esm({
37337
37909
  "packages/ralph/src/plan/resolver.ts"() {
37338
37910
  "use strict";
37339
- init_src3();
37340
- init_src();
37911
+ init_src4();
37912
+ init_src2();
37341
37913
  init_parser();
37342
37914
  }
37343
37915
  });
37344
37916
 
37345
37917
  // packages/ralph/src/plan/generator.ts
37346
- import path16 from "node:path";
37918
+ import path17 from "node:path";
37347
37919
  import * as fsPromises7 from "node:fs/promises";
37348
37920
  var PLAN_PROMPT_TEMPLATE;
37349
37921
  var init_generator = __esm({
37350
37922
  "packages/ralph/src/plan/generator.ts"() {
37351
37923
  "use strict";
37352
- init_src4();
37353
- init_src();
37924
+ init_src5();
37925
+ init_src2();
37354
37926
  init_renderer2();
37355
37927
  PLAN_PROMPT_TEMPLATE = [
37356
37928
  "# Plan",
@@ -37412,27 +37984,27 @@ function formatTimestamp3(date4) {
37412
37984
  const seconds = pad22(date4.getSeconds());
37413
37985
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
37414
37986
  }
37415
- function validateLogPath(path20) {
37416
- if (typeof path20 !== "string" || path20.trim().length === 0) {
37987
+ function validateLogPath(path21) {
37988
+ if (typeof path21 !== "string" || path21.trim().length === 0) {
37417
37989
  throw new Error(
37418
- `Invalid activity log path: expected a non-empty string, got ${String(path20)}`
37990
+ `Invalid activity log path: expected a non-empty string, got ${String(path21)}`
37419
37991
  );
37420
37992
  }
37421
- if (path20.includes("\0")) {
37993
+ if (path21.includes("\0")) {
37422
37994
  throw new Error("Invalid activity log path: contains null byte");
37423
37995
  }
37424
37996
  }
37425
- async function logActivity(path20, message, options = {}) {
37426
- validateLogPath(path20);
37997
+ async function logActivity(path21, message, options = {}) {
37998
+ validateLogPath(path21);
37427
37999
  const fs3 = options.fs ?? fsPromises8;
37428
- const parent = dirname7(path20);
38000
+ const parent = dirname7(path21);
37429
38001
  if (parent && parent !== ".") {
37430
38002
  await fs3.mkdir(parent, { recursive: true });
37431
38003
  }
37432
38004
  const entry = `[${formatTimestamp3(/* @__PURE__ */ new Date())}] ${message}
37433
38005
  `;
37434
38006
  try {
37435
- await fs3.appendFile(path20, entry, { encoding: "utf8" });
38007
+ await fs3.appendFile(path21, entry, { encoding: "utf8" });
37436
38008
  } catch (error2) {
37437
38009
  const detail = error2 instanceof Error ? error2.message : `Unknown error: ${String(error2)}`;
37438
38010
  throw new Error(`Failed to append activity log entry: ${detail}`, { cause: error2 });
@@ -37445,7 +38017,7 @@ var init_activity = __esm({
37445
38017
  });
37446
38018
 
37447
38019
  // packages/ralph/src/config/loader.ts
37448
- import path17 from "node:path";
38020
+ import path18 from "node:path";
37449
38021
  import * as fsPromises9 from "node:fs/promises";
37450
38022
  import YAML from "yaml";
37451
38023
  function isPlainObject2(value) {
@@ -37480,8 +38052,8 @@ function pickOptionalPositiveInt(config2, key, options) {
37480
38052
  return value;
37481
38053
  }
37482
38054
  async function loadSingleConfig(configDir, fs3) {
37483
- const yamlPath = path17.join(configDir, "config.yaml");
37484
- const jsonPath = path17.join(configDir, "config.json");
38055
+ const yamlPath = path18.join(configDir, "config.yaml");
38056
+ const jsonPath = path18.join(configDir, "config.json");
37485
38057
  let raw = null;
37486
38058
  let format = null;
37487
38059
  let sourcePath = null;
@@ -37554,14 +38126,14 @@ async function loadConfig(cwd, deps) {
37554
38126
  const sources = [];
37555
38127
  let merged = {};
37556
38128
  if (deps?.homeDir) {
37557
- const globalDir = path17.join(deps.homeDir, ".poe-code", "ralph");
38129
+ const globalDir = path18.join(deps.homeDir, ".poe-code", "ralph");
37558
38130
  const globalResult = await loadSingleConfig(globalDir, fs3);
37559
38131
  if (globalResult) {
37560
38132
  merged = globalResult.config;
37561
38133
  sources.push({ path: globalResult.sourcePath, scope: "global" });
37562
38134
  }
37563
38135
  }
37564
- const localDir = path17.join(cwd, ".agents", "poe-code-ralph");
38136
+ const localDir = path18.join(cwd, ".agents", "poe-code-ralph");
37565
38137
  const localResult = await loadSingleConfig(localDir, fs3);
37566
38138
  if (localResult) {
37567
38139
  merged = mergeConfigs(merged, localResult.config);
@@ -37572,7 +38144,7 @@ async function loadConfig(cwd, deps) {
37572
38144
  var init_loader = __esm({
37573
38145
  "packages/ralph/src/config/loader.ts"() {
37574
38146
  "use strict";
37575
- init_src();
38147
+ init_src2();
37576
38148
  }
37577
38149
  });
37578
38150
 
@@ -37583,7 +38155,7 @@ async function ralphBuild(options) {
37583
38155
  cwd: options.cwd ?? process.cwd()
37584
38156
  });
37585
38157
  }
37586
- var init_src9 = __esm({
38158
+ var init_src10 = __esm({
37587
38159
  "packages/ralph/src/index.ts"() {
37588
38160
  "use strict";
37589
38161
  init_loop();
@@ -37603,12 +38175,12 @@ var require_PROMPT_worktree_merge = __commonJS({
37603
38175
  });
37604
38176
 
37605
38177
  // src/cli/commands/ralph-worktree.ts
37606
- import path18 from "node:path";
38178
+ import path19 from "node:path";
37607
38179
  import { execSync as execSync3 } from "node:child_process";
37608
38180
  function registerRalphWorktreeCommand(ralph, container) {
37609
38181
  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) {
37610
38182
  const cwd = container.env.cwd;
37611
- const registryFile = path18.join(cwd, ".poe-code-ralph", "worktrees.yaml");
38183
+ const registryFile = path19.join(cwd, ".poe-code-ralph", "worktrees.yaml");
37612
38184
  const worktrees = await listWorktrees(cwd, registryFile, {
37613
38185
  fs: {
37614
38186
  readFile: (p, enc) => container.fs.readFile(p, enc),
@@ -37671,10 +38243,10 @@ function registerRalphWorktreeCommand(ralph, container) {
37671
38243
  var init_ralph_worktree = __esm({
37672
38244
  "src/cli/commands/ralph-worktree.ts"() {
37673
38245
  "use strict";
37674
- init_src3();
37675
- init_src8();
37676
38246
  init_src4();
37677
- init_src();
38247
+ init_src9();
38248
+ init_src5();
38249
+ init_src2();
37678
38250
  init_errors();
37679
38251
  }
37680
38252
  });
@@ -37750,7 +38322,7 @@ var require_activity = __commonJS({
37750
38322
  });
37751
38323
 
37752
38324
  // src/cli/commands/ralph.ts
37753
- import path19 from "node:path";
38325
+ import path20 from "node:path";
37754
38326
  async function loadRalphTemplates() {
37755
38327
  const [
37756
38328
  promptPartialPlan,
@@ -37835,7 +38407,7 @@ async function writeFileOrSkip(args) {
37835
38407
  args.logger.info(`Skip: ${args.displayPath} (already exists)`);
37836
38408
  return "skipped";
37837
38409
  }
37838
- await args.fs.mkdir(path19.dirname(args.filePath), { recursive: true });
38410
+ await args.fs.mkdir(path20.dirname(args.filePath), { recursive: true });
37839
38411
  await args.fs.writeFile(args.filePath, args.contents, { encoding: "utf8" });
37840
38412
  args.logger.info(`${exists ? "Overwrite" : "Create"}: ${args.displayPath}`);
37841
38413
  return "written";
@@ -37871,22 +38443,22 @@ async function installRalphTemplates(args) {
37871
38443
  const promptPlanContents = templates.promptPlan.replace("{{{PROMPT_PARTIAL_PLAN}}}", templates.promptPartialPlan);
37872
38444
  const templateWrites = [
37873
38445
  {
37874
- targetPath: path19.join(cwd, ".agents", "poe-code-ralph", "PROMPT_plan.md"),
38446
+ targetPath: path20.join(cwd, ".agents", "poe-code-ralph", "PROMPT_plan.md"),
37875
38447
  displayPath: ".agents/poe-code-ralph/PROMPT_plan.md",
37876
38448
  contents: promptPlanContents
37877
38449
  },
37878
38450
  {
37879
- targetPath: path19.join(cwd, ".agents", "poe-code-ralph", "PROMPT_build.md"),
38451
+ targetPath: path20.join(cwd, ".agents", "poe-code-ralph", "PROMPT_build.md"),
37880
38452
  displayPath: ".agents/poe-code-ralph/PROMPT_build.md",
37881
38453
  contents: templates.promptBuild
37882
38454
  },
37883
38455
  {
37884
- targetPath: path19.join(cwd, ".agents", "poe-code-ralph", "references", "GUARDRAILS.md"),
38456
+ targetPath: path20.join(cwd, ".agents", "poe-code-ralph", "references", "GUARDRAILS.md"),
37885
38457
  displayPath: ".agents/poe-code-ralph/references/GUARDRAILS.md",
37886
38458
  contents: templates.refGuardrails
37887
38459
  },
37888
38460
  {
37889
- targetPath: path19.join(cwd, ".agents", "poe-code-ralph", "references", "CONTEXT_ENGINEERING.md"),
38461
+ targetPath: path20.join(cwd, ".agents", "poe-code-ralph", "references", "CONTEXT_ENGINEERING.md"),
37890
38462
  displayPath: ".agents/poe-code-ralph/references/CONTEXT_ENGINEERING.md",
37891
38463
  contents: templates.refContextEngineering
37892
38464
  }
@@ -37904,22 +38476,22 @@ async function installRalphTemplates(args) {
37904
38476
  const stateFiles = [
37905
38477
  {
37906
38478
  contents: templates.stateProgress,
37907
- targetPath: path19.join(cwd, ".poe-code-ralph", "progress.md"),
38479
+ targetPath: path20.join(cwd, ".poe-code-ralph", "progress.md"),
37908
38480
  displayPath: ".poe-code-ralph/progress.md"
37909
38481
  },
37910
38482
  {
37911
38483
  contents: templates.stateGuardrails,
37912
- targetPath: path19.join(cwd, ".poe-code-ralph", "guardrails.md"),
38484
+ targetPath: path20.join(cwd, ".poe-code-ralph", "guardrails.md"),
37913
38485
  displayPath: ".poe-code-ralph/guardrails.md"
37914
38486
  },
37915
38487
  {
37916
38488
  contents: templates.stateErrors,
37917
- targetPath: path19.join(cwd, ".poe-code-ralph", "errors.log"),
38489
+ targetPath: path20.join(cwd, ".poe-code-ralph", "errors.log"),
37918
38490
  displayPath: ".poe-code-ralph/errors.log"
37919
38491
  },
37920
38492
  {
37921
38493
  contents: templates.stateActivity,
37922
- targetPath: path19.join(cwd, ".poe-code-ralph", "activity.log"),
38494
+ targetPath: path20.join(cwd, ".poe-code-ralph", "activity.log"),
37923
38495
  displayPath: ".poe-code-ralph/activity.log"
37924
38496
  }
37925
38497
  ];
@@ -37966,7 +38538,7 @@ function registerRalphCommand(program, container) {
37966
38538
  throw new ValidationError(message2);
37967
38539
  }
37968
38540
  const rawPath = options.activityLog?.trim() || configActivityLogPath || ".poe-code-ralph/activity.log";
37969
- const resolvedPath = path19.isAbsolute(rawPath) ? rawPath : path19.resolve(container.env.cwd, rawPath);
38541
+ const resolvedPath = path20.isAbsolute(rawPath) ? rawPath : path20.resolve(container.env.cwd, rawPath);
37970
38542
  await logActivity(resolvedPath, trimmedMessage, {
37971
38543
  fs: container.fs
37972
38544
  });
@@ -37978,7 +38550,7 @@ function registerRalphCommand(program, container) {
37978
38550
  if (!planPath) {
37979
38551
  throw new ValidationError("--plan <path> is required.");
37980
38552
  }
37981
- const resolvedPath = path19.isAbsolute(planPath) ? planPath : path19.resolve(cwd, planPath);
38553
+ const resolvedPath = path20.isAbsolute(planPath) ? planPath : path20.resolve(cwd, planPath);
37982
38554
  let content;
37983
38555
  try {
37984
38556
  content = await container.fs.readFile(resolvedPath, "utf8");
@@ -38152,7 +38724,7 @@ function registerRalphCommand(program, container) {
38152
38724
  } else {
38153
38725
  try {
38154
38726
  const planContent = await container.fs.readFile(
38155
- path19.resolve(cwd, planPath),
38727
+ path20.resolve(cwd, planPath),
38156
38728
  "utf8"
38157
38729
  );
38158
38730
  const plan = parsePlan(planContent);
@@ -38186,7 +38758,7 @@ function registerRalphCommand(program, container) {
38186
38758
  } else {
38187
38759
  try {
38188
38760
  const planContent = await container.fs.readFile(
38189
- path19.resolve(cwd, planPath),
38761
+ path20.resolve(cwd, planPath),
38190
38762
  "utf8"
38191
38763
  );
38192
38764
  const plan = parsePlan(planContent);
@@ -38242,10 +38814,10 @@ var templateImports, DEFAULT_RALPH_AGENT;
38242
38814
  var init_ralph = __esm({
38243
38815
  "src/cli/commands/ralph.ts"() {
38244
38816
  "use strict";
38245
- init_src3();
38246
- init_src9();
38247
- init_src7();
38248
- init_src();
38817
+ init_src4();
38818
+ init_src10();
38819
+ init_src8();
38820
+ init_src2();
38249
38821
  init_errors();
38250
38822
  init_shared();
38251
38823
  init_ralph_worktree();
@@ -38466,7 +39038,7 @@ var init_usage = __esm({
38466
39038
  "use strict";
38467
39039
  init_shared();
38468
39040
  init_errors();
38469
- init_src3();
39041
+ init_src4();
38470
39042
  }
38471
39043
  });
38472
39044
 
@@ -38559,10 +39131,7 @@ function registerModelsCommand(program, container) {
38559
39131
  const commandOptions = this.opts();
38560
39132
  resources.logger.intro("models");
38561
39133
  try {
38562
- const apiKey = await loadCredentials({
38563
- fs: container.fs,
38564
- filePath: container.env.credentialsPath
38565
- });
39134
+ const apiKey = await container.readApiKey();
38566
39135
  if (flags.dryRun) {
38567
39136
  resources.logger.dryRun(
38568
39137
  "Dry run: would fetch models from Poe API."
@@ -38750,9 +39319,8 @@ var init_models = __esm({
38750
39319
  "src/cli/commands/models.ts"() {
38751
39320
  "use strict";
38752
39321
  init_shared();
38753
- init_credentials2();
38754
39322
  init_errors();
38755
- init_src3();
39323
+ init_src4();
38756
39324
  MAX_VALUES_LENGTH = 105;
38757
39325
  MAX_DEFAULT_LENGTH = 36;
38758
39326
  }
@@ -38764,7 +39332,7 @@ var init_package = __esm({
38764
39332
  "package.json"() {
38765
39333
  package_default = {
38766
39334
  name: "poe-code",
38767
- version: "3.0.71",
39335
+ version: "3.0.72-beta.2",
38768
39336
  description: "CLI tool to configure Poe API for developer workflows.",
38769
39337
  type: "module",
38770
39338
  main: "./dist/index.js",
@@ -38846,6 +39414,7 @@ var init_package = __esm({
38846
39414
  devDependencies: {
38847
39415
  "@eslint/js": "^9.0.0",
38848
39416
  "@modelcontextprotocol/sdk": "^1.26.0",
39417
+ "@poe-code/auth": "*",
38849
39418
  "@poe-code/agent-spawn": "*",
38850
39419
  "@poe-code/config-mutations": "*",
38851
39420
  "@poe-code/design-system": "*",
@@ -38909,21 +39478,26 @@ function formatHelpText(input) {
38909
39478
  args: "<agent>",
38910
39479
  description: "Remove a previously applied configuration"
38911
39480
  },
39481
+ {
39482
+ name: "login",
39483
+ args: "",
39484
+ description: "Store a Poe API key"
39485
+ },
38912
39486
  {
38913
39487
  name: "logout",
38914
39488
  args: "",
38915
- description: "Remove all configuration and stored credentials"
39489
+ description: "Remove all configuration"
39490
+ },
39491
+ {
39492
+ name: "auth status",
39493
+ args: "",
39494
+ description: "Show login, balance, and configuration status"
38916
39495
  },
38917
39496
  {
38918
39497
  name: "spawn",
38919
39498
  args: "<agent> [prompt]",
38920
39499
  description: "Launch a coding agent"
38921
39500
  },
38922
- {
38923
- name: "research",
38924
- args: "<prompt>",
38925
- description: "Research a codebase using a coding agent"
38926
- },
38927
39501
  {
38928
39502
  name: "generate",
38929
39503
  args: "[type]",
@@ -39107,6 +39681,7 @@ function bootstrapProgram(container) {
39107
39681
  registerUnconfigureCommand(program, container);
39108
39682
  registerLoginCommand(program, container);
39109
39683
  registerLogoutCommand(program, container);
39684
+ registerAuthCommand(program, container);
39110
39685
  registerMcpCommand(program, container);
39111
39686
  registerSkillCommand(program, container);
39112
39687
  registerRalphCommand(program, container);
@@ -39148,13 +39723,14 @@ var init_program = __esm({
39148
39723
  async "src/cli/program.ts"() {
39149
39724
  "use strict";
39150
39725
  await init_container2();
39151
- init_src3();
39726
+ init_src4();
39152
39727
  init_configure();
39153
39728
  await init_spawn4();
39154
39729
  await init_research2();
39155
39730
  init_wrap();
39156
39731
  init_login();
39157
39732
  init_logout();
39733
+ init_auth();
39158
39734
  init_install();
39159
39735
  init_unconfigure();
39160
39736
  init_test();
@@ -39245,7 +39821,7 @@ function createPromptRunner(adapter = {
39245
39821
  var init_prompt_runner = __esm({
39246
39822
  "src/cli/prompt-runner.ts"() {
39247
39823
  "use strict";
39248
- init_src3();
39824
+ init_src4();
39249
39825
  init_errors();
39250
39826
  }
39251
39827
  });
@@ -39256,17 +39832,17 @@ __export(bootstrap_exports, {
39256
39832
  createCliMain: () => createCliMain,
39257
39833
  isCliInvocation: () => isCliInvocation
39258
39834
  });
39259
- import * as nodeFs from "node:fs/promises";
39835
+ import * as nodeFs2 from "node:fs/promises";
39260
39836
  import * as nodeFsSync3 from "node:fs";
39261
39837
  import { realpathSync } from "node:fs";
39262
- import { homedir as homedir3 } from "node:os";
39838
+ import { homedir as homedir4 } from "node:os";
39263
39839
  import { pathToFileURL as pathToFileURL2 } from "node:url";
39264
- import { join as join3 } from "node:path";
39840
+ import { join as join2 } from "node:path";
39265
39841
  import chalk13 from "chalk";
39266
39842
  function createCliMain(programFactory) {
39267
39843
  return async function runCli() {
39268
- const homeDir = homedir3();
39269
- const logDir = join3(homeDir, ".poe-code", "logs");
39844
+ const homeDir = homedir4();
39845
+ const logDir = join2(homeDir, ".poe-code", "logs");
39270
39846
  const promptRunner = createPromptRunner();
39271
39847
  const shouldLogToStderr = process.env.POE_CODE_STDERR_LOGS === "1" || process.env.POE_CODE_STDERR_LOGS === "true";
39272
39848
  const errorLogger = new ErrorLogger({
@@ -39301,7 +39877,7 @@ function createCliMain(programFactory) {
39301
39877
  } else {
39302
39878
  log2.error(`Error: ${error2.message}`);
39303
39879
  log2.message(
39304
- `See logs at ${join3(logDir, "errors.log")} for more details.`,
39880
+ `See logs at ${join2(logDir, "errors.log")} for more details.`,
39305
39881
  { symbol: chalk13.magenta("\u25CF") }
39306
39882
  );
39307
39883
  }
@@ -39327,11 +39903,11 @@ var fsAdapter;
39327
39903
  var init_bootstrap = __esm({
39328
39904
  "src/cli/bootstrap.ts"() {
39329
39905
  "use strict";
39330
- init_src3();
39906
+ init_src4();
39331
39907
  init_error_logger();
39332
39908
  init_errors();
39333
39909
  init_prompt_runner();
39334
- fsAdapter = nodeFs;
39910
+ fsAdapter = nodeFs2;
39335
39911
  }
39336
39912
  });
39337
39913
 
@@ -39470,6 +40046,6 @@ export {
39470
40046
  getPoeApiKey,
39471
40047
  isCliInvocation2 as isCliInvocation,
39472
40048
  main,
39473
- spawn3 as spawn
40049
+ spawn4 as spawn
39474
40050
  };
39475
40051
  //# sourceMappingURL=index.js.map