@idea1/cli 1.10.4 → 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +74 -32
  2. package/dist/commands/help.d.ts.map +1 -1
  3. package/dist/commands/help.js +30 -12
  4. package/dist/commands/help.js.map +1 -1
  5. package/dist/commands/index.d.ts +3 -1
  6. package/dist/commands/index.d.ts.map +1 -1
  7. package/dist/commands/index.js +5 -1
  8. package/dist/commands/index.js.map +1 -1
  9. package/dist/commands/login.d.ts +3 -0
  10. package/dist/commands/login.d.ts.map +1 -0
  11. package/dist/commands/login.js +15 -0
  12. package/dist/commands/login.js.map +1 -0
  13. package/dist/commands/logout.d.ts +3 -0
  14. package/dist/commands/logout.d.ts.map +1 -0
  15. package/dist/commands/logout.js +17 -0
  16. package/dist/commands/logout.js.map +1 -0
  17. package/dist/commands/release.d.ts +9 -4
  18. package/dist/commands/release.d.ts.map +1 -1
  19. package/dist/commands/release.js +53 -27
  20. package/dist/commands/release.js.map +1 -1
  21. package/dist/lib/project-item-url.d.ts +6 -0
  22. package/dist/lib/project-item-url.d.ts.map +1 -1
  23. package/dist/lib/project-item-url.js +11 -0
  24. package/dist/lib/project-item-url.js.map +1 -1
  25. package/dist/lib/settings.d.ts +25 -3
  26. package/dist/lib/settings.d.ts.map +1 -1
  27. package/dist/lib/settings.js +26 -1
  28. package/dist/lib/settings.js.map +1 -1
  29. package/dist/prompts/platform-prompts.d.ts +5 -30
  30. package/dist/prompts/platform-prompts.d.ts.map +1 -1
  31. package/dist/prompts/platform-prompts.js +5 -44
  32. package/dist/prompts/platform-prompts.js.map +1 -1
  33. package/dist/services/github.d.ts +21 -19
  34. package/dist/services/github.d.ts.map +1 -1
  35. package/dist/services/github.js +56 -64
  36. package/dist/services/github.js.map +1 -1
  37. package/dist/services/platform-auth.d.ts +44 -0
  38. package/dist/services/platform-auth.d.ts.map +1 -0
  39. package/dist/services/platform-auth.js +476 -0
  40. package/dist/services/platform-auth.js.map +1 -0
  41. package/dist/services/platform.d.ts +75 -18
  42. package/dist/services/platform.d.ts.map +1 -1
  43. package/dist/services/platform.js +254 -191
  44. package/dist/services/platform.js.map +1 -1
  45. package/dist/services/setup.d.ts.map +1 -1
  46. package/dist/services/setup.js +2 -1
  47. package/dist/services/setup.js.map +1 -1
  48. package/dist/types/index.d.ts +32 -0
  49. package/dist/types/index.d.ts.map +1 -1
  50. package/dist/types/index.js +1 -1
  51. package/dist/types/index.js.map +1 -1
  52. package/dist/workflow/data/team-member.d.ts +9 -2
  53. package/dist/workflow/data/team-member.d.ts.map +1 -1
  54. package/dist/workflow/data/team-member.js +8 -1
  55. package/dist/workflow/data/team-member.js.map +1 -1
  56. package/dist/workflow/engine/approval-flow.d.ts +28 -11
  57. package/dist/workflow/engine/approval-flow.d.ts.map +1 -1
  58. package/dist/workflow/engine/approval-flow.js +52 -17
  59. package/dist/workflow/engine/approval-flow.js.map +1 -1
  60. package/dist/workflow/engine/branch-setup.d.ts +1 -1
  61. package/dist/workflow/engine/branch-setup.js +1 -1
  62. package/dist/workflow/engine/handlers/approve-pr.d.ts +10 -9
  63. package/dist/workflow/engine/handlers/approve-pr.d.ts.map +1 -1
  64. package/dist/workflow/engine/handlers/approve-pr.js +24 -17
  65. package/dist/workflow/engine/handlers/approve-pr.js.map +1 -1
  66. package/dist/workflow/engine/release-engine.d.ts +90 -58
  67. package/dist/workflow/engine/release-engine.d.ts.map +1 -1
  68. package/dist/workflow/engine/release-engine.js +296 -161
  69. package/dist/workflow/engine/release-engine.js.map +1 -1
  70. package/dist/workflow/engine/workflow-engine.d.ts +9 -2
  71. package/dist/workflow/engine/workflow-engine.d.ts.map +1 -1
  72. package/dist/workflow/engine/workflow-engine.js +20 -2
  73. package/dist/workflow/engine/workflow-engine.js.map +1 -1
  74. package/package.json +2 -1
@@ -0,0 +1,476 @@
1
+ import { createHash, randomBytes } from 'crypto';
2
+ import { createServer } from 'http';
3
+ import { setTimeout as delay } from 'timers/promises';
4
+ import { AsyncEntry } from '@napi-rs/keyring';
5
+ import { logger } from '../lib/logger.js';
6
+ import { isUnattended } from '../lib/prompt.js';
7
+ import { openUrl } from './os-launcher.js';
8
+ /**
9
+ * The CLI's OAuth client of the Idea1 platform: it holds the credential every platform call is
10
+ * authorized with, and signs the user in and out.
11
+ *
12
+ * The CLI is a public client (no secret) that registers itself dynamically with the platform's
13
+ * authorization server, discovered at `{apiBase}/.well-known/oauth-authorization-server`. Signing in
14
+ * is the authorization code flow with PKCE: the browser opens the platform's consent page, where the
15
+ * user picks the team the grant is bound to, and the platform redirects back to a loopback server
16
+ * the CLI runs on a random port of 127.0.0.1 (the registered `http://127.0.0.1/callback` matches on
17
+ * any port). The resulting team-bound access token is short-lived; the refresh token renews it.
18
+ *
19
+ * The credential lives in the operating system's credential store (macOS Keychain, Windows
20
+ * Credential Manager, Secret Service on Linux) under the service `idea1-cli` and the API base URL as
21
+ * the account, as the JSON of a `StoredCredential`; a credential longer than one entry holds
22
+ * continues in further entries. Parallel CLI processes share it: the platform does not rotate
23
+ * refresh tokens, so concurrent refreshes all stay valid and the last write wins.
24
+ *
25
+ * `IDEA1_TOKEN`, when set, is the bearer token of every call instead (a team API client's token in
26
+ * CI, or a test's): nothing is read from or written to the credential store, and nothing is
27
+ * refreshed. `IDEA1_API_BASE_URL` points the CLI at another platform than https://api.idea1.ai.
28
+ */
29
+ export const API_BASE_URL_ENV = 'IDEA1_API_BASE_URL';
30
+ export const TOKEN_ENV = 'IDEA1_TOKEN';
31
+ const DEFAULT_API_BASE_URL = 'https://api.idea1.ai';
32
+ const CREDENTIAL_STORE_SERVICE = 'idea1-cli';
33
+ /**
34
+ * The most UTF-16 code units one credential store entry holds: Windows Credential Manager caps an
35
+ * entry at 2560 bytes. The platform's access and refresh tokens are JWTs that together exceed it,
36
+ * so a credential is kept as a run of entries, each a piece of its JSON behind a header of at most
37
+ * CREDENTIAL_PIECE_HEADER_LENGTH code units (the write's id and the run's length).
38
+ */
39
+ const CREDENTIAL_STORE_ENTRY_LENGTH = 1280;
40
+ const CREDENTIAL_PIECE_HEADER_LENGTH = 12;
41
+ const CREDENTIAL_PIECE_TEXT_LENGTH = CREDENTIAL_STORE_ENTRY_LENGTH - CREDENTIAL_PIECE_HEADER_LENGTH;
42
+ const CREDENTIAL_PIECE_PATTERN = /^([0-9a-f]{8}):(\d+):(.*)$/s;
43
+ /** How many times, and how far apart, a run whose entries are not all of one write is read. */
44
+ const STORED_CREDENTIAL_READ_ATTEMPTS = 4;
45
+ const STORED_CREDENTIAL_READ_RETRY_MS = 100;
46
+ const CLIENT_NAME = 'Idea1 CLI';
47
+ const CLIENT_SCOPE = 'team:read projects:read projects:write';
48
+ /** The redirect URI the client registers; the loopback server listens on a random port of it. */
49
+ const REGISTERED_REDIRECT_URI = 'http://127.0.0.1/callback';
50
+ const SIGN_IN_TIMEOUT_MS = 5 * 60 * 1000;
51
+ /** An access token this close to its expiry is renewed before it is used. */
52
+ const EXPIRY_MARGIN_MS = 60 * 1000;
53
+ /**
54
+ * An OAuth error response (RFC 6749 §5.2), from an endpoint or from the authorization redirect.
55
+ */
56
+ class OAuthError extends Error {
57
+ code;
58
+ constructor(code, description) {
59
+ super(description === null ? `idea1.ai sign-in failed: ${code}` : `idea1.ai sign-in failed: ${code} (${description})`);
60
+ this.code = code;
61
+ }
62
+ }
63
+ /**
64
+ * The base URL of the platform's API, without a trailing slash.
65
+ */
66
+ export function apiBaseUrl() {
67
+ const configured = process.env[API_BASE_URL_ENV]?.trim();
68
+ return (configured ? configured : DEFAULT_API_BASE_URL).replace(/\/+$/, '');
69
+ }
70
+ function tokenFromEnvironment() {
71
+ const token = process.env[TOKEN_ENV]?.trim();
72
+ return token ? token : null;
73
+ }
74
+ /**
75
+ * `fetch` with the platform credential as the bearer token. Signs the user in first when there is
76
+ * no usable credential (an unattended run fails instead, asking for `idea1 login`), renews an
77
+ * expired access token, and on a 401 renews it and retries the request once. With `IDEA1_TOKEN`
78
+ * set, that token is sent as it is and a 401 is the caller's response.
79
+ */
80
+ export async function authorizedFetch(url, init) {
81
+ const environmentToken = tokenFromEnvironment();
82
+ if (environmentToken !== null) {
83
+ return fetch(url, withBearer(init, environmentToken));
84
+ }
85
+ const credential = await serialized(() => usableCredential(null));
86
+ const response = await fetch(url, withBearer(init, credential.accessToken));
87
+ if (response.status !== 401) {
88
+ return response;
89
+ }
90
+ const renewed = await serialized(() => usableCredential(credential.accessToken));
91
+ return fetch(url, withBearer(init, renewed.accessToken));
92
+ }
93
+ /**
94
+ * Sign in through the browser, replacing any stored credential for the platform.
95
+ */
96
+ export async function login() {
97
+ if (tokenFromEnvironment() !== null) {
98
+ throw new Error(`${TOKEN_ENV} is set, and every platform call uses it: unset it to sign in with \`idea1 login\`.`);
99
+ }
100
+ await serialized(async () => {
101
+ await signIn((await readStoredCredential())?.clientId ?? null);
102
+ });
103
+ }
104
+ /**
105
+ * Revoke the stored credential's refresh token and remove the credential from the credential
106
+ * store. Returns false when there was no credential to remove.
107
+ */
108
+ export async function logout() {
109
+ return serialized(async () => {
110
+ const stored = await readStoredCredential();
111
+ if (stored === null) {
112
+ return false;
113
+ }
114
+ try {
115
+ await revoke(stored);
116
+ }
117
+ finally {
118
+ await deleteStoredCredential();
119
+ }
120
+ return true;
121
+ });
122
+ }
123
+ /**
124
+ * Credential reads, renewals and sign-ins run one at a time in a process, so parallel platform
125
+ * calls renew or sign in once.
126
+ */
127
+ let credentialQueue = Promise.resolve();
128
+ function serialized(work) {
129
+ const result = credentialQueue.then(work);
130
+ credentialQueue = result.catch(() => undefined);
131
+ return result;
132
+ }
133
+ /**
134
+ * A credential whose access token is current, other than `rejectedAccessToken` (the one a 401 was
135
+ * answered with, unless another call or process has renewed it since). A credential the platform
136
+ * no longer honours is removed, and the user signs in again.
137
+ */
138
+ async function usableCredential(rejectedAccessToken) {
139
+ const stored = await readStoredCredential();
140
+ if (stored === null) {
141
+ return signInWhenAttended(null);
142
+ }
143
+ const expired = Date.parse(stored.accessTokenExpiresAt) - EXPIRY_MARGIN_MS <= Date.now();
144
+ if (!expired && stored.accessToken !== rejectedAccessToken) {
145
+ return stored;
146
+ }
147
+ try {
148
+ return await refresh(stored);
149
+ }
150
+ catch (error) {
151
+ if (error instanceof OAuthError && (error.code === 'invalid_grant' || error.code === 'invalid_client')) {
152
+ await deleteStoredCredential();
153
+ return signInWhenAttended(error.code === 'invalid_grant' ? stored.clientId : null);
154
+ }
155
+ throw error;
156
+ }
157
+ }
158
+ async function signInWhenAttended(clientId) {
159
+ if (isUnattended()) {
160
+ throw new Error(`Not signed in to idea1.ai (${apiBaseUrl()}). Run \`idea1 login\` to sign in.`);
161
+ }
162
+ logger.step(`Signing in to idea1.ai (${apiBaseUrl()})...`);
163
+ return signIn(clientId);
164
+ }
165
+ /**
166
+ * Sign in through the browser with the given registered client, or a newly registered one, and
167
+ * store the credential: the authorization code flow with PKCE (S256) and `state`, redirected to a
168
+ * loopback server on a random port.
169
+ *
170
+ * The platform answers an authorization request it refuses outright, such as one for a client it
171
+ * no longer knows, with an error page instead of a redirect to the loopback server. So before the
172
+ * browser opens, the request for a stored client is sent once without following its redirect: a
173
+ * client the platform no longer knows is registered again, and any other refusal ends the sign-in.
174
+ */
175
+ async function signIn(storedClientId) {
176
+ const metadata = await discoverAuthorizationServer();
177
+ const codeVerifier = base64Url(randomBytes(32));
178
+ const codeChallenge = base64Url(createHash('sha256').update(codeVerifier).digest());
179
+ const state = base64Url(randomBytes(16));
180
+ const callback = await listenForAuthorizationCallback(state);
181
+ try {
182
+ const authorizationUrlFor = (clientId) => {
183
+ const url = new URL(metadata.authorization_endpoint);
184
+ url.search = new URLSearchParams({
185
+ response_type: 'code',
186
+ client_id: clientId,
187
+ redirect_uri: callback.redirectUri,
188
+ scope: CLIENT_SCOPE,
189
+ state,
190
+ code_challenge: codeChallenge,
191
+ code_challenge_method: 'S256'
192
+ }).toString();
193
+ return url.toString();
194
+ };
195
+ let clientId = storedClientId ?? await registerClient(metadata);
196
+ if (storedClientId !== null) {
197
+ const refusal = await authorizationRefusal(authorizationUrlFor(storedClientId));
198
+ if (refusal?.code === 'invalid_client') {
199
+ clientId = await registerClient(metadata);
200
+ }
201
+ else if (refusal !== null) {
202
+ throw refusal;
203
+ }
204
+ }
205
+ const [code] = await Promise.all([callback.code, openInBrowser(authorizationUrlFor(clientId))]);
206
+ const tokens = await postTokenRequest(metadata, {
207
+ grant_type: 'authorization_code',
208
+ code,
209
+ redirect_uri: callback.redirectUri,
210
+ client_id: clientId,
211
+ code_verifier: codeVerifier
212
+ });
213
+ if (tokens.refresh_token === null) {
214
+ throw new Error('idea1.ai issued no refresh token for the sign-in.');
215
+ }
216
+ return storeTokens(clientId, tokens, tokens.refresh_token);
217
+ }
218
+ finally {
219
+ callback.close();
220
+ }
221
+ }
222
+ /**
223
+ * The OAuth error the authorize endpoint answers a request with instead of redirecting it; null
224
+ * when it redirects. The endpoint validates the request and redirects to the consent page with no
225
+ * side effect, so the request is safe to send ahead of the browser.
226
+ */
227
+ async function authorizationRefusal(authorizationUrl) {
228
+ const response = await fetch(authorizationUrl, { redirect: 'manual', headers: { Accept: 'application/json' } });
229
+ const text = await response.text();
230
+ const error = response.status >= 400 && response.status < 500 ? parseOAuthError(text) : null;
231
+ return error === null ? null : new OAuthError(error.error, error.error_description ?? null);
232
+ }
233
+ async function openInBrowser(url) {
234
+ logger.dim(`Sign in to idea1.ai in your browser. If it does not open, open this URL:\n${url}`);
235
+ try {
236
+ await openUrl(url);
237
+ }
238
+ catch (error) {
239
+ logger.warning(`Could not open the browser: ${error.message}`);
240
+ }
241
+ }
242
+ /**
243
+ * A loopback HTTP server on a random port of 127.0.0.1 that receives the authorization redirect:
244
+ * `code` settles with the authorization code, the platform's error, or a timeout.
245
+ */
246
+ async function listenForAuthorizationCallback(state) {
247
+ const server = createServer();
248
+ let timeout;
249
+ const code = new Promise((resolve, reject) => {
250
+ timeout = setTimeout(() => reject(new Error(`Sign-in did not finish in the browser within ${SIGN_IN_TIMEOUT_MS / 60_000} minutes.`)), SIGN_IN_TIMEOUT_MS);
251
+ server.on('request', (request, response) => {
252
+ const url = new URL(request.url ?? '/', 'http://127.0.0.1');
253
+ // Anything other than the redirect of this sign-in (a favicon, a stale tab) is not an answer.
254
+ if (url.pathname !== '/callback' || url.searchParams.get('state') !== state) {
255
+ response.writeHead(404).end();
256
+ return;
257
+ }
258
+ const error = url.searchParams.get('error');
259
+ const authorizationCode = url.searchParams.get('code');
260
+ if (error !== null || !authorizationCode) {
261
+ writeCallbackPage(response, 'Sign-in did not complete. Return to the terminal for details; you can close this tab.');
262
+ reject(new OAuthError(error ?? 'invalid_request', url.searchParams.get('error_description')));
263
+ return;
264
+ }
265
+ writeCallbackPage(response, 'Signed in to idea1.ai. You can close this tab and return to the terminal.');
266
+ resolve(authorizationCode);
267
+ });
268
+ });
269
+ await new Promise((resolve, reject) => {
270
+ server.once('error', reject);
271
+ server.listen(0, '127.0.0.1', () => resolve());
272
+ });
273
+ const { port } = server.address();
274
+ const redirectUri = new URL(REGISTERED_REDIRECT_URI);
275
+ redirectUri.port = String(port);
276
+ return {
277
+ redirectUri: redirectUri.toString(),
278
+ code,
279
+ close: () => {
280
+ clearTimeout(timeout);
281
+ server.close();
282
+ server.closeAllConnections();
283
+ }
284
+ };
285
+ }
286
+ function writeCallbackPage(response, message) {
287
+ response.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8', Connection: 'close' });
288
+ response.end('<!doctype html><html><head><meta charset="utf-8"><title>Idea1 CLI</title></head>' +
289
+ `<body style="font-family: system-ui, sans-serif; margin: 4rem; text-align: center"><p>${message}</p></body></html>`);
290
+ }
291
+ let authorizationServerMetadata = null;
292
+ function discoverAuthorizationServer() {
293
+ authorizationServerMetadata ??= readJson(fetch(`${apiBaseUrl()}/.well-known/oauth-authorization-server`, { headers: { Accept: 'application/json' } })).catch(error => {
294
+ authorizationServerMetadata = null;
295
+ throw error;
296
+ });
297
+ return authorizationServerMetadata;
298
+ }
299
+ async function registerClient(metadata) {
300
+ const registration = await readJson(fetch(metadata.registration_endpoint, {
301
+ method: 'POST',
302
+ headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
303
+ body: JSON.stringify({
304
+ client_name: CLIENT_NAME,
305
+ redirect_uris: [REGISTERED_REDIRECT_URI],
306
+ grant_types: ['authorization_code', 'refresh_token'],
307
+ response_types: ['code'],
308
+ token_endpoint_auth_method: 'none',
309
+ scope: CLIENT_SCOPE
310
+ })
311
+ }));
312
+ return registration.client_id;
313
+ }
314
+ /**
315
+ * Renew the access token. The platform does not rotate refresh tokens, so the stored one is kept
316
+ * unless the response carries another.
317
+ */
318
+ async function refresh(stored) {
319
+ const tokens = await postTokenRequest(await discoverAuthorizationServer(), {
320
+ grant_type: 'refresh_token',
321
+ refresh_token: stored.refreshToken,
322
+ client_id: stored.clientId
323
+ });
324
+ return storeTokens(stored.clientId, tokens, tokens.refresh_token ?? stored.refreshToken);
325
+ }
326
+ async function revoke(stored) {
327
+ const metadata = await discoverAuthorizationServer();
328
+ await readSuccessBody(fetch(metadata.revocation_endpoint, {
329
+ method: 'POST',
330
+ headers: { Accept: 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' },
331
+ body: new URLSearchParams({ token: stored.refreshToken, token_type_hint: 'refresh_token', client_id: stored.clientId }).toString()
332
+ }));
333
+ }
334
+ function postTokenRequest(metadata, parameters) {
335
+ return readJson(fetch(metadata.token_endpoint, {
336
+ method: 'POST',
337
+ headers: { Accept: 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' },
338
+ body: new URLSearchParams(parameters).toString()
339
+ }));
340
+ }
341
+ /**
342
+ * The JSON body of an OAuth endpoint's success response.
343
+ */
344
+ async function readJson(pending) {
345
+ return JSON.parse(await readSuccessBody(pending));
346
+ }
347
+ /**
348
+ * The body of an OAuth endpoint's success response; an error response throws OAuthError with the
349
+ * endpoint's `error` code, or an Error naming the HTTP status when it has none.
350
+ */
351
+ async function readSuccessBody(pending) {
352
+ const response = await pending;
353
+ const text = await response.text();
354
+ if (response.ok) {
355
+ return text;
356
+ }
357
+ const error = parseOAuthError(text);
358
+ if (error !== null) {
359
+ throw new OAuthError(error.error, error.error_description ?? null);
360
+ }
361
+ throw new Error(`idea1.ai refused ${response.url} (${response.status} ${response.statusText})${text.trim() ? `: ${text.trim().slice(0, 500)}` : ''}`);
362
+ }
363
+ function parseOAuthError(text) {
364
+ try {
365
+ const body = JSON.parse(text);
366
+ return typeof body.error === 'string' ? { error: body.error, error_description: body.error_description } : null;
367
+ }
368
+ catch {
369
+ return null;
370
+ }
371
+ }
372
+ async function storeTokens(clientId, tokens, refreshToken) {
373
+ const credential = {
374
+ clientId,
375
+ refreshToken,
376
+ accessToken: tokens.access_token,
377
+ accessTokenExpiresAt: new Date(Date.now() + tokens.expires_in * 1000).toISOString()
378
+ };
379
+ await writeStoredCredential(credential);
380
+ return credential;
381
+ }
382
+ /**
383
+ * The credential's run of entries: its JSON in pieces, the first under the API base URL as the
384
+ * account and the rest under the URL suffixed `#2`, `#3`, and so on. Entries are written one at a
385
+ * time, so a run read mid-write, or left by a write that was cut short, mixes entries of different
386
+ * writes: it is read again a few times, and if it stays mixed there is no credential and the user
387
+ * signs in again. An entry of plain JSON is a whole credential on its own, and a stored text that
388
+ * is not JSON is no credential, since its parse error would quote the store's content.
389
+ */
390
+ async function readStoredCredential() {
391
+ for (let attempt = 1; attempt <= STORED_CREDENTIAL_READ_ATTEMPTS; attempt++) {
392
+ const first = await credentialStoreEntry(1).getPassword();
393
+ if (first === null) {
394
+ return null;
395
+ }
396
+ if (first.startsWith('{')) {
397
+ return parseStoredCredential(first);
398
+ }
399
+ const json = await readStoredCredentialRun(first);
400
+ if (json !== null) {
401
+ return parseStoredCredential(json);
402
+ }
403
+ await delay(STORED_CREDENTIAL_READ_RETRY_MS);
404
+ }
405
+ return null;
406
+ }
407
+ /** The JSON of the run that `first` starts, or null when its entries are not all of one write. */
408
+ async function readStoredCredentialRun(first) {
409
+ const firstPiece = parseCredentialPiece(first);
410
+ if (firstPiece === null) {
411
+ return null;
412
+ }
413
+ const texts = [firstPiece.text];
414
+ for (let index = 2; index <= firstPiece.count; index++) {
415
+ const entry = await credentialStoreEntry(index).getPassword();
416
+ const piece = entry === null ? null : parseCredentialPiece(entry);
417
+ if (piece === null || piece.writeId !== firstPiece.writeId || piece.count !== firstPiece.count) {
418
+ return null;
419
+ }
420
+ texts.push(piece.text);
421
+ }
422
+ return texts.join('');
423
+ }
424
+ function parseStoredCredential(json) {
425
+ try {
426
+ return JSON.parse(json);
427
+ }
428
+ catch (error) {
429
+ if (error instanceof SyntaxError) {
430
+ return null;
431
+ }
432
+ throw error;
433
+ }
434
+ }
435
+ function parseCredentialPiece(entry) {
436
+ const match = CREDENTIAL_PIECE_PATTERN.exec(entry);
437
+ return match === null ? null : { writeId: match[1], count: Number(match[2]), text: match[3] };
438
+ }
439
+ async function writeStoredCredential(credential) {
440
+ const json = JSON.stringify(credential);
441
+ const texts = [];
442
+ for (let start = 0; start < json.length;) {
443
+ let end = Math.min(start + CREDENTIAL_PIECE_TEXT_LENGTH, json.length);
444
+ // A surrogate pair stays in one piece: the store cannot hold half of one.
445
+ if (end < json.length && json.charCodeAt(end - 1) >= 0xd800 && json.charCodeAt(end - 1) <= 0xdbff) {
446
+ end--;
447
+ }
448
+ texts.push(json.slice(start, end));
449
+ start = end;
450
+ }
451
+ const writeId = randomBytes(4).toString('hex');
452
+ for (const [offset, text] of texts.entries()) {
453
+ await credentialStoreEntry(offset + 1).setPassword(`${writeId}:${texts.length}:${text}`);
454
+ }
455
+ await deleteStoredCredentialFrom(texts.length + 1);
456
+ }
457
+ async function deleteStoredCredential() {
458
+ await deleteStoredCredentialFrom(1);
459
+ }
460
+ /** Removes the entries of the run from `index` on, such as those a shorter credential leaves behind. */
461
+ async function deleteStoredCredentialFrom(index) {
462
+ while (await credentialStoreEntry(index).deletePassword()) {
463
+ index++;
464
+ }
465
+ }
466
+ function credentialStoreEntry(index) {
467
+ const account = index === 1 ? apiBaseUrl() : `${apiBaseUrl()}#${index}`;
468
+ return new AsyncEntry(CREDENTIAL_STORE_SERVICE, account);
469
+ }
470
+ function withBearer(init, token) {
471
+ return { ...init, headers: { ...init.headers, Authorization: `Bearer ${token}` } };
472
+ }
473
+ function base64Url(bytes) {
474
+ return bytes.toString('base64url');
475
+ }
476
+ //# sourceMappingURL=platform-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-auth.js","sourceRoot":"","sources":["../../src/services/platform-auth.ts"],"names":[],"mappings":"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"}
@@ -1,37 +1,89 @@
1
- import type { DevWorkflowType } from '../workflow/data/workflow-context.js';
1
+ import type { DevWorkflowType, WorkflowContext } from '../workflow/data/workflow-context.js';
2
2
  import type { ProjectItemSummary } from '../workflow/data/project-item.js';
3
3
  import type { TeamMember } from '../workflow/data/team-member.js';
4
4
  import type { ClaudeRunOptions } from './claude.js';
5
5
  /**
6
6
  * The CLI's access to the Idea1 cloud platform (app.idea1.ai / api.idea1.ai): reading a project
7
7
  * item's summary (by item or by branch), recording the item's workflow context, setting its workflow
8
- * status (with the teammate it is assigned to), creating items, listing the team's Projects and
9
- * members, deriving a branch name from an item. Callers use `platform.someFunction()` and know
10
- * nothing about the transport.
8
+ * status (with the teammate it is assigned to), transitioning an item on the platform and approving
9
+ * a branch's pull request (the stage-1 merges the platform performs), approving a release and
10
+ * committing its version bump (the stage-2 work the platform performs), creating items, listing the team's Projects and
11
+ * members, deriving a branch name from an item, and reading who is signed in. Callers use
12
+ * `platform.someFunction()` and know nothing about the transport.
11
13
  *
12
- * Today the transport is Claude Code driving the Idea1 MCP tools. That is an implementation detail
13
- * of this module - it may be replaced by authenticated calls to the platform's HTTP API without
14
- * touching any caller. Because these are simple tool calls rather than implementation sessions,
15
- * every Claude run here uses PLATFORM_CALL_RUN_OPTIONS. The prompts are the templates in
16
- * `src/prompts/platform-prompts.ts`; this module owns the output schemas their answers are read with.
14
+ * The transport is the platform's REST API, authorized with the user's OAuth credential or
15
+ * `IDEA1_TOKEN` (see `platform-auth.ts`), on the team that credential is bound to. Responses are the
16
+ * platform's `ApiDataResponse` envelope; a refused request surfaces as an Error carrying the
17
+ * platform's status and message. Claude is used only to name branches, on PLATFORM_CALL_RUN_OPTIONS.
17
18
  */
18
19
  /**
19
- * Model and effort for every platform call: a small, fast model at medium effort is all a
20
- * single MCP tool call needs, and pinning it keeps these calls consistent and cheap.
20
+ * Model and effort for the Claude run that names a branch: a small, fast model at medium effort is
21
+ * all a one-line answer from a description needs, and pinning it keeps the run consistent and cheap.
21
22
  */
22
23
  export declare const PLATFORM_CALL_RUN_OPTIONS: Required<ClaudeRunOptions>;
24
+ /**
25
+ * Who the platform credential signs in as: the user's email address and the team its calls work on.
26
+ */
27
+ export interface SignedInUser {
28
+ emailAddress: string;
29
+ teamName: string;
30
+ }
23
31
  /**
24
32
  * Record workflow context updates on an idea1.ai project item directly, with no side effects on the
25
33
  * platform: the CLI has already run the transition's work locally. The item must be under workflow
26
34
  * management (have a workflow context); the workflow engine is the only caller, as the persist step
27
35
  * of a transition. `assignedToEmail` names the team member the item is assigned to along with the
28
- * status; null leaves the assignment as it is.
29
- *
30
- * TODO: Direct workflow-context updates move from the update_item MCP tool to an authenticated
31
- * platform API call; the CLI will authenticate a user and call the API for direct integrations
32
- * like this, and MCP tools will be only operations that agents should run.
36
+ * status; null leaves the assignment as it is. Returns false, with a warning, when the platform did
37
+ * not record it.
33
38
  */
34
39
  export declare function setWorkflowStatus(itemUrl: string, status: string, pullRequestUrl: string | null, assignedToEmail: string | null): Promise<boolean>;
40
+ /**
41
+ * The platform's `WorkflowTransitionResponse`: the item's workflow context after the transition, and
42
+ * what was done.
43
+ */
44
+ export interface WorkflowTransitionResult {
45
+ workflowContext: WorkflowContext;
46
+ message: string;
47
+ }
48
+ /**
49
+ * Move a project item into `targetStatus` on the platform, which runs the side effects of every
50
+ * state it enters and records each one: entering Approved and Merged merges the item's pull request
51
+ * as the Idea1 GitHub App, once the signed-in user's approval is recorded on it. `expectedStatus` is
52
+ * the status the item has as far as the CLI knows; the platform refuses the transition when the item
53
+ * has moved since, so it never runs twice.
54
+ */
55
+ export declare function transitionWorkflow(itemUrl: string, expectedStatus: string, targetStatus: string): Promise<WorkflowTransitionResult>;
56
+ /**
57
+ * Approve the open pull request of a branch no project item carries: the platform records the
58
+ * signed-in user's approval on it and merges it as the Idea1 GitHub App. Returns what was done.
59
+ */
60
+ export declare function approvePullRequest(repositoryFullName: string, branchName: string): Promise<string>;
61
+ /**
62
+ * Approve the open release PR from a release branch (the base, hotfix or content release branch):
63
+ * the platform checks the signed-in user is its assignee and holds the release role, brings its
64
+ * change list up to date, records the approval on it and merges it as the Idea1 GitHub App. Returns
65
+ * what was done.
66
+ */
67
+ export declare function approveRelease(repositoryFullName: string, branchName: string): Promise<string>;
68
+ /** A version file of a version bump with its whole new content. */
69
+ export interface VersionFileContent {
70
+ path: string;
71
+ content: string;
72
+ }
73
+ /**
74
+ * The platform's `ReleaseVersionBumpResponse`.
75
+ */
76
+ interface ReleaseVersionBumpResponse {
77
+ commitSha: string;
78
+ subject: string;
79
+ }
80
+ /**
81
+ * Have the platform commit a release's version bump onto its release branch as the Idea1 GitHub
82
+ * App, for a releaser who cannot push to the branch: the new content of each version file, made
83
+ * against the branch at `expectedHeadSha`. The platform accepts only version edits of the declared
84
+ * packages' version files. Returns the commit.
85
+ */
86
+ export declare function commitVersionBump(repositoryFullName: string, branchName: string, expectedHeadSha: string, files: readonly VersionFileContent[]): Promise<ReleaseVersionBumpResponse>;
35
87
  /**
36
88
  * The summary of the project item a branch implements: null for a branch outside workflow
37
89
  * management. The repository is always named; nothing defaults it.
@@ -67,7 +119,7 @@ export interface UpsertProjectItemWorkflowContextInput {
67
119
  */
68
120
  export declare function upsertProjectItemWorkflowContext(input: UpsertProjectItemWorkflowContextInput): Promise<ProjectItemSummary>;
69
121
  /**
70
- * Generate a branch name from a project item description
122
+ * Generate a branch name from a project item's description.
71
123
  */
72
124
  export declare function generateBranchName(itemUrl: string): Promise<string>;
73
125
  /**
@@ -86,9 +138,14 @@ export declare function listTeamMembers(): Promise<TeamMember[]>;
86
138
  */
87
139
  export declare function resolveTeammate(identity: string): Promise<TeamMember>;
88
140
  /**
89
- * Create a new idea1 project item with the given title in the named Project.
141
+ * Create a new idea1 project item with the given title in the named live Project.
90
142
  * The item is created with description `# <title>`.
91
143
  * Returns the created item's URL.
92
144
  */
93
145
  export declare function createProjectItem(title: string, projectName: string): Promise<string>;
146
+ /**
147
+ * The user the platform credential signs in as, and the team its calls work on.
148
+ */
149
+ export declare function getSignedInUser(): Promise<SignedInUser>;
150
+ export {};
94
151
  //# sourceMappingURL=platform.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../src/services/platform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAelE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD;;;;;;;;;;;;GAYG;AAEH;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,gBAAgB,CAAyC,CAAC;AAgB3G;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBxJ;AAED;;;GAGG;AACH,wBAAsB,8BAA8B,CAAC,KAAK,EAAE;IAAE,kBAAkB,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAclJ;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAkBxF;AAED;;GAEG;AACH,MAAM,WAAW,qCAAqC;IACpD,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,eAAe,CAAC;IACjC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;GAMG;AACH,wBAAsB,gCAAgC,CAAC,KAAK,EAAE,qCAAqC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAkBhI;AAwED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAezE;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAUtD;AAoBD;;;GAGG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAQvD;AAkBD;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAQ3E;AA4BD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAe3F"}
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../src/services/platform.ts"],"names":[],"mappings":"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"}