@vibesdotdev/agent-execution 0.0.0-stage → 1.0.0-rc.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.
- package/LICENSE +18 -0
- package/README.md +53 -2
- package/dist/code-session/agent-code-session.consumer.descriptor.d.ts +68 -0
- package/dist/code-session/agent-code-session.consumer.descriptor.d.ts.map +1 -0
- package/dist/code-session/agent-code-session.consumer.descriptor.js +31 -0
- package/dist/code-session/agent-code-session.consumer.descriptor.js.map +1 -0
- package/dist/code-session/agent-code-session.consumer.plugin.d.ts +18 -0
- package/dist/code-session/agent-code-session.consumer.plugin.d.ts.map +1 -0
- package/dist/code-session/agent-code-session.consumer.plugin.js +47 -0
- package/dist/code-session/agent-code-session.consumer.plugin.js.map +1 -0
- package/dist/code-session/agent-code-session.descriptor.d.ts +163 -0
- package/dist/code-session/agent-code-session.descriptor.d.ts.map +1 -0
- package/dist/code-session/agent-code-session.descriptor.js +129 -0
- package/dist/code-session/agent-code-session.descriptor.js.map +1 -0
- package/dist/code-session/agent-code-session.impl.consumer.d.ts +224 -0
- package/dist/code-session/agent-code-session.impl.consumer.d.ts.map +1 -0
- package/dist/code-session/agent-code-session.impl.consumer.js +2131 -0
- package/dist/code-session/agent-code-session.impl.consumer.js.map +1 -0
- package/dist/code-session/agent-code-session.kind.d.ts +15 -0
- package/dist/code-session/agent-code-session.kind.d.ts.map +1 -0
- package/dist/code-session/agent-code-session.kind.js +17 -0
- package/dist/code-session/agent-code-session.kind.js.map +1 -0
- package/dist/code-session/agent-code-session.plugin.d.ts +17 -0
- package/dist/code-session/agent-code-session.plugin.d.ts.map +1 -0
- package/dist/code-session/agent-code-session.plugin.js +28 -0
- package/dist/code-session/agent-code-session.plugin.js.map +1 -0
- package/dist/code-session/billing/gates.d.ts +52 -0
- package/dist/code-session/billing/gates.d.ts.map +1 -0
- package/dist/code-session/billing/gates.js +75 -0
- package/dist/code-session/billing/gates.js.map +1 -0
- package/dist/code-session/client/index.d.ts +2 -0
- package/dist/code-session/client/index.d.ts.map +1 -0
- package/dist/code-session/client/index.js +2 -0
- package/dist/code-session/client/index.js.map +1 -0
- package/dist/code-session/client/resolve.d.ts +20 -0
- package/dist/code-session/client/resolve.d.ts.map +1 -0
- package/dist/code-session/client/resolve.js +145 -0
- package/dist/code-session/client/resolve.js.map +1 -0
- package/dist/code-session/docs/agent-code-session.docs.descriptor.d.ts +4 -0
- package/dist/code-session/docs/agent-code-session.docs.descriptor.d.ts.map +1 -0
- package/dist/code-session/docs/agent-code-session.docs.descriptor.js +109 -0
- package/dist/code-session/docs/agent-code-session.docs.descriptor.js.map +1 -0
- package/dist/code-session/git-credential.d.ts +87 -0
- package/dist/code-session/git-credential.d.ts.map +1 -0
- package/dist/code-session/git-credential.js +107 -0
- package/dist/code-session/git-credential.js.map +1 -0
- package/dist/code-session/host-target.d.ts +76 -0
- package/dist/code-session/host-target.d.ts.map +1 -0
- package/dist/code-session/host-target.js +81 -0
- package/dist/code-session/host-target.js.map +1 -0
- package/dist/code-session/index.d.ts +20 -0
- package/dist/code-session/index.d.ts.map +1 -0
- package/dist/code-session/index.js +20 -0
- package/dist/code-session/index.js.map +1 -0
- package/dist/code-session/interfaces/code-session.d.ts +448 -0
- package/dist/code-session/interfaces/code-session.d.ts.map +1 -0
- package/dist/code-session/interfaces/code-session.js +373 -0
- package/dist/code-session/interfaces/code-session.js.map +1 -0
- package/dist/code-session/operation-lease.d.ts +48 -0
- package/dist/code-session/operation-lease.d.ts.map +1 -0
- package/dist/code-session/operation-lease.js +73 -0
- package/dist/code-session/operation-lease.js.map +1 -0
- package/dist/code-session/remote-setup-custody.d.ts +59 -0
- package/dist/code-session/remote-setup-custody.d.ts.map +1 -0
- package/dist/code-session/remote-setup-custody.js +78 -0
- package/dist/code-session/remote-setup-custody.js.map +1 -0
- package/dist/code-session/remote-workspace-fs.d.ts +119 -0
- package/dist/code-session/remote-workspace-fs.d.ts.map +1 -0
- package/dist/code-session/remote-workspace-fs.js +257 -0
- package/dist/code-session/remote-workspace-fs.js.map +1 -0
- package/dist/code-session/session-metadata.d.ts +40 -0
- package/dist/code-session/session-metadata.d.ts.map +1 -0
- package/dist/code-session/session-metadata.js +69 -0
- package/dist/code-session/session-metadata.js.map +1 -0
- package/dist/code-session-relay/agent-code-session-relay.descriptor.d.ts +78 -0
- package/dist/code-session-relay/agent-code-session-relay.descriptor.d.ts.map +1 -0
- package/dist/code-session-relay/agent-code-session-relay.descriptor.js +38 -0
- package/dist/code-session-relay/agent-code-session-relay.descriptor.js.map +1 -0
- package/dist/code-session-relay/agent-code-session-relay.impl.d.ts +120 -0
- package/dist/code-session-relay/agent-code-session-relay.impl.d.ts.map +1 -0
- package/dist/code-session-relay/agent-code-session-relay.impl.js +1392 -0
- package/dist/code-session-relay/agent-code-session-relay.impl.js.map +1 -0
- package/dist/code-session-relay/agent-code-session-relay.plugin.d.ts +14 -0
- package/dist/code-session-relay/agent-code-session-relay.plugin.d.ts.map +1 -0
- package/dist/code-session-relay/agent-code-session-relay.plugin.js +25 -0
- package/dist/code-session-relay/agent-code-session-relay.plugin.js.map +1 -0
- package/dist/code-session-relay/index.d.ts +13 -0
- package/dist/code-session-relay/index.d.ts.map +1 -0
- package/dist/code-session-relay/index.js +13 -0
- package/dist/code-session-relay/index.js.map +1 -0
- package/dist/code-session-relay/relay-dial.d.ts +72 -0
- package/dist/code-session-relay/relay-dial.d.ts.map +1 -0
- package/dist/code-session-relay/relay-dial.js +177 -0
- package/dist/code-session-relay/relay-dial.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/sandbox/agent-sandbox.consumer.descriptor.d.ts +35 -0
- package/dist/sandbox/agent-sandbox.consumer.descriptor.d.ts.map +1 -0
- package/dist/sandbox/agent-sandbox.consumer.descriptor.js +19 -0
- package/dist/sandbox/agent-sandbox.consumer.descriptor.js.map +1 -0
- package/dist/sandbox/agent-sandbox.consumer.plugin.d.ts +9 -0
- package/dist/sandbox/agent-sandbox.consumer.plugin.d.ts.map +1 -0
- package/dist/sandbox/agent-sandbox.consumer.plugin.js +33 -0
- package/dist/sandbox/agent-sandbox.consumer.plugin.js.map +1 -0
- package/dist/sandbox/agent-sandbox.descriptor.d.ts +76 -0
- package/dist/sandbox/agent-sandbox.descriptor.d.ts.map +1 -0
- package/dist/sandbox/agent-sandbox.descriptor.js +57 -0
- package/dist/sandbox/agent-sandbox.descriptor.js.map +1 -0
- package/dist/sandbox/agent-sandbox.impl.consumer.d.ts +15 -0
- package/dist/sandbox/agent-sandbox.impl.consumer.d.ts.map +1 -0
- package/dist/sandbox/agent-sandbox.impl.consumer.js +23 -0
- package/dist/sandbox/agent-sandbox.impl.consumer.js.map +1 -0
- package/dist/sandbox/agent-sandbox.kind.d.ts +14 -0
- package/dist/sandbox/agent-sandbox.kind.d.ts.map +1 -0
- package/dist/sandbox/agent-sandbox.kind.js +16 -0
- package/dist/sandbox/agent-sandbox.kind.js.map +1 -0
- package/dist/sandbox/agent-sandbox.plugin.d.ts +15 -0
- package/dist/sandbox/agent-sandbox.plugin.d.ts.map +1 -0
- package/dist/sandbox/agent-sandbox.plugin.js +25 -0
- package/dist/sandbox/agent-sandbox.plugin.js.map +1 -0
- package/dist/sandbox/client/resolve.d.ts +21 -0
- package/dist/sandbox/client/resolve.d.ts.map +1 -0
- package/dist/sandbox/client/resolve.js +103 -0
- package/dist/sandbox/client/resolve.js.map +1 -0
- package/dist/sandbox/docs/agent-sandbox.docs.descriptor.d.ts +4 -0
- package/dist/sandbox/docs/agent-sandbox.docs.descriptor.d.ts.map +1 -0
- package/dist/sandbox/docs/agent-sandbox.docs.descriptor.js +75 -0
- package/dist/sandbox/docs/agent-sandbox.docs.descriptor.js.map +1 -0
- package/dist/sandbox/index.d.ts +15 -0
- package/dist/sandbox/index.d.ts.map +1 -0
- package/dist/sandbox/index.js +14 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/sandbox/interfaces/sandbox.d.ts +61 -0
- package/dist/sandbox/interfaces/sandbox.d.ts.map +1 -0
- package/dist/sandbox/interfaces/sandbox.js +54 -0
- package/dist/sandbox/interfaces/sandbox.js.map +1 -0
- package/dist/schemas/code-session-resolution.d.ts +20 -0
- package/dist/schemas/code-session-resolution.d.ts.map +1 -0
- package/dist/schemas/code-session-resolution.js +11 -0
- package/dist/schemas/code-session-resolution.js.map +1 -0
- package/dist/schemas/session-operation.d.ts +73 -0
- package/dist/schemas/session-operation.d.ts.map +1 -0
- package/dist/schemas/session-operation.js +47 -0
- package/dist/schemas/session-operation.js.map +1 -0
- package/dist/schemas/voice.d.ts +87 -0
- package/dist/schemas/voice.d.ts.map +1 -0
- package/dist/schemas/voice.js +70 -0
- package/dist/schemas/voice.js.map +1 -0
- package/dist/voice/agent-voice.consumer.descriptor.d.ts +43 -0
- package/dist/voice/agent-voice.consumer.descriptor.d.ts.map +1 -0
- package/dist/voice/agent-voice.consumer.descriptor.js +20 -0
- package/dist/voice/agent-voice.consumer.descriptor.js.map +1 -0
- package/dist/voice/agent-voice.consumer.plugin.d.ts +4 -0
- package/dist/voice/agent-voice.consumer.plugin.d.ts.map +1 -0
- package/dist/voice/agent-voice.consumer.plugin.js +13 -0
- package/dist/voice/agent-voice.consumer.plugin.js.map +1 -0
- package/dist/voice/agent-voice.descriptor.d.ts +82 -0
- package/dist/voice/agent-voice.descriptor.d.ts.map +1 -0
- package/dist/voice/agent-voice.descriptor.js +79 -0
- package/dist/voice/agent-voice.descriptor.js.map +1 -0
- package/dist/voice/agent-voice.impl.consumer.d.ts +35 -0
- package/dist/voice/agent-voice.impl.consumer.d.ts.map +1 -0
- package/dist/voice/agent-voice.impl.consumer.js +50 -0
- package/dist/voice/agent-voice.impl.consumer.js.map +1 -0
- package/dist/voice/agent-voice.kind.d.ts +67 -0
- package/dist/voice/agent-voice.kind.d.ts.map +1 -0
- package/dist/voice/agent-voice.kind.js +26 -0
- package/dist/voice/agent-voice.kind.js.map +1 -0
- package/dist/voice/agent-voice.plugin.d.ts +4 -0
- package/dist/voice/agent-voice.plugin.d.ts.map +1 -0
- package/dist/voice/agent-voice.plugin.js +18 -0
- package/dist/voice/agent-voice.plugin.js.map +1 -0
- package/dist/voice/client.d.ts +38 -0
- package/dist/voice/client.d.ts.map +1 -0
- package/dist/voice/client.js +29 -0
- package/dist/voice/client.js.map +1 -0
- package/dist/voice/index.d.ts +14 -0
- package/dist/voice/index.d.ts.map +1 -0
- package/dist/voice/index.js +14 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/pipeline.d.ts +66 -0
- package/dist/voice/pipeline.d.ts.map +1 -0
- package/dist/voice/pipeline.js +330 -0
- package/dist/voice/pipeline.js.map +1 -0
- package/dist/voice/session.d.ts +29 -0
- package/dist/voice/session.d.ts.map +1 -0
- package/dist/voice/session.js +78 -0
- package/dist/voice/session.js.map +1 -0
- package/package.json +279 -4
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-runtime custody of in-flight remote process setups (consumer code session).
|
|
3
|
+
*
|
|
4
|
+
* A remote spawn is owned from dispatch until its handle is delivered or its
|
|
5
|
+
* cancellation cleanup settles (`acquireWireProcess`). The consumer plugin's
|
|
6
|
+
* `onDispose` drains this custody: it cancels every in-flight setup and refuses
|
|
7
|
+
* new work. It never waits for the remote side (no bounded-wait port exists
|
|
8
|
+
* before RC07, C13) and never deletes an unresolved record: a setup whose cleanup
|
|
9
|
+
* is not confirmed at disposal fails disposal, typed, while its late-result
|
|
10
|
+
* observer stays attached so a late port is still killed once and observed.
|
|
11
|
+
*/
|
|
12
|
+
import { CapabilityError, rootIdentityOf } from '@vibesdotdev/kernel';
|
|
13
|
+
import { BaseRuntimeClient, RuntimeClientDescriptorSchema, tryGetVibesClient } from '@vibesdotdev/kernel/client';
|
|
14
|
+
export class RemoteSetupCustody {
|
|
15
|
+
pending = new Set();
|
|
16
|
+
unresolved = new Set();
|
|
17
|
+
disposed = false;
|
|
18
|
+
/** Refuse new remote work once the owning runtime is disposing. */
|
|
19
|
+
admit() {
|
|
20
|
+
if (this.disposed) {
|
|
21
|
+
throw new CapabilityError('The code session runtime is disposed; no new remote process may start', 'UNAVAILABLE', {
|
|
22
|
+
reason: 'code-session-disposed', retryable: false
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Retain `acquisition` until it is terminal; only confirmed outcomes release it. */
|
|
27
|
+
retain(acquisition) {
|
|
28
|
+
this.admit();
|
|
29
|
+
this.pending.add(acquisition);
|
|
30
|
+
void acquisition.settled.then(({ outcome }) => {
|
|
31
|
+
this.pending.delete(acquisition);
|
|
32
|
+
if (outcome === 'delivered' || outcome === 'exited')
|
|
33
|
+
this.unresolved.delete(acquisition);
|
|
34
|
+
else
|
|
35
|
+
this.unresolved.add(acquisition);
|
|
36
|
+
});
|
|
37
|
+
return acquisition;
|
|
38
|
+
}
|
|
39
|
+
/** Cancel every in-flight setup; fail typed while any cleanup is unconfirmed. */
|
|
40
|
+
dispose() {
|
|
41
|
+
this.disposed = true;
|
|
42
|
+
for (const acquisition of this.pending)
|
|
43
|
+
acquisition.cancel();
|
|
44
|
+
const open = this.pending.size + this.unresolved.size;
|
|
45
|
+
if (open > 0) {
|
|
46
|
+
throw new CapabilityError('Remote process setup cleanup is unconfirmed at disposal', 'UNAVAILABLE', {
|
|
47
|
+
reason: 'code-session-cleanup-unconfirmed', retryable: false, details: { unconfirmed: open }
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export const remoteSetupCustodyDescriptor = RuntimeClientDescriptorSchema.parse({
|
|
53
|
+
id: 'code-session-custody', kind: 'runtime/client', name: 'Code Session Remote Setup Custody'
|
|
54
|
+
});
|
|
55
|
+
/** The kernel owns this client and drains its acquisitions at disposal. */
|
|
56
|
+
export class RemoteSetupCustodyClient extends BaseRuntimeClient {
|
|
57
|
+
custody = new RemoteSetupCustody();
|
|
58
|
+
onDispose() {
|
|
59
|
+
this.custody.dispose();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** Synchronous access after the consumer plugin has activated the client. */
|
|
63
|
+
export function remoteSetupCustody(runtime) {
|
|
64
|
+
if (!rootIdentityOf(runtime)) {
|
|
65
|
+
throw new CapabilityError('Remote setup custody belongs to a runtime the kernel constructed or viewed.', 'INVALID_INPUT', {
|
|
66
|
+
reason: 'code-session-runtime-unidentified', retryable: false
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const client = tryGetVibesClient(remoteSetupCustodyDescriptor.id, runtime);
|
|
70
|
+
if (!client) {
|
|
71
|
+
throw new CapabilityError('The code session runtime custody is unavailable.', 'UNAVAILABLE', {
|
|
72
|
+
reason: 'code-session-disposed', retryable: false
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return client.custody;
|
|
76
|
+
}
|
|
77
|
+
export default RemoteSetupCustodyClient;
|
|
78
|
+
//# sourceMappingURL=remote-setup-custody.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-setup-custody.js","sourceRoot":"","sources":["../../src/code-session/remote-setup-custody.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote workspace filesystem (UNIT-B3 / D-DAEMON-CLIENT).
|
|
3
|
+
*
|
|
4
|
+
* A `{ kind:'host', hostId }` code session lives on a REMOTE fleet host. Its
|
|
5
|
+
* workspace file operations must reach that host's `filesystem/adapter` over the
|
|
6
|
+
* `runtime/rpc` wire (the fleet daemon proxies the kind — see
|
|
7
|
+
* `fleet-daemon/src/daemon-root.ts` `resolveKind`), mirroring A1's `execution()`
|
|
8
|
+
* remote branch.
|
|
9
|
+
*
|
|
10
|
+
* THE PATH-UTILITY SPLIT. `FileSystemAdapterInterface` mixes async I/O (`readFile`,
|
|
11
|
+
* `writeFile`, `list`, …) with SYNCHRONOUS path math (`join`, `dirname`,
|
|
12
|
+
* `normalize`, `resolve`, …). The async surface routes over the wire (each call is
|
|
13
|
+
* an `invoke`), but the sync path utilities CANNOT: an `invoke` is async, so a
|
|
14
|
+
* proxied `join` would return a `Promise`, breaking `resolveInWorkspace`'s
|
|
15
|
+
* synchronous guard. The path math is PURE POSIX string computation, identical on
|
|
16
|
+
* every host, so it runs LOCALLY here (`node:path/posix`) — the workspace paths a
|
|
17
|
+
* fleet host uses are POSIX. Only the async I/O crosses the wire.
|
|
18
|
+
*
|
|
19
|
+
* THE WATCH STREAM (UNIT-A8). `watch(path, callback)` is a LIVE change-callback —
|
|
20
|
+
* it has no inline wire representation, so it rides the rpc `stream` verb, the SAME
|
|
21
|
+
* wire the PTY byte channel uses. `io.watch(path)` opens a host-side watch and
|
|
22
|
+
* returns a handle; the consumer opens its {@link REMOTE_FILESYSTEM_WATCH_CHANNEL}
|
|
23
|
+
* stream, decodes each change event, and invokes the handler; the returned
|
|
24
|
+
* unsubscribe closes the stream, which releases the host watch (fleet-daemon
|
|
25
|
+
* `bindExecutionChannel`). No fs op degrades or throws "unsupported remote".
|
|
26
|
+
*/
|
|
27
|
+
import * as z from 'zod/v4';
|
|
28
|
+
import { type FileEncoding, type FileSystemAdapterDescriptor, type FileSystemAdapterInterface, type FileSystemEntry, type FileSystemStat } from '@vibesdotdev/filesystem';
|
|
29
|
+
import { type FileContentWire, type FileReadWireResult, type FileObservationWireResult, type ConditionalWriteWireResult } from '@vibesdotdev/filesystem/wire';
|
|
30
|
+
/**
|
|
31
|
+
* The ASYNC I/O surface a remote host's `filesystem/adapter` exposes over the
|
|
32
|
+
* fleet wire. Exactly the methods the fleet daemon proxies (path utilities are
|
|
33
|
+
* pure and run consumer-side, so they are NOT part of this wire surface). Matches
|
|
34
|
+
* `FileSystemAdapterInterface`'s async members so the resolved wire proxy satisfies it.
|
|
35
|
+
*/
|
|
36
|
+
export interface RemoteFileSystemIO {
|
|
37
|
+
/** Optional owner metadata; older peers expose only the conservative legacy I/O contract. */
|
|
38
|
+
describe?(): Promise<FileSystemAdapterDescriptor>;
|
|
39
|
+
observeFile?(path: string): Promise<FileObservationWireResult>;
|
|
40
|
+
readFileObserved?(...args: Parameters<NonNullable<FileSystemAdapterInterface['readFileObserved']>>): Promise<FileReadWireResult>;
|
|
41
|
+
readFileVersioned?(...args: Parameters<NonNullable<FileSystemAdapterInterface['readFileVersioned']>>): Promise<FileReadWireResult>;
|
|
42
|
+
writeFileConditional?(path: string, data: number[], options: Parameters<NonNullable<FileSystemAdapterInterface['writeFileConditional']>>[2]): Promise<ConditionalWriteWireResult>;
|
|
43
|
+
exists(path: string): Promise<boolean>;
|
|
44
|
+
stat(path: string): Promise<FileSystemStat>;
|
|
45
|
+
readFile(path: string, encoding?: FileEncoding): Promise<FileContentWire>;
|
|
46
|
+
writeFile(path: string, data: FileContentWire, options?: FileEncoding | {
|
|
47
|
+
encoding?: FileEncoding;
|
|
48
|
+
}): Promise<void>;
|
|
49
|
+
list(path: string): Promise<FileSystemEntry[]>;
|
|
50
|
+
mkdir(path: string, options?: {
|
|
51
|
+
recursive?: boolean;
|
|
52
|
+
}): Promise<void>;
|
|
53
|
+
remove(path: string, options?: {
|
|
54
|
+
recursive?: boolean;
|
|
55
|
+
}): Promise<void>;
|
|
56
|
+
rename(oldPath: string, newPath: string): Promise<void>;
|
|
57
|
+
copy(source: string, destination: string, options?: {
|
|
58
|
+
recursive?: boolean;
|
|
59
|
+
}): Promise<void>;
|
|
60
|
+
glob(pattern: string, options?: {
|
|
61
|
+
cwd?: string;
|
|
62
|
+
absolute?: boolean;
|
|
63
|
+
}): Promise<string[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Open a host-side watch on `path` (UNIT-A8). Returns a stream-capable handle;
|
|
66
|
+
* change events ride its {@link REMOTE_FILESYSTEM_WATCH_CHANNEL} stream (a live
|
|
67
|
+
* callback has no inline wire representation). Distinct from the local
|
|
68
|
+
* `watch(path, callback)`: the callback is reconstructed consumer-side.
|
|
69
|
+
*/
|
|
70
|
+
watch(path: string): Promise<RemoteWatchHandle>;
|
|
71
|
+
}
|
|
72
|
+
/** Read a remote runtime result exactly once and translate hostile proxy reads to the host refusal. */
|
|
73
|
+
export declare function parseRemoteFileSystemIO<TInput>(value: TInput, hostId: string): RemoteFileSystemIO;
|
|
74
|
+
/**
|
|
75
|
+
* The stream channel a proxied `filesystem/adapter` watch's change events ride.
|
|
76
|
+
* MUST match the daemon-side `WATCH_CHANNEL` (fleet-daemon `execution-listen-policy.ts`);
|
|
77
|
+
* the two packages are wire-independent, so they agree by convention — exactly as
|
|
78
|
+
* {@link REMOTE_FILESYSTEM_WIRE_METHODS} does with the daemon's I/O surface.
|
|
79
|
+
*/
|
|
80
|
+
export declare const REMOTE_FILESYSTEM_WATCH_CHANNEL = "fs-watch";
|
|
81
|
+
/** One complete filesystem watch event frame carried by the remote stream. */
|
|
82
|
+
export declare const RemoteFileSystemWatchEventSchema: z.ZodObject<{
|
|
83
|
+
eventType: z.ZodString;
|
|
84
|
+
filename: z.ZodString;
|
|
85
|
+
}, z.core.$strict>;
|
|
86
|
+
/** A raw byte stream channel opened on a remote ref (the rpc `stream` verb). */
|
|
87
|
+
interface RemoteStreamChannel {
|
|
88
|
+
onData(handler: (data: Uint8Array) => void): () => void;
|
|
89
|
+
write(data: Uint8Array): void;
|
|
90
|
+
close(): void;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The host-side watch handle `io.watch(path)` resolves to: a stream-capable ref
|
|
94
|
+
* whose {@link REMOTE_FILESYSTEM_WATCH_CHANNEL} carries change events. `close()`
|
|
95
|
+
* releases the host watch; disposing frees the owner-side ref entry.
|
|
96
|
+
*/
|
|
97
|
+
export interface RemoteWatchHandle {
|
|
98
|
+
__openStream(channel: string): Promise<RemoteStreamChannel>;
|
|
99
|
+
close(): Promise<void>;
|
|
100
|
+
[Symbol.dispose]?(): void;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The wire method surface the daemon exposes for a proxied `filesystem/adapter`.
|
|
104
|
+
* Shared so the daemon-side `resolveKind` and this consumer-side wrapper agree on
|
|
105
|
+
* exactly one async contract. Sync path utilities are deliberately absent.
|
|
106
|
+
*/
|
|
107
|
+
export declare const REMOTE_FILESYSTEM_WIRE_METHODS: readonly (keyof RemoteFileSystemIO)[];
|
|
108
|
+
/** Read the selected owner's declared guarantees before constructing its local wire projection. */
|
|
109
|
+
export declare function resolveRemoteWorkspaceFileSystem(io: RemoteFileSystemIO, hostId: string): Promise<FileSystemAdapterInterface>;
|
|
110
|
+
/**
|
|
111
|
+
* Wrap a remote host's `filesystem/adapter` I/O surface as a full
|
|
112
|
+
* {@link FileSystemAdapterInterface}: async I/O delegates to `io` over the wire;
|
|
113
|
+
* path utilities run locally (pure POSIX). `hostId` remains part of the public
|
|
114
|
+
* constructor seam because the binding selects the remote host before handing
|
|
115
|
+
* this wrapper its resolved I/O surface.
|
|
116
|
+
*/
|
|
117
|
+
export declare function createRemoteWorkspaceFileSystem(io: RemoteFileSystemIO, _hostId: string, description?: FileSystemAdapterDescriptor): FileSystemAdapterInterface;
|
|
118
|
+
export {};
|
|
119
|
+
//# sourceMappingURL=remote-workspace-fs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-workspace-fs.d.ts","sourceRoot":"","sources":["../../src/code-session/remote-workspace-fs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote workspace filesystem (UNIT-B3 / D-DAEMON-CLIENT).
|
|
3
|
+
*
|
|
4
|
+
* A `{ kind:'host', hostId }` code session lives on a REMOTE fleet host. Its
|
|
5
|
+
* workspace file operations must reach that host's `filesystem/adapter` over the
|
|
6
|
+
* `runtime/rpc` wire (the fleet daemon proxies the kind — see
|
|
7
|
+
* `fleet-daemon/src/daemon-root.ts` `resolveKind`), mirroring A1's `execution()`
|
|
8
|
+
* remote branch.
|
|
9
|
+
*
|
|
10
|
+
* THE PATH-UTILITY SPLIT. `FileSystemAdapterInterface` mixes async I/O (`readFile`,
|
|
11
|
+
* `writeFile`, `list`, …) with SYNCHRONOUS path math (`join`, `dirname`,
|
|
12
|
+
* `normalize`, `resolve`, …). The async surface routes over the wire (each call is
|
|
13
|
+
* an `invoke`), but the sync path utilities CANNOT: an `invoke` is async, so a
|
|
14
|
+
* proxied `join` would return a `Promise`, breaking `resolveInWorkspace`'s
|
|
15
|
+
* synchronous guard. The path math is PURE POSIX string computation, identical on
|
|
16
|
+
* every host, so it runs LOCALLY here (`node:path/posix`) — the workspace paths a
|
|
17
|
+
* fleet host uses are POSIX. Only the async I/O crosses the wire.
|
|
18
|
+
*
|
|
19
|
+
* THE WATCH STREAM (UNIT-A8). `watch(path, callback)` is a LIVE change-callback —
|
|
20
|
+
* it has no inline wire representation, so it rides the rpc `stream` verb, the SAME
|
|
21
|
+
* wire the PTY byte channel uses. `io.watch(path)` opens a host-side watch and
|
|
22
|
+
* returns a handle; the consumer opens its {@link REMOTE_FILESYSTEM_WATCH_CHANNEL}
|
|
23
|
+
* stream, decodes each change event, and invokes the handler; the returned
|
|
24
|
+
* unsubscribe closes the stream, which releases the host watch (fleet-daemon
|
|
25
|
+
* `bindExecutionChannel`). No fs op degrades or throws "unsupported remote".
|
|
26
|
+
*/
|
|
27
|
+
import * as z from 'zod/v4';
|
|
28
|
+
import { FileSystemAdapterDescriptorSchema, VersionedReadResultSchema, resolve, dirname, basename, join, relative, isAbsolute, normalize, extname } from '@vibesdotdev/filesystem';
|
|
29
|
+
import { encodeFileContent, encodeFileBytes, decodeFileContent, decodeFileRead, decodeFileObservation, decodeConditionalWrite, FileTextWireSchema } from '@vibesdotdev/filesystem/wire';
|
|
30
|
+
import { CapabilityError, CaughtFailureSchema, isCapabilityError, valueFreeFailure } from '@vibesdotdev/kernel';
|
|
31
|
+
const RemoteFileSystemIOContractSchema = z
|
|
32
|
+
.object({
|
|
33
|
+
describe: z.function().optional(),
|
|
34
|
+
observeFile: z.function().optional(),
|
|
35
|
+
readFileObserved: z.function().optional(),
|
|
36
|
+
readFileVersioned: z.function().optional(),
|
|
37
|
+
writeFileConditional: z.function().optional(),
|
|
38
|
+
exists: z.function(),
|
|
39
|
+
stat: z.function(),
|
|
40
|
+
readFile: z.function(),
|
|
41
|
+
writeFile: z.function(),
|
|
42
|
+
list: z.function(),
|
|
43
|
+
mkdir: z.function(),
|
|
44
|
+
remove: z.function(),
|
|
45
|
+
rename: z.function(),
|
|
46
|
+
copy: z.function(),
|
|
47
|
+
glob: z.function(),
|
|
48
|
+
watch: z.function()
|
|
49
|
+
})
|
|
50
|
+
.passthrough();
|
|
51
|
+
/** Admit the exact live proxy object only after its complete wire method surface is present. */
|
|
52
|
+
const RemoteFileSystemIOSchema = z.custom((value) => RemoteFileSystemIOContractSchema.safeParse(value).success);
|
|
53
|
+
/** Read a remote runtime result exactly once and translate hostile proxy reads to the host refusal. */
|
|
54
|
+
export function parseRemoteFileSystemIO(value, hostId) {
|
|
55
|
+
try {
|
|
56
|
+
const parsed = RemoteFileSystemIOSchema.safeParse(value);
|
|
57
|
+
if (!parsed.success) {
|
|
58
|
+
throw new CapabilityError('The remote host exposes no complete workspace filesystem capability.', 'UNAVAILABLE', {
|
|
59
|
+
reason: 'code-session-host-unavailable', retryable: false, details: { hostId }
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return parsed.data;
|
|
63
|
+
}
|
|
64
|
+
catch (caught) {
|
|
65
|
+
const failure = CaughtFailureSchema.parse(caught);
|
|
66
|
+
if (isCapabilityError(failure))
|
|
67
|
+
throw failure;
|
|
68
|
+
throw new CapabilityError('The remote workspace filesystem contract could not be read.', 'UNAVAILABLE', {
|
|
69
|
+
reason: 'code-session-host-unavailable',
|
|
70
|
+
retryable: false,
|
|
71
|
+
details: { hostId },
|
|
72
|
+
cause: valueFreeFailure(failure)
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The stream channel a proxied `filesystem/adapter` watch's change events ride.
|
|
78
|
+
* MUST match the daemon-side `WATCH_CHANNEL` (fleet-daemon `execution-listen-policy.ts`);
|
|
79
|
+
* the two packages are wire-independent, so they agree by convention — exactly as
|
|
80
|
+
* {@link REMOTE_FILESYSTEM_WIRE_METHODS} does with the daemon's I/O surface.
|
|
81
|
+
*/
|
|
82
|
+
export const REMOTE_FILESYSTEM_WATCH_CHANNEL = 'fs-watch';
|
|
83
|
+
/** One complete filesystem watch event frame carried by the remote stream. */
|
|
84
|
+
export const RemoteFileSystemWatchEventSchema = z
|
|
85
|
+
.object({
|
|
86
|
+
eventType: z.string().trim().min(1).max(64),
|
|
87
|
+
filename: z.string().max(4_096)
|
|
88
|
+
})
|
|
89
|
+
.strict();
|
|
90
|
+
function parseRemoteFileSystemWatchEvent(bytes, decoder) {
|
|
91
|
+
try {
|
|
92
|
+
return RemoteFileSystemWatchEventSchema.parse(JSON.parse(decoder.decode(bytes)));
|
|
93
|
+
}
|
|
94
|
+
catch (caught) {
|
|
95
|
+
return new CapabilityError('The remote filesystem watch emitted an invalid frame.', 'INTERNAL', {
|
|
96
|
+
reason: 'code-session-remote-watch-frame-invalid',
|
|
97
|
+
retryable: false,
|
|
98
|
+
cause: valueFreeFailure(CaughtFailureSchema.parse(caught))
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The wire method surface the daemon exposes for a proxied `filesystem/adapter`.
|
|
104
|
+
* Shared so the daemon-side `resolveKind` and this consumer-side wrapper agree on
|
|
105
|
+
* exactly one async contract. Sync path utilities are deliberately absent.
|
|
106
|
+
*/
|
|
107
|
+
export const REMOTE_FILESYSTEM_WIRE_METHODS = [
|
|
108
|
+
'exists',
|
|
109
|
+
'stat',
|
|
110
|
+
'readFile',
|
|
111
|
+
'writeFile',
|
|
112
|
+
'list',
|
|
113
|
+
'mkdir',
|
|
114
|
+
'remove',
|
|
115
|
+
'rename',
|
|
116
|
+
'copy',
|
|
117
|
+
'glob',
|
|
118
|
+
'watch'
|
|
119
|
+
];
|
|
120
|
+
/** The synthetic descriptor for a remote fleet workspace adapter. */
|
|
121
|
+
const REMOTE_DESCRIPTOR = FileSystemAdapterDescriptorSchema.parse({
|
|
122
|
+
id: 'filesystem-adapter-remote',
|
|
123
|
+
kind: 'filesystem/adapter',
|
|
124
|
+
name: 'Remote Fleet Workspace',
|
|
125
|
+
description: 'A fleet-host code-session workspace filesystem reached over the runtime/rpc wire (D-DAEMON-CLIENT). Async I/O crosses the wire; path math runs locally.',
|
|
126
|
+
protocols: ['file', 'directory'],
|
|
127
|
+
hardware: ['fleet-host'],
|
|
128
|
+
capabilities: ['read', 'write', 'list', 'stat', 'move', 'copy', 'glob', 'watch'],
|
|
129
|
+
supportsWatch: true
|
|
130
|
+
});
|
|
131
|
+
/** Read the selected owner's declared guarantees before constructing its local wire projection. */
|
|
132
|
+
export async function resolveRemoteWorkspaceFileSystem(io, hostId) {
|
|
133
|
+
if (!io.describe)
|
|
134
|
+
return createRemoteWorkspaceFileSystem(io, hostId);
|
|
135
|
+
const description = FileSystemAdapterDescriptorSchema.safeParse(await io.describe());
|
|
136
|
+
if (!description.success)
|
|
137
|
+
throw new CapabilityError('The remote filesystem owner returned invalid descriptor metadata.', 'UNAVAILABLE', {
|
|
138
|
+
reason: 'remote-filesystem-descriptor-invalid', retryable: false, details: { hostId },
|
|
139
|
+
cause: valueFreeFailure(description.error)
|
|
140
|
+
});
|
|
141
|
+
return createRemoteWorkspaceFileSystem(io, hostId, description.data);
|
|
142
|
+
}
|
|
143
|
+
function remoteDescriptor(io, description) {
|
|
144
|
+
if (!description)
|
|
145
|
+
return REMOTE_DESCRIPTOR;
|
|
146
|
+
const descriptor = {
|
|
147
|
+
...REMOTE_DESCRIPTOR,
|
|
148
|
+
capabilities: description.capabilities.filter(capability => REMOTE_DESCRIPTOR.capabilities.includes(capability)),
|
|
149
|
+
supportsWatch: description.supportsWatch,
|
|
150
|
+
supportsRecursive: description.supportsRecursive,
|
|
151
|
+
persistent: description.persistent
|
|
152
|
+
};
|
|
153
|
+
if (description.capabilities.includes('file-observation') && io.observeFile && io.readFileObserved) {
|
|
154
|
+
descriptor.capabilities.push('file-observation');
|
|
155
|
+
}
|
|
156
|
+
if (description.versionedFile && io.readFileVersioned) {
|
|
157
|
+
descriptor.capabilities.push('versioned-file');
|
|
158
|
+
descriptor.versionedFile = {
|
|
159
|
+
revisionScheme: description.versionedFile.revisionScheme,
|
|
160
|
+
revisionScope: description.versionedFile.revisionScope
|
|
161
|
+
};
|
|
162
|
+
if (io.writeFileConditional && description.versionedFile.conditionalWrite) {
|
|
163
|
+
descriptor.versionedFile.conditionalWrite = description.versionedFile.conditionalWrite;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return FileSystemAdapterDescriptorSchema.parse(descriptor);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Wrap a remote host's `filesystem/adapter` I/O surface as a full
|
|
170
|
+
* {@link FileSystemAdapterInterface}: async I/O delegates to `io` over the wire;
|
|
171
|
+
* path utilities run locally (pure POSIX). `hostId` remains part of the public
|
|
172
|
+
* constructor seam because the binding selects the remote host before handing
|
|
173
|
+
* this wrapper its resolved I/O surface.
|
|
174
|
+
*/
|
|
175
|
+
export function createRemoteWorkspaceFileSystem(io, _hostId, description) {
|
|
176
|
+
const observeFile = io.observeFile?.bind(io);
|
|
177
|
+
const readFileObserved = io.readFileObserved?.bind(io);
|
|
178
|
+
const readFileVersioned = io.readFileVersioned?.bind(io);
|
|
179
|
+
const writeFileConditional = io.writeFileConditional?.bind(io);
|
|
180
|
+
const requireBinaryWire = () => {
|
|
181
|
+
if (!io.describe)
|
|
182
|
+
throw new CapabilityError('This filesystem peer has no binary wire codec.', 'UNAVAILABLE', {
|
|
183
|
+
reason: 'remote-filesystem-binary-unavailable', retryable: false
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
return {
|
|
187
|
+
descriptor: remoteDescriptor(io, description),
|
|
188
|
+
// --- async I/O — routed over the fleet wire ---
|
|
189
|
+
exists: (path) => io.exists(path),
|
|
190
|
+
stat: (path) => io.stat(path),
|
|
191
|
+
readFile: async (path, encoding) => {
|
|
192
|
+
const content = await io.readFile(path, encoding);
|
|
193
|
+
if (!FileTextWireSchema.safeParse(content).success)
|
|
194
|
+
requireBinaryWire();
|
|
195
|
+
return decodeFileContent(content);
|
|
196
|
+
},
|
|
197
|
+
observeFile: observeFile ? async (...args) => decodeFileObservation(await observeFile(...args)) : undefined,
|
|
198
|
+
readFileObserved: readFileObserved ? async (...args) => decodeFileRead(await readFileObserved(...args)) : undefined,
|
|
199
|
+
readFileVersioned: readFileVersioned ? async (...args) => VersionedReadResultSchema.parse(decodeFileRead(await readFileVersioned(...args))) : undefined,
|
|
200
|
+
writeFileConditional: writeFileConditional ? async (path, data, options) => {
|
|
201
|
+
requireBinaryWire();
|
|
202
|
+
return decodeConditionalWrite(await writeFileConditional(path, encodeFileBytes(data), options));
|
|
203
|
+
} : undefined,
|
|
204
|
+
writeFile: async (path, data, options) => {
|
|
205
|
+
if (!FileTextWireSchema.safeParse(data).success)
|
|
206
|
+
requireBinaryWire();
|
|
207
|
+
await io.writeFile(path, encodeFileContent(data), options);
|
|
208
|
+
},
|
|
209
|
+
list: (path) => io.list(path),
|
|
210
|
+
mkdir: (path, options) => io.mkdir(path, options),
|
|
211
|
+
remove: (path, options) => io.remove(path, options),
|
|
212
|
+
rename: (oldPath, newPath) => io.rename(oldPath, newPath),
|
|
213
|
+
copy: (source, destination, options) => io.copy(source, destination, options),
|
|
214
|
+
glob: (pattern, options) => io.glob(pattern, options),
|
|
215
|
+
// A live change callback rides the rpc `stream` verb (UNIT-A8): open a
|
|
216
|
+
// host-side watch, subscribe to its change-event stream, and reconstruct the
|
|
217
|
+
// (eventType, filename) callback. The returned unsubscribe closes the stream,
|
|
218
|
+
// which releases the host watch (fleet-daemon bindExecutionChannel).
|
|
219
|
+
watch: async (path, callback) => {
|
|
220
|
+
const handle = await io.watch(path);
|
|
221
|
+
const channel = await handle.__openStream(REMOTE_FILESYSTEM_WATCH_CHANNEL);
|
|
222
|
+
const decoder = new TextDecoder();
|
|
223
|
+
let stopped = false;
|
|
224
|
+
let stopData;
|
|
225
|
+
const stop = () => {
|
|
226
|
+
if (stopped)
|
|
227
|
+
return;
|
|
228
|
+
stopped = true;
|
|
229
|
+
stopData?.();
|
|
230
|
+
channel.close();
|
|
231
|
+
handle[Symbol.dispose]?.();
|
|
232
|
+
};
|
|
233
|
+
stopData = channel.onData((bytes) => {
|
|
234
|
+
if (stopped)
|
|
235
|
+
return;
|
|
236
|
+
const event = parseRemoteFileSystemWatchEvent(bytes, decoder);
|
|
237
|
+
if ('eventType' in event)
|
|
238
|
+
return callback(event.eventType, event.filename);
|
|
239
|
+
// FileSystemWatchCallback is the filesystem contract's failure channel.
|
|
240
|
+
// Close first so even a throwing subscriber cannot leave the remote watch live.
|
|
241
|
+
stop();
|
|
242
|
+
return callback('error', '', event);
|
|
243
|
+
});
|
|
244
|
+
return stop;
|
|
245
|
+
},
|
|
246
|
+
// --- pure POSIX path math — runs LOCALLY (host-independent), never the wire ---
|
|
247
|
+
resolve: (...segments) => resolve(...segments),
|
|
248
|
+
dirname: (path) => dirname(path),
|
|
249
|
+
basename: (path, ext) => basename(path, ext),
|
|
250
|
+
join: (...segments) => join(...segments),
|
|
251
|
+
relative: (from, to) => relative(from, to),
|
|
252
|
+
isAbsolute: (path) => isAbsolute(path),
|
|
253
|
+
normalize: (path) => normalize(path),
|
|
254
|
+
extname: (path) => extname(path)
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=remote-workspace-fs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-workspace-fs.js","sourceRoot":"","sources":["../../src/code-session/remote-workspace-fs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as z from 'zod/v4';
|
|
2
|
+
export declare const CODE_SESSION_METADATA_FILENAME = ".vibes-code-session.json";
|
|
3
|
+
export declare const PersistedCodeSessionMetadataSchema: z.ZodObject<{
|
|
4
|
+
sessionId: z.ZodString;
|
|
5
|
+
operationId: z.ZodOptional<z.ZodString>;
|
|
6
|
+
operationFingerprint: z.ZodOptional<z.ZodString>;
|
|
7
|
+
workspacePath: z.ZodOptional<z.ZodString>;
|
|
8
|
+
workspaceOwnership: z.ZodOptional<z.ZodEnum<{
|
|
9
|
+
owned: "owned";
|
|
10
|
+
borrowed: "borrowed";
|
|
11
|
+
}>>;
|
|
12
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
13
|
+
hostTarget: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
14
|
+
kind: z.ZodLiteral<"cloud">;
|
|
15
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
16
|
+
kind: z.ZodLiteral<"host">;
|
|
17
|
+
hostId: z.ZodString;
|
|
18
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
19
|
+
kind: z.ZodLiteral<"provisioned">;
|
|
20
|
+
adapter: z.ZodString;
|
|
21
|
+
region: z.ZodOptional<z.ZodString>;
|
|
22
|
+
size: z.ZodOptional<z.ZodString>;
|
|
23
|
+
image: z.ZodOptional<z.ZodString>;
|
|
24
|
+
repo: z.ZodOptional<z.ZodString>;
|
|
25
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
26
|
+
ttlHours: z.ZodOptional<z.ZodNumber>;
|
|
27
|
+
providerConfig: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
28
|
+
}, z.core.$strip>], "kind">;
|
|
29
|
+
repositoryId: z.ZodOptional<z.ZodString>;
|
|
30
|
+
cloneUrl: z.ZodOptional<z.ZodString>;
|
|
31
|
+
ephemeral: z.ZodOptional<z.ZodBoolean>;
|
|
32
|
+
checkoutRef: z.ZodOptional<z.ZodString>;
|
|
33
|
+
exposedPorts: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
34
|
+
previewUrl: z.ZodOptional<z.ZodString>;
|
|
35
|
+
pausedAt: z.ZodOptional<z.ZodString>;
|
|
36
|
+
}, z.core.$strip>;
|
|
37
|
+
export type PersistedCodeSessionMetadata = z.infer<typeof PersistedCodeSessionMetadataSchema>;
|
|
38
|
+
export declare function serializeCodeSessionMetadata(metadata: PersistedCodeSessionMetadata): string;
|
|
39
|
+
export declare function parseCodeSessionMetadata(value: string | null | undefined): PersistedCodeSessionMetadata | null;
|
|
40
|
+
//# sourceMappingURL=session-metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-metadata.d.ts","sourceRoot":"","sources":["../../src/code-session/session-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAK5B,eAAO,MAAM,8BAA8B,6BAA6B,CAAC;AAEzE,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0B7C,CAAC;AAEH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAU9F,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,4BAA4B,GAAG,MAAM,CAI3F;AAED,wBAAgB,wBAAwB,CACvC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC9B,4BAA4B,GAAG,IAAI,CAkBrC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import * as z from 'zod/v4';
|
|
2
|
+
import { CapabilityError, CaughtFailureSchema, valueFreeFailure } from '@vibesdotdev/kernel';
|
|
3
|
+
import { JsonValueSchema } from '@vibesdotdev/kernel/schemas/json';
|
|
4
|
+
import { SessionHostTargetSchema } from "./host-target.js";
|
|
5
|
+
export const CODE_SESSION_METADATA_FILENAME = '.vibes-code-session.json';
|
|
6
|
+
export const PersistedCodeSessionMetadataSchema = z.object({
|
|
7
|
+
sessionId: z.string().trim().min(1),
|
|
8
|
+
/** Stable create operation that owns this allocation, when supplied. */
|
|
9
|
+
operationId: z.string().trim().min(1).optional(),
|
|
10
|
+
/** Hash of the immutable, non-secret initialization configuration. */
|
|
11
|
+
operationFingerprint: z.string().trim().min(1).optional(),
|
|
12
|
+
/** Managed location for borrowed workspaces; owned sessions infer this from their session root. */
|
|
13
|
+
workspacePath: z.string().trim().min(1).optional(),
|
|
14
|
+
workspaceOwnership: z.enum(['owned', 'borrowed']).optional(),
|
|
15
|
+
createdAt: z.string().trim().min(1).optional(),
|
|
16
|
+
hostTarget: SessionHostTargetSchema,
|
|
17
|
+
repositoryId: z.string().optional(),
|
|
18
|
+
cloneUrl: z.string().optional(),
|
|
19
|
+
ephemeral: z.boolean().optional(),
|
|
20
|
+
checkoutRef: z.string().optional(),
|
|
21
|
+
exposedPorts: z.array(z.string()).optional(),
|
|
22
|
+
previewUrl: z.string().optional(),
|
|
23
|
+
/** ISO time the session was paused; absent when running. */
|
|
24
|
+
pausedAt: z.string().optional()
|
|
25
|
+
}).superRefine((metadata, context) => {
|
|
26
|
+
if ((metadata.operationId === undefined) === (metadata.operationFingerprint === undefined))
|
|
27
|
+
return;
|
|
28
|
+
context.addIssue({
|
|
29
|
+
code: 'custom',
|
|
30
|
+
message: 'operationId and operationFingerprint must be present together',
|
|
31
|
+
path: ['operationId']
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
function metadataInvalid(failureClass) {
|
|
35
|
+
return new CapabilityError('Code-session metadata is invalid.', 'INVALID_INPUT', {
|
|
36
|
+
reason: 'code-session-metadata-invalid',
|
|
37
|
+
retryable: false,
|
|
38
|
+
details: { failureClass }
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
export function serializeCodeSessionMetadata(metadata) {
|
|
42
|
+
const parsed = PersistedCodeSessionMetadataSchema.safeParse(metadata);
|
|
43
|
+
if (!parsed.success)
|
|
44
|
+
throw metadataInvalid('ZodError');
|
|
45
|
+
return JSON.stringify(parsed.data, null, 2);
|
|
46
|
+
}
|
|
47
|
+
export function parseCodeSessionMetadata(value) {
|
|
48
|
+
if (value === null || value === undefined)
|
|
49
|
+
return null;
|
|
50
|
+
let raw;
|
|
51
|
+
try {
|
|
52
|
+
raw = JsonValueSchema.parse(JSON.parse(value));
|
|
53
|
+
}
|
|
54
|
+
catch (caught) {
|
|
55
|
+
const failure = CaughtFailureSchema.parse(caught);
|
|
56
|
+
const facts = valueFreeFailure(failure);
|
|
57
|
+
throw new CapabilityError('Code-session metadata is not valid JSON.', 'INVALID_INPUT', {
|
|
58
|
+
reason: 'code-session-metadata-invalid',
|
|
59
|
+
retryable: false,
|
|
60
|
+
details: { failureClass: facts.name },
|
|
61
|
+
cause: facts
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
const parsed = PersistedCodeSessionMetadataSchema.safeParse(raw);
|
|
65
|
+
if (!parsed.success)
|
|
66
|
+
throw metadataInvalid('ZodError');
|
|
67
|
+
return parsed.data;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=session-metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-metadata.js","sourceRoot":"","sources":["../../src/code-session/session-metadata.ts"],"names":[],"mappings":"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"}
|