@intentic/sync 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/dist/agent.d.ts +2 -0
  3. package/dist/agent.d.ts.map +1 -0
  4. package/dist/agent.js +101 -0
  5. package/dist/agent.js.map +1 -0
  6. package/dist/app.d.ts +2 -0
  7. package/dist/app.d.ts.map +1 -0
  8. package/dist/app.js +7 -0
  9. package/dist/app.js.map +1 -0
  10. package/dist/auth.d.ts +3 -0
  11. package/dist/auth.d.ts.map +1 -0
  12. package/dist/auth.js +75 -0
  13. package/dist/auth.js.map +1 -0
  14. package/dist/cli.d.ts +3 -0
  15. package/dist/cli.d.ts.map +1 -0
  16. package/dist/cli.js +5 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/client.d.ts +11 -0
  19. package/dist/client.d.ts.map +1 -0
  20. package/dist/client.js +94 -0
  21. package/dist/client.js.map +1 -0
  22. package/dist/commands.d.ts +9 -0
  23. package/dist/commands.d.ts.map +1 -0
  24. package/dist/commands.js +107 -0
  25. package/dist/commands.js.map +1 -0
  26. package/dist/config.d.ts +15 -0
  27. package/dist/config.d.ts.map +1 -0
  28. package/dist/config.js +15 -0
  29. package/dist/config.js.map +1 -0
  30. package/dist/engine.d.ts +21 -0
  31. package/dist/engine.d.ts.map +1 -0
  32. package/dist/engine.js +0 -0
  33. package/dist/engine.js.map +1 -0
  34. package/dist/fs-util.d.ts +12 -0
  35. package/dist/fs-util.d.ts.map +1 -0
  36. package/dist/fs-util.js +61 -0
  37. package/dist/fs-util.js.map +1 -0
  38. package/dist/install.d.ts +3 -0
  39. package/dist/install.d.ts.map +1 -0
  40. package/dist/install.js +93 -0
  41. package/dist/install.js.map +1 -0
  42. package/dist/manifest.d.ts +8 -0
  43. package/dist/manifest.d.ts.map +1 -0
  44. package/dist/manifest.js +15 -0
  45. package/dist/manifest.js.map +1 -0
  46. package/dist/mutagen.d.ts +12 -0
  47. package/dist/mutagen.d.ts.map +1 -0
  48. package/dist/mutagen.js +81 -0
  49. package/dist/mutagen.js.map +1 -0
  50. package/dist/ssh.d.ts +13 -0
  51. package/dist/ssh.d.ts.map +1 -0
  52. package/dist/ssh.js +47 -0
  53. package/dist/ssh.js.map +1 -0
  54. package/package.json +38 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Artur Kurowski
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ export declare const run: () => Promise<void>;
2
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAwCA,eAAO,MAAM,GAAG,QAAa,OAAO,CAAC,IAAI,CA8ExC,CAAC"}
package/dist/agent.js ADDED
@@ -0,0 +1,101 @@
1
+ import { relative, sep } from "node:path";
2
+ import { watch } from "chokidar";
3
+ import { idTokenFromRefresh } from "./auth.js";
4
+ import { createSandboxClient } from "./client.js";
5
+ import { manifestPath, readConfig, readCredentials } from "./config.js";
6
+ import { createSyncEngine } from "./engine.js";
7
+ import { isIgnored } from "./fs-util.js";
8
+ import { loadManifest, saveManifest } from "./manifest.js";
9
+ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
10
+ const decodeExpSeconds = (jwt) => {
11
+ const payload = jwt.split(".")[1];
12
+ if (payload === undefined) {
13
+ return 0;
14
+ }
15
+ try {
16
+ return JSON.parse(Buffer.from(payload, "base64url").toString("utf8")).exp ?? 0;
17
+ }
18
+ catch {
19
+ return 0;
20
+ }
21
+ };
22
+ const createTokenProvider = (clientId, clientSecret, refreshToken) => {
23
+ let cached;
24
+ return async () => {
25
+ if (cached !== undefined && cached.exp - 60 > Date.now() / 1000) {
26
+ return cached.token;
27
+ }
28
+ const token = await idTokenFromRefresh(clientId, clientSecret, refreshToken);
29
+ cached = { token, exp: decodeExpSeconds(token) };
30
+ return token;
31
+ };
32
+ };
33
+ export const run = async () => {
34
+ const config = await readConfig();
35
+ const credentials = await readCredentials();
36
+ if (credentials === undefined) {
37
+ throw new Error("intentic-sync is not set up — run `intentic-sync setup` first.");
38
+ }
39
+ const getToken = createTokenProvider(config.googleClientId, config.googleClientSecret, credentials.refreshToken);
40
+ const client = createSandboxClient(config.sandboxUrl, getToken);
41
+ const manifestFile = manifestPath(config.sandboxId);
42
+ const manifest = await loadManifest(manifestFile);
43
+ const log = (message) => void process.stdout.write(`${new Date().toISOString()} ${message}\n`);
44
+ let dirty = false;
45
+ let saveTimer;
46
+ const persist = () => {
47
+ dirty = true;
48
+ if (saveTimer !== undefined) {
49
+ return;
50
+ }
51
+ saveTimer = setTimeout(() => {
52
+ saveTimer = undefined;
53
+ if (dirty) {
54
+ dirty = false;
55
+ void saveManifest(manifestFile, manifest);
56
+ }
57
+ }, 500);
58
+ };
59
+ const engine = createSyncEngine({ localDir: config.localDir, client, manifest, persist, log, now: () => Date.now() });
60
+ let chain = Promise.resolve();
61
+ const serialize = (operation) => {
62
+ const next = chain.then(operation, operation);
63
+ chain = next.then(() => undefined, () => undefined);
64
+ return next;
65
+ };
66
+ const watcher = watch(config.localDir, {
67
+ ignoreInitial: true,
68
+ awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 50 },
69
+ ignored: (candidate) => {
70
+ const rel = relative(config.localDir, candidate).split(sep).join("/");
71
+ return rel !== "" && isIgnored(rel);
72
+ },
73
+ });
74
+ const onLocal = (candidate) => {
75
+ const rel = relative(config.localDir, candidate).split(sep).join("/");
76
+ if (rel === "") {
77
+ return;
78
+ }
79
+ void serialize(() => engine.onLocalPath(rel)).catch((error) => log(`local sync error on ${rel}: ${error instanceof Error ? error.message : String(error)}`));
80
+ };
81
+ watcher.on("add", onLocal).on("change", onLocal).on("unlink", onLocal);
82
+ log(`mirroring ${config.sandboxUrl} → ${config.localDir}`);
83
+ for (;;) {
84
+ const controller = new AbortController();
85
+ try {
86
+ await serialize(() => engine.reconcile());
87
+ log("reconciled; watching for changes");
88
+ for await (const change of client.watch(controller.signal)) {
89
+ await serialize(() => engine.onRemoteChange(change)).catch((error) => log(`remote sync error on ${change.path}: ${error instanceof Error ? error.message : String(error)}`));
90
+ }
91
+ }
92
+ catch (error) {
93
+ log(`stream dropped: ${error instanceof Error ? error.message : String(error)}; retrying in 5s`);
94
+ }
95
+ finally {
96
+ controller.abort();
97
+ }
98
+ await delay(5000);
99
+ }
100
+ };
101
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
package/dist/app.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare const app: import("@stricli/core").Application<import("@stricli/core").CommandContext>;
2
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,GAAG,6EAMf,CAAC"}
package/dist/app.js ADDED
@@ -0,0 +1,7 @@
1
+ import { buildApplication, buildRouteMap } from "@stricli/core";
2
+ import { commands } from "./commands.js";
3
+ export const app = buildApplication(buildRouteMap({
4
+ routes: commands,
5
+ docs: { brief: "intentic-sync — mirror a remote sandbox to a local directory" },
6
+ }), { name: "intentic-sync", scanner: { caseStyle: "allow-kebab-for-camel" } });
7
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAKzC,MAAM,CAAC,MAAM,GAAG,GAAG,gBAAgB,CAC/B,aAAa,CAAC;IACV,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,EAAE,KAAK,EAAE,8DAA8D,EAAE;CAClF,CAAC,EACF,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,uBAAuB,EAAE,EAAE,CAC7E,CAAC"}
package/dist/auth.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export declare const authorizeInteractive: (clientId: string, clientSecret: string) => Promise<string>;
2
+ export declare const idTokenFromRefresh: (clientId: string, clientSecret: string, refreshToken: string) => Promise<string>;
3
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAoDA,eAAO,MAAM,oBAAoB,GAAU,UAAU,MAAM,EAAE,cAAc,MAAM,KAAG,OAAO,CAAC,MAAM,CAiBjG,CAAC;AAKF,eAAO,MAAM,kBAAkB,GAAU,UAAU,MAAM,EAAE,cAAc,MAAM,EAAE,cAAc,MAAM,KAAG,OAAO,CAAC,MAAM,CAcrH,CAAC"}
package/dist/auth.js ADDED
@@ -0,0 +1,75 @@
1
+ import { spawn } from "node:child_process";
2
+ import { createServer } from "node:http";
3
+ import { OAuth2Client } from "google-auth-library";
4
+ const SCOPES = ["openid", "email", "profile"];
5
+ const TOKEN_URL = "https://oauth2.googleapis.com/token";
6
+ const openBrowser = (url) => {
7
+ const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
8
+ const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
9
+ try {
10
+ spawn(command, args, { stdio: "ignore", detached: true }).unref();
11
+ }
12
+ catch {
13
+ }
14
+ };
15
+ const startLoopback = () => new Promise((resolveServer) => {
16
+ let resolveCode;
17
+ let rejectCode;
18
+ const code = new Promise((resolve, reject) => {
19
+ resolveCode = resolve;
20
+ rejectCode = reject;
21
+ });
22
+ const server = createServer((request, response) => {
23
+ const url = new URL(request.url ?? "/", "http://localhost");
24
+ const received = url.searchParams.get("code");
25
+ const error = url.searchParams.get("error");
26
+ response.writeHead(200, { "content-type": "text/html" });
27
+ response.end("<html><body>intentic-sync authorized. You can close this tab.</body></html>");
28
+ if (received !== null) {
29
+ resolveCode(received);
30
+ return;
31
+ }
32
+ if (error !== null) {
33
+ rejectCode(new Error(`Google authorization was denied: ${error}`));
34
+ }
35
+ });
36
+ server.listen(0, "127.0.0.1", () => {
37
+ const address = server.address();
38
+ resolveServer({ server, port: typeof address === "object" && address !== null ? address.port : 0, code });
39
+ });
40
+ });
41
+ export const authorizeInteractive = async (clientId, clientSecret) => {
42
+ const { server, port, code } = await startLoopback();
43
+ const redirectUri = `http://localhost:${port}`;
44
+ const client = new OAuth2Client({ clientId, clientSecret, redirectUri });
45
+ const authUrl = client.generateAuthUrl({ access_type: "offline", prompt: "consent", scope: SCOPES });
46
+ openBrowser(authUrl);
47
+ process.stdout.write(`\nAuthorize intentic-sync in your browser (opening it now):\n${authUrl}\n\n`);
48
+ try {
49
+ const authorizationCode = await code;
50
+ const { tokens } = await client.getToken({ code: authorizationCode, redirect_uri: redirectUri });
51
+ if (typeof tokens.refresh_token !== "string" || tokens.refresh_token === "") {
52
+ throw new Error("Google returned no refresh token — remove intentic-sync from your Google account's third-party access and retry.");
53
+ }
54
+ return tokens.refresh_token;
55
+ }
56
+ finally {
57
+ server.close();
58
+ }
59
+ };
60
+ export const idTokenFromRefresh = async (clientId, clientSecret, refreshToken) => {
61
+ const response = await fetch(TOKEN_URL, {
62
+ method: "POST",
63
+ headers: { "content-type": "application/x-www-form-urlencoded" },
64
+ body: new URLSearchParams({ client_id: clientId, client_secret: clientSecret, refresh_token: refreshToken, grant_type: "refresh_token" }),
65
+ });
66
+ if (!response.ok) {
67
+ throw new Error(`Google token refresh failed (${response.status}): ${await response.text()}`);
68
+ }
69
+ const payload = (await response.json());
70
+ if (typeof payload.id_token !== "string") {
71
+ throw new Error("Google token refresh returned no id_token");
72
+ }
73
+ return payload.id_token;
74
+ };
75
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { run } from "@stricli/core";
3
+ import { app } from "./app.js";
4
+ await run(app, process.argv.slice(2), { process: process });
5
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEpC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,MAAM,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,OAAyB,EAAE,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { WorkspaceChange, WorkspaceTree } from "@intentic/sandbox-contract";
2
+ export interface SandboxClient {
3
+ tree(): Promise<WorkspaceTree>;
4
+ raw(path: string): Promise<Uint8Array | undefined>;
5
+ upload(path: string, bytes: Uint8Array): Promise<void>;
6
+ remove(path: string): Promise<void>;
7
+ mkdir(path: string): Promise<void>;
8
+ watch(signal: AbortSignal): AsyncGenerator<WorkspaceChange>;
9
+ }
10
+ export declare const createSandboxClient: (baseUrl: string, getToken: () => Promise<string>) => SandboxClient;
11
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAIjF,MAAM,WAAW,aAAa;IAC1B,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAG/B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IACnD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,cAAc,CAAC,eAAe,CAAC,CAAC;CAC/D;AAuCD,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,EAAE,UAAU,MAAM,OAAO,CAAC,MAAM,CAAC,KAAG,aA8DtF,CAAC"}
package/dist/client.js ADDED
@@ -0,0 +1,94 @@
1
+ const encodeQuery = (path) => `path=${encodeURIComponent(path)}`;
2
+ async function* parseSse(body, signal) {
3
+ const reader = body.getReader();
4
+ const decoder = new TextDecoder();
5
+ let buffer = "";
6
+ signal.addEventListener("abort", () => void reader.cancel(), { once: true });
7
+ for (;;) {
8
+ const { done, value } = await reader.read();
9
+ if (done) {
10
+ return;
11
+ }
12
+ buffer += decoder.decode(value, { stream: true });
13
+ let separator = buffer.indexOf("\n\n");
14
+ while (separator !== -1) {
15
+ const frame = buffer.slice(0, separator);
16
+ buffer = buffer.slice(separator + 2);
17
+ separator = buffer.indexOf("\n\n");
18
+ const dataLine = frame.split("\n").find((line) => line.startsWith("data:"));
19
+ if (dataLine === undefined) {
20
+ continue;
21
+ }
22
+ const payload = dataLine.slice(5).trim();
23
+ if (payload.length === 0) {
24
+ continue;
25
+ }
26
+ try {
27
+ yield JSON.parse(payload);
28
+ }
29
+ catch {
30
+ }
31
+ }
32
+ }
33
+ }
34
+ export const createSandboxClient = (baseUrl, getToken) => {
35
+ const root = baseUrl.replace(/\/$/, "");
36
+ const authHeader = async () => ({ authorization: `Bearer ${await getToken()}` });
37
+ return {
38
+ tree: async () => {
39
+ const response = await fetch(`${root}/workspace/tree`, { headers: await authHeader() });
40
+ if (!response.ok) {
41
+ throw new Error(`GET /workspace/tree failed: ${response.status}`);
42
+ }
43
+ return (await response.json());
44
+ },
45
+ raw: async (path) => {
46
+ const response = await fetch(`${root}/workspace/raw?${encodeQuery(path)}`, { headers: await authHeader() });
47
+ if (response.status === 404) {
48
+ return undefined;
49
+ }
50
+ if (!response.ok) {
51
+ throw new Error(`GET /workspace/raw ${path} failed: ${response.status}`);
52
+ }
53
+ return new Uint8Array(await response.arrayBuffer());
54
+ },
55
+ upload: async (path, bytes) => {
56
+ const response = await fetch(`${root}/workspace/upload?${encodeQuery(path)}`, {
57
+ method: "POST",
58
+ headers: { ...(await authHeader()), "content-type": "application/octet-stream" },
59
+ body: bytes,
60
+ });
61
+ if (!response.ok) {
62
+ throw new Error(`POST /workspace/upload ${path} failed: ${response.status}`);
63
+ }
64
+ },
65
+ remove: async (path) => {
66
+ const response = await fetch(`${root}/workspace/entry`, {
67
+ method: "DELETE",
68
+ headers: { ...(await authHeader()), "content-type": "application/json" },
69
+ body: JSON.stringify({ path }),
70
+ });
71
+ if (!response.ok) {
72
+ throw new Error(`DELETE /workspace/entry ${path} failed: ${response.status}`);
73
+ }
74
+ },
75
+ mkdir: async (path) => {
76
+ const response = await fetch(`${root}/workspace/dir`, {
77
+ method: "POST",
78
+ headers: { ...(await authHeader()), "content-type": "application/json" },
79
+ body: JSON.stringify({ path }),
80
+ });
81
+ if (!response.ok) {
82
+ throw new Error(`POST /workspace/dir ${path} failed: ${response.status}`);
83
+ }
84
+ },
85
+ watch: async function* (signal) {
86
+ const response = await fetch(`${root}/workspace/watch`, { headers: { ...(await authHeader()), accept: "text/event-stream" }, signal });
87
+ if (!response.ok || response.body === null) {
88
+ throw new Error(`GET /workspace/watch failed: ${response.status}`);
89
+ }
90
+ yield* parseSse(response.body, signal);
91
+ },
92
+ };
93
+ };
94
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type CommandContext } from "@stricli/core";
2
+ export declare const commands: {
3
+ setup: import("@stricli/core").Command<CommandContext>;
4
+ status: import("@stricli/core").Command<CommandContext>;
5
+ pause: import("@stricli/core").Command<CommandContext>;
6
+ resume: import("@stricli/core").Command<CommandContext>;
7
+ uninstall: import("@stricli/core").Command<CommandContext>;
8
+ };
9
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAoIlE,eAAO,MAAM,QAAQ;;;;;;CAA8C,CAAC"}
@@ -0,0 +1,107 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { join, resolve } from "node:path";
4
+ import { buildCommand } from "@stricli/core";
5
+ import { knownHostsPath, readConfig, sshConfigPath, sshKeyPath, writeConfig } from "./config.js";
6
+ import { ensureCloudflared, ensureMutagen, mutagenCreateArgs, runMutagen, sessionName } from "./mutagen.js";
7
+ import { ensureSshKey, sanitizeId, sshAlias, sshConfigBlock, writeManagedSshConfig } from "./ssh.js";
8
+ const enrollKey = async (sandboxUrl, pairToken, key) => {
9
+ const response = await fetch(`${sandboxUrl.replace(/\/$/, "")}/system/authorized-key`, {
10
+ method: "POST",
11
+ headers: { "content-type": "application/json", "x-intentic-pair": pairToken },
12
+ body: JSON.stringify({ key }),
13
+ });
14
+ if (response.status === 401) {
15
+ throw new Error("pairing expired — click “Enable desktop sync” again in your browser for a fresh command.");
16
+ }
17
+ if (!response.ok) {
18
+ throw new Error(`enrolling the sync key failed (${response.status}): ${await response.text()}`);
19
+ }
20
+ const body = (await response.json());
21
+ if (body.sshHostname === undefined) {
22
+ throw new Error("this sandbox has no SSH tunnel configured for sync — reconnect it so its tunnel routes ssh-<id>.<zone>.");
23
+ }
24
+ return body.sshHostname;
25
+ };
26
+ const setup = buildCommand({
27
+ docs: { brief: "Enroll an SSH key with a pairing token and start a Mutagen sync of the local dir ↔ sandbox /work" },
28
+ parameters: {
29
+ flags: {
30
+ url: { kind: "parsed", parse: String, brief: "The sandbox's public URL (e.g. https://sandbox-xxx.example.dev)" },
31
+ pair: { kind: "parsed", parse: String, brief: "The one-time pairing token from the Desktop sync card" },
32
+ dir: { kind: "parsed", parse: String, optional: true, brief: "Local directory to sync (default: ~/intentic/<sandbox>)" },
33
+ sandboxId: { kind: "parsed", parse: String, optional: true, brief: "Session/alias id (default: the sandbox URL host)" },
34
+ },
35
+ },
36
+ async func(flags) {
37
+ const out = (message) => void this.process.stdout.write(`${message}\n`);
38
+ const publicKey = await ensureSshKey();
39
+ const sshHostname = await enrollKey(flags.url, flags.pair, publicKey);
40
+ out(`enrolled SSH key; sandbox reachable at ${sshHostname}`);
41
+ const sandboxId = flags.sandboxId ?? sanitizeId(new URL(flags.url).host);
42
+ const localDir = resolve(flags.dir ?? join(homedir(), "intentic", sandboxId));
43
+ const cloudflaredPath = await ensureCloudflared();
44
+ const mutagen = await ensureMutagen();
45
+ await writeManagedSshConfig(sshConfigBlock({
46
+ alias: sshAlias(sandboxId),
47
+ hostname: sshHostname,
48
+ identityFile: sshKeyPath,
49
+ knownHostsFile: knownHostsPath,
50
+ cloudflaredPath,
51
+ }));
52
+ const config = { sandboxUrl: flags.url, sandboxId, sshHostname, localDir };
53
+ await writeConfig(config);
54
+ runMutagen(mutagen, mutagenCreateArgs({ name: sessionName(sandboxId), localDir: config.localDir, alias: sshAlias(sandboxId), remoteDir: "/work" }));
55
+ try {
56
+ runMutagen(mutagen, ["daemon", "register"]);
57
+ }
58
+ catch (error) {
59
+ out(`note: could not register the Mutagen daemon for autostart (${error instanceof Error ? error.message : String(error)}); it still runs while you're logged in.`);
60
+ }
61
+ out(`Sync started: ${config.localDir} ↔ ${sshHostname}:/work. Check it with \`intentic-sync status\`.`);
62
+ },
63
+ });
64
+ const withMutagen = async (run) => {
65
+ const config = await readConfig();
66
+ run(await ensureMutagen(), sessionName(config.sandboxId));
67
+ };
68
+ const status = buildCommand({
69
+ docs: { brief: "Show Mutagen sync status" },
70
+ parameters: { flags: {} },
71
+ async func() {
72
+ runMutagen(await ensureMutagen(), ["sync", "list"]);
73
+ },
74
+ });
75
+ const pause = buildCommand({
76
+ docs: { brief: "Pause syncing" },
77
+ parameters: { flags: {} },
78
+ async func() {
79
+ await withMutagen((mutagen, name) => runMutagen(mutagen, ["sync", "pause", name]));
80
+ },
81
+ });
82
+ const resume = buildCommand({
83
+ docs: { brief: "Resume syncing" },
84
+ parameters: { flags: {} },
85
+ async func() {
86
+ await withMutagen((mutagen, name) => runMutagen(mutagen, ["sync", "resume", name]));
87
+ },
88
+ });
89
+ const uninstall = buildCommand({
90
+ docs: { brief: "Terminate the sync session and remove the managed ssh-config include" },
91
+ parameters: { flags: {} },
92
+ async func() {
93
+ await withMutagen((mutagen, name) => runMutagen(mutagen, ["sync", "terminate", name]));
94
+ const userConfig = join(homedir(), ".ssh", "config");
95
+ const current = await readFile(userConfig, "utf8").catch(() => "");
96
+ const stripped = current
97
+ .split("\n")
98
+ .filter((line) => line.trim() !== `Include ${sshConfigPath}`)
99
+ .join("\n");
100
+ if (stripped !== current) {
101
+ await writeFile(userConfig, stripped, { mode: 0o600 });
102
+ }
103
+ this.process.stdout.write("Sync terminated; ssh-config include removed. (The Mutagen daemon stays registered — `mutagen daemon unregister` to remove it.)\n");
104
+ },
105
+ });
106
+ export const commands = { setup, status, pause, resume, uninstall };
107
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export declare const baseDir: string;
2
+ export declare const configPath: string;
3
+ export declare const sshKeyPath: string;
4
+ export declare const sshConfigPath: string;
5
+ export declare const knownHostsPath: string;
6
+ export declare const binDir: string;
7
+ export interface SyncConfig {
8
+ readonly sandboxUrl: string;
9
+ readonly sandboxId: string;
10
+ readonly sshHostname: string;
11
+ readonly localDir: string;
12
+ }
13
+ export declare const readConfig: () => Promise<SyncConfig>;
14
+ export declare const writeConfig: (config: SyncConfig) => Promise<void>;
15
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,OAAO,QAAuC,CAAC;AAC5D,eAAO,MAAM,UAAU,QAA+B,CAAC;AACvD,eAAO,MAAM,UAAU,QAA8B,CAAC;AACtD,eAAO,MAAM,aAAa,QAA8B,CAAC;AACzD,eAAO,MAAM,cAAc,QAA+B,CAAC;AAC3D,eAAO,MAAM,MAAM,QAAuB,CAAC;AAI3C,MAAM,WAAW,UAAU;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC7B;AAED,eAAO,MAAM,UAAU,QAAa,OAAO,CAAC,UAAU,CAAiE,CAAC;AAExH,eAAO,MAAM,WAAW,GAAU,QAAQ,UAAU,KAAG,OAAO,CAAC,IAAI,CAGlE,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,15 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ export const baseDir = join(homedir(), ".intentic", "sync");
5
+ export const configPath = join(baseDir, "config.json");
6
+ export const sshKeyPath = join(baseDir, "id_ed25519");
7
+ export const sshConfigPath = join(baseDir, "ssh_config");
8
+ export const knownHostsPath = join(baseDir, "known_hosts");
9
+ export const binDir = join(baseDir, "bin");
10
+ export const readConfig = async () => JSON.parse(await readFile(configPath, "utf8"));
11
+ export const writeConfig = async (config) => {
12
+ await mkdir(baseDir, { recursive: true });
13
+ await writeFile(configPath, JSON.stringify(config, undefined, 2), "utf8");
14
+ };
15
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAKjC,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;AAC5D,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;AACvD,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AACtD,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AACzD,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAW3C,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,IAAyB,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAe,CAAC;AAExH,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,MAAkB,EAAiB,EAAE;IACnE,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AAC9E,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { WorkspaceChange } from "@intentic/sandbox-contract";
2
+ import type { SandboxClient } from "./client.js";
3
+ import type { Manifest } from "./manifest.js";
4
+ export type SyncAction = "noop" | "pullToLocal" | "pushToRemote" | "deleteLocal" | "deleteRemote" | "conflict";
5
+ export declare const decide: (localHash: string | undefined, remoteHash: string | undefined, manifestHash: string | undefined) => SyncAction;
6
+ export declare const resolveConflict: (localMtime: number, remoteMtime: number) => "local" | "remote";
7
+ export interface SyncEngine {
8
+ reconcile(): Promise<void>;
9
+ onRemoteChange(change: WorkspaceChange): Promise<void>;
10
+ onLocalPath(relPath: string): Promise<void>;
11
+ }
12
+ export interface EngineDeps {
13
+ readonly localDir: string;
14
+ readonly client: SandboxClient;
15
+ readonly manifest: Manifest;
16
+ readonly persist: () => void;
17
+ readonly log: (message: string) => void;
18
+ readonly now: () => number;
19
+ }
20
+ export declare const createSyncEngine: (deps: EngineDeps) => SyncEngine;
21
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,4BAA4B,CAAC;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAI9C,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,aAAa,GAAG,cAAc,GAAG,aAAa,GAAG,cAAc,GAAG,UAAU,CAAC;AAS/G,eAAO,MAAM,MAAM,GAAI,WAAW,MAAM,GAAG,SAAS,EAAE,YAAY,MAAM,GAAG,SAAS,EAAE,cAAc,MAAM,GAAG,SAAS,KAAG,UAWxH,CAAC;AAKF,eAAO,MAAM,eAAe,GAAI,YAAY,MAAM,EAAE,aAAa,MAAM,KAAG,OAAO,GAAG,QAA4D,CAAC;AAuBjJ,MAAM,WAAW,UAAU;IAGvB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,UAAU;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC;CAC9B;AAED,eAAO,MAAM,gBAAgB,GAAI,MAAM,UAAU,KAAG,UAwJnD,CAAC"}
package/dist/engine.js ADDED
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export declare const IGNORED_DIRS: Set<string>;
2
+ export declare const isIgnored: (relPath: string) => boolean;
3
+ export declare const hashBytes: (bytes: Uint8Array) => string;
4
+ export declare const readLocalBytes: (absPath: string) => Promise<Uint8Array | undefined>;
5
+ export declare const hashLocalFile: (absPath: string) => Promise<string | undefined>;
6
+ export interface LocalMeta {
7
+ readonly size: number;
8
+ readonly mtime: number;
9
+ }
10
+ export declare const statLocal: (absPath: string) => Promise<LocalMeta | undefined>;
11
+ export declare const walkLocalFiles: (root: string) => Promise<Map<string, LocalMeta>>;
12
+ //# sourceMappingURL=fs-util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-util.d.ts","sourceRoot":"","sources":["../src/fs-util.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,YAAY,aAAqF,CAAC;AAK/G,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,KAAG,OAM3C,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,OAAO,UAAU,KAAG,MAA0D,CAAC;AAEzG,eAAO,MAAM,cAAc,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAMpF,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAG/E,CAAC;AAEF,MAAM,WAAW,SAAS;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CAC1B;AAED,eAAO,MAAM,SAAS,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAO9E,CAAC;AAIF,eAAO,MAAM,cAAc,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAyBjF,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readdir, readFile, stat } from "node:fs/promises";
3
+ import { join, relative, sep } from "node:path";
4
+ export const IGNORED_DIRS = new Set([".git", "node_modules", "dist", ".cache", ".turbo", ".next", ".angular"]);
5
+ const isSecretFile = (name) => name === ".secrets.json" || name === "claude.json" || name === "capabilities.json" || (name.startsWith(".env") && name !== ".env.example");
6
+ export const isIgnored = (relPath) => {
7
+ const segments = relPath.split(/[\\/]/).filter((segment) => segment.length > 0);
8
+ if (segments.some((segment) => IGNORED_DIRS.has(segment))) {
9
+ return true;
10
+ }
11
+ return isSecretFile(segments.at(-1) ?? "");
12
+ };
13
+ export const hashBytes = (bytes) => createHash("sha256").update(bytes).digest("hex");
14
+ export const readLocalBytes = async (absPath) => {
15
+ try {
16
+ return await readFile(absPath);
17
+ }
18
+ catch {
19
+ return undefined;
20
+ }
21
+ };
22
+ export const hashLocalFile = async (absPath) => {
23
+ const bytes = await readLocalBytes(absPath);
24
+ return bytes === undefined ? undefined : hashBytes(bytes);
25
+ };
26
+ export const statLocal = async (absPath) => {
27
+ try {
28
+ const info = await stat(absPath);
29
+ return { size: info.size, mtime: info.mtimeMs };
30
+ }
31
+ catch {
32
+ return undefined;
33
+ }
34
+ };
35
+ export const walkLocalFiles = async (root) => {
36
+ const files = new Map();
37
+ const walk = async (dir) => {
38
+ const dirents = await readdir(dir, { withFileTypes: true }).catch(() => []);
39
+ for (const dirent of dirents) {
40
+ const abs = join(dir, dirent.name);
41
+ const rel = relative(root, abs).split(sep).join("/");
42
+ if (isIgnored(rel) || dirent.isSymbolicLink()) {
43
+ continue;
44
+ }
45
+ if (dirent.isDirectory()) {
46
+ await walk(abs);
47
+ continue;
48
+ }
49
+ if (!dirent.isFile()) {
50
+ continue;
51
+ }
52
+ const meta = await statLocal(abs);
53
+ if (meta !== undefined) {
54
+ files.set(rel, meta);
55
+ }
56
+ }
57
+ };
58
+ await walk(root);
59
+ return files;
60
+ };
61
+ //# sourceMappingURL=fs-util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-util.js","sourceRoot":"","sources":["../src/fs-util.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare const install: (command: readonly string[]) => Promise<string>;
2
+ export declare const uninstall: () => Promise<string>;
3
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AA0EA,eAAO,MAAM,OAAO,GAAU,SAAS,SAAS,MAAM,EAAE,KAAG,OAAO,CAAC,MAAM,CAWxE,CAAC;AAEF,eAAO,MAAM,SAAS,QAAa,OAAO,CAAC,MAAM,CAgBhD,CAAC"}
@@ -0,0 +1,93 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { mkdir, rm, writeFile } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import { join } from "node:path";
5
+ const SERVICE = "intentic-sync";
6
+ const quote = (arg) => (arg.includes(" ") ? `"${arg}"` : arg);
7
+ const systemdUnitPath = () => join(homedir(), ".config", "systemd", "user", `${SERVICE}.service`);
8
+ const launchdPlistPath = () => join(homedir(), "Library", "LaunchAgents", "dev.intentic.sync.plist");
9
+ const installLinux = async (command) => {
10
+ const path = systemdUnitPath();
11
+ const unit = [
12
+ "[Unit]",
13
+ "Description=intentic-sync — mirror a sandbox to a local directory",
14
+ "After=network-online.target",
15
+ "",
16
+ "[Service]",
17
+ `ExecStart=${command.map(quote).join(" ")}`,
18
+ "Restart=always",
19
+ "RestartSec=5",
20
+ "",
21
+ "[Install]",
22
+ "WantedBy=default.target",
23
+ "",
24
+ ].join("\n");
25
+ await mkdir(join(homedir(), ".config", "systemd", "user"), { recursive: true });
26
+ await writeFile(path, unit, "utf8");
27
+ spawnSync("systemctl", ["--user", "daemon-reload"], { stdio: "ignore" });
28
+ const enabled = spawnSync("systemctl", ["--user", "enable", "--now", SERVICE], { stdio: "inherit" });
29
+ spawnSync("loginctl", ["enable-linger"], { stdio: "ignore" });
30
+ return enabled.status === 0 ? `enabled systemd user service (${path})` : `wrote ${path} — enable with: systemctl --user enable --now ${SERVICE}`;
31
+ };
32
+ const installMac = async (command) => {
33
+ const path = launchdPlistPath();
34
+ const args = command.map((arg) => ` <string>${arg}</string>`).join("\n");
35
+ const plist = [
36
+ '<?xml version="1.0" encoding="UTF-8"?>',
37
+ '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
38
+ '<plist version="1.0">',
39
+ "<dict>",
40
+ " <key>Label</key>",
41
+ " <string>dev.intentic.sync</string>",
42
+ " <key>ProgramArguments</key>",
43
+ " <array>",
44
+ args,
45
+ " </array>",
46
+ " <key>RunAtLoad</key>",
47
+ " <true/>",
48
+ " <key>KeepAlive</key>",
49
+ " <true/>",
50
+ "</dict>",
51
+ "</plist>",
52
+ "",
53
+ ].join("\n");
54
+ await mkdir(join(homedir(), "Library", "LaunchAgents"), { recursive: true });
55
+ await writeFile(path, plist, "utf8");
56
+ spawnSync("launchctl", ["unload", path], { stdio: "ignore" });
57
+ spawnSync("launchctl", ["load", "-w", path], { stdio: "inherit" });
58
+ return `loaded launchd agent (${path})`;
59
+ };
60
+ const installWindows = (command) => {
61
+ const result = spawnSync("schtasks", ["/Create", "/TN", SERVICE, "/TR", command.map(quote).join(" "), "/SC", "ONLOGON", "/F"], { stdio: "inherit" });
62
+ return result.status === 0 ? `registered scheduled task "${SERVICE}" (runs at logon)` : `failed to register scheduled task — run schtasks manually`;
63
+ };
64
+ export const install = async (command) => {
65
+ if (process.platform === "linux") {
66
+ return installLinux(command);
67
+ }
68
+ if (process.platform === "darwin") {
69
+ return installMac(command);
70
+ }
71
+ if (process.platform === "win32") {
72
+ return installWindows(command);
73
+ }
74
+ throw new Error(`autostart is not supported on ${process.platform} — run \`intentic-sync run\` yourself.`);
75
+ };
76
+ export const uninstall = async () => {
77
+ if (process.platform === "linux") {
78
+ spawnSync("systemctl", ["--user", "disable", "--now", SERVICE], { stdio: "ignore" });
79
+ await rm(systemdUnitPath(), { force: true });
80
+ return "removed systemd user service";
81
+ }
82
+ if (process.platform === "darwin") {
83
+ spawnSync("launchctl", ["unload", launchdPlistPath()], { stdio: "ignore" });
84
+ await rm(launchdPlistPath(), { force: true });
85
+ return "removed launchd agent";
86
+ }
87
+ if (process.platform === "win32") {
88
+ spawnSync("schtasks", ["/Delete", "/TN", SERVICE, "/F"], { stdio: "ignore" });
89
+ return "removed scheduled task";
90
+ }
91
+ throw new Error(`autostart is not supported on ${process.platform}`);
92
+ };
93
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export interface ManifestEntry {
2
+ readonly size: number;
3
+ readonly hash: string;
4
+ }
5
+ export type Manifest = Map<string, ManifestEntry>;
6
+ export declare const loadManifest: (path: string) => Promise<Manifest>;
7
+ export declare const saveManifest: (path: string, manifest: Manifest) => Promise<void>;
8
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACzB;AACD,MAAM,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAElD,eAAO,MAAM,YAAY,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,QAAQ,CAMjE,CAAC;AAEF,eAAO,MAAM,YAAY,GAAU,MAAM,MAAM,EAAE,UAAU,QAAQ,KAAG,OAAO,CAAC,IAAI,CAGjF,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { dirname } from "node:path";
3
+ export const loadManifest = async (path) => {
4
+ try {
5
+ return new Map(Object.entries(JSON.parse(await readFile(path, "utf8"))));
6
+ }
7
+ catch {
8
+ return new Map();
9
+ }
10
+ };
11
+ export const saveManifest = async (path, manifest) => {
12
+ await mkdir(dirname(path), { recursive: true });
13
+ await writeFile(path, JSON.stringify(Object.fromEntries(manifest)), "utf8");
14
+ };
15
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,IAAY,EAAqB,EAAE;IAClE,IAAI,CAAC;QACD,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAkC,CAAC,CAAC,CAAC;IAC9G,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,GAAG,EAAE,CAAC;IACrB,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,IAAY,EAAE,QAAkB,EAAiB,EAAE;IAClF,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AAChF,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type SpawnSyncReturns } from "node:child_process";
2
+ export declare const sessionName: (sandboxId: string) => string;
3
+ export declare const mutagenCreateArgs: (args: {
4
+ readonly name: string;
5
+ readonly localDir: string;
6
+ readonly alias: string;
7
+ readonly remoteDir: string;
8
+ }) => string[];
9
+ export declare const ensureCloudflared: () => Promise<string>;
10
+ export declare const ensureMutagen: () => Promise<string>;
11
+ export declare const runMutagen: (mutagen: string, args: string[]) => SpawnSyncReturns<Buffer>;
12
+ //# sourceMappingURL=mutagen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutagen.d.ts","sourceRoot":"","sources":["../src/mutagen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAa,MAAM,oBAAoB,CAAC;AAWtE,eAAO,MAAM,WAAW,GAAI,WAAW,MAAM,KAAG,MAA6C,CAAC;AAK9F,eAAO,MAAM,iBAAiB,GAAI,MAAM;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC9B,KAAG,MAAM,EAWT,CAAC;AAkCF,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,MAAM,CAWxD,CAAC;AAIF,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,MAAM,CAgBpD,CAAC;AAGF,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,EAAE,MAAM,MAAM,EAAE,KAAG,gBAAgB,CAAC,MAAM,CASnF,CAAC"}
@@ -0,0 +1,81 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { chmod, mkdir, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { binDir } from "./config.js";
5
+ import { IGNORES, sanitizeId } from "./ssh.js";
6
+ const MUTAGEN_VERSION = "0.18.1";
7
+ const CLOUDFLARED_VERSION = "2026.6.1";
8
+ export const sessionName = (sandboxId) => `intentic-${sanitizeId(sandboxId)}`;
9
+ export const mutagenCreateArgs = (args) => [
10
+ "sync",
11
+ "create",
12
+ "--name",
13
+ args.name,
14
+ "--ignore-vcs",
15
+ ...IGNORES.flatMap((pattern) => ["--ignore", pattern]),
16
+ "--stage-mode-beta",
17
+ "neighboring",
18
+ args.localDir,
19
+ `${args.alias}:${args.remoteDir}`,
20
+ ];
21
+ const osToken = () => {
22
+ if (process.platform === "linux" || process.platform === "darwin") {
23
+ return process.platform;
24
+ }
25
+ throw new Error(`auto-download isn't supported on ${process.platform} — install mutagen and cloudflared manually, then re-run.`);
26
+ };
27
+ const archToken = () => {
28
+ if (process.arch === "x64") {
29
+ return "amd64";
30
+ }
31
+ if (process.arch === "arm64") {
32
+ return "arm64";
33
+ }
34
+ throw new Error(`unsupported CPU arch ${process.arch} — install mutagen and cloudflared manually, then re-run.`);
35
+ };
36
+ const onPath = (binary, versionArgs) => {
37
+ const result = spawnSync(binary, versionArgs, { stdio: "ignore" });
38
+ return result.error === undefined && result.status === 0;
39
+ };
40
+ const download = async (url, dest) => {
41
+ const response = await fetch(url);
42
+ if (!response.ok) {
43
+ throw new Error(`download failed (${response.status}): ${url}`);
44
+ }
45
+ await mkdir(binDir, { recursive: true });
46
+ await writeFile(dest, new Uint8Array(await response.arrayBuffer()));
47
+ };
48
+ export const ensureCloudflared = async () => {
49
+ if (onPath("cloudflared", ["--version"])) {
50
+ return "cloudflared";
51
+ }
52
+ const dest = join(binDir, "cloudflared");
53
+ await download(`https://github.com/cloudflare/cloudflared/releases/download/${CLOUDFLARED_VERSION}/cloudflared-${osToken()}-${archToken()}`, dest);
54
+ await chmod(dest, 0o755);
55
+ return dest;
56
+ };
57
+ export const ensureMutagen = async () => {
58
+ if (onPath("mutagen", ["version"])) {
59
+ return "mutagen";
60
+ }
61
+ const dest = join(binDir, "mutagen");
62
+ const tarball = join(binDir, "mutagen.tar.gz");
63
+ await download(`https://github.com/mutagen-io/mutagen/releases/download/v${MUTAGEN_VERSION}/mutagen_${osToken()}_${archToken()}_v${MUTAGEN_VERSION}.tar.gz`, tarball);
64
+ const extract = spawnSync("tar", ["-xzf", tarball, "-C", binDir], { stdio: "inherit" });
65
+ if (extract.status !== 0) {
66
+ throw new Error("failed to extract the mutagen release (is `tar` installed?)");
67
+ }
68
+ await chmod(dest, 0o755);
69
+ return dest;
70
+ };
71
+ export const runMutagen = (mutagen, args) => {
72
+ const result = spawnSync(mutagen, args, { stdio: "inherit" });
73
+ if (result.error !== undefined) {
74
+ throw result.error;
75
+ }
76
+ if (result.status !== 0) {
77
+ throw new Error(`mutagen ${args[0] ?? ""} exited with code ${result.status}`);
78
+ }
79
+ return result;
80
+ };
81
+ //# sourceMappingURL=mutagen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutagen.js","sourceRoot":"","sources":["../src/mutagen.ts"],"names":[],"mappings":"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"}
package/dist/ssh.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ export declare const IGNORES: string[];
2
+ export declare const sanitizeId: (raw: string) => string;
3
+ export declare const sshAlias: (sandboxId: string) => string;
4
+ export declare const sshConfigBlock: (args: {
5
+ readonly alias: string;
6
+ readonly hostname: string;
7
+ readonly identityFile: string;
8
+ readonly knownHostsFile: string;
9
+ readonly cloudflaredPath: string;
10
+ }) => string;
11
+ export declare const ensureSshKey: () => Promise<string>;
12
+ export declare const writeManagedSshConfig: (block: string) => Promise<void>;
13
+ //# sourceMappingURL=ssh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh.d.ts","sourceRoot":"","sources":["../src/ssh.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,OAAO,UAAiI,CAAC;AAGtJ,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,KAAG,MAAoE,CAAC;AAE9G,eAAO,MAAM,QAAQ,GAAI,WAAW,MAAM,KAAG,MAAkD,CAAC;AAKhG,eAAO,MAAM,cAAc,GAAI,MAAM;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CACpC,KAAG,MAWY,CAAC;AAKjB,eAAO,MAAM,YAAY,QAAa,OAAO,CAAC,MAAM,CAYnD,CAAC;AAIF,eAAO,MAAM,qBAAqB,GAAU,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CAavE,CAAC"}
package/dist/ssh.js ADDED
@@ -0,0 +1,47 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { baseDir, sshConfigPath, sshKeyPath } from "./config.js";
6
+ export const IGNORES = ["node_modules", "dist", ".turbo", ".cache", ".next", ".angular", ".env", ".secrets.json", "claude.json", "capabilities.json"];
7
+ export const sanitizeId = (raw) => raw.replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "");
8
+ export const sshAlias = (sandboxId) => `intentic-sync-${sanitizeId(sandboxId)}`;
9
+ export const sshConfigBlock = (args) => [
10
+ `Host ${args.alias}`,
11
+ ` HostName ${args.hostname}`,
12
+ " User root",
13
+ ` IdentityFile ${args.identityFile}`,
14
+ " IdentitiesOnly yes",
15
+ ` UserKnownHostsFile ${args.knownHostsFile}`,
16
+ " StrictHostKeyChecking accept-new",
17
+ ` ProxyCommand ${args.cloudflaredPath} access ssh --hostname %h`,
18
+ "",
19
+ ].join("\n");
20
+ const INCLUDE_MARKER = `Include ${sshConfigPath}`;
21
+ export const ensureSshKey = async () => {
22
+ await mkdir(baseDir, { recursive: true });
23
+ const pub = `${sshKeyPath}.pub`;
24
+ const existing = await readFile(pub, "utf8").catch(() => undefined);
25
+ if (existing !== undefined) {
26
+ return existing.trim();
27
+ }
28
+ const result = spawnSync("ssh-keygen", ["-t", "ed25519", "-N", "", "-C", "intentic-sync", "-f", sshKeyPath], { stdio: "inherit" });
29
+ if (result.status !== 0) {
30
+ throw new Error("ssh-keygen failed — is an OpenSSH client installed?");
31
+ }
32
+ return (await readFile(pub, "utf8")).trim();
33
+ };
34
+ export const writeManagedSshConfig = async (block) => {
35
+ await mkdir(baseDir, { recursive: true });
36
+ await writeFile(sshConfigPath, block, { mode: 0o600 });
37
+ const userConfig = join(homedir(), ".ssh", "config");
38
+ const current = await readFile(userConfig, "utf8").catch(() => "");
39
+ if (current.includes(INCLUDE_MARKER)) {
40
+ return;
41
+ }
42
+ await mkdir(join(homedir(), ".ssh"), { recursive: true, mode: 0o700 });
43
+ const tmp = `${userConfig}.intentic-tmp`;
44
+ await writeFile(tmp, `${INCLUDE_MARKER}\n${current}`, { mode: 0o600 });
45
+ await rename(tmp, userConfig);
46
+ };
47
+ //# sourceMappingURL=ssh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh.js","sourceRoot":"","sources":["../src/ssh.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@intentic/sync",
3
+ "version": "0.0.0",
4
+ "description": "Local background agent that keeps a directory bidirectionally in sync with a remote intentic sandbox over its HTTP API",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/radarsu/intentic.git",
10
+ "directory": "_apps/sync"
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "publishConfig": {
16
+ "access": "public",
17
+ "registry": "https://registry.npmjs.org/"
18
+ },
19
+ "bin": {
20
+ "intentic-sync": "./dist/cli.js"
21
+ },
22
+ "dependencies": {
23
+ "@stricli/core": "1.2.8",
24
+ "tslib": "2.8.1"
25
+ },
26
+ "devDependencies": {
27
+ "@types/node": "24.13.2",
28
+ "typescript": "5.9.3",
29
+ "vitest": "4.1.9",
30
+ "@intentic/tsconfig": "0.0.0"
31
+ },
32
+ "scripts": {
33
+ "build": "tsc",
34
+ "watch": "tsc --build --watch",
35
+ "test": "vitest run",
36
+ "test:watch": "vitest"
37
+ }
38
+ }