@google/jules-merge 0.0.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 (67) hide show
  1. package/README.md +201 -0
  2. package/dist/cli/check-conflicts.command.mjs +387 -0
  3. package/dist/cli/index.mjs +28 -0
  4. package/dist/cli/init.command.mjs +159 -0
  5. package/dist/core/src/activities/client.d.ts +131 -0
  6. package/dist/core/src/activities/summary.d.ts +22 -0
  7. package/dist/core/src/activities/types.d.ts +79 -0
  8. package/dist/core/src/api.d.ts +49 -0
  9. package/dist/core/src/artifacts.d.ts +105 -0
  10. package/dist/core/src/caching.d.ts +31 -0
  11. package/dist/core/src/client.d.ts +180 -0
  12. package/dist/core/src/errors.d.ts +97 -0
  13. package/dist/core/src/index.d.ts +49 -0
  14. package/dist/core/src/mappers.d.ts +53 -0
  15. package/dist/core/src/network/adapter.d.ts +47 -0
  16. package/dist/core/src/platform/node.d.ts +45 -0
  17. package/dist/core/src/platform/types.d.ts +88 -0
  18. package/dist/core/src/polling.d.ts +43 -0
  19. package/dist/core/src/query/computed.d.ts +86 -0
  20. package/dist/core/src/query/projection.d.ts +80 -0
  21. package/dist/core/src/query/schema.d.ts +124 -0
  22. package/dist/core/src/query/select.d.ts +21 -0
  23. package/dist/core/src/query/validate.d.ts +68 -0
  24. package/dist/core/src/session.d.ts +195 -0
  25. package/dist/core/src/sessions.d.ts +87 -0
  26. package/dist/core/src/snapshot.d.ts +46 -0
  27. package/dist/core/src/sources.d.ts +23 -0
  28. package/dist/core/src/storage/cache-info.d.ts +43 -0
  29. package/dist/core/src/storage/memory.d.ts +69 -0
  30. package/dist/core/src/storage/node-fs.d.ts +95 -0
  31. package/dist/core/src/storage/root.d.ts +17 -0
  32. package/dist/core/src/storage/types.d.ts +115 -0
  33. package/dist/core/src/streaming.d.ts +47 -0
  34. package/dist/core/src/types.d.ts +1418 -0
  35. package/dist/core/src/utils/page-token.d.ts +55 -0
  36. package/dist/core/src/utils.d.ts +27 -0
  37. package/dist/index.mjs +395 -0
  38. package/dist/merge/src/__tests__/conflicts/git-handler.test.d.ts +1 -0
  39. package/dist/merge/src/__tests__/conflicts/git-spec.test.d.ts +1 -0
  40. package/dist/merge/src/__tests__/conflicts/session-handler.test.d.ts +1 -0
  41. package/dist/merge/src/__tests__/conflicts/session-spec.test.d.ts +1 -0
  42. package/dist/merge/src/__tests__/init/init-handler.test.d.ts +1 -0
  43. package/dist/merge/src/__tests__/init/init-spec.test.d.ts +1 -0
  44. package/dist/merge/src/__tests__/init/templates.test.d.ts +1 -0
  45. package/dist/merge/src/__tests__/shared/git.test.d.ts +1 -0
  46. package/dist/merge/src/__tests__/shared/github.test.d.ts +1 -0
  47. package/dist/merge/src/__tests__/shared/session.test.d.ts +1 -0
  48. package/dist/merge/src/cli/check-conflicts.command.d.ts +24 -0
  49. package/dist/merge/src/cli/index.d.ts +2 -0
  50. package/dist/merge/src/cli/init.command.d.ts +23 -0
  51. package/dist/merge/src/conflicts/git-handler.d.ts +4 -0
  52. package/dist/merge/src/conflicts/git-spec.d.ts +43 -0
  53. package/dist/merge/src/conflicts/index.d.ts +4 -0
  54. package/dist/merge/src/conflicts/session-handler.d.ts +9 -0
  55. package/dist/merge/src/conflicts/session-spec.d.ts +43 -0
  56. package/dist/merge/src/index.d.ts +5 -0
  57. package/dist/merge/src/init/index.d.ts +4 -0
  58. package/dist/merge/src/init/init-handler.d.ts +4 -0
  59. package/dist/merge/src/init/init-spec.d.ts +41 -0
  60. package/dist/merge/src/init/templates.d.ts +10 -0
  61. package/dist/merge/src/mcp/index.d.ts +1 -0
  62. package/dist/merge/src/mcp/server.d.ts +2 -0
  63. package/dist/merge/src/shared/git.d.ts +17 -0
  64. package/dist/merge/src/shared/github.d.ts +18 -0
  65. package/dist/merge/src/shared/result.d.ts +19 -0
  66. package/dist/merge/src/shared/session.d.ts +16 -0
  67. package/package.json +60 -0
@@ -0,0 +1,1418 @@
1
+ /**
2
+ * Copyright 2026 Google LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { ActivityClient, SelectOptions } from './activities/types.js';
17
+ import { ActivityStorage, SessionStorage } from './storage/types.js';
18
+ import { ListSessionsOptions, SessionCursor } from './sessions.js';
19
+ export { SelectOptions };
20
+ /**
21
+ * A factory object that creates storage instances.
22
+ * @internal
23
+ */
24
+ export type StorageFactory = {
25
+ activity: (sessionId: string) => ActivityStorage;
26
+ session: () => SessionStorage;
27
+ };
28
+ /**
29
+ * Configuration options for the Jules SDK client.
30
+ *
31
+ * @example
32
+ * import { Jules } from '@google/jules-sdk';
33
+ *
34
+ * const jules = Jules({
35
+ * apiKey: 'YOUR_API_KEY',
36
+ * config: {
37
+ * requestTimeoutMs: 60000, // 1 minute
38
+ * }
39
+ * });
40
+ */
41
+ export interface JulesOptions {
42
+ /**
43
+ * The API key used for authentication.
44
+ * If not provided, the SDK will attempt to read it from the JULES_API_KEY environment variable.
45
+ * Authenticates requests via the `X-Goog-Api-Key` header.
46
+ */
47
+ apiKey?: string;
48
+ /**
49
+ * **FOR TEST/DEV USE ONLY.**
50
+ * Explicitly sets the API key for client-side environments (like browsers).
51
+ * Do NOT use this in production as it exposes your credentials.
52
+ *
53
+ * @deprecated Use `apiKey` in secure server-side environments instead.
54
+ */
55
+ apiKey_TEST_ONLY_DO_NOT_USE_IN_PRODUCTION?: string;
56
+ /**
57
+ * The base URL for the Jules API.
58
+ * @default 'https://jules.googleapis.com/v1alpha'
59
+ */
60
+ baseUrl?: string;
61
+ /**
62
+ * (Internal) A factory for creating storage instances.
63
+ * This is used to inject platform-specific storage implementations (Node vs. Browser).
64
+ * @internal
65
+ */
66
+ storageFactory?: StorageFactory;
67
+ /**
68
+ * (Internal) The platform implementation.
69
+ * This is used to inject platform-specific functionality (Node vs. Browser).
70
+ * @internal
71
+ */
72
+ platform?: any;
73
+ /**
74
+ * Advanced operational parameters for the SDK.
75
+ */
76
+ config?: {
77
+ /**
78
+ * The interval in milliseconds to poll for session and activity updates.
79
+ * @default 5000
80
+ */
81
+ pollingIntervalMs?: number;
82
+ /**
83
+ * The timeout in milliseconds for individual HTTP requests to the Jules API.
84
+ * @default 30000
85
+ */
86
+ requestTimeoutMs?: number;
87
+ /**
88
+ * Configuration for 429 rate limit retry behavior.
89
+ * The SDK will automatically retry rate-limited requests with exponential backoff
90
+ * until the configured time window is exhausted.
91
+ */
92
+ rateLimitRetry?: {
93
+ /**
94
+ * Maximum time in milliseconds to keep retrying before throwing JulesRateLimitError.
95
+ * @default 300000 (5 minutes)
96
+ */
97
+ maxRetryTimeMs?: number;
98
+ /**
99
+ * Base delay in milliseconds for exponential backoff.
100
+ * @default 1000
101
+ */
102
+ baseDelayMs?: number;
103
+ /**
104
+ * Maximum delay in milliseconds between retry attempts.
105
+ * @default 30000
106
+ */
107
+ maxDelayMs?: number;
108
+ };
109
+ };
110
+ }
111
+ /**
112
+ * Ergonomic definition for specifying a source context when creating a session or run.
113
+ * This simplifies the process of targeting a specific GitHub repository and branch.
114
+ *
115
+ * @example
116
+ * const sourceInput: SourceInput = {
117
+ * github: 'my-org/my-repo',
118
+ * baseBranch: 'main'
119
+ * };
120
+ */
121
+ export interface SourceInput {
122
+ /**
123
+ * The GitHub repository identifier in the format 'owner/repo'.
124
+ * The SDK will resolve this to the full source name (e.g., 'sources/github/owner/repo').
125
+ */
126
+ github: string;
127
+ /**
128
+ * The base branch that Jules will branch off of when starting the session.
129
+ * Maps to `sourceContext.githubRepoContext.startingBranch` in the REST API.
130
+ */
131
+ baseBranch: string;
132
+ }
133
+ /**
134
+ * Configuration options for starting a new session or run.
135
+ * This is the primary input for `jules.run()` and `jules.session()`.
136
+ *
137
+ * @example
138
+ * const config: SessionConfig = {
139
+ * prompt: "Fix the login button bug.",
140
+ * source: { github: 'my-org/my-repo', baseBranch: 'main' },
141
+ * requireApproval: false
142
+ * };
143
+ */
144
+ export interface SessionConfig {
145
+ /**
146
+ * The initial instruction or task description for the agent.
147
+ * Required. Maps to `prompt` in the REST API `POST /sessions` payload.
148
+ */
149
+ prompt: string;
150
+ /**
151
+ * The source code context for the session.
152
+ * Optional. If omitted, creates a "repoless" session not attached to any repository.
153
+ * The SDK constructs the `sourceContext` payload from this input when provided.
154
+ */
155
+ source?: SourceInput;
156
+ /**
157
+ * A short, descriptive title for the session. Strongly recommended.
158
+ * This title is displayed in the Jules UI and helps identify the session at a glance.
159
+ * If omitted, the session will have no title in the UI.
160
+ * Maps to `title` in the REST API.
161
+ */
162
+ title?: string;
163
+ /**
164
+ * If true, the agent will pause and wait for explicit approval (via `session.approve()`)
165
+ * before executing any generated plan.
166
+ *
167
+ * @default false for `jules.run()`
168
+ * @default true for `jules.session()`
169
+ */
170
+ requireApproval?: boolean;
171
+ /**
172
+ * If true, the agent will automatically create a Pull Request when the task is completed.
173
+ * Maps to `automationMode: AUTO_CREATE_PR` in the REST API.
174
+ * If false, maps to `AUTOMATION_MODE_UNSPECIFIED`.
175
+ *
176
+ * @default true for `jules.run()`
177
+ */
178
+ autoPr?: boolean;
179
+ }
180
+ /**
181
+ * Raw REST API representation of a GitHub Repo.
182
+ */
183
+ export interface RestGitHubRepo {
184
+ owner: string;
185
+ repo: string;
186
+ isPrivate: boolean;
187
+ defaultBranch?: {
188
+ displayName: string;
189
+ };
190
+ branches?: {
191
+ displayName: string;
192
+ }[];
193
+ }
194
+ /**
195
+ * Raw REST API representation of a Source.
196
+ */
197
+ export interface RestSource {
198
+ name: string;
199
+ id: string;
200
+ githubRepo?: RestGitHubRepo;
201
+ }
202
+ /**
203
+ * Represents the details of a GitHub repository connected to Jules.
204
+ * Maps to the `GitHubRepo` message in the REST API.
205
+ */
206
+ export interface GitHubRepo {
207
+ owner: string;
208
+ repo: string;
209
+ isPrivate: boolean;
210
+ defaultBranch?: string;
211
+ branches?: string[];
212
+ }
213
+ /**
214
+ * An input source of data for a session (e.g., a GitHub repository).
215
+ * This is a discriminated union based on the `type` property.
216
+ * Maps to the `Source` resource in the REST API.
217
+ *
218
+ * @example
219
+ * async (source: Source) => {
220
+ * if (source.type === 'githubRepo') {
221
+ * console.log(source.githubRepo.owner);
222
+ * }
223
+ * }
224
+ */
225
+ export type Source = {
226
+ /**
227
+ * The full resource name (e.g., "sources/github/owner/repo").
228
+ */
229
+ name: string;
230
+ /**
231
+ * The short identifier of the source (e.g., "github/owner/repo").
232
+ */
233
+ id: string;
234
+ } & {
235
+ type: 'githubRepo';
236
+ githubRepo: GitHubRepo;
237
+ };
238
+ /**
239
+ * Raw REST API representation of a Pull Request.
240
+ */
241
+ export interface RestPullRequest {
242
+ url: string;
243
+ title: string;
244
+ description: string;
245
+ baseRef?: string;
246
+ headRef?: string;
247
+ }
248
+ /**
249
+ * Raw REST API representation of a Session Output.
250
+ */
251
+ export interface RestSessionOutput {
252
+ pullRequest?: RestPullRequest;
253
+ changeSet?: ChangeSet;
254
+ }
255
+ export type AutomationMode = 'AUTOMATION_MODE_UNSPECIFIED' | 'AUTO_CREATE_PR';
256
+ /**
257
+ * Raw REST API representation of a Session Resource.
258
+ */
259
+ export interface RestSessionResource {
260
+ name: string;
261
+ id: string;
262
+ prompt: string;
263
+ sourceContext: SourceContext;
264
+ source?: RestSource;
265
+ title: string;
266
+ createTime: string;
267
+ updateTime: string;
268
+ state: string;
269
+ requirePlanApproval?: boolean;
270
+ automationMode?: string;
271
+ url: string;
272
+ outputs?: RestSessionOutput[];
273
+ activities?: any[];
274
+ generatedFiles?: GeneratedFile[];
275
+ archived?: boolean;
276
+ }
277
+ /**
278
+ * Represents the possible states of a session.
279
+ * Maps to the `State` enum in the REST API `Session` resource.
280
+ */
281
+ export type SessionState = 'unspecified' | 'queued' | 'planning'
282
+ /** The agent is waiting for plan approval. Call `session.approve()`. */
283
+ | 'awaitingPlanApproval' | 'awaitingUserFeedback' | 'inProgress' | 'paused' | 'failed' | 'completed';
284
+ /**
285
+ * The entity that an activity originates from.
286
+ */
287
+ export type Origin = 'user' | 'agent' | 'system';
288
+ /**
289
+ * A pull request created by the session.
290
+ * Maps to the `PullRequest` message in the REST API.
291
+ */
292
+ export interface PullRequest {
293
+ url: string;
294
+ title: string;
295
+ description: string;
296
+ baseRef?: string;
297
+ headRef?: string;
298
+ }
299
+ /**
300
+ * An output of a session, such as a pull request or changeset.
301
+ * This is a discriminated union based on the `type` property.
302
+ * Maps to the `SessionOutput` message in the REST API.
303
+ *
304
+ * @example
305
+ * (output: SessionOutput) => {
306
+ * if (output.type === 'pullRequest') {
307
+ * console.log('PR URL:', output.pullRequest.url);
308
+ * } else if (output.type === 'changeSet') {
309
+ * console.log('Changes:', output.changeSet.gitPatch.unidiffPatch);
310
+ * }
311
+ * }
312
+ */
313
+ export type SessionOutput = {
314
+ type: 'pullRequest';
315
+ pullRequest: PullRequest;
316
+ } | {
317
+ type: 'changeSet';
318
+ changeSet: ChangeSet;
319
+ };
320
+ /**
321
+ * Represents the context used when the session was created.
322
+ * Maps to the `SourceContext` message in the REST API.
323
+ */
324
+ export interface SourceContext {
325
+ /**
326
+ * The name of the source (e.g., "sources/github/owner/repo").
327
+ */
328
+ source: string;
329
+ /**
330
+ * Context specific to GitHub repos.
331
+ */
332
+ githubRepoContext?: {
333
+ startingBranch: string;
334
+ };
335
+ workingBranch?: string;
336
+ environmentVariablesEnabled?: boolean;
337
+ }
338
+ /**
339
+ * The underlying data structure representing a Session resource from the REST API.
340
+ * The SDK enhances this with helper methods in the `SessionClient`.
341
+ */
342
+ export interface SessionResource {
343
+ /**
344
+ * The full resource name (e.g., "sessions/314159...").
345
+ */
346
+ name: string;
347
+ /**
348
+ * The unique ID of the session.
349
+ */
350
+ id: string;
351
+ prompt: string;
352
+ sourceContext: SourceContext;
353
+ source?: Source;
354
+ title: string;
355
+ requirePlanApproval?: boolean;
356
+ automationMode?: AutomationMode;
357
+ /**
358
+ * The time the session was created (RFC 3339 timestamp).
359
+ */
360
+ createTime: string;
361
+ /**
362
+ * The time the session was last updated (RFC 3339 timestamp).
363
+ */
364
+ updateTime: string;
365
+ /**
366
+ * The current state of the session.
367
+ */
368
+ state: SessionState;
369
+ /**
370
+ * The URL to view the session in the Jules web app.
371
+ */
372
+ url: string;
373
+ /**
374
+ * The outputs of the session, if any.
375
+ */
376
+ outputs: SessionOutput[];
377
+ /**
378
+ * The activities associated with the session.
379
+ * Only populated when `include: { activities: true }` is used in `jules.select()`.
380
+ */
381
+ activities?: Activity[];
382
+ outcome: SessionOutcome;
383
+ /**
384
+ * The generated files of the session if it reaches a stable state.
385
+ */
386
+ generatedFiles?: GeneratedFile[];
387
+ archived: boolean;
388
+ }
389
+ /**
390
+ * A single step within an agent's plan.
391
+ * Maps to the `PlanStep` message in the REST API.
392
+ */
393
+ export interface PlanStep {
394
+ id: string;
395
+ title: string;
396
+ description?: string;
397
+ index: number;
398
+ }
399
+ /**
400
+ * A sequence of steps that the agent will take to complete the task.
401
+ * Maps to the `Plan` message in the REST API.
402
+ */
403
+ export interface Plan {
404
+ id: string;
405
+ steps: PlanStep[];
406
+ createTime: string;
407
+ }
408
+ /**
409
+ * A patch in Git's unidiff format.
410
+ * Maps to the `GitPatch` message in the REST API.
411
+ */
412
+ export interface GitPatch {
413
+ /**
414
+ * The patch content.
415
+ */
416
+ unidiffPatch: string;
417
+ /**
418
+ * The base commit id the patch should be applied to.
419
+ */
420
+ baseCommitId: string;
421
+ /**
422
+ * A suggested commit message for the.
423
+ */
424
+ suggestedCommitMessage: string;
425
+ }
426
+ /**
427
+ * A set of changes to be applied to a source.
428
+ * Maps to the `ChangeSet` message in the REST API.
429
+ */
430
+ export interface ChangeSet {
431
+ source: string;
432
+ gitPatch: GitPatch;
433
+ }
434
+ /**
435
+ * A single file change extracted from a unified diff.
436
+ */
437
+ export interface ParsedFile {
438
+ /** The file path relative to the repository root */
439
+ path: string;
440
+ /** The type of change */
441
+ changeType: 'created' | 'modified' | 'deleted';
442
+ /** Number of lines added */
443
+ additions: number;
444
+ /** Number of lines removed */
445
+ deletions: number;
446
+ }
447
+ /**
448
+ * Parsed representation of a ChangeSet's unified diff.
449
+ */
450
+ export interface ParsedChangeSet {
451
+ /** Individual file changes */
452
+ files: ParsedFile[];
453
+ /** Summary counts */
454
+ summary: {
455
+ totalFiles: number;
456
+ created: number;
457
+ modified: number;
458
+ deleted: number;
459
+ };
460
+ }
461
+ /**
462
+ * A file generated by a session, with full content extracted from the diff.
463
+ * This is an SDK-specific enhancement for accessing session outputs as files.
464
+ *
465
+ * @example
466
+ * const files = result.generatedFiles();
467
+ * const readme = files.get('README.md');
468
+ * console.log(readme?.content);
469
+ */
470
+ export interface GeneratedFile {
471
+ /** The file path relative to the repository root */
472
+ path: string;
473
+ /** The type of change */
474
+ changeType: 'created' | 'modified' | 'deleted';
475
+ /**
476
+ * The full content of the file.
477
+ * For 'created' files: the complete file content.
478
+ * For 'modified' files: only the added lines (base content is not available).
479
+ * For 'deleted' files: empty string.
480
+ */
481
+ content: string;
482
+ /** Number of lines added */
483
+ additions: number;
484
+ /** Number of lines removed */
485
+ deletions: number;
486
+ }
487
+ /**
488
+ * A collection of generated files with helper methods for ergonomic access.
489
+ *
490
+ * @example
491
+ * const files = result.generatedFiles();
492
+ *
493
+ * // Get a specific file by path
494
+ * const answer = files.get('answer.md');
495
+ *
496
+ * // Get all new files
497
+ * const newFiles = files.filter('created');
498
+ *
499
+ * // Iterate all files
500
+ * for (const file of files.all()) {
501
+ * console.log(`${file.path}: ${file.content.length} chars`);
502
+ * }
503
+ */
504
+ export interface GeneratedFiles {
505
+ /** Returns all generated files */
506
+ all(): GeneratedFile[];
507
+ /** Find a file by its path */
508
+ get(path: string): GeneratedFile | undefined;
509
+ /** Filter files by change type */
510
+ filter(changeType: 'created' | 'modified' | 'deleted'): GeneratedFile[];
511
+ }
512
+ /**
513
+ * A set of code changes with a helper method to parse the diff.
514
+ * This is an SDK-specific enhancement.
515
+ */
516
+ export interface ChangeSetArtifact {
517
+ readonly type: 'changeSet';
518
+ readonly source: string;
519
+ readonly gitPatch: GitPatch;
520
+ /**
521
+ * Parses the unified diff and returns structured file change information.
522
+ *
523
+ * @returns Parsed diff with file paths, change types, and line counts.
524
+ *
525
+ * @example
526
+ * if (artifact.type === 'changeSet') {
527
+ * const parsed = artifact.parsed();
528
+ * console.log(`Changed ${parsed.summary.totalFiles} files`);
529
+ * for (const file of parsed.files) {
530
+ * console.log(`${file.changeType}: ${file.path} (+${file.additions}/-${file.deletions})`);
531
+ * }
532
+ * }
533
+ */
534
+ parsed(): ParsedChangeSet;
535
+ }
536
+ /**
537
+ * A media output (e.g., an image) with a helper method to save the data.
538
+ * This is an SDK-specific enhancement.
539
+ */
540
+ export interface MediaArtifact {
541
+ readonly type: 'media';
542
+ /**
543
+ * The base64-encoded media data.
544
+ */
545
+ readonly data: string;
546
+ /**
547
+ * The format of the media (e.g., 'image/png').
548
+ */
549
+ readonly format: string;
550
+ /**
551
+ * Saves the media data to a file.
552
+ * This method is only available in Node.js environments.
553
+ *
554
+ * @param filepath The path to save the file to.
555
+ * @throws {Error} If called in a non-Node.js environment.
556
+ *
557
+ * @example
558
+ * if (artifact.type === 'media' && artifact.format.startsWith('image/')) {
559
+ * await artifact.save('./screenshot.png');
560
+ * }
561
+ */
562
+ save(filepath: string): Promise<void>;
563
+ /**
564
+ * Creates a blob URL for the media data.
565
+ * This works in both Node.js and browser environments.
566
+ *
567
+ * @returns A URL string that can be used to display or download the media.
568
+ *
569
+ * @example
570
+ * if (artifact.type === 'media') {
571
+ * const url = artifact.toUrl();
572
+ * // Browser: <img src={url} />
573
+ * // Node: console.log('Media URL:', url);
574
+ * }
575
+ */
576
+ toUrl(): string;
577
+ }
578
+ /**
579
+ * Output from a bash command execution, with a helper method to format the output.
580
+ * This is an SDK-specific enhancement.
581
+ */
582
+ export interface BashArtifact {
583
+ readonly type: 'bashOutput';
584
+ readonly command: string;
585
+ readonly stdout: string;
586
+ readonly stderr: string;
587
+ readonly exitCode: number | null;
588
+ /**
589
+ * Returns a cleanly formatted string combining the command, output, and exit code.
590
+ *
591
+ * @example
592
+ * if (artifact.type === 'bashOutput') {
593
+ * console.log(artifact.toString());
594
+ * }
595
+ */
596
+ toString(): string;
597
+ }
598
+ /**
599
+ * A single unit of data produced by an activity, enhanced with SDK helper methods.
600
+ * This is a discriminated union based on the `type` property.
601
+ * Maps to the `Artifact` resource in the REST API.
602
+ *
603
+ * @example
604
+ * (artifact: Artifact) => {
605
+ * if (artifact.type === 'changeSet') {
606
+ * const parsed = artifact.parsed();
607
+ * console.log(`Modified ${parsed.summary.totalFiles} files`);
608
+ * }
609
+ * }
610
+ */
611
+ export type Artifact = ChangeSetArtifact | MediaArtifact | BashArtifact;
612
+ export interface RestChangeSetArtifact {
613
+ changeSet: ChangeSet;
614
+ }
615
+ export interface RestMediaArtifact {
616
+ media: {
617
+ data: string;
618
+ mimeType: string;
619
+ };
620
+ }
621
+ export interface RestBashOutputArtifact {
622
+ bashOutput: {
623
+ command: string;
624
+ output: string;
625
+ exitCode: number | null;
626
+ };
627
+ }
628
+ export type RestArtifact = RestChangeSetArtifact | RestMediaArtifact | RestBashOutputArtifact;
629
+ /**
630
+ * Base structure for all activities.
631
+ */
632
+ interface BaseActivity {
633
+ /**
634
+ * The full resource name (e.g., "sessions/{session}/activities/{activity}").
635
+ */
636
+ name: string;
637
+ id: string;
638
+ /**
639
+ * A generic, human-readable description for the activity.
640
+ */
641
+ description?: string;
642
+ /**
643
+ * The time at which this activity was created (RFC 3339 timestamp).
644
+ */
645
+ createTime: string;
646
+ /**
647
+ * The entity that this activity originated from.
648
+ */
649
+ originator: 'user' | 'agent' | 'system';
650
+ /**
651
+ * The artifacts produced by this activity.
652
+ */
653
+ artifacts: Artifact[];
654
+ /**
655
+ * The session that this activity belongs to.
656
+ * Only populated when `include: { session: true }` is used in `jules.select()`.
657
+ */
658
+ session?: SessionResource;
659
+ }
660
+ /**
661
+ * An activity representing a message from the agent.
662
+ */
663
+ export interface ActivityAgentMessaged extends BaseActivity {
664
+ type: 'agentMessaged';
665
+ /**
666
+ * The message the agent posted.
667
+ */
668
+ message: string;
669
+ }
670
+ /**
671
+ * An activity representing a message from the user.
672
+ */
673
+ export interface ActivityUserMessaged extends BaseActivity {
674
+ type: 'userMessaged';
675
+ /**
676
+ * The message the user posted.
677
+ */
678
+ message: string;
679
+ }
680
+ /**
681
+ * An activity representing a newly generated plan.
682
+ */
683
+ export interface ActivityPlanGenerated extends BaseActivity {
684
+ type: 'planGenerated';
685
+ /**
686
+ * The plan that was generated.
687
+ */
688
+ plan: Plan;
689
+ }
690
+ /**
691
+ * An activity representing the approval of a plan.
692
+ */
693
+ export interface ActivityPlanApproved extends BaseActivity {
694
+ type: 'planApproved';
695
+ /**
696
+ * The ID of the plan that was approved.
697
+ */
698
+ planId: string;
699
+ }
700
+ /**
701
+ * An activity representing a progress update from the agent.
702
+ */
703
+ export interface ActivityProgressUpdated extends BaseActivity {
704
+ type: 'progressUpdated';
705
+ /**
706
+ * The title of the progress update.
707
+ */
708
+ title: string;
709
+ /**
710
+ * The description of the progress update.
711
+ */
712
+ description: string;
713
+ }
714
+ /**
715
+ * An activity signifying the successful completion of a session.
716
+ */
717
+ export interface ActivitySessionCompleted extends BaseActivity {
718
+ type: 'sessionCompleted';
719
+ }
720
+ /**
721
+ * An activity signifying the failure of a session.
722
+ */
723
+ export interface ActivitySessionFailed extends BaseActivity {
724
+ type: 'sessionFailed';
725
+ /**
726
+ * The reason the session failed.
727
+ */
728
+ reason: string;
729
+ }
730
+ /**
731
+ * A lightweight summary of an activity, designed for token-efficient transmission.
732
+ */
733
+ export interface ActivitySummary {
734
+ id: string;
735
+ type: string;
736
+ createTime: string;
737
+ summary: string;
738
+ }
739
+ /**
740
+ * A media artifact with its base64 data stripped.
741
+ */
742
+ export type StrippedMediaArtifact = Omit<MediaArtifact, 'data'> & {
743
+ dataStripped: true;
744
+ hasData: true;
745
+ };
746
+ /**
747
+ * A union of artifact types that can be included in a lightweight activity.
748
+ */
749
+ export type LightweightArtifact = Exclude<Artifact, MediaArtifact> | StrippedMediaArtifact;
750
+ /**
751
+ * A lightweight representation of an activity, with artifacts stripped by default.
752
+ */
753
+ export interface LightweightActivity extends ActivitySummary {
754
+ /**
755
+ * The full message content for activities that have one (agentMessaged, userMessaged).
756
+ * Unlike `summary`, this is not truncated.
757
+ */
758
+ message?: string;
759
+ artifacts: LightweightArtifact[] | null;
760
+ artifactCount: number;
761
+ }
762
+ /**
763
+ * A single event or unit of work within a session.
764
+ * This discriminated union represents all possible activities streamed by the SDK.
765
+ * Maps to the `Activity` resource in the REST API.
766
+ *
767
+ * @example
768
+ * (activity: Activity) => {
769
+ * switch (activity.type) {
770
+ * case 'planGenerated':
771
+ * console.log('Plan:', activity.plan.steps.map(s => s.title));
772
+ * break;
773
+ * case 'agentMessaged':
774
+ * console.log('Agent says:', activity.message);
775
+ * break;
776
+ * }
777
+ * }
778
+ */
779
+ export type Activity = ActivityAgentMessaged | ActivityUserMessaged | ActivityPlanGenerated | ActivityPlanApproved | ActivityProgressUpdated | ActivitySessionCompleted | ActivitySessionFailed;
780
+ /**
781
+ * The final outcome of a completed session or run.
782
+ * This is derived from the final SessionResource state.
783
+ *
784
+ * @example
785
+ * (outcome: SessionOutcome) => {
786
+ * if (outcome.state === 'completed' && outcome.pullRequest) {
787
+ * console.log(`Success! PR: ${outcome.pullRequest.url}`);
788
+ * }
789
+ * }
790
+ */
791
+ export interface SessionOutcome {
792
+ sessionId: string;
793
+ title: string;
794
+ state: 'completed' | 'failed';
795
+ /**
796
+ * The primary Pull Request created by the session, if applicable.
797
+ */
798
+ pullRequest?: PullRequest;
799
+ /**
800
+ * All outputs generated by the session.
801
+ */
802
+ outputs: SessionOutput[];
803
+ /**
804
+ * Returns all files generated by this session with their full content.
805
+ * This is a convenience method for accessing session outputs as files.
806
+ *
807
+ * @example
808
+ * const result = await session.result();
809
+ * const files = result.generatedFiles();
810
+ * const answer = files.get('answer.md');
811
+ * console.log(answer?.content);
812
+ */
813
+ generatedFiles(): GeneratedFiles;
814
+ /**
815
+ * Returns the change set artifact if one exists, providing access to
816
+ * the unified diff and parsed file changes.
817
+ *
818
+ * @example
819
+ * const result = await session.result();
820
+ * const changeSet = result.changeSet();
821
+ * if (changeSet) {
822
+ * const parsed = changeSet.parsed();
823
+ * console.log(`${parsed.summary.totalFiles} files changed`);
824
+ * }
825
+ */
826
+ changeSet(): ChangeSetArtifact | undefined;
827
+ }
828
+ /**
829
+ * Represents a Jules Session in automated mode, initiated by `jules.run()`.
830
+ *
831
+ * It provides methods for real-time observation and retrieving the final outcome.
832
+ */
833
+ export interface AutomatedSession {
834
+ /**
835
+ * The unique ID of the session.
836
+ */
837
+ readonly id: string;
838
+ /**
839
+ * Provides a real-time stream of activities as the automated run progresses.
840
+ * This uses an Async Iterator, making it easy to consume events as they happen.
841
+ *
842
+ * @example
843
+ * const run = await jules.run({ ... });
844
+ * for await (const activity of run.stream()) {
845
+ * console.log(`[${activity.type}]`);
846
+ * }
847
+ */
848
+ stream(): AsyncIterable<Activity>;
849
+ /**
850
+ * Waits for the session to complete and returns the final outcome.
851
+ *
852
+ * @example
853
+ * const run = await jules.run({ ... });
854
+ * const outcome = await run.result();
855
+ */
856
+ result(): Promise<SessionOutcome>;
857
+ }
858
+ /**
859
+ * Valid root domains for the local graph.
860
+ */
861
+ export type JulesDomain = 'sessions' | 'activities';
862
+ /**
863
+ * Filter operators for the 'where' clause.
864
+ */
865
+ export type FilterOp<V> = V | {
866
+ eq?: V;
867
+ neq?: V;
868
+ contains?: string;
869
+ gt?: V;
870
+ lt?: V;
871
+ gte?: V;
872
+ lte?: V;
873
+ in?: V[];
874
+ exists?: boolean;
875
+ };
876
+ /**
877
+ * Domain-specific filter definitions.
878
+ */
879
+ export type WhereClause<T extends JulesDomain> = T extends 'sessions' ? {
880
+ id?: FilterOp<string>;
881
+ state?: FilterOp<string>;
882
+ title?: FilterOp<string>;
883
+ search?: string;
884
+ } : {
885
+ id?: FilterOp<string>;
886
+ type?: FilterOp<string>;
887
+ sessionId?: FilterOp<string>;
888
+ search?: string;
889
+ };
890
+ /**
891
+ * Defines which related nodes to fetch.
892
+ */
893
+ export type IncludeClause<T extends JulesDomain> = T extends 'sessions' ? {
894
+ activities?: boolean | {
895
+ where?: WhereClause<'activities'>;
896
+ limit?: number;
897
+ select?: (keyof Activity)[];
898
+ };
899
+ } : {
900
+ session?: boolean | {
901
+ select?: (keyof SessionResource)[];
902
+ };
903
+ };
904
+ /**
905
+ * The Unified Query Schema.
906
+ */
907
+ export interface JulesQuery<T extends JulesDomain> {
908
+ from: T;
909
+ select?: T extends 'sessions' ? (keyof SessionResource)[] : (keyof Activity)[];
910
+ where?: WhereClause<T>;
911
+ include?: IncludeClause<T>;
912
+ limit?: number;
913
+ offset?: number;
914
+ order?: 'asc' | 'desc';
915
+ startAt?: string;
916
+ startAfter?: string;
917
+ }
918
+ /**
919
+ * Maps the domain to its resulting object type.
920
+ */
921
+ export type QueryResult<T extends JulesDomain> = T extends 'sessions' ? SessionResource : Activity;
922
+ /**
923
+ * Options for streaming activities, such as filtering.
924
+ * This is a forward declaration; the actual type is in `streaming.ts`
925
+ * to avoid circular dependencies.
926
+ * @internal
927
+ */
928
+ export type StreamActivitiesOptions = {
929
+ exclude?: {
930
+ originator: Origin;
931
+ };
932
+ };
933
+ /**
934
+ * Represents an active, interactive session with the Jules agent.
935
+ * This is the primary interface for managing the lifecycle of an interactive session.
936
+ */
937
+ export interface SessionClient {
938
+ /**
939
+ * The unique ID of the session.
940
+ */
941
+ readonly id: string;
942
+ /**
943
+ * Scoped access to activity-specific operations.
944
+ */
945
+ readonly activities: ActivityClient;
946
+ /**
947
+ * COLD STREAM: Yields all known past activities from local storage.
948
+ * Ends immediately after yielding the last known activity.
949
+ * Does NOT open a network connection.
950
+ */
951
+ history(): AsyncIterable<Activity>;
952
+ /**
953
+ * HOT STREAM: Yields ONLY future activities as they arrive from the network.
954
+ * Blocks indefinitely.
955
+ */
956
+ updates(): AsyncIterable<Activity>;
957
+ /**
958
+ * LOCAL QUERY: Performs rich filtering against local storage only.
959
+ * Fast, but might be incomplete if not synced.
960
+ *
961
+ * @deprecated Use `session.activities.select()` instead.
962
+ */
963
+ select(options?: SelectOptions): Promise<Activity[]>;
964
+ /**
965
+ * Provides a real-time stream of activities for the session.
966
+ * This uses an Async Iterator to abstract the polling of the ListActivities endpoint.
967
+ *
968
+ * @param options Options to control the stream, such as filters.
969
+ * @example
970
+ * // Filter out activities originated by the user
971
+ * for await (const activity of session.stream({ exclude: { originator: 'user' } })) {
972
+ * console.log(activity.type);
973
+ * }
974
+ */
975
+ stream(options?: StreamActivitiesOptions): AsyncIterable<Activity>;
976
+ /**
977
+ * Approves the currently pending plan.
978
+ * Only valid if the session state is `awaitingPlanApproval`.
979
+ *
980
+ * @example
981
+ * await session.waitFor('awaitingPlanApproval');
982
+ * await session.approve();
983
+ */
984
+ approve(): Promise<void>;
985
+ /**
986
+ * Sends a message (prompt) to the agent in the context of the current session.
987
+ * This is a fire-and-forget operation. To see the response, use `stream()` or `ask()`.
988
+ *
989
+ * @param prompt The message to send.
990
+ * @example
991
+ * await session.send("Can you start working on the first step?");
992
+ */
993
+ send(prompt: string): Promise<void>;
994
+ /**
995
+ * Sends a message to the agent and waits specifically for the agent's immediate reply.
996
+ * This provides a convenient request/response flow for conversational interactions.
997
+ *
998
+ * @param prompt The message to send.
999
+ * @returns The agent's reply activity.
1000
+ * @example
1001
+ * const reply = await session.ask("What is the status of the plan?");
1002
+ * console.log(reply.message);
1003
+ */
1004
+ ask(prompt: string): Promise<ActivityAgentMessaged>;
1005
+ /**
1006
+ * Waits for the session to reach a terminal state (completed or failed) and returns the result.
1007
+ *
1008
+ * @returns The final outcome of the session.
1009
+ * @example
1010
+ * const outcome = await session.result();
1011
+ * console.log(`Session finished with state: ${outcome.state}`);
1012
+ */
1013
+ result(): Promise<SessionOutcome>;
1014
+ /**
1015
+ * Pauses execution and waits until the session to reach a specific state.
1016
+ *
1017
+ * @param state The target state to wait for.
1018
+ * @example
1019
+ * console.log('Waiting for the agent to finish planning...');
1020
+ * await session.waitFor('awaitingPlanApproval');
1021
+ * console.log('Plan is ready for review.');
1022
+ */
1023
+ waitFor(state: SessionState): Promise<void>;
1024
+ /**
1025
+ * Retrieves the latest state of the underlying session resource from the API.
1026
+ *
1027
+ * @returns The latest session data.
1028
+ * @example
1029
+ * const sessionInfo = await session.info();
1030
+ * console.log(`Current state: ${sessionInfo.state}`);
1031
+ */
1032
+ info(): Promise<SessionResource>;
1033
+ /**
1034
+ * Archives the session.
1035
+ * This removes the session from the default list view and marks it as archived.
1036
+ * Archived sessions can still be accessed by ID or by filtering for `archived = true`.
1037
+ *
1038
+ * @example
1039
+ * await session.archive();
1040
+ */
1041
+ archive(): Promise<void>;
1042
+ /**
1043
+ * Unarchives the session.
1044
+ * This restores the session to the default list view.
1045
+ *
1046
+ * @example
1047
+ * await session.unarchive();
1048
+ */
1049
+ unarchive(): Promise<void>;
1050
+ /**
1051
+ * Creates a point-in-time snapshot of the session with all activities loaded and derived analytics computed.
1052
+ * This is a network operation with cache heuristics.
1053
+ *
1054
+ * @param options Optional configuration for the snapshot.
1055
+ * @param options.activities If true, includes all activities in the snapshot. Defaults to true.
1056
+ * @returns A Promise resolving to the session snapshot.
1057
+ */
1058
+ snapshot(options?: {
1059
+ activities?: boolean;
1060
+ }): Promise<SessionSnapshot>;
1061
+ }
1062
+ /**
1063
+ * A point-in-time, immutable view of a session with all activities loaded and derived analytics computed.
1064
+ */
1065
+ export interface SessionSnapshot {
1066
+ readonly id: string;
1067
+ readonly state: SessionState;
1068
+ readonly url: string;
1069
+ readonly createdAt: Date;
1070
+ readonly updatedAt: Date;
1071
+ readonly durationMs: number;
1072
+ readonly prompt: string;
1073
+ readonly title: string;
1074
+ readonly pr?: PullRequest;
1075
+ readonly activities: readonly Activity[];
1076
+ readonly activityCounts: Readonly<Record<string, number>>;
1077
+ readonly timeline: readonly TimelineEntry[];
1078
+ readonly insights: SessionInsights;
1079
+ readonly generatedFiles: GeneratedFiles;
1080
+ readonly changeSet: () => ChangeSet | undefined;
1081
+ toJSON(options?: ToJSONOptions): Partial<SerializedSnapshot>;
1082
+ toMarkdown(): string;
1083
+ }
1084
+ /**
1085
+ * An entry in the computed session timeline, representing a single activity.
1086
+ */
1087
+ export interface TimelineEntry {
1088
+ readonly time: string;
1089
+ readonly type: string;
1090
+ readonly summary: string;
1091
+ }
1092
+ /**
1093
+ * Computed analytics and insights derived from the session's activities.
1094
+ */
1095
+ export interface SessionInsights {
1096
+ readonly completionAttempts: number;
1097
+ readonly planRegenerations: number;
1098
+ readonly userInterventions: number;
1099
+ readonly failedCommands: readonly Activity[];
1100
+ }
1101
+ /**
1102
+ * Valid field names for the SerializedSnapshot, used for type-safe field masks.
1103
+ */
1104
+ export type SnapshotField = keyof SerializedSnapshot;
1105
+ /**
1106
+ * Options for controlling which fields are included in the serialized output.
1107
+ */
1108
+ export interface ToJSONOptions {
1109
+ /**
1110
+ * Fields to include in the output. If specified, only these fields are returned.
1111
+ * Takes precedence over `exclude` if both are provided.
1112
+ */
1113
+ include?: SnapshotField[];
1114
+ /**
1115
+ * Fields to exclude from the output. Ignored if `include` is specified.
1116
+ */
1117
+ exclude?: SnapshotField[];
1118
+ }
1119
+ /**
1120
+ * The JSON-serializable representation of a SessionSnapshot.
1121
+ */
1122
+ export interface SerializedSnapshot {
1123
+ id: string;
1124
+ state: string;
1125
+ url: string;
1126
+ createdAt: string;
1127
+ updatedAt: string;
1128
+ durationMs: number;
1129
+ prompt: string;
1130
+ title: string;
1131
+ activities: Activity[];
1132
+ activityCounts: Record<string, number>;
1133
+ timeline: TimelineEntry[];
1134
+ generatedFiles: GeneratedFile[];
1135
+ insights: {
1136
+ completionAttempts: number;
1137
+ planRegenerations: number;
1138
+ userInterventions: number;
1139
+ failedCommandCount: number;
1140
+ };
1141
+ pr?: {
1142
+ url: string;
1143
+ title: string;
1144
+ description: string;
1145
+ };
1146
+ }
1147
+ /**
1148
+ * Options for listing sources.
1149
+ */
1150
+ export interface ListSourcesOptions {
1151
+ /**
1152
+ * A filter expression to filter sources.
1153
+ * Currently supports filtering by name (e.g., 'name="sources/github/owner/repo"').
1154
+ */
1155
+ filter?: string;
1156
+ /**
1157
+ * The maximum number of sources to return per page.
1158
+ * @default 100
1159
+ */
1160
+ pageSize?: number;
1161
+ }
1162
+ /**
1163
+ * Interface for managing and locating connected sources.
1164
+ * Accessed via `jules.sources`.
1165
+ */
1166
+ export interface SourceManager {
1167
+ /**
1168
+ * Iterates over all connected sources.
1169
+ * Uses an Async Iterator to abstract API pagination.
1170
+ *
1171
+ * @param options Optional configuration for listing sources (filter, pageSize).
1172
+ * @example
1173
+ * for await (const source of jules.sources({ filter: 'name="sources/github/owner/repo"' })) {
1174
+ * if (source.type === 'githubRepo') {
1175
+ * console.log(`Found repo: ${source.githubRepo.owner}/${source.githubRepo.repo}`);
1176
+ * }
1177
+ * }
1178
+ */
1179
+ (options?: ListSourcesOptions): AsyncIterable<Source>;
1180
+ /**
1181
+ * Locates a specific source based on ergonomic filters.
1182
+ *
1183
+ * @param filter The filter criteria (e.g., { github: 'owner/repo' }).
1184
+ * @returns The matching Source or undefined if not found.
1185
+ * @example
1186
+ * const myRepo = await jules.sources.get({ github: 'my-org/my-project' });
1187
+ */
1188
+ get(filter: {
1189
+ github: string;
1190
+ }): Promise<Source | undefined>;
1191
+ }
1192
+ /**
1193
+ * The main client interface for interacting with the Jules API.
1194
+ */
1195
+ export interface JulesClient {
1196
+ /**
1197
+ * Executes a task in automated mode.
1198
+ * This is a high-level abstraction for "fire-and-forget" tasks.
1199
+ *
1200
+ * @param config The configuration for the run.
1201
+ * @returns A `AutomatedSession` object, which is an enhanced Promise that resolves to the final outcome.
1202
+ *
1203
+ * @example
1204
+ * const run = await jules.run({
1205
+ * prompt: "Fix the bug described in issue #123",
1206
+ * source: { github: 'my-org/my-project', baseBranch: 'main' }
1207
+ * });
1208
+ * // The session is now running in the background.
1209
+ * // You can optionally wait for the result:
1210
+ * // const outcome = await run.result();
1211
+ */
1212
+ run(config: SessionConfig): Promise<AutomatedSession>;
1213
+ /**
1214
+ * Creates a new interactive session for workflows requiring human oversight.
1215
+ *
1216
+ * @param config The configuration for the session.
1217
+ * @returns A Promise resolving to the interactive `SessionClient`.
1218
+ *
1219
+ * @example
1220
+ * const session = await jules.session({
1221
+ * prompt: "Let's refactor the authentication module.",
1222
+ * source: { github: 'my-org/my-project', baseBranch: 'develop' }
1223
+ * });
1224
+ */
1225
+ session(config: SessionConfig): Promise<SessionClient>;
1226
+ /**
1227
+ * Rehydrates an existing session from its ID, allowing you to resume interaction.
1228
+ *
1229
+ * @param sessionId The ID of the existing session.
1230
+ * @returns The interactive `SessionClient`.
1231
+ *
1232
+ * @example
1233
+ * const session = jules.session('EXISTING_SESSION_ID');
1234
+ * // now you can interact with it
1235
+ * const info = await session.info();
1236
+ */
1237
+ session(sessionId: string): SessionClient;
1238
+ /**
1239
+ * Provides access to the Source Management interface.
1240
+ *
1241
+ * @example
1242
+ * const sources = jules.sources;
1243
+ * const allSources = await Array.fromAsync(sources());
1244
+ */
1245
+ sources: SourceManager;
1246
+ /**
1247
+ * Creates a new Jules client instance with updated configuration.
1248
+ * This is an immutable operation; the original client instance remains unchanged.
1249
+ *
1250
+ * @param options The new configuration options to merge with the existing ones.
1251
+ * @returns A new JulesClient instance with the updated configuration.
1252
+ *
1253
+ * @example
1254
+ * const specialized = jules.with({ apiKey: 'NEW_KEY' });
1255
+ */
1256
+ with(options: JulesOptions): JulesClient;
1257
+ /**
1258
+ * Connects to the Jules service with the provided configuration.
1259
+ * Acts as a factory method for creating a new client instance.
1260
+ *
1261
+ * @param options Configuration options for the client.
1262
+ * @returns A new JulesClient instance.
1263
+ */
1264
+ connect(options: JulesOptions): JulesClient;
1265
+ /**
1266
+ * Lists sessions with a fluent, pagination-friendly API.
1267
+ *
1268
+ * @param options Configuration for pagination (pageSize, limit, pageToken)
1269
+ * @returns A SessionCursor that can be awaited (first page) or iterated (all pages).
1270
+ *
1271
+ * @example
1272
+ * // Get the first page
1273
+ * const page = await jules.sessions({ pageSize: 10 });
1274
+ *
1275
+ * // Stream all sessions
1276
+ * for await (const session of jules.sessions()) {
1277
+ * console.log(session.id);
1278
+ * }
1279
+ */
1280
+ sessions(options?: ListSessionsOptions): SessionCursor;
1281
+ /**
1282
+ * Executes a batch of automated sessions in parallel, with concurrency control.
1283
+ *
1284
+ * @param items The raw data to process.
1285
+ * @param mapper A function that transforms each item into a `SessionConfig` object.
1286
+ * @param options Configuration for the batch operation.
1287
+ * @returns A Promise resolving to an array of `AutomatedSession` objects, preserving the order of the input items.
1288
+ *
1289
+ * @example
1290
+ * const todos = ['Fix login', 'Add tests'];
1291
+ * const sessions = await jules.all(todos, (task) => ({
1292
+ * prompt: task,
1293
+ * source: { github: 'user/repo', baseBranch: 'main' }
1294
+ * }));
1295
+ */
1296
+ all<T>(items: T[], mapper: (item: T) => SessionConfig | Promise<SessionConfig>, options?: {
1297
+ /**
1298
+ * The maximum number of concurrent sessions to run.
1299
+ * @default 4
1300
+ */
1301
+ concurrency?: number;
1302
+ /**
1303
+ * If true, the batch operation will stop immediately if any session fails to start.
1304
+ * If false, it will continue processing the remaining items.
1305
+ * @default true
1306
+ */
1307
+ stopOnError?: boolean;
1308
+ /**
1309
+ * The delay in milliseconds between starting each session.
1310
+ * @default 0
1311
+ */
1312
+ delayMs?: number;
1313
+ }): Promise<AutomatedSession[]>;
1314
+ /**
1315
+ * Internal storage access for advanced queries.
1316
+ */
1317
+ readonly storage: SessionStorage;
1318
+ /**
1319
+ * Fluent API for rich local querying across sessions and activities.
1320
+ */
1321
+ select<T extends JulesDomain>(query: JulesQuery<T>): Promise<QueryResult<T>[]>;
1322
+ /**
1323
+ * Synchronizes the local cache with the authoritative API.
1324
+ * This is a "Reconciliation Engine" that ensures local data is consistent
1325
+ * with the server, enabling high-performance local queries.
1326
+ *
1327
+ * @param options Configuration for the sync job (depth, limit, concurrency).
1328
+ */
1329
+ sync(options?: SyncOptions): Promise<SyncStats>;
1330
+ }
1331
+ /**
1332
+ * Defines the depth of data ingestion.
1333
+ * - 'metadata': Only SessionResource fields (lightweight).
1334
+ * - 'activities': Full hydration including all event logs (heavyweight).
1335
+ */
1336
+ export type SyncDepth = 'metadata' | 'activities';
1337
+ /**
1338
+ * Progress updates for observability.
1339
+ */
1340
+ export interface SyncProgress {
1341
+ phase: 'fetching_list' | 'hydrating_records' | 'hydrating_activities' | 'checkpoint';
1342
+ current: number;
1343
+ total?: number;
1344
+ lastIngestedId?: string;
1345
+ activityCount?: number;
1346
+ }
1347
+ /**
1348
+ * Metrics resulting from a completed sync job.
1349
+ */
1350
+ export interface SyncStats {
1351
+ sessionsIngested: number;
1352
+ activitiesIngested: number;
1353
+ isComplete: boolean;
1354
+ durationMs: number;
1355
+ }
1356
+ /**
1357
+ * Checkpoint data persisted between sync runs.
1358
+ */
1359
+ export interface SyncCheckpoint {
1360
+ lastProcessedSessionId: string;
1361
+ sessionsProcessed: number;
1362
+ startedAt: string;
1363
+ }
1364
+ /**
1365
+ * Configuration for the Reconciliation Engine.
1366
+ */
1367
+ export interface SyncOptions {
1368
+ /**
1369
+ * If set, syncs only this specific session.
1370
+ * Overrides `limit` and full-scan behavior.
1371
+ */
1372
+ sessionId?: string;
1373
+ /**
1374
+ * Maximum number of sessions to ingest in one pass.
1375
+ * @default 100
1376
+ */
1377
+ limit?: number;
1378
+ /**
1379
+ * Data depth per session.
1380
+ * @default 'metadata'
1381
+ */
1382
+ depth?: SyncDepth;
1383
+ /**
1384
+ * If true, stops when hitting a record already in the local cache.
1385
+ * @default true
1386
+ */
1387
+ incremental?: boolean;
1388
+ /**
1389
+ * Simultaneous hydration jobs. Use low values for SBCs/low bandwidth.
1390
+ * @default 3
1391
+ */
1392
+ concurrency?: number;
1393
+ /**
1394
+ * Optional callback for UI/CLI progress bars.
1395
+ */
1396
+ onProgress?: (progress: SyncProgress) => void;
1397
+ /**
1398
+ * If true, saves progress to disk and resumes from checkpoint on restart.
1399
+ * Checkpoint stored at .jules/cache/sync-checkpoint.json
1400
+ */
1401
+ checkpoint?: boolean;
1402
+ /**
1403
+ * AbortSignal to gracefully cancel the sync operation.
1404
+ * When aborted, sync returns partial stats with isComplete: false.
1405
+ * Does NOT throw an error.
1406
+ */
1407
+ signal?: AbortSignal;
1408
+ }
1409
+ /**
1410
+ * The main entry point for the Jules SDK.
1411
+ * This is a pre-initialized client that can be used immediately with default settings
1412
+ * (e.g., reading API keys from environment variables).
1413
+ *
1414
+ * @example
1415
+ * import { jules } from '@google/jules-sdk';
1416
+ * const session = await jules.session({ ... });
1417
+ */
1418
+ export declare const jules: JulesClient;