modjules 0.1.1 → 0.2.0
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.
- package/README.md +10 -6
- package/dist/activities/client.d.ts +44 -1
- package/dist/activities/types.d.ts +7 -0
- package/dist/activity/summary.d.ts +7 -0
- package/dist/api.d.ts +31 -1
- package/dist/artifacts.d.ts +22 -1
- package/dist/browser.d.ts +9 -1
- package/dist/browser.mjs +304 -0
- package/dist/browser.mjs.map +1 -0
- package/dist/caching.d.ts +16 -0
- package/dist/client.d.ts +53 -1
- package/dist/errors.d.ts +7 -0
- package/dist/github/adapter.d.ts +2 -0
- package/dist/github/api.d.ts +6 -0
- package/dist/github/caching.d.ts +2 -0
- package/dist/github/errors.d.ts +17 -0
- package/dist/github/index.d.ts +3 -0
- package/dist/github/pr-client.d.ts +12 -0
- package/dist/github/types.d.ts +72 -0
- package/dist/index.d.ts +24 -2
- package/dist/index.mjs +1438 -0
- package/dist/index.mjs.map +1 -0
- package/dist/memory-DE2Wujcu.js +2573 -0
- package/dist/memory-DE2Wujcu.js.map +1 -0
- package/dist/platform/browser.d.ts +13 -1
- package/dist/platform/node.d.ts +15 -1
- package/dist/platform/types.d.ts +56 -1
- package/dist/platform/web.d.ts +29 -0
- package/dist/query/computed.d.ts +65 -0
- package/dist/query/projection.d.ts +65 -0
- package/dist/query/schema.d.ts +109 -0
- package/dist/query/select.d.ts +6 -0
- package/dist/query/validate.d.ts +59 -0
- package/dist/session.d.ts +30 -6
- package/dist/sessions.d.ts +65 -0
- package/dist/snapshot.d.ts +23 -0
- package/dist/storage/cache-info.d.ts +28 -0
- package/dist/storage/memory.d.ts +15 -2
- package/dist/storage/node-fs.d.ts +19 -3
- package/dist/storage/root.d.ts +2 -0
- package/dist/storage/types.d.ts +63 -1
- package/dist/types.d.ts +422 -11
- package/dist/utils/page-token.d.ts +60 -0
- package/dist/utils.d.ts +1 -1
- package/package.json +14 -44
- package/dist/browser.es.js +0 -158
- package/dist/client-D2GRjxRE.mjs +0 -927
- package/dist/index.es.js +0 -140
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Activity } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* List of computed field names for activities
|
|
4
|
+
*/
|
|
5
|
+
export declare const ACTIVITY_COMPUTED_FIELDS: readonly ["artifactCount", "summary"];
|
|
6
|
+
/**
|
|
7
|
+
* List of computed field names for sessions
|
|
8
|
+
*/
|
|
9
|
+
export declare const SESSION_COMPUTED_FIELDS: readonly ["durationMs"];
|
|
10
|
+
/**
|
|
11
|
+
* Check if a field name is a computed field for activities
|
|
12
|
+
*/
|
|
13
|
+
export declare function isActivityComputedField(field: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Check if a field name is a computed field for sessions
|
|
16
|
+
*/
|
|
17
|
+
export declare function isSessionComputedField(field: string): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Compute the artifactCount for an activity
|
|
20
|
+
*/
|
|
21
|
+
export declare function computeArtifactCount(activity: Activity): number;
|
|
22
|
+
/**
|
|
23
|
+
* Compute the summary for an activity
|
|
24
|
+
* Delegates to existing toSummary implementation
|
|
25
|
+
*/
|
|
26
|
+
export declare function computeSummary(activity: Activity): string;
|
|
27
|
+
/**
|
|
28
|
+
* Compute the duration in milliseconds for a session
|
|
29
|
+
*/
|
|
30
|
+
export declare function computeDurationMs(session: {
|
|
31
|
+
createTime?: string;
|
|
32
|
+
updateTime?: string;
|
|
33
|
+
}): number;
|
|
34
|
+
/**
|
|
35
|
+
* Inject computed fields into an activity based on selected fields
|
|
36
|
+
*
|
|
37
|
+
* @param activity The activity to augment
|
|
38
|
+
* @param selectFields The fields being selected (or undefined for default)
|
|
39
|
+
* @returns Activity with computed fields added
|
|
40
|
+
*/
|
|
41
|
+
export declare function injectActivityComputedFields(activity: Activity, selectFields?: string[]): Activity & {
|
|
42
|
+
artifactCount?: number;
|
|
43
|
+
summary?: string;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Inject computed fields into a session based on selected fields
|
|
47
|
+
*
|
|
48
|
+
* @param session The session to augment
|
|
49
|
+
* @param selectFields The fields being selected (or undefined for default)
|
|
50
|
+
* @returns Session with computed fields added
|
|
51
|
+
*/
|
|
52
|
+
export declare function injectSessionComputedFields<T extends {
|
|
53
|
+
createTime?: string;
|
|
54
|
+
updateTime?: string;
|
|
55
|
+
}>(session: T, selectFields?: string[]): T & {
|
|
56
|
+
durationMs?: number;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Default projection fields for activities (includes computed fields)
|
|
60
|
+
*/
|
|
61
|
+
export declare const DEFAULT_ACTIVITY_PROJECTION: string[];
|
|
62
|
+
/**
|
|
63
|
+
* Default projection fields for sessions
|
|
64
|
+
*/
|
|
65
|
+
export declare const DEFAULT_SESSION_PROJECTION: string[];
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projection Engine for Jules Query Language
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Dot notation field paths: "plan.steps.title"
|
|
6
|
+
* - Wildcard inclusion: "*"
|
|
7
|
+
* - Exclusion prefix: "-artifacts.data"
|
|
8
|
+
* - Implicit array traversal: "artifacts.type" works on arrays
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Parsed select expression
|
|
12
|
+
*/
|
|
13
|
+
export interface SelectExpression {
|
|
14
|
+
path: string[];
|
|
15
|
+
exclude: boolean;
|
|
16
|
+
wildcard: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse a select expression string into structured form
|
|
20
|
+
*
|
|
21
|
+
* Examples:
|
|
22
|
+
* - "id" → { path: ["id"], exclude: false, wildcard: false }
|
|
23
|
+
* - "plan.steps.title" → { path: ["plan", "steps", "title"], exclude: false, wildcard: false }
|
|
24
|
+
* - "-artifacts.data" → { path: ["artifacts", "data"], exclude: true, wildcard: false }
|
|
25
|
+
* - "*" → { path: [], exclude: false, wildcard: true }
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseSelectExpression(expr: string): SelectExpression;
|
|
28
|
+
/**
|
|
29
|
+
* Get a value at a nested path, handling arrays transparently
|
|
30
|
+
*
|
|
31
|
+
* For paths that traverse arrays, returns an array of values from each element.
|
|
32
|
+
*
|
|
33
|
+
* Examples:
|
|
34
|
+
* - getPath({a: {b: 1}}, ["a", "b"]) → 1
|
|
35
|
+
* - getPath({items: [{x: 1}, {x: 2}]}, ["items", "x"]) → [1, 2]
|
|
36
|
+
*/
|
|
37
|
+
export declare function getPath(obj: unknown, path: string[]): unknown;
|
|
38
|
+
/**
|
|
39
|
+
* Set a value at a nested path, creating intermediate objects as needed
|
|
40
|
+
*
|
|
41
|
+
* For array paths, preserves array structure.
|
|
42
|
+
*/
|
|
43
|
+
export declare function setPath(obj: Record<string, unknown>, path: string[], value: unknown): void;
|
|
44
|
+
/**
|
|
45
|
+
* Delete a value at a nested path
|
|
46
|
+
*
|
|
47
|
+
* For paths ending in array elements, removes the field from each element.
|
|
48
|
+
*/
|
|
49
|
+
export declare function deletePath(obj: unknown, path: string[]): void;
|
|
50
|
+
/**
|
|
51
|
+
* Deep clone an object
|
|
52
|
+
*/
|
|
53
|
+
export declare function deepClone<T>(obj: T): T;
|
|
54
|
+
/**
|
|
55
|
+
* Project a document according to select expressions
|
|
56
|
+
*
|
|
57
|
+
* @param doc The source document
|
|
58
|
+
* @param selects Array of select expression strings
|
|
59
|
+
* @returns Projected document with only selected fields
|
|
60
|
+
*/
|
|
61
|
+
export declare function projectDocument(doc: Record<string, unknown>, selects: string[]): Record<string, unknown>;
|
|
62
|
+
/**
|
|
63
|
+
* Check if a path is a prefix of another path
|
|
64
|
+
*/
|
|
65
|
+
export declare function isPathPrefix(prefix: string[], path: string[]): boolean;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema Introspection for Jules Query Language
|
|
3
|
+
*
|
|
4
|
+
* Provides TypeScript type definitions and field metadata for LLM discoverability.
|
|
5
|
+
* These schemas help LLMs understand the shape of Session, Activity, and related types
|
|
6
|
+
* to translate natural language queries into proper JQL.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Field metadata for schema introspection
|
|
10
|
+
*/
|
|
11
|
+
export interface FieldMeta {
|
|
12
|
+
/** Field name */
|
|
13
|
+
name: string;
|
|
14
|
+
/** TypeScript type representation */
|
|
15
|
+
type: string;
|
|
16
|
+
/** Human-readable description */
|
|
17
|
+
description: string;
|
|
18
|
+
/** Whether field is optional */
|
|
19
|
+
optional?: boolean;
|
|
20
|
+
/** Whether field is computed (not stored, derived at query time) */
|
|
21
|
+
computed?: boolean;
|
|
22
|
+
/** Whether field can be filtered in where clause */
|
|
23
|
+
filterable?: boolean;
|
|
24
|
+
/** Whether field can be used in select projection */
|
|
25
|
+
selectable?: boolean;
|
|
26
|
+
/** Nested fields if this is an object or array type */
|
|
27
|
+
fields?: FieldMeta[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Schema definition for a domain
|
|
31
|
+
*/
|
|
32
|
+
export interface DomainSchema {
|
|
33
|
+
/** Domain name */
|
|
34
|
+
domain: 'sessions' | 'activities';
|
|
35
|
+
/** Human-readable description */
|
|
36
|
+
description: string;
|
|
37
|
+
/** All fields in this domain */
|
|
38
|
+
fields: FieldMeta[];
|
|
39
|
+
/** Example queries for this domain */
|
|
40
|
+
examples: QueryExample[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Example query for documentation
|
|
44
|
+
*/
|
|
45
|
+
export interface QueryExample {
|
|
46
|
+
/** Natural language description */
|
|
47
|
+
description: string;
|
|
48
|
+
/** JQL query */
|
|
49
|
+
query: Record<string, unknown>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Schema for SessionResource
|
|
53
|
+
*/
|
|
54
|
+
export declare const SESSION_SCHEMA: DomainSchema;
|
|
55
|
+
/**
|
|
56
|
+
* Schema for Activity types
|
|
57
|
+
*/
|
|
58
|
+
export declare const ACTIVITY_SCHEMA: DomainSchema;
|
|
59
|
+
/**
|
|
60
|
+
* FilterOp schema for where clause operators
|
|
61
|
+
*/
|
|
62
|
+
export declare const FILTER_OP_SCHEMA: {
|
|
63
|
+
description: string;
|
|
64
|
+
operators: {
|
|
65
|
+
name: string;
|
|
66
|
+
description: string;
|
|
67
|
+
example: string;
|
|
68
|
+
}[];
|
|
69
|
+
dotNotation: {
|
|
70
|
+
description: string;
|
|
71
|
+
examples: string[];
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Projection schema for select clause
|
|
76
|
+
*/
|
|
77
|
+
export declare const PROJECTION_SCHEMA: {
|
|
78
|
+
description: string;
|
|
79
|
+
syntax: {
|
|
80
|
+
name: string;
|
|
81
|
+
description: string;
|
|
82
|
+
example: string;
|
|
83
|
+
}[];
|
|
84
|
+
defaults: {
|
|
85
|
+
sessions: string[];
|
|
86
|
+
activities: string[];
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Get the full schema for a domain
|
|
91
|
+
*/
|
|
92
|
+
export declare function getSchema(domain: 'sessions' | 'activities'): DomainSchema;
|
|
93
|
+
/**
|
|
94
|
+
* Get all schemas with filter and projection documentation
|
|
95
|
+
*/
|
|
96
|
+
export declare function getAllSchemas(): {
|
|
97
|
+
sessions: DomainSchema;
|
|
98
|
+
activities: DomainSchema;
|
|
99
|
+
filterOps: typeof FILTER_OP_SCHEMA;
|
|
100
|
+
projection: typeof PROJECTION_SCHEMA;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Generate TypeScript type definition string for a domain
|
|
104
|
+
*/
|
|
105
|
+
export declare function generateTypeDefinition(domain: 'sessions' | 'activities'): string;
|
|
106
|
+
/**
|
|
107
|
+
* Generate markdown documentation for LLM consumption
|
|
108
|
+
*/
|
|
109
|
+
export declare function generateMarkdownDocs(): string;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { JulesClient, JulesQuery, JulesDomain, QueryResult } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Standalone query engine function.
|
|
4
|
+
* Handles planning, index scanning, and hydration.
|
|
5
|
+
*/
|
|
6
|
+
export declare function select<T extends JulesDomain>(client: JulesClient, query: JulesQuery<T>): Promise<QueryResult<T>[]>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Validator for Jules Query Language
|
|
3
|
+
*
|
|
4
|
+
* Validates queries before execution, providing actionable error messages
|
|
5
|
+
* for LLMs to self-correct their queries.
|
|
6
|
+
*/
|
|
7
|
+
export interface ValidationError {
|
|
8
|
+
/** Error code for programmatic handling */
|
|
9
|
+
code: ValidationErrorCode;
|
|
10
|
+
/** JSON path to the error location (e.g., "where.artifacts.type") */
|
|
11
|
+
path: string;
|
|
12
|
+
/** Human-readable error message */
|
|
13
|
+
message: string;
|
|
14
|
+
/** Suggested fix or valid alternatives */
|
|
15
|
+
suggestion?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ValidationWarning {
|
|
18
|
+
/** Warning code */
|
|
19
|
+
code: string;
|
|
20
|
+
/** JSON path to the warning location */
|
|
21
|
+
path: string;
|
|
22
|
+
/** Human-readable warning message */
|
|
23
|
+
message: string;
|
|
24
|
+
}
|
|
25
|
+
export interface ValidationResult {
|
|
26
|
+
/** Whether the query is valid */
|
|
27
|
+
valid: boolean;
|
|
28
|
+
/** Validation errors (if any) */
|
|
29
|
+
errors: ValidationError[];
|
|
30
|
+
/** Validation warnings (non-blocking issues) */
|
|
31
|
+
warnings: ValidationWarning[];
|
|
32
|
+
/** Auto-corrected query (if corrections were possible) */
|
|
33
|
+
correctedQuery?: Record<string, unknown>;
|
|
34
|
+
}
|
|
35
|
+
export type ValidationErrorCode = 'INVALID_STRUCTURE' | 'MISSING_REQUIRED_FIELD' | 'INVALID_DOMAIN' | 'INVALID_FIELD_PATH' | 'INVALID_OPERATOR' | 'INVALID_OPERATOR_VALUE' | 'COMPUTED_FIELD_FILTER' | 'INVALID_ORDER' | 'INVALID_LIMIT' | 'INVALID_SELECT_EXPRESSION';
|
|
36
|
+
/**
|
|
37
|
+
* Validate a Jules Query Language query
|
|
38
|
+
*
|
|
39
|
+
* @param query - The query object to validate
|
|
40
|
+
* @returns Validation result with errors, warnings, and optional corrections
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const result = validateQuery({
|
|
45
|
+
* from: 'activities',
|
|
46
|
+
* where: { type: 'agentMessaged' },
|
|
47
|
+
* select: ['id', 'message']
|
|
48
|
+
* });
|
|
49
|
+
*
|
|
50
|
+
* if (!result.valid) {
|
|
51
|
+
* console.log('Errors:', result.errors);
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function validateQuery(query: unknown): ValidationResult;
|
|
56
|
+
/**
|
|
57
|
+
* Format validation result as a human-readable string
|
|
58
|
+
*/
|
|
59
|
+
export declare function formatValidationResult(result: ValidationResult): string;
|
package/dist/session.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { SelectOptions } from './activities/types.js';
|
|
1
|
+
import { ActivityClient, SelectOptions } from './activities/types.js';
|
|
2
2
|
import { ApiClient } from './api.js';
|
|
3
3
|
import { InternalConfig } from './client.js';
|
|
4
|
-
import { ActivityStorage } from './storage/types.js';
|
|
4
|
+
import { ActivityStorage, SessionStorage } from './storage/types.js';
|
|
5
5
|
import { StreamActivitiesOptions } from './streaming.js';
|
|
6
|
-
import { Activity, ActivityAgentMessaged, Outcome, SessionClient, SessionResource, SessionState } from './types.js';
|
|
6
|
+
import { Activity, ActivityAgentMessaged, Outcome, SessionClient, SessionResource, SessionState, SessionSnapshot } from './types.js';
|
|
7
7
|
/**
|
|
8
8
|
* Implementation of the SessionClient interface.
|
|
9
9
|
* Manages an interactive session with the Jules agent.
|
|
@@ -12,6 +12,7 @@ export declare class SessionClientImpl implements SessionClient {
|
|
|
12
12
|
readonly id: string;
|
|
13
13
|
private apiClient;
|
|
14
14
|
private config;
|
|
15
|
+
private sessionStorage;
|
|
15
16
|
private _activities;
|
|
16
17
|
/**
|
|
17
18
|
* Creates a new instance of SessionClientImpl.
|
|
@@ -19,22 +20,37 @@ export declare class SessionClientImpl implements SessionClient {
|
|
|
19
20
|
* @param sessionId The ID of the session.
|
|
20
21
|
* @param apiClient The API client to use for network requests.
|
|
21
22
|
* @param config The configuration options.
|
|
22
|
-
* @param
|
|
23
|
+
* @param activityStorage The storage engine for activities.
|
|
24
|
+
* @param sessionStorage The storage engine for sessions.
|
|
23
25
|
* @param platform The platform adapter.
|
|
24
26
|
*/
|
|
25
|
-
constructor(sessionId: string, apiClient: ApiClient, config: InternalConfig,
|
|
27
|
+
constructor(sessionId: string, apiClient: ApiClient, config: InternalConfig, activityStorage: ActivityStorage, sessionStorage: SessionStorage, // Injected dependency
|
|
28
|
+
platform: any);
|
|
29
|
+
private request;
|
|
26
30
|
/**
|
|
27
31
|
* COLD STREAM: Yields all known past activities from local storage.
|
|
32
|
+
* If local cache is empty, fetches from network first.
|
|
28
33
|
*/
|
|
29
34
|
history(): AsyncIterable<Activity>;
|
|
35
|
+
/**
|
|
36
|
+
* Forces a full sync of activities from the network to local cache.
|
|
37
|
+
* @returns The number of new activities synced.
|
|
38
|
+
*/
|
|
39
|
+
hydrate(): Promise<number>;
|
|
30
40
|
/**
|
|
31
41
|
* HOT STREAM: Yields ONLY future activities as they arrive from the network.
|
|
32
42
|
*/
|
|
33
43
|
updates(): AsyncIterable<Activity>;
|
|
34
44
|
/**
|
|
35
45
|
* LOCAL QUERY: Performs rich filtering against local storage only.
|
|
46
|
+
*
|
|
47
|
+
* @deprecated Use `session.activities.select()` instead.
|
|
36
48
|
*/
|
|
37
49
|
select(options?: SelectOptions): Promise<Activity[]>;
|
|
50
|
+
/**
|
|
51
|
+
* Scoped access to activity-specific operations.
|
|
52
|
+
*/
|
|
53
|
+
get activities(): ActivityClient;
|
|
38
54
|
/**
|
|
39
55
|
* Provides a real-time stream of activities for the session.
|
|
40
56
|
*
|
|
@@ -115,7 +131,15 @@ export declare class SessionClientImpl implements SessionClient {
|
|
|
115
131
|
*/
|
|
116
132
|
waitFor(targetState: SessionState): Promise<void>;
|
|
117
133
|
/**
|
|
118
|
-
* Retrieves the latest state of the underlying session resource
|
|
134
|
+
* Retrieves the latest state of the underlying session resource.
|
|
135
|
+
* Implements "Iceberg" Read-Through caching.
|
|
119
136
|
*/
|
|
120
137
|
info(): Promise<SessionResource>;
|
|
138
|
+
/**
|
|
139
|
+
* Creates a point-in-time snapshot of the session.
|
|
140
|
+
* This is a network operation that fetches the latest session info and all activities.
|
|
141
|
+
*
|
|
142
|
+
* @returns A `SessionSnapshot` instance.
|
|
143
|
+
*/
|
|
144
|
+
snapshot(): Promise<SessionSnapshot>;
|
|
121
145
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ApiClient } from './api.js';
|
|
2
|
+
import { SessionResource } from './types.js';
|
|
3
|
+
import { SessionStorage } from './storage/types.js';
|
|
4
|
+
export type ListSessionsOptions = {
|
|
5
|
+
pageSize?: number;
|
|
6
|
+
pageToken?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Hard limit on the number of items to yield when iterating.
|
|
9
|
+
* Useful if you want "The last 50" without manual counting.
|
|
10
|
+
*/
|
|
11
|
+
limit?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Whether to persist fetched sessions to local storage.
|
|
14
|
+
* Defaults to `true` (Write-Through Caching).
|
|
15
|
+
* Set to `false` to disable side effects.
|
|
16
|
+
*/
|
|
17
|
+
persist?: boolean;
|
|
18
|
+
};
|
|
19
|
+
export type ListSessionsResponse = {
|
|
20
|
+
sessions: SessionResource[];
|
|
21
|
+
nextPageToken?: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* The SessionCursor handles the complexity of pagination state.
|
|
25
|
+
* It is "Thenable" (acts like a Promise) and "AsyncIterable".
|
|
26
|
+
*
|
|
27
|
+
* This allows two usage patterns:
|
|
28
|
+
* 1. `await jules.sessions()` - Get the first page (Promise behavior).
|
|
29
|
+
* 2. `for await (const session of jules.sessions())` - Stream all sessions (AsyncIterable behavior).
|
|
30
|
+
*
|
|
31
|
+
* **Design Notes:**
|
|
32
|
+
* - **Pagination:** Handles `nextPageToken` automatically during iteration. For manual control,
|
|
33
|
+
* access the `nextPageToken` property on the promised response.
|
|
34
|
+
* - **Limiting:** The `limit` option hard-stops the iteration after N items, preventing over-fetching.
|
|
35
|
+
* - **Write-Through Caching:** Fetched sessions are automatically persisted to local storage
|
|
36
|
+
* using `storage.upsertMany()`. This ensures the local graph is populated during listing.
|
|
37
|
+
* - **Platform:** Fully platform-agnostic (Node.js/Browser/GAS) via the injected `ApiClient`.
|
|
38
|
+
*/
|
|
39
|
+
export declare class SessionCursor implements PromiseLike<ListSessionsResponse>, AsyncIterable<SessionResource> {
|
|
40
|
+
private apiClient;
|
|
41
|
+
private storage;
|
|
42
|
+
private options;
|
|
43
|
+
constructor(apiClient: ApiClient, storage: SessionStorage, options?: ListSessionsOptions);
|
|
44
|
+
/**
|
|
45
|
+
* DX Feature: Promise Compatibility.
|
|
46
|
+
* Allows `const page = await jules.sessions()` to just get the first page.
|
|
47
|
+
* This is great for UIs that render a list and a "Load More" button.
|
|
48
|
+
*/
|
|
49
|
+
then<TResult1 = ListSessionsResponse, TResult2 = never>(onfulfilled?: ((value: ListSessionsResponse) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): PromiseLike<TResult1 | TResult2>;
|
|
50
|
+
/**
|
|
51
|
+
* DX Feature: Async Iterator.
|
|
52
|
+
* Allows `for await (const s of jules.sessions())` to stream ALL items.
|
|
53
|
+
* Automatically handles page tokens and fetching behind the scenes.
|
|
54
|
+
*/
|
|
55
|
+
[Symbol.asyncIterator](): AsyncIterator<SessionResource>;
|
|
56
|
+
/**
|
|
57
|
+
* Helper to fetch all pages into a single array.
|
|
58
|
+
* WARNING: Use with caution on large datasets.
|
|
59
|
+
*/
|
|
60
|
+
all(): Promise<SessionResource[]>;
|
|
61
|
+
/**
|
|
62
|
+
* Internal fetcher that maps the options to the REST parameters.
|
|
63
|
+
*/
|
|
64
|
+
private fetchPage;
|
|
65
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Activity, PullRequest, SessionInsights, SessionResource, SessionSnapshot, SessionState, SerializedSnapshot, TimelineEntry } from './types.js';
|
|
2
|
+
export declare class SessionSnapshotImpl implements SessionSnapshot {
|
|
3
|
+
readonly id: string;
|
|
4
|
+
readonly state: SessionState;
|
|
5
|
+
readonly url: string;
|
|
6
|
+
readonly createdAt: Date;
|
|
7
|
+
readonly updatedAt: Date;
|
|
8
|
+
readonly durationMs: number;
|
|
9
|
+
readonly prompt: string;
|
|
10
|
+
readonly title: string;
|
|
11
|
+
readonly pr?: PullRequest;
|
|
12
|
+
readonly activities: readonly Activity[];
|
|
13
|
+
readonly activityCounts: Readonly<Record<string, number>>;
|
|
14
|
+
readonly timeline: readonly TimelineEntry[];
|
|
15
|
+
readonly insights: SessionInsights;
|
|
16
|
+
constructor(session: SessionResource, activities: Activity[]);
|
|
17
|
+
private computeActivityCounts;
|
|
18
|
+
private computeTimeline;
|
|
19
|
+
private generateSummary;
|
|
20
|
+
private computeInsights;
|
|
21
|
+
toJSON(): SerializedSnapshot;
|
|
22
|
+
toMarkdown(): string;
|
|
23
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Activity } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Represents the cache information for a single session.
|
|
4
|
+
*/
|
|
5
|
+
export type SessionCacheInfo = {
|
|
6
|
+
sessionId: string;
|
|
7
|
+
activityCount: number;
|
|
8
|
+
lastSyncedAt: Date;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Represents global cache information.
|
|
12
|
+
*/
|
|
13
|
+
export type GlobalCacheInfo = {
|
|
14
|
+
lastSyncedAt: Date;
|
|
15
|
+
sessionCount: number;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Retrieves cache information for a specific session.
|
|
19
|
+
*
|
|
20
|
+
* @param sessionId - The ID of the session.
|
|
21
|
+
* @returns A promise that resolves with the session's cache information, or null if not found.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getSessionCacheInfo(sessionId: string, rootDirOverride?: string): Promise<SessionCacheInfo | null>;
|
|
24
|
+
export declare function updateGlobalCacheMetadata(rootDirOverride?: string): Promise<void>;
|
|
25
|
+
export declare function getCacheInfo(rootDirOverride?: string): Promise<GlobalCacheInfo>;
|
|
26
|
+
export declare function getSessionCount(rootDirOverride?: string): Promise<number>;
|
|
27
|
+
export declare function getActivityCount(sessionId: string, rootDirOverride?: string): Promise<number>;
|
|
28
|
+
export declare function getLatestActivities(sessionId: string, n: number, rootDirOverride?: string): Promise<Activity[]>;
|
package/dist/storage/memory.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Activity } from '../types.js';
|
|
2
|
-
import { ActivityStorage } from './types.js';
|
|
1
|
+
import { Activity, SessionResource } from '../types.js';
|
|
2
|
+
import { ActivityStorage, SessionStorage, CachedSession, SessionIndexEntry } from './types.js';
|
|
3
3
|
/**
|
|
4
4
|
* In-memory implementation of ActivityStorage.
|
|
5
5
|
* Useful for testing or environments where persistence is not required.
|
|
@@ -38,3 +38,16 @@ export declare class MemoryStorage implements ActivityStorage {
|
|
|
38
38
|
*/
|
|
39
39
|
scan(): AsyncIterable<Activity>;
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* In-memory implementation of SessionStorage.
|
|
43
|
+
*/
|
|
44
|
+
export declare class MemorySessionStorage implements SessionStorage {
|
|
45
|
+
private sessions;
|
|
46
|
+
private index;
|
|
47
|
+
init(): Promise<void>;
|
|
48
|
+
upsert(session: SessionResource): Promise<void>;
|
|
49
|
+
upsertMany(sessions: SessionResource[]): Promise<void>;
|
|
50
|
+
get(sessionId: string): Promise<CachedSession | undefined>;
|
|
51
|
+
delete(sessionId: string): Promise<void>;
|
|
52
|
+
scanIndex(): AsyncIterable<SessionIndexEntry>;
|
|
53
|
+
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { Activity } from '../types.js';
|
|
2
|
-
import { ActivityStorage } from './types.js';
|
|
1
|
+
import { Activity, SessionResource } from '../types.js';
|
|
2
|
+
import { ActivityStorage, SessionStorage, CachedSession, SessionIndexEntry } from './types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Node.js filesystem implementation of ActivityStorage.
|
|
5
5
|
* Stores activities in a JSONL file located at `.jules/cache/<sessionId>/activities.jsonl`.
|
|
6
6
|
*/
|
|
7
7
|
export declare class NodeFileStorage implements ActivityStorage {
|
|
8
8
|
private filePath;
|
|
9
|
+
private metadataPath;
|
|
9
10
|
private initialized;
|
|
10
|
-
constructor(sessionId: string, rootDir
|
|
11
|
+
constructor(sessionId: string, rootDir: string);
|
|
11
12
|
/**
|
|
12
13
|
* Initializes the storage by ensuring the cache directory exists.
|
|
13
14
|
*
|
|
@@ -20,6 +21,8 @@ export declare class NodeFileStorage implements ActivityStorage {
|
|
|
20
21
|
* Closes the storage.
|
|
21
22
|
*/
|
|
22
23
|
close(): Promise<void>;
|
|
24
|
+
private _readMetadata;
|
|
25
|
+
private _writeMetadata;
|
|
23
26
|
/**
|
|
24
27
|
* Appends an activity to the file.
|
|
25
28
|
*
|
|
@@ -52,3 +55,16 @@ export declare class NodeFileStorage implements ActivityStorage {
|
|
|
52
55
|
*/
|
|
53
56
|
scan(): AsyncIterable<Activity>;
|
|
54
57
|
}
|
|
58
|
+
export declare class NodeSessionStorage implements SessionStorage {
|
|
59
|
+
private cacheDir;
|
|
60
|
+
private indexFilePath;
|
|
61
|
+
private initialized;
|
|
62
|
+
constructor(rootDir: string);
|
|
63
|
+
init(): Promise<void>;
|
|
64
|
+
private getSessionPath;
|
|
65
|
+
upsert(session: SessionResource): Promise<void>;
|
|
66
|
+
upsertMany(sessions: SessionResource[]): Promise<void>;
|
|
67
|
+
get(sessionId: string): Promise<CachedSession | undefined>;
|
|
68
|
+
delete(sessionId: string): Promise<void>;
|
|
69
|
+
scanIndex(): AsyncIterable<SessionIndexEntry>;
|
|
70
|
+
}
|
package/dist/storage/types.d.ts
CHANGED
|
@@ -1,4 +1,62 @@
|
|
|
1
|
-
import { Activity } from '../types.js';
|
|
1
|
+
import { Activity, SessionResource } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Represents the wrapper around the raw resource, adding local metadata.
|
|
4
|
+
*/
|
|
5
|
+
export type CachedSession = {
|
|
6
|
+
resource: SessionResource;
|
|
7
|
+
_lastSyncedAt: number;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Subset of session fields required for the high-speed index.
|
|
11
|
+
* These are the fields we can filter on without opening the heavy session file.
|
|
12
|
+
*/
|
|
13
|
+
export type SessionIndexEntry = {
|
|
14
|
+
id: string;
|
|
15
|
+
title: string;
|
|
16
|
+
state: string;
|
|
17
|
+
createTime: string;
|
|
18
|
+
source: string;
|
|
19
|
+
_updatedAt: number;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Ephemeral (but persisted) metadata about a session's cache state.
|
|
23
|
+
* Stored separately from the main session.json to allow for frequent updates
|
|
24
|
+
* without rewriting the larger session object.
|
|
25
|
+
*/
|
|
26
|
+
export type SessionMetadata = {
|
|
27
|
+
activityCount: number;
|
|
28
|
+
};
|
|
29
|
+
export interface SessionStorage {
|
|
30
|
+
/**
|
|
31
|
+
* Initializes the storage (ensure directories exist).
|
|
32
|
+
*/
|
|
33
|
+
init(): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Persists a session state.
|
|
36
|
+
* 1. Writes the full resource to atomic storage (.jules/cache/<id>/session.json).
|
|
37
|
+
* 2. Appends metadata to the high-speed index (.jules/cache/sessions.jsonl).
|
|
38
|
+
*/
|
|
39
|
+
upsert(session: SessionResource): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Bulk optimization for upserting pages from the API.
|
|
42
|
+
*/
|
|
43
|
+
upsertMany(sessions: SessionResource[]): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Retrieves a specific session by ID.
|
|
46
|
+
* Returns undefined if not found or if the file is corrupt.
|
|
47
|
+
*/
|
|
48
|
+
get(sessionId: string): Promise<CachedSession | undefined>;
|
|
49
|
+
/**
|
|
50
|
+
* Deletes a session and its associated artifacts from local cache.
|
|
51
|
+
*/
|
|
52
|
+
delete(sessionId: string): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Scans the high-speed index.
|
|
55
|
+
* Implementation MUST handle deduplication (Last-Write-Wins) because the
|
|
56
|
+
* index is an append-only log.
|
|
57
|
+
*/
|
|
58
|
+
scanIndex(): AsyncIterable<SessionIndexEntry>;
|
|
59
|
+
}
|
|
2
60
|
/**
|
|
3
61
|
* Abstract interface for the isomorphic storage layer.
|
|
4
62
|
* Implementations handle the specifics of persisting immutable activities
|
|
@@ -36,3 +94,7 @@ export interface ActivityStorage {
|
|
|
36
94
|
*/
|
|
37
95
|
scan(): AsyncIterable<Activity>;
|
|
38
96
|
}
|
|
97
|
+
export interface GlobalCacheMetadata {
|
|
98
|
+
lastSyncedAt: number;
|
|
99
|
+
sessionCount: number;
|
|
100
|
+
}
|