@agentteams/cli 0.1.83 → 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 (102) hide show
  1. package/.eslintcache +1 -1
  2. package/dist/auth/activeCredential.d.ts +22 -0
  3. package/dist/auth/activeCredential.d.ts.map +1 -0
  4. package/dist/auth/activeCredential.js +25 -0
  5. package/dist/auth/activeCredential.js.map +1 -0
  6. package/dist/auth/credentialStore.d.ts +89 -0
  7. package/dist/auth/credentialStore.d.ts.map +1 -0
  8. package/dist/auth/credentialStore.js +254 -0
  9. package/dist/auth/credentialStore.js.map +1 -0
  10. package/dist/auth/personalTokenClient.d.ts +155 -0
  11. package/dist/auth/personalTokenClient.d.ts.map +1 -0
  12. package/dist/auth/personalTokenClient.js +312 -0
  13. package/dist/auth/personalTokenClient.js.map +1 -0
  14. package/dist/auth/personalTokenStore.d.ts +16 -0
  15. package/dist/auth/personalTokenStore.d.ts.map +1 -0
  16. package/dist/auth/personalTokenStore.js +27 -0
  17. package/dist/auth/personalTokenStore.js.map +1 -0
  18. package/dist/commands/agentConfig.d.ts.map +1 -1
  19. package/dist/commands/agentConfig.js +8 -6
  20. package/dist/commands/agentConfig.js.map +1 -1
  21. package/dist/commands/auth.d.ts +97 -0
  22. package/dist/commands/auth.d.ts.map +1 -0
  23. package/dist/commands/auth.js +245 -0
  24. package/dist/commands/auth.js.map +1 -0
  25. package/dist/commands/config.d.ts.map +1 -1
  26. package/dist/commands/config.js +16 -2
  27. package/dist/commands/config.js.map +1 -1
  28. package/dist/commands/convention.d.ts +11 -0
  29. package/dist/commands/convention.d.ts.map +1 -1
  30. package/dist/commands/convention.js +35 -11
  31. package/dist/commands/convention.js.map +1 -1
  32. package/dist/commands/dependency.d.ts.map +1 -1
  33. package/dist/commands/dependency.js +8 -6
  34. package/dist/commands/dependency.js.map +1 -1
  35. package/dist/commands/index.d.ts.map +1 -1
  36. package/dist/commands/index.js +19 -14
  37. package/dist/commands/index.js.map +1 -1
  38. package/dist/commands/init.d.ts +17 -0
  39. package/dist/commands/init.d.ts.map +1 -1
  40. package/dist/commands/init.js +90 -9
  41. package/dist/commands/init.js.map +1 -1
  42. package/dist/index.js +101 -15
  43. package/dist/index.js.map +1 -1
  44. package/dist/mcp/context.d.ts +15 -1
  45. package/dist/mcp/context.d.ts.map +1 -1
  46. package/dist/mcp/context.js +24 -5
  47. package/dist/mcp/context.js.map +1 -1
  48. package/dist/mcp/server.d.ts +1 -1
  49. package/dist/mcp/server.d.ts.map +1 -1
  50. package/dist/mcp/server.js +5 -2
  51. package/dist/mcp/server.js.map +1 -1
  52. package/dist/mcp/tools.d.ts.map +1 -1
  53. package/dist/mcp/tools.js +25 -22
  54. package/dist/mcp/tools.js.map +1 -1
  55. package/dist/mcp-registration/clients.d.ts.map +1 -1
  56. package/dist/mcp-registration/clients.js +1 -9
  57. package/dist/mcp-registration/clients.js.map +1 -1
  58. package/dist/mcp-registration/doctor.d.ts +38 -0
  59. package/dist/mcp-registration/doctor.d.ts.map +1 -0
  60. package/dist/mcp-registration/doctor.js +379 -0
  61. package/dist/mcp-registration/doctor.js.map +1 -0
  62. package/dist/mcp-registration/index.d.ts +7 -5
  63. package/dist/mcp-registration/index.d.ts.map +1 -1
  64. package/dist/mcp-registration/index.js +46 -21
  65. package/dist/mcp-registration/index.js.map +1 -1
  66. package/dist/mcp-registration/install.d.ts.map +1 -1
  67. package/dist/mcp-registration/install.js +12 -15
  68. package/dist/mcp-registration/install.js.map +1 -1
  69. package/dist/mcp-registration/render.d.ts +8 -6
  70. package/dist/mcp-registration/render.d.ts.map +1 -1
  71. package/dist/mcp-registration/render.js +15 -36
  72. package/dist/mcp-registration/render.js.map +1 -1
  73. package/dist/mcp-registration/serverSpec.d.ts +31 -18
  74. package/dist/mcp-registration/serverSpec.d.ts.map +1 -1
  75. package/dist/mcp-registration/serverSpec.js +36 -20
  76. package/dist/mcp-registration/serverSpec.js.map +1 -1
  77. package/dist/mcp-registration/types.d.ts +0 -3
  78. package/dist/mcp-registration/types.d.ts.map +1 -1
  79. package/dist/types/index.d.ts +10 -0
  80. package/dist/types/index.d.ts.map +1 -1
  81. package/dist/utils/apiKeyInput.d.ts +16 -0
  82. package/dist/utils/apiKeyInput.d.ts.map +1 -0
  83. package/dist/utils/apiKeyInput.js +47 -0
  84. package/dist/utils/apiKeyInput.js.map +1 -0
  85. package/dist/utils/authServer.d.ts +32 -3
  86. package/dist/utils/authServer.d.ts.map +1 -1
  87. package/dist/utils/authServer.js +46 -6
  88. package/dist/utils/authServer.js.map +1 -1
  89. package/dist/utils/config.d.ts +118 -15
  90. package/dist/utils/config.d.ts.map +1 -1
  91. package/dist/utils/config.js +182 -8
  92. package/dist/utils/config.js.map +1 -1
  93. package/dist/utils/errors.d.ts.map +1 -1
  94. package/dist/utils/errors.js +16 -0
  95. package/dist/utils/errors.js.map +1 -1
  96. package/dist/utils/httpClient.d.ts.map +1 -1
  97. package/dist/utils/httpClient.js +25 -0
  98. package/dist/utils/httpClient.js.map +1 -1
  99. package/dist/utils/initOutput.d.ts.map +1 -1
  100. package/dist/utils/initOutput.js +30 -0
  101. package/dist/utils/initOutput.js.map +1 -1
  102. package/package.json +1 -1
@@ -0,0 +1,245 @@
1
+ /**
2
+ * `agentteams auth login | status | logout`.
3
+ *
4
+ * The default authentication path for new projects and the migration path for
5
+ * legacy configs. The stored credential is picked up by `resolveCredential()`
6
+ * when the config has no `key_`, or when a migrated legacy project carries
7
+ * `authMode: 'personal-token'`.
8
+ */
9
+ import open from 'open';
10
+ import { getPersonalTokenClient, PersonalTokenError } from '../auth/personalTokenClient.js';
11
+ import { startAuthorizationCodeServer, createAuthState, createPkcePair } from '../utils/authServer.js';
12
+ import { DEFAULT_API_URL, findProjectConfig, loadProjectConfig, resolveCredential, setProjectAuthMode, } from '../utils/config.js';
13
+ import { createSpinner } from '../utils/spinner.js';
14
+ import { withCommandContext } from '../utils/commandContext.js';
15
+ const AUTH_BASE_URL = process.env.AGENTTEAMS_WEB_URL || 'https://agentteams.run';
16
+ /**
17
+ * Where to log in. Unlike the legacy `init` path this honours the project's own
18
+ * `apiUrl`, because a refresh token issued by the dev API is worthless against
19
+ * production and storing it under the wrong server would silently fail later.
20
+ */
21
+ export function resolveAuthApiUrl(options) {
22
+ const candidate = (typeof options?.apiUrl === 'string' && options.apiUrl.length > 0 ? options.apiUrl : undefined) ??
23
+ process.env.AGENTTEAMS_API_URL ??
24
+ loadProjectConfig()?.apiUrl ??
25
+ DEFAULT_API_URL;
26
+ return candidate.replace(/\/+$/, '');
27
+ }
28
+ export function buildPersonalTokenAuthorizeUrl(input) {
29
+ const params = new URLSearchParams({
30
+ port: String(input.port),
31
+ state: input.state,
32
+ code_challenge: input.codeChallenge,
33
+ });
34
+ if (input.projectName) {
35
+ params.set('projectName', input.projectName);
36
+ }
37
+ return `${AUTH_BASE_URL.replace(/\/+$/, '')}/cli/authorize?${params.toString()}`;
38
+ }
39
+ function isSshEnvironment() {
40
+ return Boolean(process.env.SSH_CONNECTION || process.env.SSH_CLIENT || process.env.SSH_TTY);
41
+ }
42
+ async function tryOpenBrowser(url) {
43
+ console.log('🔐 Complete the AgentTeams login in your browser:');
44
+ console.log(url);
45
+ // Headless and SSH sessions have no browser to open; the printed URL is the
46
+ // whole interface there, exactly as in `init`.
47
+ if (isSshEnvironment()) {
48
+ return;
49
+ }
50
+ try {
51
+ await open(url);
52
+ }
53
+ catch {
54
+ // Already printed.
55
+ }
56
+ }
57
+ /**
58
+ * Run the browser round trip and exchange the resulting code for tokens.
59
+ *
60
+ * Exported so `init --auth personal-token` reuses the identical flow rather than
61
+ * growing a second copy of the PKCE handshake.
62
+ */
63
+ export async function performPersonalTokenLogin(input) {
64
+ const client = getPersonalTokenClient(input.apiUrl);
65
+ const pkce = createPkcePair();
66
+ const authContext = await startAuthorizationCodeServer({ state: createAuthState() });
67
+ const authUrl = buildPersonalTokenAuthorizeUrl({
68
+ port: authContext.port,
69
+ state: authContext.state,
70
+ codeChallenge: pkce.challenge,
71
+ ...(input.projectName ? { projectName: input.projectName } : {}),
72
+ });
73
+ await tryOpenBrowser(authUrl);
74
+ const spinner = createSpinner('Waiting for authorization... (Ctrl+C to cancel)');
75
+ try {
76
+ const callback = await authContext.waitForCallback();
77
+ spinner?.succeed();
78
+ const session = await client.exchangeAuthorizationCode({
79
+ code: callback.code,
80
+ codeVerifier: pkce.verifier,
81
+ // Must match the redirect the web registered the code against.
82
+ redirectUri: `http://localhost:${authContext.port}/callback`,
83
+ });
84
+ const state = client.state();
85
+ return {
86
+ authUrl,
87
+ identity: session.identity,
88
+ persisted: state.persisted,
89
+ storeBackend: state.storeBackend,
90
+ storeReason: state.storeReason,
91
+ };
92
+ }
93
+ catch (error) {
94
+ spinner?.fail();
95
+ throw error;
96
+ }
97
+ finally {
98
+ if (authContext.server.listening) {
99
+ authContext.server.close();
100
+ }
101
+ }
102
+ }
103
+ async function login(options) {
104
+ const requestedApiUrl = typeof options.apiUrl === 'string' ? options.apiUrl : undefined;
105
+ const apiUrl = resolveAuthApiUrl({ apiUrl: requestedApiUrl });
106
+ // What every later command will resolve against. The refresh token is filed
107
+ // under the server that issued it, so logging in to a different one would
108
+ // store the credential in a slot nothing ever reads — a "success" that makes
109
+ // the very next command fail.
110
+ const projectApiUrl = resolveAuthApiUrl();
111
+ if (apiUrl !== projectApiUrl) {
112
+ throw new PersonalTokenError('TRANSIENT', `This project talks to ${projectApiUrl}, so a login to ${apiUrl} would be stored where no command looks for it. ` +
113
+ `Point the project at that server first (set apiUrl in .agentteams/config.json or AGENTTEAMS_API_URL), then run 'agentteams auth login' without --api-url.`);
114
+ }
115
+ const outcome = await performPersonalTokenLogin({ apiUrl });
116
+ const configPath = findProjectConfig(process.cwd());
117
+ // Opting the project in is what makes later commands prefer this credential.
118
+ // Only ever done for a credential that outlives this process: flipping the
119
+ // project over to a login the next command cannot find would lock it out
120
+ // entirely when there is no `key_` left to fall back to.
121
+ const opted = configPath && outcome.persisted ? setProjectAuthMode(configPath, 'personal-token') : false;
122
+ const result = {
123
+ success: true,
124
+ authUrl: outcome.authUrl,
125
+ apiUrl,
126
+ identity: outcome.identity,
127
+ persisted: outcome.persisted,
128
+ storeBackend: outcome.storeBackend,
129
+ storeReason: outcome.storeReason,
130
+ configPath: opted ? configPath : null,
131
+ authMode: 'personal-token',
132
+ };
133
+ if (!outcome.persisted) {
134
+ result.warning =
135
+ 'The login is kept in memory for this process only, so this project was left on its existing credential. ' +
136
+ 'For CI and headless machines, keep using an API key (AGENTTEAMS_API_KEY).';
137
+ }
138
+ else if (!opted) {
139
+ result.warning =
140
+ "No project config was found, so nothing was switched to the personal login. Run 'agentteams init' in the project first, then run this again.";
141
+ }
142
+ return result;
143
+ }
144
+ async function status(options = {}) {
145
+ const apiUrl = resolveAuthApiUrl({ apiUrl: typeof options.apiUrl === 'string' ? options.apiUrl : undefined });
146
+ const projectConfig = loadProjectConfig();
147
+ const client = getPersonalTokenClient(apiUrl);
148
+ // Reading the state must not require a working network: a token that cannot
149
+ // be refreshed right now is still worth reporting as present.
150
+ const tokenState = client.state();
151
+ let credentialSource = null;
152
+ let problem;
153
+ try {
154
+ // The same apiUrl this command reports, so `apiUrl` and `credentialSource`
155
+ // can never describe two different servers.
156
+ credentialSource = (await resolveCredential({ apiUrl }))?.source ?? null;
157
+ }
158
+ catch (error) {
159
+ problem = error instanceof Error ? error.message : String(error);
160
+ }
161
+ const refreshedState = client.state();
162
+ const result = {
163
+ apiUrl,
164
+ configPath: findProjectConfig(process.cwd()),
165
+ credentialSource,
166
+ authMode: projectConfig?.authMode ?? null,
167
+ hasProjectApiKey: typeof projectConfig?.apiKey === 'string' && projectConfig.apiKey.length > 0,
168
+ personalToken: {
169
+ connected: tokenState.connected,
170
+ persisted: tokenState.persisted,
171
+ storeBackend: tokenState.storeBackend,
172
+ storeReason: tokenState.storeReason,
173
+ reconnectRequired: refreshedState.reconnectRequired,
174
+ identity: refreshedState.identity,
175
+ expiresAt: refreshedState.expiresAt ? new Date(refreshedState.expiresAt).toISOString() : null,
176
+ },
177
+ };
178
+ if (problem)
179
+ result.problem = problem;
180
+ return result;
181
+ }
182
+ /**
183
+ * Leave the personal-token path.
184
+ *
185
+ * Reverting `authMode` is the part that must always be reachable: a project
186
+ * left on `personal-token` with no credential fails every command, so a missing
187
+ * keychain entry or an unreachable server cannot be allowed to trap the user in
188
+ * a state only a hand-edited config file gets out of.
189
+ */
190
+ async function logout(options = {}) {
191
+ const apiUrl = resolveAuthApiUrl({ apiUrl: typeof options.apiUrl === 'string' ? options.apiUrl : undefined });
192
+ const client = getPersonalTokenClient(apiUrl);
193
+ const localOnly = options.local === true;
194
+ let revokedOnServer = false;
195
+ let warning;
196
+ if (!client.hasCredential()) {
197
+ warning = `No AgentTeams login was stored for ${apiUrl}; only the project setting was reverted.`;
198
+ }
199
+ else if (localOnly) {
200
+ client.forgetLocalCredential();
201
+ warning =
202
+ 'The local credential was removed without contacting the server, so the token is still valid there. ' +
203
+ 'Revoke it from the AgentTeams web app if you no longer want it.';
204
+ }
205
+ else {
206
+ try {
207
+ // Server first: clearing locally and then failing the revoke would leave a
208
+ // live refresh token the owner can no longer see or cancel.
209
+ await client.revoke();
210
+ revokedOnServer = true;
211
+ }
212
+ catch (error) {
213
+ const detail = error instanceof Error ? error.message : String(error);
214
+ throw new PersonalTokenError('REVOKE_FAILED', `${detail} Run 'agentteams auth logout --local' to leave the personal login path anyway.`);
215
+ }
216
+ }
217
+ const configPath = findProjectConfig(process.cwd());
218
+ const reverted = configPath ? setProjectAuthMode(configPath, null) : false;
219
+ const projectConfig = loadProjectConfig();
220
+ const result = {
221
+ success: true,
222
+ apiUrl,
223
+ configPath: reverted ? configPath : null,
224
+ revokedOnServer,
225
+ fellBackToApiKey: typeof projectConfig?.apiKey === 'string' && projectConfig.apiKey.length > 0,
226
+ };
227
+ if (warning)
228
+ result.warning = warning;
229
+ return result;
230
+ }
231
+ export async function executeAuthCommand(action, options = {}) {
232
+ return withCommandContext(`auth:${action}`, async () => {
233
+ switch (action) {
234
+ case 'login':
235
+ return login(options);
236
+ case 'status':
237
+ return status(options);
238
+ case 'logout':
239
+ return logout(options);
240
+ default:
241
+ throw new Error(`Unknown action: ${action}. Expected one of: login, status, logout.`);
242
+ }
243
+ });
244
+ }
245
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAE5F,OAAO,EAAE,4BAA4B,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACvG,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,GAEnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,wBAAwB,CAAC;AAmDjF;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAA6B;IAC7D,MAAM,SAAS,GACb,CAAC,OAAO,OAAO,EAAE,MAAM,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QAC/F,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAC9B,iBAAiB,EAAE,EAAE,MAAM;QAC3B,eAAe,CAAC;IAClB,OAAO,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,KAK9C;IACC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;QACxB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,cAAc,EAAE,KAAK,CAAC,aAAa;KACpC,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,kBAAkB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;AACnF,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC9F,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,GAAW;IACvC,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEjB,4EAA4E;IAC5E,+CAA+C;IAC/C,IAAI,gBAAgB,EAAE,EAAE,CAAC;QACvB,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,mBAAmB;IACrB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,KAA+C;IAO7F,MAAM,MAAM,GAAG,sBAAsB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAC9B,MAAM,WAAW,GAAG,MAAM,4BAA4B,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;IAErF,MAAM,OAAO,GAAG,8BAA8B,CAAC;QAC7C,IAAI,EAAE,WAAW,CAAC,IAAI;QACtB,KAAK,EAAE,WAAW,CAAC,KAAK;QACxB,aAAa,EAAE,IAAI,CAAC,SAAS;QAC7B,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACjE,CAAC,CAAC;IAEH,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAC9B,MAAM,OAAO,GAAG,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAEjF,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,eAAe,EAAE,CAAC;QACrD,OAAO,EAAE,OAAO,EAAE,CAAC;QAEnB,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC;YACrD,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,YAAY,EAAE,IAAI,CAAC,QAAQ;YAC3B,+DAA+D;YAC/D,WAAW,EAAE,oBAAoB,WAAW,CAAC,IAAI,WAAW;SAC7D,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;QAC7B,OAAO;YACL,OAAO;YACP,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,WAAW,EAAE,KAAK,CAAC,WAAW;SAC/B,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,IAAI,EAAE,CAAC;QAChB,MAAM,KAAK,CAAC;IACd,CAAC;YAAS,CAAC;QACT,IAAI,WAAW,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACjC,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC7B,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,KAAK,CAAC,OAAgC;IACnD,MAAM,eAAe,GAAG,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IACxF,MAAM,MAAM,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC;IAC9D,4EAA4E;IAC5E,0EAA0E;IAC1E,6EAA6E;IAC7E,8BAA8B;IAC9B,MAAM,aAAa,GAAG,iBAAiB,EAAE,CAAC;IAE1C,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;QAC7B,MAAM,IAAI,kBAAkB,CAC1B,WAAW,EACX,yBAAyB,aAAa,mBAAmB,MAAM,kDAAkD;YAC/G,2JAA2J,CAC9J,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,yBAAyB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAE5D,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACpD,6EAA6E;IAC7E,2EAA2E;IAC3E,yEAAyE;IACzE,yDAAyD;IACzD,MAAM,KAAK,GAAG,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAEzG,MAAM,MAAM,GAAoB;QAC9B,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,MAAM;QACN,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;QACrC,QAAQ,EAAE,gBAAgB;KAC3B,CAAC;IAEF,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACvB,MAAM,CAAC,OAAO;YACZ,0GAA0G;gBAC1G,2EAA2E,CAAC;IAChF,CAAC;SAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,CAAC,OAAO;YACZ,8IAA8I,CAAC;IACnJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,UAAmC,EAAE;IACzD,MAAM,MAAM,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IAC9G,MAAM,aAAa,GAAG,iBAAiB,EAAE,CAAC;IAC1C,MAAM,MAAM,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAE9C,4EAA4E;IAC5E,8DAA8D;IAC9D,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAElC,IAAI,gBAAgB,GAA4B,IAAI,CAAC;IACrD,IAAI,OAA2B,CAAC;IAChC,IAAI,CAAC;QACH,2EAA2E;QAC3E,4CAA4C;QAC5C,gBAAgB,GAAG,CAAC,MAAM,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,IAAI,IAAI,CAAC;IAC3E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAEtC,MAAM,MAAM,GAAqB;QAC/B,MAAM;QACN,UAAU,EAAE,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QAC5C,gBAAgB;QAChB,QAAQ,EAAE,aAAa,EAAE,QAAQ,IAAI,IAAI;QACzC,gBAAgB,EAAE,OAAO,aAAa,EAAE,MAAM,KAAK,QAAQ,IAAI,aAAa,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;QAC9F,aAAa,EAAE;YACb,SAAS,EAAE,UAAU,CAAC,SAAS;YAC/B,SAAS,EAAE,UAAU,CAAC,SAAS;YAC/B,YAAY,EAAE,UAAU,CAAC,YAAY;YACrC,WAAW,EAAE,UAAU,CAAC,WAAW;YACnC,iBAAiB,EAAE,cAAc,CAAC,iBAAiB;YACnD,QAAQ,EAAE,cAAc,CAAC,QAAQ;YACjC,SAAS,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI;SAC9F;KACF,CAAC;IAEF,IAAI,OAAO;QAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;IACtC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,MAAM,CAAC,UAAmC,EAAE;IACzD,MAAM,MAAM,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IAC9G,MAAM,MAAM,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC;IAEzC,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,IAAI,OAA2B,CAAC;IAEhC,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,CAAC;QAC5B,OAAO,GAAG,sCAAsC,MAAM,0CAA0C,CAAC;IACnG,CAAC;SAAM,IAAI,SAAS,EAAE,CAAC;QACrB,MAAM,CAAC,qBAAqB,EAAE,CAAC;QAC/B,OAAO;YACL,qGAAqG;gBACrG,iEAAiE,CAAC;IACtE,CAAC;SAAM,CAAC;QACN,IAAI,CAAC;YACH,2EAA2E;YAC3E,4DAA4D;YAC5D,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;YACtB,eAAe,GAAG,IAAI,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACtE,MAAM,IAAI,kBAAkB,CAC1B,eAAe,EACf,GAAG,MAAM,gFAAgF,CAC1F,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,kBAAkB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC3E,MAAM,aAAa,GAAG,iBAAiB,EAAE,CAAC;IAE1C,MAAM,MAAM,GAAqB;QAC/B,OAAO,EAAE,IAAI;QACb,MAAM;QACN,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;QACxC,eAAe;QACf,gBAAgB,EAAE,OAAO,aAAa,EAAE,MAAM,KAAK,QAAQ,IAAI,aAAa,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;KAC/F,CAAC;IACF,IAAI,OAAO;QAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;IACtC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAc,EAAE,UAAmC,EAAE;IAC5F,OAAO,kBAAkB,CAAC,QAAQ,MAAM,EAAE,EAAE,KAAK,IAAI,EAAE;QACrD,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,OAAO;gBACV,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC;YACxB,KAAK,QAAQ;gBACX,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;YACzB,KAAK,QAAQ;gBACX,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;YACzB;gBACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,2CAA2C,CAAC,CAAC;QAC1F,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAEA,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA0BvE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAEA,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAyCvE"}
@@ -1,16 +1,28 @@
1
- import { findProjectConfig, loadConfig } from '../utils/config.js';
1
+ import { findProjectConfig, loadConfigWithCredential, loadProjectConfig } from '../utils/config.js';
2
2
  export async function executeConfigCommand(action) {
3
3
  switch (action) {
4
4
  case 'whoami': {
5
5
  const configPath = findProjectConfig(process.cwd());
6
- const config = loadConfig();
6
+ const authMode = loadProjectConfig()?.authMode ?? null;
7
+ // `whoami` is the command people run *because* something is wrong, so a
8
+ // credential that cannot be resolved is reported, never thrown.
9
+ let config = null;
10
+ let problem;
11
+ try {
12
+ config = await loadConfigWithCredential();
13
+ }
14
+ catch (error) {
15
+ problem = error instanceof Error ? error.message : String(error);
16
+ }
7
17
  if (!config) {
8
18
  return {
9
19
  apiUrl: process.env.AGENTTEAMS_API_URL,
10
20
  projectId: process.env.AGENTTEAMS_PROJECT_ID,
11
21
  teamId: process.env.AGENTTEAMS_TEAM_ID,
12
22
  hasApiKey: Boolean(process.env.AGENTTEAMS_API_KEY),
23
+ authMode,
13
24
  configPath,
25
+ ...(problem ? { problem } : {}),
14
26
  };
15
27
  }
16
28
  return {
@@ -18,6 +30,8 @@ export async function executeConfigCommand(action) {
18
30
  projectId: config.projectId,
19
31
  teamId: config.teamId,
20
32
  hasApiKey: Boolean(config.apiKey),
33
+ credentialSource: config.credentialSource,
34
+ authMode,
21
35
  configPath,
22
36
  };
23
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEnE,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAc;IACvD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YACpD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO;oBACL,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;oBACtC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB;oBAC5C,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;oBACtC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;oBAClD,UAAU;iBACX,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;gBACjC,UAAU;aACX,CAAC;QACJ,CAAC;QACD;YACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;IACjD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEpG,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAc;IACvD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YACpD,MAAM,QAAQ,GAAG,iBAAiB,EAAE,EAAE,QAAQ,IAAI,IAAI,CAAC;YAEvD,wEAAwE;YACxE,gEAAgE;YAChE,IAAI,MAAM,GAAG,IAAI,CAAC;YAClB,IAAI,OAA2B,CAAC;YAChC,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,wBAAwB,EAAE,CAAC;YAC5C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACnE,CAAC;YAED,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO;oBACL,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;oBACtC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB;oBAC5C,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;oBACtC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;oBAClD,QAAQ;oBACR,UAAU;oBACV,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAChC,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;gBACjC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;gBACzC,QAAQ;gBACR,UAAU;aACX,CAAC;QACJ,CAAC;QACD;YACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;IACjD,CAAC;AACH,CAAC"}
@@ -49,6 +49,12 @@ export type ConventionStatusResult = {
49
49
  hints: string[];
50
50
  /** One-line human-readable summary. */
51
51
  summary: string;
52
+ /**
53
+ * Set when the project *is* configured but its credential could not be
54
+ * resolved. Distinguishes "nothing to check" from "could not check" — the
55
+ * latter must never read as "up to date".
56
+ */
57
+ credentialProblem?: string;
52
58
  };
53
59
  export declare function buildStatusSummary(result: ConventionFreshnessResult): string;
54
60
  /**
@@ -58,6 +64,11 @@ export declare function buildStatusSummary(result: ConventionFreshnessResult): s
58
64
  * update is available — it never downloads or mutates anything. Degrades gracefully
59
65
  * (exit 0, updateAvailable=false) when the project is not configured or has no local
60
66
  * conventions yet, so callers can safely "check then skip when unavailable".
67
+ *
68
+ * "Not configured" and "configured but the credential failed" are reported
69
+ * differently on purpose. The platform convention makes this the session-start
70
+ * freshness gate, so a project whose login is broken must say so instead of
71
+ * quietly claiming its rules are current.
61
72
  */
62
73
  export declare function conventionStatus(options?: ConventionCommandOptions): Promise<ConventionStatusResult>;
63
74
  export declare function conventionList(): Promise<any>;
@@ -1 +1 @@
1
- {"version":3,"file":"convention.d.ts","sourceRoot":"","sources":["../../src/commands/convention.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"convention.d.ts","sourceRoot":"","sources":["../../src/commands/convention.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ import { isAxiosError } from 'axios';
7
7
  import { downloadAllConventions, listConventions } from '../api/convention.js';
8
8
  import matter from 'gray-matter';
9
9
  import { diffLines, createTwoFilesPatch } from 'diff';
10
- import { loadConfig, findProjectConfig, getConfigurationNotFoundMessage } from '../utils/config.js';
10
+ import { loadConfigWithCredential, findProjectConfig, getConfigurationNotFoundMessage } from '../utils/config.js';
11
11
  import { withSpinner } from '../utils/spinner.js';
12
12
  import { withoutJsonContentType } from '../utils/httpHeaders.js';
13
13
  import { compareVersions, getLatestCliVersion } from '../utils/updateCheck.js';
@@ -28,8 +28,11 @@ function findProjectRoot(cwd) {
28
28
  function getApiBaseUrl(apiUrl) {
29
29
  return apiUrl.endsWith('/') ? apiUrl.slice(0, -1) : apiUrl;
30
30
  }
31
- function getApiConfigOrThrow(options) {
32
- const config = options?.config ?? loadConfig();
31
+ async function getApiConfigOrThrow(options) {
32
+ // Credential-aware: a personal-token project keeps no `apiKey` on disk, and
33
+ // the conventions these commands sync become always-on agent rules — reading
34
+ // "not initialized" there would silently freeze a project's rules.
35
+ const config = options?.config ?? (await loadConfigWithCredential());
33
36
  if (!config) {
34
37
  throw new Error(getConfigurationNotFoundMessage(options?.cwd));
35
38
  }
@@ -216,7 +219,7 @@ function toOptionalStringOrNullIfPresent(data, key) {
216
219
  return undefined;
217
220
  }
218
221
  export async function conventionShow() {
219
- const { config, apiUrl, headers } = getApiConfigOrThrow();
222
+ const { config, apiUrl, headers } = await getApiConfigOrThrow();
220
223
  const conventions = await fetchConventionsWithContent(apiUrl, config.projectId, headers);
221
224
  if (!conventions || conventions.length === 0) {
222
225
  throw new Error('No conventions found for this project. Create one via the web dashboard first.');
@@ -342,10 +345,14 @@ function buildStatusResult(params) {
342
345
  if (conventionUpdateAvailable) {
343
346
  hints.push(`ACTION REQUIRED: Sync conventions now: ${actions.syncConventions}. After syncing, re-read .agentteams/convention.md and any changed rule files before continuing.`);
344
347
  }
348
+ else if (params.credentialProblem) {
349
+ hints.push(`WARNING: Convention freshness was NOT checked — ${params.credentialProblem} Conventions may be stale; fix the login, then re-run 'agentteams convention status'.`);
350
+ }
345
351
  else {
346
352
  hints.push('OK: Conventions and platform guides are up to date.');
347
353
  }
348
354
  return {
355
+ ...(params.credentialProblem ? { credentialProblem: params.credentialProblem } : {}),
349
356
  updateAvailable: conventionUpdateAvailable,
350
357
  conventionUpdateAvailable,
351
358
  platformGuidesChanged: params.freshness.platformGuidesChanged,
@@ -353,7 +360,7 @@ function buildStatusResult(params) {
353
360
  cliUpdateAvailable: params.cliUpdateAvailable,
354
361
  currentCliVersion: params.currentCliVersion,
355
362
  latestCliVersion: params.latestCliVersion,
356
- actionRequired: conventionUpdateAvailable || params.cliUpdateAvailable,
363
+ actionRequired: conventionUpdateAvailable || params.cliUpdateAvailable || Boolean(params.credentialProblem),
357
364
  actions,
358
365
  hints,
359
366
  summary: buildCombinedStatusSummary({
@@ -371,16 +378,33 @@ function buildStatusResult(params) {
371
378
  * update is available — it never downloads or mutates anything. Degrades gracefully
372
379
  * (exit 0, updateAvailable=false) when the project is not configured or has no local
373
380
  * conventions yet, so callers can safely "check then skip when unavailable".
381
+ *
382
+ * "Not configured" and "configured but the credential failed" are reported
383
+ * differently on purpose. The platform convention makes this the session-start
384
+ * freshness gate, so a project whose login is broken must say so instead of
385
+ * quietly claiming its rules are current.
374
386
  */
375
387
  export async function conventionStatus(options) {
376
- const config = options?.config ?? loadConfig();
377
388
  const projectRoot = findProjectRoot(options?.cwd);
378
389
  const cliStatus = await resolveCliUpdateStatus(options);
390
+ let config = options?.config ?? null;
391
+ let credentialProblem;
392
+ if (!config) {
393
+ try {
394
+ config = await loadConfigWithCredential();
395
+ }
396
+ catch (error) {
397
+ credentialProblem = error instanceof Error ? error.message : String(error);
398
+ }
399
+ }
379
400
  // Not configured or no local conventions → nothing to compare; treat as up to date.
380
401
  if (!config || !projectRoot) {
381
402
  return buildStatusResult({
382
403
  freshness: { platformGuidesChanged: false, conventionChanges: [] },
383
404
  ...cliStatus,
405
+ // Only a project that exists locally can have a credential problem worth
406
+ // reporting; without a project root there is nothing to be stale.
407
+ ...(credentialProblem && projectRoot ? { credentialProblem } : {}),
384
408
  });
385
409
  }
386
410
  const apiUrl = getApiBaseUrl(config.apiUrl);
@@ -392,7 +416,7 @@ export async function conventionStatus(options) {
392
416
  return buildStatusResult({ freshness, ...cliStatus });
393
417
  }
394
418
  export async function conventionList() {
395
- const { config, apiUrl, headers } = getApiConfigOrThrow();
419
+ const { config, apiUrl, headers } = await getApiConfigOrThrow();
396
420
  const conventions = await fetchAllConventions(apiUrl, config.projectId, headers);
397
421
  if (!Array.isArray(conventions)) {
398
422
  return { data: conventions };
@@ -504,7 +528,7 @@ async function downloadReportingTemplate(projectRoot, config, apiUrl, headers) {
504
528
  return true;
505
529
  }
506
530
  export async function conventionDownload(options) {
507
- const { config, apiUrl, headers } = getApiConfigOrThrow(options);
531
+ const { config, apiUrl, headers } = await getApiConfigOrThrow(options);
508
532
  const projectRoot = findProjectRoot(options?.cwd);
509
533
  if (!projectRoot) {
510
534
  throw new Error("No .agentteams directory found. Run 'agentteams init' first.");
@@ -590,7 +614,7 @@ function parseConventionMarkdown(fileRelativePath, markdown) {
590
614
  }
591
615
  }
592
616
  export async function conventionCreate(options) {
593
- const { config, apiUrl, headers } = getApiConfigOrThrow(options);
617
+ const { config, apiUrl, headers } = await getApiConfigOrThrow(options);
594
618
  const projectRoot = findProjectRoot(options?.cwd);
595
619
  if (!projectRoot) {
596
620
  throw new Error("No .agentteams directory found. Run 'agentteams init' first.");
@@ -670,7 +694,7 @@ export async function conventionCreate(options) {
670
694
  return results.join('\n');
671
695
  }
672
696
  export async function conventionUpdate(options) {
673
- const { config, apiUrl, headers } = getApiConfigOrThrow(options);
697
+ const { config, apiUrl, headers } = await getApiConfigOrThrow(options);
674
698
  const projectRoot = findProjectRoot(options?.cwd);
675
699
  if (!projectRoot) {
676
700
  throw new Error("No .agentteams directory found. Run 'agentteams init' first.");
@@ -748,7 +772,7 @@ export async function conventionUpdate(options) {
748
772
  return results.join('\n\n');
749
773
  }
750
774
  export async function conventionDelete(options) {
751
- const { config, apiUrl, headers } = getApiConfigOrThrow(options);
775
+ const { config, apiUrl, headers } = await getApiConfigOrThrow(options);
752
776
  const projectRoot = findProjectRoot(options?.cwd);
753
777
  if (!projectRoot) {
754
778
  throw new Error("No .agentteams directory found. Run 'agentteams init' first.");