@relayfile/sdk 0.8.10 → 0.8.12
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/dist/client.d.ts +6 -1
- package/dist/client.js +20 -1
- package/dist/index.d.ts +2 -2
- package/dist/mount-launcher.js +33 -4
- package/dist/setup-types.d.ts +8 -0
- package/dist/setup.js +32 -1
- package/dist/types.d.ts +46 -0
- package/package.json +2 -2
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AdminIngressStatusResponse, type AdminSyncStatusResponse, type BulkWriteInput, type BulkWriteResponse, type BackendStatusResponse, type AckResponse, type CommitForkInput, type CommitForkResponse, type CreateForkInput, type DeleteFileInput, type DeadLetterItem, type DeadLetterFeedResponse, type DiscardForkInput, type EventFeedResponse, type ExportJsonResponse, type ExportOptions, type FileQueryResponse, type FileReadResponse, type FilesystemEvent, type GetEventsOptions, type GetAdminIngressStatusOptions, type GetAdminSyncStatusOptions, type GetOperationsOptions, type GetSyncDeadLettersOptions, type GetSyncIngressStatusOptions, type GetSyncStatusOptions, type ListTreeOptions, type OperationFeedResponse, type OperationStatusResponse, type QueuedResponse, type ResourceAtEventResult, type ReadFileInput, type QueryFilesOptions, type Subscription, type SyncIngressStatusResponse, type SyncStatusResponse, type TreeResponse, type WriteFileInput, type WriteQueuedResponse, type IngestWebhookInput, type WritebackItem, type AckWritebackInput, type AckWritebackResponse, type ChangeEvent, type ChangeLogQueryResult, type ChangeStreamConnection, type ChangeStreamConnectionOptions, type SubscribeOptions } from "./types.js";
|
|
1
|
+
import { type AdminIngressStatusResponse, type AdminSyncStatusResponse, type BulkWriteInput, type BulkWriteResponse, type BackendStatusResponse, type AckResponse, type CommitForkInput, type CommitForkResponse, type CreateForkInput, type DeleteFileInput, type DeadLetterItem, type DeadLetterFeedResponse, type DiscardForkInput, type EventFeedResponse, type ExportJsonResponse, type ExportOptions, type FileQueryResponse, type FileReadResponse, type FilesystemEvent, type GetEventsOptions, type GetAdminIngressStatusOptions, type GetAdminSyncStatusOptions, type GetOperationsOptions, type GetSyncDeadLettersOptions, type GetSyncIngressStatusOptions, type GetSyncStatusOptions, type ListTreeOptions, type OperationFeedResponse, type OperationStatusResponse, type QueuedResponse, type ResourceAtEventResult, type ReadFileInput, type QueryFilesOptions, type Subscription, type SyncIngressStatusResponse, type SyncStatusResponse, type TreeResponse, type WriteFileInput, type WriteQueuedResponse, type IngestWebhookInput, type WritebackItem, type AckWritebackInput, type AckWritebackResponse, type SweepWritebackDraftsInput, type SweepWritebackDraftsResponse, type ChangeEvent, type ChangeLogQueryResult, type ChangeStreamConnection, type ChangeStreamConnectionOptions, type SubscribeOptions } from "./types.js";
|
|
2
2
|
import type { ForkHandle } from "@relayfile/core";
|
|
3
3
|
/**
|
|
4
4
|
* Bearer token or token factory used for Relayfile API requests.
|
|
@@ -127,6 +127,11 @@ export declare class RelayFileClient {
|
|
|
127
127
|
ingestWebhook(input: IngestWebhookInput): Promise<QueuedResponse>;
|
|
128
128
|
listPendingWritebacks(workspaceId: string, correlationId?: string, signal?: AbortSignal): Promise<WritebackItem[]>;
|
|
129
129
|
ackWriteback(input: AckWritebackInput): Promise<AckWritebackResponse>;
|
|
130
|
+
/**
|
|
131
|
+
* One-time residue sweep for accumulated writeback drafts (issue #242).
|
|
132
|
+
* Dry run unless `apply` is true; classification-exempt service-side.
|
|
133
|
+
*/
|
|
134
|
+
sweepWritebackDrafts(input: SweepWritebackDraftsInput): Promise<SweepWritebackDraftsResponse>;
|
|
130
135
|
private cacheWireChangeEvent;
|
|
131
136
|
private primeReplayCache;
|
|
132
137
|
private resolveWorkspaceId;
|
package/dist/client.js
CHANGED
|
@@ -1523,7 +1523,26 @@ export class RelayFileClient {
|
|
|
1523
1523
|
correlationId: input.correlationId,
|
|
1524
1524
|
body: {
|
|
1525
1525
|
success: input.success,
|
|
1526
|
-
error: input.error
|
|
1526
|
+
error: input.error,
|
|
1527
|
+
externalId: input.externalId,
|
|
1528
|
+
canonicalPath: input.canonicalPath
|
|
1529
|
+
},
|
|
1530
|
+
signal: input.signal
|
|
1531
|
+
});
|
|
1532
|
+
}
|
|
1533
|
+
/**
|
|
1534
|
+
* One-time residue sweep for accumulated writeback drafts (issue #242).
|
|
1535
|
+
* Dry run unless `apply` is true; classification-exempt service-side.
|
|
1536
|
+
*/
|
|
1537
|
+
async sweepWritebackDrafts(input) {
|
|
1538
|
+
return this.request({
|
|
1539
|
+
method: "POST",
|
|
1540
|
+
path: `/v1/workspaces/${encodeURIComponent(input.workspaceId)}/writeback/sweep-drafts`,
|
|
1541
|
+
correlationId: input.correlationId,
|
|
1542
|
+
body: {
|
|
1543
|
+
pathPrefix: input.pathPrefix,
|
|
1544
|
+
patterns: input.patterns,
|
|
1545
|
+
apply: input.apply === true
|
|
1527
1546
|
},
|
|
1528
1547
|
signal: input.signal
|
|
1529
1548
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -2,14 +2,14 @@ export { RelayFileClient, DEFAULT_RELAYFILE_BASE_URL, type AccessTokenProvider,
|
|
|
2
2
|
export { RelayfileSetup, RELAYFILE_SDK_VERSION, WorkspaceHandle } from "./setup.js";
|
|
3
3
|
export { type RelayfileCloudLoginOptions, type RelayfileCloudTokenSet, type RelayfileCloudTokenSetupOptions } from "./cloud-login.js";
|
|
4
4
|
export { CloudAbortError, CloudApiError, CloudTimeoutError, InvalidLocalDirError, InvalidMountModeError, InvalidRemotePathError, IntegrationConnectionTimeoutError, MalformedCloudResponseError, MissingConnectionIdError, MountModeUnavailableError, MountReadyTimeoutError, MountSessionInputError, ProviderNotConnectedError, ProviderNotReadyError, RelayfileSetupError, UnknownProviderError } from "./setup-errors.js";
|
|
5
|
-
export { type EnsureMountedWorkspaceInput, WORKSPACE_INTEGRATION_PROVIDERS, type AgentWorkspaceInvite, type AgentWorkspaceInviteOptions, type AgentWorkspaceScopedInviteOptions, type ConnectIntegrationOptions, type ConnectIntegrationResult, type CreateWorkspaceOptions, type JoinWorkspaceOptions, type MountLauncher, type MountLauncherEvent, type MountLauncherInstance, type MountLauncherStart, type MountMode, type MountSessionRequest, type MountSessionResponse, type MountSessionResult, type MountedWorkspaceHandle, type MountedWorkspaceStatus, type MountWorkspaceInput, type ReadMountedWorkspaceStatusInput, type RelayfileSetupOptions, type RelayfileSetupRetryOptions, type WaitForConnectionOptions, type WorkspaceInfo, type WorkspaceIntegrationProvider, type WorkspaceMountEnv, type WorkspaceMountEnvOptions, type WorkspacePermissions } from "./setup-types.js";
|
|
5
|
+
export { type EnsureMountedWorkspaceInput, WORKSPACE_INTEGRATION_PROVIDERS, type AgentWorkspaceInvite, type AgentWorkspaceInviteOptions, type AgentWorkspaceScopedInviteOptions, type ConnectIntegrationOptions, type ConnectIntegrationResult, type CreateWorkspaceOptions, type JoinWorkspaceOptions, type MountLauncher, type MountLauncherEvent, type MountLauncherInstance, type MountLauncherStart, type MountLocalLayout, type MountMode, type MountSessionRequest, type MountSessionResponse, type MountSessionResult, type MountSyncMode, type MountedWorkspaceHandle, type MountedWorkspaceStatus, type MountWorkspaceInput, type ReadMountedWorkspaceStatusInput, type RelayfileSetupOptions, type RelayfileSetupRetryOptions, type WaitForConnectionOptions, type WorkspaceInfo, type WorkspaceIntegrationProvider, type WorkspaceMountEnv, type WorkspaceMountEnvOptions, type WorkspacePermissions } from "./setup-types.js";
|
|
6
6
|
export { RelayFileSync, type RelayFileSyncOptions, type RelayFileSyncPong, type RelayFileSyncReconnectOptions, type RelayFileSyncSocket, type RelayFileSyncStart, type RelayFileSyncState, type RelayFileSyncTokenProvider } from "./sync.js";
|
|
7
7
|
export { onWrite, pathMatches, type OnWriteClient, type OnWriteHandler, type OnWriteHandlerError, type OnWriteOptions } from "./onWrite.js";
|
|
8
8
|
export { InvalidStateError, PayloadTooLargeError, QueueFullError, RelayFileApiError, RevisionConflictError } from "./errors.js";
|
|
9
9
|
export { IntegrationProvider, computeCanonicalPath } from "./provider.js";
|
|
10
10
|
export type { WebhookInput, ListProviderFilesOptions, WatchProviderEventsOptions } from "./provider.js";
|
|
11
11
|
export type { ConnectionProvider, NormalizedWebhook, ProxyHeaders, ProxyMethod, ProxyQuery, ProxyRequest, ProxyResponse, } from "./connection.js";
|
|
12
|
-
export type { AckResponse, AckWritebackInput, AckWritebackResponse, AdminIngressAlert, AdminIngressAlertProfile, AdminIngressEffectiveAlertProfile, AdminIngressAlertSeverity, AdminIngressAlertThresholds, AdminIngressAlertTotals, AdminIngressAlertType, AdminIngressStatusResponse, AdminSyncAlert, AdminSyncAlertSeverity, AdminSyncAlertThresholds, AdminSyncAlertTotals, AdminSyncAlertType, AdminSyncStatusResponse, BackendStatusResponse, BulkWriteFile, BulkWriteInput, BulkWriteResponse, ChangeLogQueryResult, ChangeEvent, ChangeEventActor, ChangeEventResource, ChangeEventSummary, ChangeStreamConnection, ChangeStreamConnectionOptions, CommitForkInput, CommitForkResponse, ConflictErrorResponse, CreateForkInput, ContentIdentity, DeleteFileInput, DeadLetterFeedResponse, DeadLetterItem, DigestBullet, DigestContext, DigestHandler, DigestSection, DigestWindow, DiscardForkInput, ErrorResponse, EventSummary, EventFeedResponse, ExportFormat, ExportJsonResponse, ExportOptions, FileQueryItem, FileQueryResponse, FileReadResponse, FileSemantics, FileWriteRequest, FilesystemEvent, FilesystemEventType, EventOrigin, Expansion, ExpansionLevel, GetEventsOptions, GetAdminSyncStatusOptions, GetAdminIngressStatusOptions, GetOperationsOptions, GetSyncDeadLettersOptions, GetSyncIngressStatusOptions, GetSyncStatusOptions, IngestWebhookInput, LayoutManifest, LayoutManifestAlias, LayoutManifestResource, ListTreeOptions, OperationFeedResponse, OperationStatus, OperationStatusResponse, QueuedResponse, QueryFilesOptions, ReadFileInput, ReplayOptions, ResourceAtEventResult, SummaryExpansion, FullExpansion, DiffExpansion, ThreadExpansion, RelayFileJwtClaims, SubscribeOptions, Subscription, SyncIngressStatusResponse, SyncProviderStatus, SyncProviderStatusState, SyncRefreshRequest, SyncStatusResponse, TreeEntry, TreeResponse, WritebackActionType, WritebackDeadLetterError, WritebackDeadLetterErrorCode, WritebackListState, WritebackState, WritebackItem, WritebackItemDetail, WritebackSchemaRef, WriteFileInput, WriteQueuedResponse } from "./types.js";
|
|
12
|
+
export type { AckResponse, AckWritebackInput, AckWritebackDraftDisposition, AckWritebackResponse, AdminIngressAlert, AdminIngressAlertProfile, AdminIngressEffectiveAlertProfile, AdminIngressAlertSeverity, AdminIngressAlertThresholds, AdminIngressAlertTotals, AdminIngressAlertType, AdminIngressStatusResponse, AdminSyncAlert, AdminSyncAlertSeverity, AdminSyncAlertThresholds, AdminSyncAlertTotals, AdminSyncAlertType, AdminSyncStatusResponse, BackendStatusResponse, BulkWriteFile, BulkWriteInput, BulkWriteResponse, ChangeLogQueryResult, ChangeEvent, ChangeEventActor, ChangeEventResource, ChangeEventSummary, ChangeStreamConnection, ChangeStreamConnectionOptions, CommitForkInput, CommitForkResponse, ConflictErrorResponse, CreateForkInput, ContentIdentity, DeleteFileInput, DeadLetterFeedResponse, DeadLetterItem, DigestBullet, DigestContext, DigestHandler, DigestSection, DigestWindow, DiscardForkInput, ErrorResponse, EventSummary, EventFeedResponse, ExportFormat, ExportJsonResponse, ExportOptions, FileQueryItem, FileQueryResponse, FileReadResponse, FileSemantics, FileWriteRequest, FilesystemEvent, FilesystemEventType, EventOrigin, Expansion, ExpansionLevel, GetEventsOptions, GetAdminSyncStatusOptions, GetAdminIngressStatusOptions, GetOperationsOptions, GetSyncDeadLettersOptions, GetSyncIngressStatusOptions, GetSyncStatusOptions, IngestWebhookInput, LayoutManifest, LayoutManifestAlias, LayoutManifestResource, ListTreeOptions, OperationFeedResponse, OperationStatus, OperationStatusResponse, QueuedResponse, QueryFilesOptions, ReadFileInput, ReplayOptions, ResourceAtEventResult, SummaryExpansion, FullExpansion, DiffExpansion, ThreadExpansion, RelayFileJwtClaims, SubscribeOptions, Subscription, SyncIngressStatusResponse, SyncProviderStatus, SyncProviderStatusState, SyncRefreshRequest, SyncStatusResponse, SweepWritebackDraftsInput, SweepWritebackDraftsResponse, TreeEntry, TreeResponse, WritebackActionType, WritebackDeadLetterError, WritebackDeadLetterErrorCode, WritebackListState, WritebackState, WritebackItem, WritebackItemDetail, WritebackSchemaRef, WriteFileInput, WriteQueuedResponse } from "./types.js";
|
|
13
13
|
export type { ForkHandle, ForkOptions } from "@relayfile/core";
|
|
14
14
|
export type { WriteEvent, WriteEventActor, WriteEventOperation, WriteEventSource } from "@relayfile/core";
|
|
15
15
|
export { WritebackConsumer } from "./writeback-consumer.js";
|
package/dist/mount-launcher.js
CHANGED
|
@@ -20,7 +20,7 @@ export function createDefaultMountLauncher(options = {}) {
|
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
export async function readMountedWorkspaceStatus(input) {
|
|
23
|
-
const state = await readMountStateFile(input.localDir);
|
|
23
|
+
const state = await readMountStateFile(resolveMountLocalDir(input.localDir, input.remotePath, input.localLayout));
|
|
24
24
|
if (state && !isMountStateStale(state)) {
|
|
25
25
|
return {
|
|
26
26
|
ready: isMountStateReady(state),
|
|
@@ -46,7 +46,8 @@ export async function readMountedWorkspaceStatus(input) {
|
|
|
46
46
|
}
|
|
47
47
|
async function startRelayfileMount(input, options) {
|
|
48
48
|
const localDir = path.resolve(input.env.RELAYFILE_LOCAL_DIR ?? process.cwd());
|
|
49
|
-
const
|
|
49
|
+
const mountLocalDir = resolveMountLocalDir(localDir, input.env.RELAYFILE_REMOTE_PATH, input.env.RELAYFILE_MOUNT_LOCAL_LAYOUT);
|
|
50
|
+
const relayDir = path.join(mountLocalDir, ".relay");
|
|
50
51
|
const logPath = path.join(relayDir, "mount.log");
|
|
51
52
|
const pidPath = path.join(relayDir, "mount.pid");
|
|
52
53
|
await mkdir(relayDir, { recursive: true });
|
|
@@ -54,7 +55,7 @@ async function startRelayfileMount(input, options) {
|
|
|
54
55
|
const command = await resolveRelayfileMountCommand();
|
|
55
56
|
const args = input.background === false ? ["--once"] : [];
|
|
56
57
|
const child = (options.spawnImpl ?? spawn)(command, args, {
|
|
57
|
-
cwd: input.cwd ??
|
|
58
|
+
cwd: input.cwd ?? mountLocalDir,
|
|
58
59
|
env: {
|
|
59
60
|
...process.env,
|
|
60
61
|
...input.env
|
|
@@ -73,7 +74,7 @@ async function startRelayfileMount(input, options) {
|
|
|
73
74
|
pidPath,
|
|
74
75
|
outputBuffer,
|
|
75
76
|
input,
|
|
76
|
-
localDir,
|
|
77
|
+
localDir: mountLocalDir,
|
|
77
78
|
now: options.now ?? Date.now,
|
|
78
79
|
readyPollIntervalMs: options.readyPollIntervalMs ?? DEFAULT_READY_POLL_INTERVAL_MS
|
|
79
80
|
});
|
|
@@ -113,6 +114,8 @@ class RelayfileMountProcessInstance {
|
|
|
113
114
|
workspaceId: this.input.env.RELAYFILE_WORKSPACE ?? "",
|
|
114
115
|
remotePath: this.input.env.RELAYFILE_REMOTE_PATH ?? "/",
|
|
115
116
|
mode: normalizeMountMode(this.input.env.RELAYFILE_MOUNT_MODE) ?? "poll",
|
|
117
|
+
localLayout: normalizeMountLocalLayout(this.input.env.RELAYFILE_MOUNT_LOCAL_LAYOUT),
|
|
118
|
+
syncMode: normalizeMountSyncMode(this.input.env.RELAYFILE_MOUNT_SYNC_MODE),
|
|
116
119
|
relayfileBaseUrl: this.input.env.RELAYFILE_BASE_URL ?? "",
|
|
117
120
|
relayfileToken: this.input.env.RELAYFILE_TOKEN ?? "",
|
|
118
121
|
expiresAt: null,
|
|
@@ -251,6 +254,32 @@ function isMountStateStale(state) {
|
|
|
251
254
|
function normalizeMountMode(mode) {
|
|
252
255
|
return mode === "fuse" ? "fuse" : mode === "poll" ? "poll" : undefined;
|
|
253
256
|
}
|
|
257
|
+
function normalizeMountLocalLayout(layout) {
|
|
258
|
+
return layout === "scoped" ? "scoped" : "exact";
|
|
259
|
+
}
|
|
260
|
+
function normalizeMountSyncMode(mode) {
|
|
261
|
+
return mode === "write-only" ? "write-only" : "mirror";
|
|
262
|
+
}
|
|
263
|
+
function resolveMountLocalDir(localDir, remotePath, localLayout) {
|
|
264
|
+
const root = path.resolve(localDir);
|
|
265
|
+
if (normalizeMountLocalLayout(localLayout) !== "scoped") {
|
|
266
|
+
return root;
|
|
267
|
+
}
|
|
268
|
+
const normalizedRemote = normalizeRemotePath(remotePath);
|
|
269
|
+
if (normalizedRemote === "/") {
|
|
270
|
+
return root;
|
|
271
|
+
}
|
|
272
|
+
return path.join(root, ...normalizedRemote.split("/").filter(Boolean));
|
|
273
|
+
}
|
|
274
|
+
function normalizeRemotePath(remotePath) {
|
|
275
|
+
const trimmed = typeof remotePath === "string" ? remotePath.trim() : "";
|
|
276
|
+
if (!trimmed || trimmed === "/") {
|
|
277
|
+
return "/";
|
|
278
|
+
}
|
|
279
|
+
const slashNormalized = trimmed.replace(/\\/g, "/");
|
|
280
|
+
const normalized = path.posix.normalize(slashNormalized.startsWith("/") ? slashNormalized : `/${slashNormalized}`);
|
|
281
|
+
return normalized === "/" ? "/" : normalized.replace(/\/+$/, "");
|
|
282
|
+
}
|
|
254
283
|
function normalizeIsoString(value) {
|
|
255
284
|
if (typeof value !== "string" || value.trim() === "") {
|
|
256
285
|
return undefined;
|
package/dist/setup-types.d.ts
CHANGED
|
@@ -67,6 +67,8 @@ export interface WorkspaceMountEnvOptions {
|
|
|
67
67
|
}
|
|
68
68
|
export type WorkspaceMountEnv = Record<string, string>;
|
|
69
69
|
export type MountMode = "poll" | "fuse";
|
|
70
|
+
export type MountLocalLayout = "exact" | "scoped";
|
|
71
|
+
export type MountSyncMode = "mirror" | "write-only";
|
|
70
72
|
export interface MountSessionRequest {
|
|
71
73
|
localDir: string;
|
|
72
74
|
remotePath?: string;
|
|
@@ -98,6 +100,8 @@ export interface MountSessionResult {
|
|
|
98
100
|
remotePath: string;
|
|
99
101
|
localDir: string;
|
|
100
102
|
mode: MountMode;
|
|
103
|
+
localLayout: MountLocalLayout;
|
|
104
|
+
syncMode: MountSyncMode;
|
|
101
105
|
scopes: string[];
|
|
102
106
|
tokenIssuedAt: string | null;
|
|
103
107
|
expiresAt: string | null;
|
|
@@ -122,6 +126,8 @@ export interface ReadMountedWorkspaceStatusInput {
|
|
|
122
126
|
workspaceId: string;
|
|
123
127
|
remotePath: string;
|
|
124
128
|
mode: MountMode;
|
|
129
|
+
localLayout?: MountLocalLayout;
|
|
130
|
+
syncMode?: MountSyncMode;
|
|
125
131
|
relayfileBaseUrl: string;
|
|
126
132
|
relayfileToken: string;
|
|
127
133
|
expiresAt: string | null;
|
|
@@ -167,6 +173,8 @@ export interface MountWorkspaceInput {
|
|
|
167
173
|
localDir: string;
|
|
168
174
|
remotePath?: string;
|
|
169
175
|
mode?: MountMode;
|
|
176
|
+
localLayout?: MountLocalLayout;
|
|
177
|
+
syncMode?: MountSyncMode;
|
|
170
178
|
background?: boolean;
|
|
171
179
|
agentName?: string;
|
|
172
180
|
scopes?: string[];
|
package/dist/setup.js
CHANGED
|
@@ -16,6 +16,8 @@ const DEFAULT_WAIT_INTERVAL_MS = 2_000;
|
|
|
16
16
|
const DEFAULT_WAIT_TIMEOUT_MS = 300_000;
|
|
17
17
|
const DEFAULT_MOUNT_READY_TIMEOUT_MS = 60_000;
|
|
18
18
|
const DEFAULT_MOUNT_AGENT_NAME = "relayfile-mount";
|
|
19
|
+
const DEFAULT_MOUNT_LOCAL_LAYOUT = "exact";
|
|
20
|
+
const DEFAULT_MOUNT_SYNC_MODE = "mirror";
|
|
19
21
|
const TOKEN_REFRESH_AGE_MS = 55 * 60 * 1000;
|
|
20
22
|
const nodeOnlyMountLauncher = {
|
|
21
23
|
async start() {
|
|
@@ -142,6 +144,8 @@ export class RelayfileSetup {
|
|
|
142
144
|
localDir: normalized.localDir,
|
|
143
145
|
remotePath: normalized.remotePath,
|
|
144
146
|
mode: normalized.mode,
|
|
147
|
+
localLayout: normalized.localLayout,
|
|
148
|
+
syncMode: normalized.syncMode,
|
|
145
149
|
background: normalized.background,
|
|
146
150
|
agentName: normalized.agentName,
|
|
147
151
|
scopes: normalized.scopes,
|
|
@@ -246,13 +250,18 @@ export class RelayfileSetup {
|
|
|
246
250
|
: undefined
|
|
247
251
|
});
|
|
248
252
|
try {
|
|
249
|
-
|
|
253
|
+
const session = validateMountSessionResponse(await workspace.requestJson({
|
|
250
254
|
operation: "mountWorkspace",
|
|
251
255
|
method: "POST",
|
|
252
256
|
path: `api/v1/workspaces/${encodeURIComponent(workspace.workspaceId)}/relayfile/mount-session`,
|
|
253
257
|
body: request,
|
|
254
258
|
signal: input.signal
|
|
255
259
|
}), input.localDir);
|
|
260
|
+
return {
|
|
261
|
+
...session,
|
|
262
|
+
localLayout: input.localLayout,
|
|
263
|
+
syncMode: input.syncMode
|
|
264
|
+
};
|
|
256
265
|
}
|
|
257
266
|
catch (error) {
|
|
258
267
|
throw mapMountSessionError(error, request);
|
|
@@ -731,6 +740,8 @@ class MountedWorkspaceHandleImpl {
|
|
|
731
740
|
workspaceId: this.workspaceId,
|
|
732
741
|
remotePath: this.remotePath,
|
|
733
742
|
mode: this.mode,
|
|
743
|
+
localLayout: this.mountSession.localLayout,
|
|
744
|
+
syncMode: this.mountSession.syncMode,
|
|
734
745
|
relayfileBaseUrl: this.mountSession.relayfileBaseUrl,
|
|
735
746
|
relayfileToken: this.mountSession.relayfileToken,
|
|
736
747
|
expiresAt: this.expiresAt,
|
|
@@ -837,6 +848,8 @@ function validateMountSessionResponse(payload, localDir) {
|
|
|
837
848
|
remotePath: requireStringField(payload, "remotePath"),
|
|
838
849
|
localDir,
|
|
839
850
|
mode: requireMountModeField(payload, "mode"),
|
|
851
|
+
localLayout: DEFAULT_MOUNT_LOCAL_LAYOUT,
|
|
852
|
+
syncMode: DEFAULT_MOUNT_SYNC_MODE,
|
|
840
853
|
scopes: requireStringArrayField(payload, "scopes"),
|
|
841
854
|
tokenIssuedAt: readNullableStringField(payload, "tokenIssuedAt"),
|
|
842
855
|
expiresAt: readNullableStringField(payload, "expiresAt"),
|
|
@@ -930,6 +943,8 @@ function normalizeMountWorkspaceInput(input) {
|
|
|
930
943
|
localDir: resolveLocalDir(localDir),
|
|
931
944
|
remotePath: normalizeMountRemotePath(input.remotePath),
|
|
932
945
|
mode: normalizeMountModeInput(input.mode),
|
|
946
|
+
localLayout: normalizeMountLocalLayoutInput(input.localLayout),
|
|
947
|
+
syncMode: normalizeMountSyncModeInput(input.syncMode),
|
|
933
948
|
background: input.background !== false,
|
|
934
949
|
agentName: normalizeNonEmptyString(input.agentName),
|
|
935
950
|
scopes: input.scopes && input.scopes.length > 0 ? [...input.scopes] : undefined,
|
|
@@ -954,6 +969,20 @@ function normalizeMountModeInput(mode) {
|
|
|
954
969
|
}
|
|
955
970
|
return normalized;
|
|
956
971
|
}
|
|
972
|
+
function normalizeMountLocalLayoutInput(layout) {
|
|
973
|
+
const normalized = normalizeNonEmptyString(layout) ?? DEFAULT_MOUNT_LOCAL_LAYOUT;
|
|
974
|
+
if (normalized !== "exact" && normalized !== "scoped") {
|
|
975
|
+
throw new MountSessionInputError(`Invalid localLayout "${normalized}" for mount session.`);
|
|
976
|
+
}
|
|
977
|
+
return normalized;
|
|
978
|
+
}
|
|
979
|
+
function normalizeMountSyncModeInput(mode) {
|
|
980
|
+
const normalized = normalizeNonEmptyString(mode) ?? DEFAULT_MOUNT_SYNC_MODE;
|
|
981
|
+
if (normalized !== "mirror" && normalized !== "write-only") {
|
|
982
|
+
throw new MountSessionInputError(`Invalid syncMode "${normalized}" for mount session.`);
|
|
983
|
+
}
|
|
984
|
+
return normalized;
|
|
985
|
+
}
|
|
957
986
|
function normalizeMountRemotePath(remotePath) {
|
|
958
987
|
const normalized = normalizeNonEmptyString(remotePath) ?? "/";
|
|
959
988
|
if (normalized.includes("\u0000")) {
|
|
@@ -1052,6 +1081,8 @@ function buildMountedWorkspaceEnv(mountSession) {
|
|
|
1052
1081
|
RELAYFILE_REMOTE_PATH: mountSession.remotePath,
|
|
1053
1082
|
RELAYFILE_LOCAL_DIR: mountSession.localDir,
|
|
1054
1083
|
RELAYFILE_MOUNT_MODE: mountSession.mode,
|
|
1084
|
+
RELAYFILE_MOUNT_LOCAL_LAYOUT: mountSession.localLayout,
|
|
1085
|
+
RELAYFILE_MOUNT_SYNC_MODE: mountSession.syncMode,
|
|
1055
1086
|
RELAYCAST_API_KEY: mountSession.relaycastApiKey,
|
|
1056
1087
|
RELAY_API_KEY: mountSession.relaycastApiKey,
|
|
1057
1088
|
RELAYCAST_BASE_URL: relaycastBaseUrl,
|
package/dist/types.d.ts
CHANGED
|
@@ -700,12 +700,58 @@ export interface AckWritebackInput {
|
|
|
700
700
|
itemId: string;
|
|
701
701
|
success: boolean;
|
|
702
702
|
error?: string;
|
|
703
|
+
/**
|
|
704
|
+
* Provider-assigned id of the created/updated object (e.g. the Slack
|
|
705
|
+
* message ts). When present on a successful ack, the service reconciles
|
|
706
|
+
* the agent-authored draft file per the draftFile() rename contract
|
|
707
|
+
* (issue #242): the draft is renamed to the canonical id, or removed when
|
|
708
|
+
* the canonical record already materialized. The mutation is
|
|
709
|
+
* classification-exempt — it can never enqueue a new writeback.
|
|
710
|
+
*/
|
|
711
|
+
externalId?: string;
|
|
712
|
+
/**
|
|
713
|
+
* Optional canonical projection path for the draft rename. Must stay under
|
|
714
|
+
* the same provider root as the draft; otherwise the service falls back to
|
|
715
|
+
* the externalId-derived name next to the draft.
|
|
716
|
+
*/
|
|
717
|
+
canonicalPath?: string;
|
|
703
718
|
correlationId?: string;
|
|
704
719
|
signal?: AbortSignal;
|
|
705
720
|
}
|
|
721
|
+
/** Disposition of the agent-authored draft file after a successful ack. */
|
|
722
|
+
export interface AckWritebackDraftDisposition {
|
|
723
|
+
action: "renamed" | "removed" | "none";
|
|
724
|
+
from?: string;
|
|
725
|
+
to?: string;
|
|
726
|
+
}
|
|
706
727
|
export interface AckWritebackResponse {
|
|
707
728
|
status: "acknowledged";
|
|
708
729
|
id: string;
|
|
709
730
|
correlationId?: string;
|
|
710
731
|
success: boolean;
|
|
732
|
+
/** Present only when the ack was successful and carried an externalId. */
|
|
733
|
+
draft?: AckWritebackDraftDisposition;
|
|
734
|
+
}
|
|
735
|
+
export interface SweepWritebackDraftsInput {
|
|
736
|
+
workspaceId: string;
|
|
737
|
+
/** Restrict the sweep to a subtree. */
|
|
738
|
+
pathPrefix?: string;
|
|
739
|
+
/** Basename globs for hand-named drafts, e.g. "wb-*.json". */
|
|
740
|
+
patterns?: string[];
|
|
741
|
+
/** Execute removals; when false the sweep is a dry run. */
|
|
742
|
+
apply?: boolean;
|
|
743
|
+
correlationId?: string;
|
|
744
|
+
signal?: AbortSignal;
|
|
745
|
+
}
|
|
746
|
+
export interface SweepWritebackDraftsResponse {
|
|
747
|
+
dryRun: boolean;
|
|
748
|
+
scanned: number;
|
|
749
|
+
removed: Array<{
|
|
750
|
+
path: string;
|
|
751
|
+
reason: "space-uuid-draft" | "pattern";
|
|
752
|
+
}>;
|
|
753
|
+
skipped: Array<{
|
|
754
|
+
path: string;
|
|
755
|
+
reason: "pending-writeback" | "provider-linked";
|
|
756
|
+
}>;
|
|
711
757
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@relayfile/sdk",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.12",
|
|
4
4
|
"description": "TypeScript SDK for relayfile — real-time filesystem for humans and agents",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"prepublishOnly": "npm run build"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@relayfile/core": "0.8.
|
|
58
|
+
"@relayfile/core": "0.8.12",
|
|
59
59
|
"ignore": "^7.0.5",
|
|
60
60
|
"tar": "^7.5.10"
|
|
61
61
|
},
|