@agentteams/cli 0.1.82 → 0.1.84

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 (111) hide show
  1. package/.eslintcache +1 -1
  2. package/README.md +4 -3
  3. package/dist/auth/activeCredential.d.ts +22 -0
  4. package/dist/auth/activeCredential.d.ts.map +1 -0
  5. package/dist/auth/activeCredential.js +25 -0
  6. package/dist/auth/activeCredential.js.map +1 -0
  7. package/dist/auth/credentialStore.d.ts +89 -0
  8. package/dist/auth/credentialStore.d.ts.map +1 -0
  9. package/dist/auth/credentialStore.js +254 -0
  10. package/dist/auth/credentialStore.js.map +1 -0
  11. package/dist/auth/personalTokenClient.d.ts +155 -0
  12. package/dist/auth/personalTokenClient.d.ts.map +1 -0
  13. package/dist/auth/personalTokenClient.js +312 -0
  14. package/dist/auth/personalTokenClient.js.map +1 -0
  15. package/dist/auth/personalTokenStore.d.ts +16 -0
  16. package/dist/auth/personalTokenStore.d.ts.map +1 -0
  17. package/dist/auth/personalTokenStore.js +27 -0
  18. package/dist/auth/personalTokenStore.js.map +1 -0
  19. package/dist/commands/agentConfig.d.ts.map +1 -1
  20. package/dist/commands/agentConfig.js +8 -6
  21. package/dist/commands/agentConfig.js.map +1 -1
  22. package/dist/commands/auth.d.ts +97 -0
  23. package/dist/commands/auth.d.ts.map +1 -0
  24. package/dist/commands/auth.js +245 -0
  25. package/dist/commands/auth.js.map +1 -0
  26. package/dist/commands/config.d.ts.map +1 -1
  27. package/dist/commands/config.js +16 -2
  28. package/dist/commands/config.js.map +1 -1
  29. package/dist/commands/convention.d.ts +11 -0
  30. package/dist/commands/convention.d.ts.map +1 -1
  31. package/dist/commands/convention.js +35 -11
  32. package/dist/commands/convention.js.map +1 -1
  33. package/dist/commands/dependency.d.ts.map +1 -1
  34. package/dist/commands/dependency.js +8 -6
  35. package/dist/commands/dependency.js.map +1 -1
  36. package/dist/commands/doctor.d.ts.map +1 -1
  37. package/dist/commands/doctor.js +75 -2
  38. package/dist/commands/doctor.js.map +1 -1
  39. package/dist/commands/index.d.ts.map +1 -1
  40. package/dist/commands/index.js +19 -14
  41. package/dist/commands/index.js.map +1 -1
  42. package/dist/commands/init.d.ts +18 -1
  43. package/dist/commands/init.d.ts.map +1 -1
  44. package/dist/commands/init.js +114 -20
  45. package/dist/commands/init.js.map +1 -1
  46. package/dist/index.js +101 -15
  47. package/dist/index.js.map +1 -1
  48. package/dist/mcp/context.d.ts +15 -1
  49. package/dist/mcp/context.d.ts.map +1 -1
  50. package/dist/mcp/context.js +24 -5
  51. package/dist/mcp/context.js.map +1 -1
  52. package/dist/mcp/server.d.ts +1 -1
  53. package/dist/mcp/server.d.ts.map +1 -1
  54. package/dist/mcp/server.js +5 -2
  55. package/dist/mcp/server.js.map +1 -1
  56. package/dist/mcp/tools.d.ts.map +1 -1
  57. package/dist/mcp/tools.js +25 -22
  58. package/dist/mcp/tools.js.map +1 -1
  59. package/dist/mcp-registration/atomicWrite.d.ts +9 -3
  60. package/dist/mcp-registration/atomicWrite.d.ts.map +1 -1
  61. package/dist/mcp-registration/atomicWrite.js +58 -15
  62. package/dist/mcp-registration/atomicWrite.js.map +1 -1
  63. package/dist/mcp-registration/clients.d.ts.map +1 -1
  64. package/dist/mcp-registration/clients.js +1 -9
  65. package/dist/mcp-registration/clients.js.map +1 -1
  66. package/dist/mcp-registration/doctor.d.ts +38 -0
  67. package/dist/mcp-registration/doctor.d.ts.map +1 -0
  68. package/dist/mcp-registration/doctor.js +379 -0
  69. package/dist/mcp-registration/doctor.js.map +1 -0
  70. package/dist/mcp-registration/index.d.ts +7 -5
  71. package/dist/mcp-registration/index.d.ts.map +1 -1
  72. package/dist/mcp-registration/index.js +46 -21
  73. package/dist/mcp-registration/index.js.map +1 -1
  74. package/dist/mcp-registration/install.d.ts.map +1 -1
  75. package/dist/mcp-registration/install.js +12 -15
  76. package/dist/mcp-registration/install.js.map +1 -1
  77. package/dist/mcp-registration/render.d.ts +8 -6
  78. package/dist/mcp-registration/render.d.ts.map +1 -1
  79. package/dist/mcp-registration/render.js +15 -36
  80. package/dist/mcp-registration/render.js.map +1 -1
  81. package/dist/mcp-registration/serverSpec.d.ts +31 -18
  82. package/dist/mcp-registration/serverSpec.d.ts.map +1 -1
  83. package/dist/mcp-registration/serverSpec.js +36 -20
  84. package/dist/mcp-registration/serverSpec.js.map +1 -1
  85. package/dist/mcp-registration/types.d.ts +0 -3
  86. package/dist/mcp-registration/types.d.ts.map +1 -1
  87. package/dist/types/index.d.ts +10 -0
  88. package/dist/types/index.d.ts.map +1 -1
  89. package/dist/utils/apiKeyInput.d.ts +16 -0
  90. package/dist/utils/apiKeyInput.d.ts.map +1 -0
  91. package/dist/utils/apiKeyInput.js +47 -0
  92. package/dist/utils/apiKeyInput.js.map +1 -0
  93. package/dist/utils/authServer.d.ts +39 -4
  94. package/dist/utils/authServer.d.ts.map +1 -1
  95. package/dist/utils/authServer.js +146 -62
  96. package/dist/utils/authServer.js.map +1 -1
  97. package/dist/utils/config.d.ts +121 -10
  98. package/dist/utils/config.d.ts.map +1 -1
  99. package/dist/utils/config.js +204 -5
  100. package/dist/utils/config.js.map +1 -1
  101. package/dist/utils/errors.d.ts.map +1 -1
  102. package/dist/utils/errors.js +16 -0
  103. package/dist/utils/errors.js.map +1 -1
  104. package/dist/utils/httpClient.d.ts.map +1 -1
  105. package/dist/utils/httpClient.js +25 -0
  106. package/dist/utils/httpClient.js.map +1 -1
  107. package/dist/utils/initOutput.d.ts.map +1 -1
  108. package/dist/utils/initOutput.js +30 -0
  109. package/dist/utils/initOutput.js.map +1 -1
  110. package/package.json +1 -1
  111. package/web-compatibility.json +4 -0
@@ -1,6 +1,10 @@
1
1
  import type { Config } from '../types/index.js';
2
+ import { type PersonalTokenClient } from '../auth/personalTokenClient.js';
2
3
  export declare const DEFAULT_API_URL = "https://api.agentteams.run";
3
- export type PersistedConfig = Pick<Config, 'teamId' | 'projectId' | 'apiKey'> & Partial<Pick<Config, 'apiUrl'>>;
4
+ /** Local config may contain a legacy API key, so it must not be group- or world-readable. */
5
+ export declare const CONFIG_FILE_MODE = 384;
6
+ export type PersistedConfig = Pick<Config, 'teamId' | 'projectId'> & Partial<Pick<Config, 'apiUrl' | 'authMode'>>;
7
+ export type LegacyApiKeyPersistedConfig = PersistedConfig & Pick<Config, 'apiKey'>;
4
8
  /** Read only the repository/worktree config, without environment or global fallbacks. */
5
9
  export declare function loadProjectConfig(startDir?: string): Partial<Config> | null;
6
10
  /**
@@ -12,25 +16,132 @@ export declare function loadProjectConfig(startDir?: string): Partial<Config> |
12
16
  export declare function findProjectConfig(startDir: string): string | null;
13
17
  export declare function getConfigurationNotFoundMessage(startDir?: string, userHomeDir?: string): string;
14
18
  /**
15
- * Load configuration with priority-based merging.
19
+ * The merge above, gated on a `key_` being present.
16
20
  *
17
- * Priority (highest lowest):
18
- * 1. CLI options (passed as argument)
19
- * 2. Environment variables (AGENTTEAMS_*)
20
- * 3. Project config (.agentteams/config.json in nearest ancestor)
21
- * 4. Global config (~/.agentteams/config.json)
22
- *
23
- * @param options - CLI argument overrides (highest priority)
24
- * @returns Merged Config if all required fields are present, otherwise null
21
+ * ⚠️ Not for command paths. A personal-login project writes no `apiKey`, so this
22
+ * returns null there and the caller reports a configured project as "run
23
+ * `agentteams init` first". Use {@link loadConfigWithCredential} to run a
24
+ * command, or {@link loadConfigIdentity} when only the project binding matters.
25
25
  */
26
26
  export declare function loadConfig(options?: Partial<Config>): Config | null;
27
+ /**
28
+ * The project binding on its own — no credential required.
29
+ *
30
+ * A personal-token project keeps no `apiKey` on disk, so `loadConfig()` reports
31
+ * it as uninitialized. Callers that only need to know *which* project this is
32
+ * (MCP registration renders the binding into a client config) ask for this
33
+ * instead of forcing a keychain round trip they have no use for.
34
+ */
35
+ export interface ConfigIdentity {
36
+ teamId: string;
37
+ projectId: string;
38
+ apiUrl: string;
39
+ authMode?: Config['authMode'];
40
+ }
41
+ export declare function loadConfigIdentity(options?: Partial<Config>): ConfigIdentity | null;
42
+ /**
43
+ * Which credential the CLI is about to authenticate with.
44
+ *
45
+ * `auth status` reports this verbatim, so the choice must never be implicit —
46
+ * "why is my key not being used" is unanswerable otherwise.
47
+ */
48
+ export type CredentialSource = 'explicit-api-key' | 'personal-token' | 'config-api-key';
49
+ export interface ResolvedCredential {
50
+ source: CredentialSource;
51
+ /**
52
+ * The value that goes on the wire. `apiContext.buildAuthHeaders()` picks the
53
+ * header from the prefix (`key_` → `X-API-Key`, otherwise `Bearer`), which is
54
+ * exactly why a personal access token can be handed over in the same slot and
55
+ * the HTTP layer needs no change at all.
56
+ */
57
+ apiKey: string;
58
+ expiresAt?: number;
59
+ }
60
+ export declare class CredentialResolutionError extends Error {
61
+ constructor(message: string);
62
+ }
63
+ export type ResolvedConfig = Config & {
64
+ credentialSource: CredentialSource;
65
+ };
66
+ export interface ResolveCredentialDeps {
67
+ /** Injection point for tests; production always uses the per-server singleton. */
68
+ getClient?: (apiUrl: string) => PersonalTokenClient;
69
+ }
70
+ /** Reset only the process-level warning latch used by isolated tests. */
71
+ export declare function resetLegacyApiKeyWarningForTest(): void;
72
+ /**
73
+ * Which credential *would* be used, decided from config files alone.
74
+ *
75
+ * Split out of {@link resolveCredential} so callers that only need the choice —
76
+ * MCP registration deciding whether to write an API key into a client config —
77
+ * get the answer without a keychain lookup or a token refresh, and without a
78
+ * second copy of the priority rule going stale.
79
+ */
80
+ export type CredentialPlan = {
81
+ source: 'explicit-api-key';
82
+ apiKey: string;
83
+ apiUrl: string;
84
+ }
85
+ /**
86
+ * `optedIn` separates "the project chose this path" from "there is no `key_`
87
+ * left, so try it". Only the first makes a missing credential fatal.
88
+ */
89
+ | {
90
+ source: 'personal-token';
91
+ apiUrl: string;
92
+ optedIn: boolean;
93
+ fallbackApiKey?: string;
94
+ } | {
95
+ source: 'config-api-key';
96
+ apiKey: string;
97
+ apiUrl: string;
98
+ };
99
+ /**
100
+ * Priority, highest first:
101
+ * 1. `--api-key` / `AGENTTEAMS_API_KEY` — the CI path, and an explicit
102
+ * override always beats stored state.
103
+ * 2. A personal token from the OS credential store — but **only** when the
104
+ * project opted in (`authMode: 'personal-token'`) or there is no `key_` to
105
+ * fall back to. A project that still carries an agent key must never pay
106
+ * for a keychain lookup, let alone be blocked by one that fails.
107
+ * 3. The `key_` in `.agentteams/config.json` — the original path, unchanged.
108
+ */
109
+ export declare function planCredential(options?: Partial<Config>): CredentialPlan;
110
+ /** Decide which credential to authenticate with, and produce the value to send. */
111
+ export declare function resolveCredential(options?: Partial<Config>, deps?: ResolveCredentialDeps): Promise<ResolvedCredential | null>;
112
+ /**
113
+ * `loadConfig()` plus credential resolution.
114
+ *
115
+ * The credential is substituted into `apiKey` at load time on purpose: `Config.apiKey`
116
+ * stays a required `string`, so every command and every `resolveApiContext()` call
117
+ * downstream is untouched by the new auth path.
118
+ */
119
+ export declare function loadConfigWithCredential(options?: Partial<Config>, deps?: ResolveCredentialDeps): Promise<ResolvedConfig | null>;
120
+ /**
121
+ * Flip a project between the two auth paths without disturbing anything else in
122
+ * its config file.
123
+ *
124
+ * `saveConfig` rewrites the whole document from a typed shape, which would drop
125
+ * any field this CLI version does not know about — including one a newer CLI
126
+ * wrote. Removing `authMode` (on logout) is what lets a project fall back to the
127
+ * `key_` it may still have.
128
+ */
129
+ export declare function setProjectAuthMode(configPath: string, authMode: Config['authMode'] | null): boolean;
27
130
  /**
28
131
  * Save configuration to a JSON file.
29
132
  * Creates parent directories if they don't exist.
30
133
  *
134
+ * The document is written through a temp file in the same directory and renamed
135
+ * into place: a crash or a full disk can never leave a truncated config behind.
136
+ * The result is always {@link CONFIG_FILE_MODE}; repairing configs this function
137
+ * does not write is `agentteams doctor`'s job, not this one's. This normal path
138
+ * deliberately cannot persist `apiKey`; only the explicit legacy helper can.
139
+ *
31
140
  * @param configPath - Absolute path to write the config file
32
141
  * @param config - Configuration object to persist
33
142
  * @throws Error if write fails
34
143
  */
35
144
  export declare function saveConfig(configPath: string, config: PersistedConfig): void;
145
+ /** Compatibility-only persistence for an explicit `agentteams init --auth api-key`. */
146
+ export declare function saveLegacyApiKeyConfig(configPath: string, config: LegacyApiKeyPersistedConfig): void;
36
147
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAMhD,eAAO,MAAM,eAAe,+BAA+B,CAAC;AAC5D,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AAehH,yFAAyF;AACzF,wBAAgB,iBAAiB,CAAC,QAAQ,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAG1F;AAuBD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA+BjE;AAED,wBAAgB,+BAA+B,CAC7C,QAAQ,GAAE,MAAsB,EAChC,WAAW,GAAE,MAAkB,GAC9B,MAAM,CAmBR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAwBnE;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAQ5E"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAA0B,KAAK,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAMlG,eAAO,MAAM,eAAe,+BAA+B,CAAC;AAE5D,6FAA6F;AAC7F,eAAO,MAAM,gBAAgB,MAAQ,CAAC;AACtC,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC;AAClH,MAAM,MAAM,2BAA2B,GAAG,eAAe,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAenF,yFAAyF;AACzF,wBAAgB,iBAAiB,CAAC,QAAQ,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAG1F;AAuBD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA+BjE;AAED,wBAAgB,+BAA+B,CAC7C,QAAQ,GAAE,MAAsB,EAChC,WAAW,GAAE,MAAkB,GAC9B,MAAM,CAmBR;AAoCD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAUnE;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;CAC/B;AAED,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,cAAc,GAAG,IAAI,CAUnF;AAED;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,kBAAkB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AAExF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,gBAAgB,CAAC;IACzB;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG;IAAE,gBAAgB,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE7E,MAAM,WAAW,qBAAqB;IACpC,kFAAkF;IAClF,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,mBAAmB,CAAC;CACrD;AAYD,yEAAyE;AACzE,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD;AASD;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,MAAM,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAChE;;;GAGG;GACD;IAAE,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GACvF;IAAE,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjE;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,cAAc,CAmBxE;AAED,mFAAmF;AACnF,wBAAsB,iBAAiB,CACrC,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EACzB,IAAI,GAAE,qBAA0B,GAC/B,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAyDpC;AAED;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EACzB,IAAI,GAAE,qBAA0B,GAC/B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAQhC;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,OAAO,CAanG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAE5E;AAED,uFAAuF;AACvF,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,2BAA2B,GAAG,IAAI,CAEpG"}
@@ -1,11 +1,15 @@
1
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
1
+ import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
2
2
  import { join, dirname, resolve } from 'node:path';
3
3
  import { homedir } from 'node:os';
4
+ import { setActiveCredential } from '../auth/activeCredential.js';
5
+ import { getPersonalTokenClient } from '../auth/personalTokenClient.js';
4
6
  import { resolveGitTopLevel, resolveMainCheckoutRoot } from './git.js';
5
7
  import { canonicalizePath } from './path.js';
6
8
  const CONFIG_DIR = '.agentteams';
7
9
  const CONFIG_FILE = 'config.json';
8
10
  export const DEFAULT_API_URL = 'https://api.agentteams.run';
11
+ /** Local config may contain a legacy API key, so it must not be group- or world-readable. */
12
+ export const CONFIG_FILE_MODE = 0o600;
9
13
  const CONFIGURATION_NOT_FOUND_MESSAGE = "Configuration not found. Run 'agentteams init' first or set AGENTTEAMS_* environment variables.";
10
14
  function readConfigFile(filePath) {
11
15
  try {
@@ -112,38 +116,233 @@ export function getConfigurationNotFoundMessage(startDir = process.cwd(), userHo
112
116
  * @param options - CLI argument overrides (highest priority)
113
117
  * @returns Merged Config if all required fields are present, otherwise null
114
118
  */
115
- export function loadConfig(options) {
119
+ function mergeConfigSources(options) {
116
120
  const globalPath = join(homedir(), CONFIG_DIR, CONFIG_FILE);
117
121
  const globalConfig = readConfigFile(globalPath) ?? {};
118
122
  const projectConfig = loadProjectConfig() ?? {};
119
123
  const envConfig = loadEnvConfig();
120
124
  const cliOptions = options ?? {};
121
- const merged = {
125
+ return {
122
126
  apiUrl: DEFAULT_API_URL,
123
127
  ...globalConfig,
124
128
  ...projectConfig,
125
129
  ...envConfig,
126
130
  ...cliOptions,
127
131
  };
132
+ }
133
+ function isNonEmptyString(value) {
134
+ return typeof value === 'string' && value.length > 0;
135
+ }
136
+ /**
137
+ * The merge above, gated on a `key_` being present.
138
+ *
139
+ * ⚠️ Not for command paths. A personal-login project writes no `apiKey`, so this
140
+ * returns null there and the caller reports a configured project as "run
141
+ * `agentteams init` first". Use {@link loadConfigWithCredential} to run a
142
+ * command, or {@link loadConfigIdentity} when only the project binding matters.
143
+ */
144
+ export function loadConfig(options) {
145
+ const merged = mergeConfigSources(options);
128
146
  const requiredFields = ['teamId', 'projectId', 'apiKey'];
129
- const hasAllFields = requiredFields.every((field) => typeof merged[field] === 'string' && merged[field].length > 0);
147
+ const hasAllFields = requiredFields.every((field) => isNonEmptyString(merged[field]));
130
148
  if (!hasAllFields)
131
149
  return null;
132
150
  return merged;
133
151
  }
152
+ export function loadConfigIdentity(options) {
153
+ const merged = mergeConfigSources(options);
154
+ if (!isNonEmptyString(merged.teamId) || !isNonEmptyString(merged.projectId))
155
+ return null;
156
+ return {
157
+ teamId: merged.teamId,
158
+ projectId: merged.projectId,
159
+ apiUrl: merged.apiUrl,
160
+ ...(merged.authMode ? { authMode: merged.authMode } : {}),
161
+ };
162
+ }
163
+ export class CredentialResolutionError extends Error {
164
+ constructor(message) {
165
+ super(message);
166
+ this.name = 'CredentialResolutionError';
167
+ }
168
+ }
169
+ let legacyApiKeyWarningPrinted = false;
170
+ function warnAboutLegacyApiKey() {
171
+ if (legacyApiKeyWarningPrinted)
172
+ return;
173
+ legacyApiKeyWarningPrinted = true;
174
+ process.stderr.write("[warn] This project still stores a legacy key_ credential in .agentteams/config.json. Run 'agentteams auth login', verify it with 'agentteams auth status', then remove apiKey from the project config.\n");
175
+ }
176
+ /** Reset only the process-level warning latch used by isolated tests. */
177
+ export function resetLegacyApiKeyWarningForTest() {
178
+ legacyApiKeyWarningPrinted = false;
179
+ }
180
+ /** An explicit flag or environment variable wins over anything stored on disk or in a keychain. */
181
+ function explicitApiKey(options) {
182
+ if (isNonEmptyString(options?.apiKey))
183
+ return options.apiKey;
184
+ if (isNonEmptyString(process.env.AGENTTEAMS_API_KEY))
185
+ return process.env.AGENTTEAMS_API_KEY;
186
+ return undefined;
187
+ }
188
+ /**
189
+ * Priority, highest first:
190
+ * 1. `--api-key` / `AGENTTEAMS_API_KEY` — the CI path, and an explicit
191
+ * override always beats stored state.
192
+ * 2. A personal token from the OS credential store — but **only** when the
193
+ * project opted in (`authMode: 'personal-token'`) or there is no `key_` to
194
+ * fall back to. A project that still carries an agent key must never pay
195
+ * for a keychain lookup, let alone be blocked by one that fails.
196
+ * 3. The `key_` in `.agentteams/config.json` — the original path, unchanged.
197
+ */
198
+ export function planCredential(options) {
199
+ const merged = mergeConfigSources(options);
200
+ const explicit = explicitApiKey(options);
201
+ if (explicit)
202
+ return { source: 'explicit-api-key', apiKey: explicit, apiUrl: merged.apiUrl };
203
+ const configApiKey = isNonEmptyString(merged.apiKey) ? merged.apiKey : undefined;
204
+ const optedIn = merged.authMode === 'personal-token';
205
+ if (optedIn || !configApiKey) {
206
+ return {
207
+ source: 'personal-token',
208
+ apiUrl: merged.apiUrl,
209
+ optedIn,
210
+ ...(configApiKey ? { fallbackApiKey: configApiKey } : {}),
211
+ };
212
+ }
213
+ return { source: 'config-api-key', apiKey: configApiKey, apiUrl: merged.apiUrl };
214
+ }
215
+ /** Decide which credential to authenticate with, and produce the value to send. */
216
+ export async function resolveCredential(options, deps = {}) {
217
+ const plan = planCredential(options);
218
+ if (plan.source === 'explicit-api-key') {
219
+ setActiveCredential(null);
220
+ return { source: 'explicit-api-key', apiKey: plan.apiKey };
221
+ }
222
+ const configApiKey = plan.source === 'personal-token' ? plan.fallbackApiKey : plan.apiKey;
223
+ // The warning belongs here, not in `planCredential`. Planning is a pure decision that
224
+ // callers make without authenticating — `mcp config` renders a snippet and touches no
225
+ // file — and attaching stderr output to it made those commands nag about a key they
226
+ // never read.
227
+ if (configApiKey) {
228
+ warnAboutLegacyApiKey();
229
+ }
230
+ if (plan.source === 'personal-token') {
231
+ const optedIn = plan.optedIn;
232
+ const client = (deps.getClient ?? getPersonalTokenClient)(plan.apiUrl);
233
+ if (client.hasCredential()) {
234
+ const accessToken = await client.getAccessToken();
235
+ if (accessToken) {
236
+ // Only this branch arms the HTTP layer's 401 retry. A `key_` has nothing
237
+ // to refresh, so leaving the slot empty is the guard.
238
+ setActiveCredential({
239
+ refresh: async () => {
240
+ client.invalidateAccessToken();
241
+ return client.getAccessToken();
242
+ },
243
+ });
244
+ const expiresAt = client.state().expiresAt;
245
+ return expiresAt === null
246
+ ? { source: 'personal-token', apiKey: accessToken }
247
+ : { source: 'personal-token', apiKey: accessToken, expiresAt };
248
+ }
249
+ // A stored-but-unusable token is only fatal when there is nothing else to
250
+ // try; otherwise the `key_` below still works and the user sees nothing.
251
+ if (!configApiKey) {
252
+ throw new CredentialResolutionError(client.state().reconnectRequired
253
+ ? "Your AgentTeams login was revoked or expired. Run 'agentteams auth login' to sign in again."
254
+ : "Could not refresh your AgentTeams login. Check your network connection, then retry or run 'agentteams auth login'.");
255
+ }
256
+ }
257
+ else if (optedIn && !configApiKey) {
258
+ throw new CredentialResolutionError("This project is configured to use a personal login, but no credential is stored. Run 'agentteams auth login'.");
259
+ }
260
+ }
261
+ setActiveCredential(null);
262
+ return configApiKey ? { source: 'config-api-key', apiKey: configApiKey } : null;
263
+ }
264
+ /**
265
+ * `loadConfig()` plus credential resolution.
266
+ *
267
+ * The credential is substituted into `apiKey` at load time on purpose: `Config.apiKey`
268
+ * stays a required `string`, so every command and every `resolveApiContext()` call
269
+ * downstream is untouched by the new auth path.
270
+ */
271
+ export async function loadConfigWithCredential(options, deps = {}) {
272
+ const merged = mergeConfigSources(options);
273
+ if (!isNonEmptyString(merged.teamId) || !isNonEmptyString(merged.projectId))
274
+ return null;
275
+ const credential = await resolveCredential(options, deps);
276
+ if (!credential)
277
+ return null;
278
+ return { ...merged, apiKey: credential.apiKey, credentialSource: credential.source };
279
+ }
280
+ /**
281
+ * Flip a project between the two auth paths without disturbing anything else in
282
+ * its config file.
283
+ *
284
+ * `saveConfig` rewrites the whole document from a typed shape, which would drop
285
+ * any field this CLI version does not know about — including one a newer CLI
286
+ * wrote. Removing `authMode` (on logout) is what lets a project fall back to the
287
+ * `key_` it may still have.
288
+ */
289
+ export function setProjectAuthMode(configPath, authMode) {
290
+ const existing = readConfigFile(configPath);
291
+ if (!existing)
292
+ return false;
293
+ const next = { ...existing };
294
+ if (authMode) {
295
+ next.authMode = authMode;
296
+ }
297
+ else {
298
+ delete next.authMode;
299
+ }
300
+ writeConfigDocument(configPath, next);
301
+ return true;
302
+ }
134
303
  /**
135
304
  * Save configuration to a JSON file.
136
305
  * Creates parent directories if they don't exist.
137
306
  *
307
+ * The document is written through a temp file in the same directory and renamed
308
+ * into place: a crash or a full disk can never leave a truncated config behind.
309
+ * The result is always {@link CONFIG_FILE_MODE}; repairing configs this function
310
+ * does not write is `agentteams doctor`'s job, not this one's. This normal path
311
+ * deliberately cannot persist `apiKey`; only the explicit legacy helper can.
312
+ *
138
313
  * @param configPath - Absolute path to write the config file
139
314
  * @param config - Configuration object to persist
140
315
  * @throws Error if write fails
141
316
  */
142
317
  export function saveConfig(configPath, config) {
318
+ writeConfigDocument(configPath, config);
319
+ }
320
+ /** Compatibility-only persistence for an explicit `agentteams init --auth api-key`. */
321
+ export function saveLegacyApiKeyConfig(configPath, config) {
322
+ writeConfigDocument(configPath, config);
323
+ }
324
+ function writeConfigDocument(configPath, config) {
143
325
  const dir = dirname(configPath);
144
326
  if (!existsSync(dir)) {
145
327
  mkdirSync(dir, { recursive: true });
146
328
  }
147
- writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
329
+ const body = JSON.stringify(config, null, 2) + '\n';
330
+ // Same directory as the target: `rename` is only atomic within a filesystem.
331
+ const temporaryPath = join(dir, `.${Date.now().toString(36)}-${process.pid}.agentteams-tmp`);
332
+ try {
333
+ // `mode` on open is masked by umask, so chmod restates it unconditionally.
334
+ writeFileSync(temporaryPath, body, { encoding: 'utf-8', mode: CONFIG_FILE_MODE });
335
+ chmodSync(temporaryPath, CONFIG_FILE_MODE);
336
+ renameSync(temporaryPath, configPath);
337
+ }
338
+ catch (error) {
339
+ try {
340
+ unlinkSync(temporaryPath);
341
+ }
342
+ catch {
343
+ // The temp file may never have been created; the original is untouched either way.
344
+ }
345
+ throw error;
346
+ }
148
347
  }
149
348
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAsCF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAYjF;AA4BD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAmF1E"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAsCF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAYjF;AA4BD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAkG1E"}
@@ -1,4 +1,5 @@
1
1
  import { isAxiosError } from 'axios';
2
+ import { getActiveCredential } from '../auth/activeCredential.js';
2
3
  function translateServerMessage(message) {
3
4
  const mapping = [
4
5
  { match: '컨벤션 수정 권한이 없습니다', translated: "You don't have permission to modify conventions." },
@@ -61,6 +62,7 @@ export function handleError(error, context) {
61
62
  const rawMessage = typeof data?.message === 'string' ? data.message : error.message;
62
63
  const message = typeof rawMessage === 'string' ? translateServerMessage(rawMessage) : String(rawMessage);
63
64
  const errorCode = typeof data?.errorCode === 'string' ? data.errorCode : undefined;
65
+ const errorDetailCode = typeof data?.errorDetailCode === 'string' ? data.errorDetailCode : undefined;
64
66
  const minimumVersion = typeof data?.minimumVersion === 'string' ? data.minimumVersion : undefined;
65
67
  if (status === 426 || errorCode === 'CLI_UPGRADE_REQUIRED') {
66
68
  return formatUpgradeRequiredMessage({ message, minimumVersion });
@@ -74,6 +76,20 @@ Details: ${message}`;
74
76
  }
75
77
  return `Bad request. Check your flags and payload.\nNext: Verify required options (e.g., --id/--plan-id) and try again.\nDetails: ${message}`;
76
78
  case 401:
79
+ // An agent key that ran out its 30-day TTL is not a wrong key, and telling
80
+ // someone to check AGENTTEAMS_API_KEY sends them looking at a value that is
81
+ // exactly right. This is the only signal a runner gets, so it has to name
82
+ // the cause and the fix.
83
+ if (errorDetailCode === 'AGENT_API_KEY_EXPIRED') {
84
+ return `This agent API key is no longer valid: it expired or was revoked.
85
+ Next: Reissue it in the AgentTeams web app (project settings → agents) and update .agentteams/config.json, or re-run 'agentteams init' to switch this project to a personal login that refreshes itself.
86
+ Details: ${message}`;
87
+ }
88
+ // A personal login that still fails after the automatic refresh is a
89
+ // different problem from a wrong API key, and needs a different fix.
90
+ if (getActiveCredential()) {
91
+ return `Your AgentTeams login is no longer valid.\nNext: Run 'agentteams auth login' to sign in again.\nDetails: ${message}`;
92
+ }
77
93
  if (errorCode === 'AUTH_REQUIRED') {
78
94
  return `Authentication required.
79
95
  Next: Verify your AGENTTEAMS_API_KEY and ensure credentials are configured.
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"httpClient.d.ts","sourceRoot":"","sources":["../../src/utils/httpClient.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAkF1B,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"httpClient.d.ts","sourceRoot":"","sources":["../../src/utils/httpClient.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAsH1B,eAAe,KAAK,CAAC"}
@@ -1,11 +1,22 @@
1
1
  import { createRequire } from 'node:module';
2
2
  import axios from 'axios';
3
+ import { getActiveCredential } from '../auth/activeCredential.js';
3
4
  import { getCommandContext } from './commandContext.js';
4
5
  import { writeCache } from './updateCheck.js';
5
6
  const require = createRequire(import.meta.url);
6
7
  const pkg = require('../../package.json');
7
8
  const MAX_RETRIES = 3;
8
9
  const BASE_DELAY_MS = 1_000;
10
+ /**
11
+ * Only a request that authenticated with a bearer token can be fixed by a
12
+ * refresh. An `X-API-Key` request carries a long-lived agent key with nothing
13
+ * behind it, so a 401 there means the key itself is wrong.
14
+ */
15
+ function usedBearerCredential(config) {
16
+ const headers = config.headers;
17
+ const read = (name) => typeof headers?.get === 'function' ? headers.get(name) : headers?.[name];
18
+ return typeof read('Authorization') === 'string' && read('X-API-Key') === undefined;
19
+ }
9
20
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
10
21
  const getRetryDelay = (error, attempt) => {
11
22
  const retryAfterHeader = error.response?.headers?.['retry-after'];
@@ -44,6 +55,20 @@ axios.interceptors.response.use((response) => {
44
55
  return response;
45
56
  }, async (error) => {
46
57
  const config = error.config;
58
+ // A personal access token lives 15 minutes, so a long command can outlive
59
+ // the one it started with. Refresh once and replay; anything beyond that is
60
+ // a genuine authentication failure and must reach the user.
61
+ if (config && error.response?.status === 401 && !config._authRefreshAttempted && usedBearerCredential(config)) {
62
+ const credential = getActiveCredential();
63
+ if (credential) {
64
+ config._authRefreshAttempted = true;
65
+ const accessToken = await credential.refresh();
66
+ if (accessToken) {
67
+ setRequestHeader(config, 'Authorization', `Bearer ${accessToken}`);
68
+ return axios.request(config);
69
+ }
70
+ }
71
+ }
47
72
  if (!config || error.response?.status !== 429) {
48
73
  throw error;
49
74
  }
@@ -1 +1 @@
1
- {"version":3,"file":"httpClient.js","sourceRoot":"","sources":["../../src/utils/httpClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"httpClient.js","sourceRoot":"","sources":["../../src/utils/httpClient.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"initOutput.d.ts","sourceRoot":"","sources":["../../src/utils/initOutput.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,CAAC;AAyChD,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAqG/E"}
1
+ {"version":3,"file":"initOutput.d.ts","sourceRoot":"","sources":["../../src/utils/initOutput.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,CAAC;AAqDhD,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAqI/E"}
@@ -1,5 +1,11 @@
1
1
  import chalk from 'chalk';
2
2
  import { formatOutput } from './formatter.js';
3
+ /** Mirrors AGENT_API_KEY_TTL_MS in api/src/services/agentApiKey.ts. */
4
+ const AGENT_API_KEY_TTL_DAYS = 30;
5
+ function agentApiKeyExpiryLabel() {
6
+ const expiresAt = new Date(Date.now() + AGENT_API_KEY_TTL_DAYS * 24 * 60 * 60 * 1000);
7
+ return expiresAt.toISOString().slice(0, 10);
8
+ }
3
9
  function isInitResult(result) {
4
10
  if (!result || typeof result !== 'object')
5
11
  return false;
@@ -79,6 +85,30 @@ export function printInitResult(result, format) {
79
85
  return;
80
86
  }
81
87
  console.log(`✓ Authenticated as ${result.agentName}`);
88
+ // The human view is the default, so anything the personal-token path decided
89
+ // has to show up here — a warning only `--format json` reveals is a warning
90
+ // nobody reads.
91
+ if (result.authMode === 'personal-token') {
92
+ if (result.personalLogin) {
93
+ console.log(`✓ Signed in as ${result.personalLogin.email} (${result.personalLogin.nickname})`);
94
+ console.log(result.personalLogin.persisted
95
+ ? '✓ Login stored in the OS credential store; no long-lived key was written to this repository.'
96
+ : '⚠ Login kept in memory for this process only.');
97
+ }
98
+ if (result.agentKeyRevoked === true) {
99
+ console.log('✓ The setup agent key was revoked; nothing long-lived is left on the server.');
100
+ }
101
+ }
102
+ // The compatibility path has a hard 30-day server-side TTL and no renewal of its own.
103
+ // Saying so here is the difference between a planned reissue and a runner that starts
104
+ // failing with a bare 401 exactly one month from today.
105
+ if (result.authMode === 'api-key') {
106
+ console.log(`⚠ This agent API key expires in 30 days (${agentApiKeyExpiryLabel()}) and does not renew itself.`);
107
+ console.log(" Reissue it in the web app (project settings → agents) before then, or run 'agentteams init' to switch to a personal login that refreshes automatically.");
108
+ }
109
+ if (result.warning) {
110
+ console.warn(`⚠ ${result.warning}`);
111
+ }
82
112
  console.log(`✓ Config saved: ${result.configPath}`);
83
113
  console.log(`✓ Convention saved: ${result.conventionPath}`);
84
114
  console.log(`✓ Conventions synced to .agentteams/`);