@hydraharness/harness-client-runtime 0.0.0-stage → 0.1.1-rc.7
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/LICENSE +21 -0
- package/README.md +96 -2
- package/lib/client.js +10964 -0
- package/lib/index.js +6 -0
- package/lib/invariant.js +36 -0
- package/lib/types/client/agents/scope.d.ts +35 -0
- package/lib/types/client/contract/conversation.d.ts +242 -0
- package/lib/types/client/contract/session.d.ts +97 -0
- package/lib/types/client/contract/sessions-port.d.ts +55 -0
- package/lib/types/client/contract/sessions.d.ts +164 -0
- package/lib/types/client/contract/settings-scope.d.ts +79 -0
- package/lib/types/client/contract/store.d.ts +90 -0
- package/lib/types/client/contract/workspaces.d.ts +102 -0
- package/lib/types/client/conversation/definition-registry.d.ts +30 -0
- package/lib/types/client/conversation/event-registry.d.ts +27 -0
- package/lib/types/client/conversation/view-registry.d.ts +15 -0
- package/lib/types/client/index.d.ts +128 -0
- package/lib/types/client/ordered-baseline.d.ts +12 -0
- package/lib/types/client/sessions/assistant-timing.d.ts +34 -0
- package/lib/types/client/sessions/context-provenance.d.ts +58 -0
- package/lib/types/client/sessions/conversation-assembler.d.ts +107 -0
- package/lib/types/client/sessions/conversation-context.d.ts +22 -0
- package/lib/types/client/sessions/conversation-location-index.d.ts +70 -0
- package/lib/types/client/sessions/conversation-versions.d.ts +25 -0
- package/lib/types/client/sessions/conversation.d.ts +422 -0
- package/lib/types/client/sessions/failure-display.d.ts +7 -0
- package/lib/types/client/sessions/lineage.d.ts +47 -0
- package/lib/types/client/sessions/manager.d.ts +300 -0
- package/lib/types/client/sessions/notifier.d.ts +35 -0
- package/lib/types/client/sessions/partial.d.ts +40 -0
- package/lib/types/client/sessions/pending.d.ts +55 -0
- package/lib/types/client/sessions/projection-store.d.ts +111 -0
- package/lib/types/client/sessions/provide.d.ts +79 -0
- package/lib/types/client/sessions/queue-mirror.d.ts +33 -0
- package/lib/types/client/sessions/remotes.d.ts +10 -0
- package/lib/types/client/sessions/request-inspection.d.ts +74 -0
- package/lib/types/client/sessions/service.d.ts +415 -0
- package/lib/types/client/sessions/session.d.ts +287 -0
- package/lib/types/client/sessions/steering-history.d.ts +23 -0
- package/lib/types/client/sessions/subagent-lineage.d.ts +24 -0
- package/lib/types/client/sessions/tool-call-tree.d.ts +45 -0
- package/lib/types/client/slots.d.ts +191 -0
- package/lib/types/client/time-zone.d.ts +8 -0
- package/lib/types/client/workspaces/manager.d.ts +182 -0
- package/lib/types/client/workspaces/path.d.ts +17 -0
- package/lib/types/client/workspaces/service.d.ts +179 -0
- package/lib/types/client/workspaces/workspace.d.ts +65 -0
- package/lib/types/index.d.ts +4 -0
- package/lib/types/invariant.d.ts +16 -0
- package/package.json +94 -3
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/** Workspace baseline, incremental-frame, and unary-action owner. */
|
|
2
|
+
import type { HostFrame, IApiClient, RpcError, RpcRequest, RpcResult, SessionId, WorkspaceId, WorkspaceView } from '@hydraharness/harness-api-remotes/client';
|
|
3
|
+
import { type WorkspaceCreateInput } from './workspace.ts';
|
|
4
|
+
/** Monotone workspace-list arrival lifecycle. */
|
|
5
|
+
export type WorkspaceListPhase = 'pending' | 'ready';
|
|
6
|
+
/** Immutable workspace-list snapshot. */
|
|
7
|
+
export interface WorkspaceListSnapshot {
|
|
8
|
+
items: readonly WorkspaceView[];
|
|
9
|
+
/**
|
|
10
|
+
* Registry-global archive set in Host order (hidden from grouping
|
|
11
|
+
* surfaces; accounting slots retained). A plain array, not a Set: public
|
|
12
|
+
* snapshot state stays in the store engine's plain-data vocabulary
|
|
13
|
+
* (immer drafts reject Sets without the MapSet plugin); membership
|
|
14
|
+
* lookups build their own transient Set where they need one.
|
|
15
|
+
*/
|
|
16
|
+
archivedSessionIds: readonly SessionId[];
|
|
17
|
+
state: 'idle' | 'loading' | 'error';
|
|
18
|
+
phase: WorkspaceListPhase;
|
|
19
|
+
error: RpcError | null;
|
|
20
|
+
}
|
|
21
|
+
/** Workspace object cluster driven by one list baseline and changed-frame upserts. */
|
|
22
|
+
export declare class WorkspaceManager {
|
|
23
|
+
private readonly api;
|
|
24
|
+
private items;
|
|
25
|
+
private itemViewsSource;
|
|
26
|
+
private itemViewsCache;
|
|
27
|
+
private archivedSessionIds;
|
|
28
|
+
private state;
|
|
29
|
+
private phase;
|
|
30
|
+
private error;
|
|
31
|
+
private inflight;
|
|
32
|
+
private refreshFrames;
|
|
33
|
+
/**
|
|
34
|
+
* True once a frame or unary echo installed the archive set while a list
|
|
35
|
+
* request was in flight: that install is newer than the pending baseline,
|
|
36
|
+
* so the baseline's (older) set must not roll it back — the archive
|
|
37
|
+
* mirror of replaying refreshFrames over the item baseline.
|
|
38
|
+
*/
|
|
39
|
+
private archivedSupersedesRefresh;
|
|
40
|
+
/** Latest local reorder request; only its unary echo may install order. */
|
|
41
|
+
private orderRequestGeneration;
|
|
42
|
+
/** Increments on order frames so a later remote commit outranks an older unary echo. */
|
|
43
|
+
private orderFrameGeneration;
|
|
44
|
+
/** Last complete order accepted from a Host baseline, frame, or current unary echo. */
|
|
45
|
+
private committedOrder;
|
|
46
|
+
/**
|
|
47
|
+
* Ids this process has seen removed, kept for the connection's lifetime so
|
|
48
|
+
* a late changed frame or a stale baseline row cannot resurrect a deleted
|
|
49
|
+
* row. Correctness rests on Host ids never being reused (the registry mints
|
|
50
|
+
* a fresh `randomUUID` per record, including when the same directory is
|
|
51
|
+
* registered again) — a path-derived id scheme would turn these entries
|
|
52
|
+
* into permanent blindfolds and must clear them instead.
|
|
53
|
+
*/
|
|
54
|
+
private readonly removedIds;
|
|
55
|
+
private snapshotCache;
|
|
56
|
+
private readonly notifier;
|
|
57
|
+
/** @param api - shared wire client. */
|
|
58
|
+
constructor(api: IApiClient);
|
|
59
|
+
/**
|
|
60
|
+
* Refresh from workspace.list. The first successful response establishes
|
|
61
|
+
* Host order; later responses re-establish the durable order so reconnects
|
|
62
|
+
* adopt reorders committed while this client was offline. Frames arriving
|
|
63
|
+
* during the RPC are replayed over its response.
|
|
64
|
+
* @returns the shared in-flight refresh.
|
|
65
|
+
*/
|
|
66
|
+
refresh(): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Create or resolve a real Workspace, then publish its returned snapshot
|
|
69
|
+
* without waiting for the changed frame.
|
|
70
|
+
* @param input - the existing absolute path to adopt.
|
|
71
|
+
* @returns the wire result.
|
|
72
|
+
*/
|
|
73
|
+
create(input: WorkspaceCreateInput): Promise<RpcResult<{
|
|
74
|
+
workspace: WorkspaceView;
|
|
75
|
+
created: boolean;
|
|
76
|
+
}>>;
|
|
77
|
+
/**
|
|
78
|
+
* Rename a Workspace, then publish its returned snapshot without waiting
|
|
79
|
+
* for the changed frame.
|
|
80
|
+
* @param workspaceId - target workspace.
|
|
81
|
+
* @param title - new display title.
|
|
82
|
+
* @returns the wire result.
|
|
83
|
+
*/
|
|
84
|
+
rename(workspaceId: WorkspaceId, title: string): Promise<RpcResult<{
|
|
85
|
+
workspace: WorkspaceView;
|
|
86
|
+
}>>;
|
|
87
|
+
/**
|
|
88
|
+
* Delete a Workspace registration and remove its local projection from the
|
|
89
|
+
* unary response without waiting for the Host frame.
|
|
90
|
+
* @param workspaceId - target workspace.
|
|
91
|
+
* @returns the wire result.
|
|
92
|
+
*/
|
|
93
|
+
delete(workspaceId: WorkspaceId): Promise<RpcResult<{
|
|
94
|
+
deleted: true;
|
|
95
|
+
}>>;
|
|
96
|
+
/**
|
|
97
|
+
* Move a Workspace within the registry display order and install the full
|
|
98
|
+
* returned order without waiting for the Host frame.
|
|
99
|
+
* @param workspaceId - Workspace to move.
|
|
100
|
+
* @param beforeWorkspaceId - Anchor workspace; omitted appends.
|
|
101
|
+
* @returns the wire result.
|
|
102
|
+
*/
|
|
103
|
+
insertBefore(workspaceId: WorkspaceId, beforeWorkspaceId?: WorkspaceId): Promise<RpcResult<{
|
|
104
|
+
workspaceIds: WorkspaceId[];
|
|
105
|
+
}>>;
|
|
106
|
+
/**
|
|
107
|
+
* Move a session within its Workspace's manual order, then publish the
|
|
108
|
+
* returned snapshot without waiting for the changed frame.
|
|
109
|
+
* @param workspaceId - owning workspace.
|
|
110
|
+
* @param sessionId - accounted session to move.
|
|
111
|
+
* @param beforeSessionId - accounted anchor to insert before; omitted appends.
|
|
112
|
+
* @returns the wire result.
|
|
113
|
+
*/
|
|
114
|
+
insertSessionBefore(workspaceId: WorkspaceId, sessionId: SessionId, beforeSessionId?: SessionId): Promise<RpcResult<{
|
|
115
|
+
workspace: WorkspaceView;
|
|
116
|
+
}>>;
|
|
117
|
+
/**
|
|
118
|
+
* Archive one session in the registry-global set, then install the
|
|
119
|
+
* returned full set without waiting for the changed frame.
|
|
120
|
+
* @param sessionId - session to archive.
|
|
121
|
+
* @returns the wire result.
|
|
122
|
+
*/
|
|
123
|
+
archiveSession(sessionId: SessionId): Promise<RpcResult<{
|
|
124
|
+
archivedSessionIds: SessionId[];
|
|
125
|
+
}>>;
|
|
126
|
+
/**
|
|
127
|
+
* Restore one session from the registry-global archive set, then install
|
|
128
|
+
* the returned full set without waiting for the changed frame.
|
|
129
|
+
* @param sessionId - session to restore.
|
|
130
|
+
* @returns the wire result.
|
|
131
|
+
*/
|
|
132
|
+
unarchiveSession(sessionId: SessionId): Promise<RpcResult<{
|
|
133
|
+
archivedSessionIds: SessionId[];
|
|
134
|
+
}>>;
|
|
135
|
+
/**
|
|
136
|
+
* Prepend a session onto a materialized Workspace account without waiting
|
|
137
|
+
* for the Host changed frame. `session.create({ workspaceId })` has already
|
|
138
|
+
* attached; New Session reads this list in the same turn for reuse and the
|
|
139
|
+
* hero composer. Live items update immediately; an in-flight `workspace.list`
|
|
140
|
+
* is not patched, so a stale baseline can drop the id until the later
|
|
141
|
+
* changed frame. Direct adopt avoids recording a full-view upsert into
|
|
142
|
+
* that refresh replay, which would replace a newer Host row.
|
|
143
|
+
* @param workspaceId - Workspace that just attached the session.
|
|
144
|
+
* @param sessionId - attached session.
|
|
145
|
+
*/
|
|
146
|
+
accountSession(workspaceId: WorkspaceId, sessionId: SessionId): void;
|
|
147
|
+
/**
|
|
148
|
+
* Host-frame entry. Non-workspace frames are ignored so the runtime can
|
|
149
|
+
* fan one host stream out to both object managers.
|
|
150
|
+
* @param envelope - host stream envelope.
|
|
151
|
+
*/
|
|
152
|
+
handleHostEnvelope(envelope: RpcRequest<HostFrame>): void;
|
|
153
|
+
/** Re-pull the baseline after each connection generation. */
|
|
154
|
+
handleConnected(): void;
|
|
155
|
+
/**
|
|
156
|
+
* Subscribe to workspace snapshot invalidation.
|
|
157
|
+
* @param listener - snapshot invalidation callback.
|
|
158
|
+
* @returns unsubscribe function.
|
|
159
|
+
*/
|
|
160
|
+
subscribe(listener: () => void): () => void;
|
|
161
|
+
/**
|
|
162
|
+
* Read the cached workspace snapshot after flushing pending notifications.
|
|
163
|
+
* @returns the cached workspace snapshot.
|
|
164
|
+
*/
|
|
165
|
+
getSnapshot(): WorkspaceListSnapshot;
|
|
166
|
+
private buildSnapshot;
|
|
167
|
+
/**
|
|
168
|
+
* Replace the archive set when membership actually changed (array identity
|
|
169
|
+
* backs Object.is short-circuits). Host snapshots are append-ordered, so
|
|
170
|
+
* positional comparison is exact, not merely heuristic.
|
|
171
|
+
*/
|
|
172
|
+
private installArchived;
|
|
173
|
+
/** Reorder known Workspace objects, optionally recording a Host-committed sequence. */
|
|
174
|
+
private installOrder;
|
|
175
|
+
/** Upsert one Host view, optionally retaining the local object that materialized it. */
|
|
176
|
+
private upsert;
|
|
177
|
+
/** Remove one id idempotently and retain a tombstone against late echoes. */
|
|
178
|
+
private remove;
|
|
179
|
+
private installViews;
|
|
180
|
+
private itemViews;
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve a workspace-relative path into the Host-facing spelling used by openPath.
|
|
3
|
+
* @param cwd - session workspace root, when known.
|
|
4
|
+
* @param path - absolute or workspace-relative path.
|
|
5
|
+
* @returns an absolute path when a workspace root is available, otherwise the original path.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveWorkspacePath(cwd: string | undefined, path: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Display-only POSIX home abbreviation. Windows drive and UNC paths stay
|
|
10
|
+
* verbatim, including when `home` itself is a Windows path. A missing, empty,
|
|
11
|
+
* or filesystem-root `home` leaves `path` unchanged so `/` cannot become `~`.
|
|
12
|
+
* @param path - absolute or already-short display path.
|
|
13
|
+
* @param home - host account home from `host.describe`; absent skips abbreviation.
|
|
14
|
+
* @returns `~` or `~/…` for the POSIX home and its descendants, otherwise `path`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function abbreviateHomePath(path: string, home?: string): string;
|
|
17
|
+
//# sourceMappingURL=path.d.ts.map
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/** WorkspaceRuntime projects the Workspace object manager for UI consumers. */
|
|
2
|
+
import type { Context } from '@hydraharness/cordis';
|
|
3
|
+
import type { DirectoryListing, IApiClient, RpcError, SessionId, WorkspaceId, WorkspaceView } from '@hydraharness/harness-api-remotes/client';
|
|
4
|
+
import type { SnapshotStore } from '../contract/store.ts';
|
|
5
|
+
import type { SessionsPort } from '../contract/sessions-port.ts';
|
|
6
|
+
import type { IWorkspaces } from '../contract/workspaces.ts';
|
|
7
|
+
import { WorkspaceManager, type WorkspaceListPhase } from './manager.ts';
|
|
8
|
+
/** Workspace list plus the two-baseline readiness and default-target projection. */
|
|
9
|
+
export interface WorkspaceListState {
|
|
10
|
+
items: readonly WorkspaceView[];
|
|
11
|
+
/**
|
|
12
|
+
* Registry-global archive set in Host order: grouping surfaces hide these
|
|
13
|
+
* sessions everywhere (workspace groups and the ungrouped bucket) while
|
|
14
|
+
* their session logs and workspace accounting slots remain. A plain array
|
|
15
|
+
* (store-engine vocabulary; immer drafts reject Sets) — membership lookups
|
|
16
|
+
* build their own transient Set.
|
|
17
|
+
*/
|
|
18
|
+
archivedSessionIds: readonly SessionId[];
|
|
19
|
+
state: 'idle' | 'loading' | 'error';
|
|
20
|
+
phase: WorkspaceListPhase;
|
|
21
|
+
error: RpcError | null;
|
|
22
|
+
/** True only after both workspace.list and session.list have succeeded. */
|
|
23
|
+
baselinesReady: boolean;
|
|
24
|
+
/** Most recently active Workspace, derived without changing `items` order. */
|
|
25
|
+
recentWorkspaceId: WorkspaceId | undefined;
|
|
26
|
+
}
|
|
27
|
+
/** Structured create failure for UI flows that distinguish Host business errors. */
|
|
28
|
+
export declare class WorkspaceCreateError extends Error {
|
|
29
|
+
readonly rpcError: RpcError;
|
|
30
|
+
constructor(rpcError: RpcError);
|
|
31
|
+
}
|
|
32
|
+
/** Structured browse failure so the directory browser can branch on Host business codes. */
|
|
33
|
+
export declare class DirectoryBrowseError extends Error {
|
|
34
|
+
readonly rpcError: RpcError;
|
|
35
|
+
constructor(rpcError: RpcError);
|
|
36
|
+
}
|
|
37
|
+
/** Real Workspace object layer and Host actions. */
|
|
38
|
+
export declare class WorkspaceRuntime implements IWorkspaces {
|
|
39
|
+
private readonly api;
|
|
40
|
+
private readonly sessions;
|
|
41
|
+
/** UI-facing immutable projection; the manager remains wire truth. */
|
|
42
|
+
readonly list: SnapshotStore<WorkspaceListState>;
|
|
43
|
+
/** Workspace baseline and frame owner. */
|
|
44
|
+
private readonly manager;
|
|
45
|
+
/** In-flight blank-session connects keyed by workspace (reuse or create). */
|
|
46
|
+
private readonly connecting;
|
|
47
|
+
/** Guards the runtime-owned one-shot initial-selection subscription. */
|
|
48
|
+
private initialSelectionStarted;
|
|
49
|
+
/**
|
|
50
|
+
* @param ctx - client root context.
|
|
51
|
+
* @param api - shared wire client.
|
|
52
|
+
* @param sessions - cross-domain sessions face used for recency and blank-session reuse.
|
|
53
|
+
*/
|
|
54
|
+
constructor(ctx: Context, api: IApiClient, sessions: SessionsPort);
|
|
55
|
+
/**
|
|
56
|
+
* Resolve the session a New Session flow lands in once this Workspace is
|
|
57
|
+
* chosen: explicitly adopt the workspace's existing blank session when one
|
|
58
|
+
* is in the list mirror, else create a fresh one on the host
|
|
59
|
+
* (`session.create` births or resumes the full Session+Agent — the client
|
|
60
|
+
* holds no intermediate state). The adoption tells optional default owners
|
|
61
|
+
* that this exact session passed the reuse checks.
|
|
62
|
+
* caller owns navigation: take the returned id to `sessions.open`.
|
|
63
|
+
* Resolution guarantee (both arms): the returned id is already in the list
|
|
64
|
+
* store and `sessions.binding(id)` resolves synchronously — draft hand-off
|
|
65
|
+
* may write the new scope's machine before opening. The create arm also
|
|
66
|
+
* fills the session row's cwd from the Workspace path and prepends the id
|
|
67
|
+
* onto that Workspace's local `sessionIds` before resolving, so the hero
|
|
68
|
+
* composer and a follow-up reuse scan do not wait for Host frames.
|
|
69
|
+
* @param workspaceId - chosen Workspace (must be in the workspace list).
|
|
70
|
+
* @returns the reused or newly created session id.
|
|
71
|
+
*/
|
|
72
|
+
connectWorkspace(workspaceId: WorkspaceId): Promise<SessionId>;
|
|
73
|
+
/**
|
|
74
|
+
* Follow the first complete Workspace/Session baseline and select a default
|
|
75
|
+
* session exactly once. A restored current session wins; otherwise the most
|
|
76
|
+
* recent Workspace is connected (reusing or creating its blank session).
|
|
77
|
+
* Later explicit clears stay cleared instead of retriggering this startup
|
|
78
|
+
* policy. A failed connect may retry on the next baseline projection.
|
|
79
|
+
* @returns disposer for the baseline subscription; late work cannot navigate after disposal.
|
|
80
|
+
*/
|
|
81
|
+
startInitialSelection(): () => void;
|
|
82
|
+
/**
|
|
83
|
+
* The shared New Session action behind the shell entry points (sidebar
|
|
84
|
+
* button, workspace browser): resolve the target Workspace — explicit wins,
|
|
85
|
+
* then the current Session's Workspace, then the recent-Workspace
|
|
86
|
+
* projection — connect its blank session and navigate there; with no
|
|
87
|
+
* Workspace at all, clear the selection into the New Session view state.
|
|
88
|
+
* Connect failures are non-fatal (console diagnostics; the current view
|
|
89
|
+
* stays usable).
|
|
90
|
+
* @param workspaceId - explicit target Workspace for scoped actions.
|
|
91
|
+
*/
|
|
92
|
+
startSession(workspaceId?: WorkspaceId): void;
|
|
93
|
+
/**
|
|
94
|
+
* Register an existing path as a Workspace.
|
|
95
|
+
* @param input - the Host create payload.
|
|
96
|
+
* @returns the created or idempotently resolved Workspace.
|
|
97
|
+
*/
|
|
98
|
+
create(input: {
|
|
99
|
+
path: string;
|
|
100
|
+
}): Promise<WorkspaceView>;
|
|
101
|
+
/**
|
|
102
|
+
* Open the Host's native directory picker (the `native` capability).
|
|
103
|
+
* @returns the selected path, or null when the user cancelled.
|
|
104
|
+
*/
|
|
105
|
+
pickDirectory(): Promise<string | null>;
|
|
106
|
+
/**
|
|
107
|
+
* List one directory level through the Host's `browse` capability.
|
|
108
|
+
* @param path - absolute directory to list; absent lists the Host home directory.
|
|
109
|
+
* @param signal - aborts the wire request (and the Host's scan) when the caller supersedes it.
|
|
110
|
+
* @returns the level's listing with breadcrumb ancestry.
|
|
111
|
+
*/
|
|
112
|
+
listDirectory(path?: string, signal?: AbortSignal): Promise<DirectoryListing>;
|
|
113
|
+
/**
|
|
114
|
+
* Create one child directory through the Host's `browse` capability.
|
|
115
|
+
* @param path - absolute existing parent directory.
|
|
116
|
+
* @param name - single non-blank path segment.
|
|
117
|
+
* @returns the created directory's absolute path.
|
|
118
|
+
*/
|
|
119
|
+
createDirectory(path: string, name: string): Promise<string>;
|
|
120
|
+
/**
|
|
121
|
+
* Open a filesystem path with the Host operating system's default application.
|
|
122
|
+
* @param path - absolute or host-resolvable path.
|
|
123
|
+
*/
|
|
124
|
+
openPath(path: string): Promise<void>;
|
|
125
|
+
/**
|
|
126
|
+
* Rename a Workspace.
|
|
127
|
+
* @param workspaceId - target workspace.
|
|
128
|
+
* @param title - new display title (trimmed non-empty by the Host).
|
|
129
|
+
* @returns the renamed Workspace view.
|
|
130
|
+
*/
|
|
131
|
+
rename(workspaceId: WorkspaceId, title: string): Promise<WorkspaceView>;
|
|
132
|
+
/**
|
|
133
|
+
* Delete one Workspace registration. Sessions, session logs, and the
|
|
134
|
+
* directory remain Host-owned outside this operation.
|
|
135
|
+
* @param workspaceId - target workspace.
|
|
136
|
+
*/
|
|
137
|
+
delete(workspaceId: WorkspaceId): Promise<void>;
|
|
138
|
+
/**
|
|
139
|
+
* Move a Workspace within the durable registry display order.
|
|
140
|
+
* @param workspaceId - Workspace to move.
|
|
141
|
+
* @param beforeWorkspaceId - Anchor workspace; omitted appends.
|
|
142
|
+
*/
|
|
143
|
+
insertBefore(workspaceId: WorkspaceId, beforeWorkspaceId?: WorkspaceId): Promise<void>;
|
|
144
|
+
/**
|
|
145
|
+
* Archive a session into the registry-global set. Clearing an archived
|
|
146
|
+
* current selection is the projection sweep's job (one rule for the local
|
|
147
|
+
* echo and a remote tab's frame alike).
|
|
148
|
+
* @param sessionId - session to archive.
|
|
149
|
+
*/
|
|
150
|
+
archiveSession(sessionId: SessionId): Promise<void>;
|
|
151
|
+
/**
|
|
152
|
+
* Restore a session from the registry-global archive set. Its retained
|
|
153
|
+
* Workspace account makes it reappear under the same Workspace.
|
|
154
|
+
* @param sessionId - session to restore.
|
|
155
|
+
*/
|
|
156
|
+
unarchiveSession(sessionId: SessionId): Promise<void>;
|
|
157
|
+
/**
|
|
158
|
+
* Move a session within its Workspace's manual order (DOM-insertBefore-like).
|
|
159
|
+
* @param workspaceId - owning workspace.
|
|
160
|
+
* @param sessionId - accounted session to move.
|
|
161
|
+
* @param beforeSessionId - accounted anchor to insert before; omitted appends.
|
|
162
|
+
* @returns the updated Workspace view.
|
|
163
|
+
*/
|
|
164
|
+
insertSessionBefore(workspaceId: WorkspaceId, sessionId: SessionId, beforeSessionId?: SessionId): Promise<WorkspaceView>;
|
|
165
|
+
/**
|
|
166
|
+
* Refresh the workspace baseline, reusing an in-flight pull.
|
|
167
|
+
* @returns completion of the current or newly started workspace baseline pull.
|
|
168
|
+
*/
|
|
169
|
+
refresh(): Promise<void>;
|
|
170
|
+
/**
|
|
171
|
+
* Route a Host stream envelope into the Workspace object layer.
|
|
172
|
+
* @param envelope - validated Host stream envelope.
|
|
173
|
+
*/
|
|
174
|
+
handleHostEnvelope(envelope: Parameters<WorkspaceManager['handleHostEnvelope']>[0]): void;
|
|
175
|
+
/** Rebuild the Workspace baseline after connection. */
|
|
176
|
+
handleConnected(): void;
|
|
177
|
+
private project;
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/** React-free Workspace entity with a client-local materialization lifecycle. */
|
|
2
|
+
import type { IApiClient, RpcResult, WorkspaceView } from '@hydraharness/harness-api-remotes/client';
|
|
3
|
+
import type { ObservableSnapshot } from '../contract/store.ts';
|
|
4
|
+
/** Host input retained by a local Workspace until materialization succeeds. */
|
|
5
|
+
export type WorkspaceCreateInput = {
|
|
6
|
+
path: string;
|
|
7
|
+
};
|
|
8
|
+
/** Observable state of a client-local Workspace intent. */
|
|
9
|
+
export interface WorkspaceIntentSnapshot {
|
|
10
|
+
name: string;
|
|
11
|
+
phase: 'ready' | 'creating';
|
|
12
|
+
error?: string;
|
|
13
|
+
}
|
|
14
|
+
/** A Workspace is either a local intent or a materialized Host view. */
|
|
15
|
+
export interface WorkspaceSnapshot {
|
|
16
|
+
view: WorkspaceView | undefined;
|
|
17
|
+
intent: WorkspaceIntentSnapshot | undefined;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Observable Workspace object whose identity survives Host materialization.
|
|
21
|
+
* Local instances retain their create input and failure state; materialized
|
|
22
|
+
* instances expose the latest Host view.
|
|
23
|
+
*/
|
|
24
|
+
export declare class Workspace implements ObservableSnapshot<WorkspaceSnapshot> {
|
|
25
|
+
private readonly api;
|
|
26
|
+
private view;
|
|
27
|
+
private intent;
|
|
28
|
+
private materialization;
|
|
29
|
+
private snapshotCache;
|
|
30
|
+
private readonly notifier;
|
|
31
|
+
/**
|
|
32
|
+
* @param api - shared wire client.
|
|
33
|
+
* @param source - local create input or an existing Host Workspace view.
|
|
34
|
+
*/
|
|
35
|
+
constructor(api: IApiClient, source: WorkspaceCreateInput | WorkspaceView);
|
|
36
|
+
/**
|
|
37
|
+
* Materialize this local Workspace through the Host create API.
|
|
38
|
+
* Re-entry shares the in-flight completion; a materialized instance returns undefined.
|
|
39
|
+
* @returns the Host result, or undefined when this Workspace is already materialized.
|
|
40
|
+
*/
|
|
41
|
+
materialize(): Promise<RpcResult<{
|
|
42
|
+
workspace: WorkspaceView;
|
|
43
|
+
created: boolean;
|
|
44
|
+
}>> | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Adopt a Host view without replacing this Workspace object.
|
|
47
|
+
* An existing materialized identity accepts updates only for the same Workspace id.
|
|
48
|
+
* @param view - latest Host projection.
|
|
49
|
+
*/
|
|
50
|
+
adopt(view: WorkspaceView): void;
|
|
51
|
+
/**
|
|
52
|
+
* Subscribe to Workspace snapshot invalidation.
|
|
53
|
+
* @param listener - snapshot invalidation callback.
|
|
54
|
+
* @returns unsubscribe function.
|
|
55
|
+
*/
|
|
56
|
+
subscribe(listener: () => void): () => void;
|
|
57
|
+
/**
|
|
58
|
+
* Read the cached Workspace snapshot after flushing pending notifications.
|
|
59
|
+
* @returns the cached Workspace snapshot.
|
|
60
|
+
*/
|
|
61
|
+
getSnapshot(): WorkspaceSnapshot;
|
|
62
|
+
private completeMaterialization;
|
|
63
|
+
private buildSnapshot;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=workspace.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-owned invariant companion for `@hydraharness/harness-client-runtime`.
|
|
3
|
+
* @module @hydraharness/harness-client-runtime/invariant
|
|
4
|
+
*/
|
|
5
|
+
import type { Context } from '@hydraharness/cordis';
|
|
6
|
+
/** Cordis companion plugin name. */
|
|
7
|
+
export declare const name = "client-runtime-invariant";
|
|
8
|
+
/** Service required before the companion can register. */
|
|
9
|
+
export declare const inject: string[];
|
|
10
|
+
/**
|
|
11
|
+
* Register this package's invariant companion.
|
|
12
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
13
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
14
|
+
*/
|
|
15
|
+
export declare const apply: (ctx: Context) => Promise<() => void>;
|
|
16
|
+
//# sourceMappingURL=invariant.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,97 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hydraharness/harness-client-runtime",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"description": "Client core services: SlotRegistry, SessionRuntime (scope tree + object layer)",
|
|
4
|
+
"version": "0.1.1-rc.7",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/MaiHongPhong1902/Hydra-Harness.git",
|
|
11
|
+
"directory": "packages/client/runtime"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "lib/index.js",
|
|
15
|
+
"types": "lib/types/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./lib/types/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./invariant": {
|
|
22
|
+
"types": "./lib/types/invariant.d.ts",
|
|
23
|
+
"default": "./lib/invariant.js"
|
|
24
|
+
},
|
|
25
|
+
"./client": {
|
|
26
|
+
"types": "./lib/types/client/index.d.ts",
|
|
27
|
+
"default": "./lib/client.js"
|
|
28
|
+
},
|
|
29
|
+
"./src/*": "./src/*",
|
|
30
|
+
"./package.json": "./package.json"
|
|
31
|
+
},
|
|
32
|
+
"hydra": {
|
|
33
|
+
"plugin": {
|
|
34
|
+
"application": "Keep the interface's session and workspace state synchronized with Host updates."
|
|
35
|
+
},
|
|
36
|
+
"client": {
|
|
37
|
+
"inject": [
|
|
38
|
+
"@hydraharness/harness-client-connection",
|
|
39
|
+
"@hydraharness/harness-typert-registry",
|
|
40
|
+
"@hydraharness/harness-api-remotes"
|
|
41
|
+
],
|
|
42
|
+
"platform": "web",
|
|
43
|
+
"immediately": true
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"immer": "^11.1.18",
|
|
49
|
+
"zustand": "~4.4.7"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"@hydraharness/cordis": "^4.0.2",
|
|
53
|
+
"@hydraharness/harness-api-remotes": "^0.1.1-rc.7",
|
|
54
|
+
"@hydraharness/harness-invariants": "^0.1.1-rc.7",
|
|
55
|
+
"@hydraharness/harness-typert-registry": "^0.1.1-rc.7",
|
|
56
|
+
"@hydraharness/harness-typert-protocol": "^0.1.1-rc.7",
|
|
57
|
+
"@hydraharness/harness-agent": "^0.1.1-rc.7",
|
|
58
|
+
"@hydraharness/harness-attachment": "^0.1.1-rc.7",
|
|
59
|
+
"@hydraharness/harness-client-connection": "^0.1.1-rc.7",
|
|
60
|
+
"@hydraharness/harness-commands": "^0.1.1-rc.7",
|
|
61
|
+
"@hydraharness/harness-llm-retry": "^0.1.1-rc.7",
|
|
62
|
+
"@hydraharness/harness-host-apiproxy": "^0.1.1-rc.7",
|
|
63
|
+
"@hydraharness/harness-llm": "^0.1.1-rc.7",
|
|
64
|
+
"@hydraharness/harness-session": "^0.1.1-rc.7",
|
|
65
|
+
"@hydraharness/harness-session-projection": "^0.1.1-rc.7",
|
|
66
|
+
"@hydraharness/harness-session-title": "^0.1.1-rc.7",
|
|
67
|
+
"@hydraharness/harness-tools": "^0.1.1-rc.7"
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@types/react": "~18.3.1",
|
|
71
|
+
"react": "^18.2.0",
|
|
72
|
+
"@hydraharness/cordis": "^4.0.2",
|
|
73
|
+
"@hydraharness/harness-invariants": "^0.1.1-rc.7",
|
|
74
|
+
"@hydraharness/harness-timeout": "^0.1.1-rc.7",
|
|
75
|
+
"@hydraharness/harness-typert-protocol": "^0.1.1-rc.7",
|
|
76
|
+
"@hydraharness/harness-typert-registry": "^0.1.1-rc.7",
|
|
77
|
+
"@hydraharness/harness-api-remotes": "^0.1.1-rc.7",
|
|
78
|
+
"@hydraharness/harness-client-ui-slots": "^0.1.1-rc.7",
|
|
79
|
+
"@hydraharness/harness-agent": "^0.1.1-rc.7",
|
|
80
|
+
"@hydraharness/harness-attachment": "^0.1.1-rc.7",
|
|
81
|
+
"@hydraharness/harness-client-connection": "^0.1.1-rc.7",
|
|
82
|
+
"@hydraharness/harness-commands": "^0.1.1-rc.7",
|
|
83
|
+
"@hydraharness/harness-llm": "^0.1.1-rc.7",
|
|
84
|
+
"@hydraharness/harness-host-apiproxy": "^0.1.1-rc.7",
|
|
85
|
+
"@hydraharness/harness-session": "^0.1.1-rc.7",
|
|
86
|
+
"@hydraharness/harness-session-projection": "^0.1.1-rc.7",
|
|
87
|
+
"@hydraharness/harness-tools": "^0.1.1-rc.7",
|
|
88
|
+
"@hydraharness/harness-session-title": "^0.1.1-rc.7",
|
|
89
|
+
"@hydraharness/harness-llm-retry": "^0.1.1-rc.7"
|
|
90
|
+
},
|
|
91
|
+
"files": [
|
|
92
|
+
"lib/index.js",
|
|
93
|
+
"lib/invariant.js",
|
|
94
|
+
"lib/client.js",
|
|
95
|
+
"lib/types/**/*.d.ts"
|
|
96
|
+
]
|
|
6
97
|
}
|