@alfe.ai/openclaw-sync 0.1.10 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/cli/index.cjs +12 -8
- package/dist/cli/index.js +13 -9
- package/dist/cli/index.js.map +1 -1
- package/dist/defaults/common.alfesyncignore +43 -0
- package/dist/defaults/hermes.alfesyncignore +14 -0
- package/dist/defaults/openclaw.alfesyncignore +17 -0
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +213 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +213 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/plugin.d.cts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin2.cjs +23 -13
- package/dist/plugin2.js +24 -14
- package/dist/plugin2.js.map +1 -1
- package/dist/sync-engine.cjs +98 -33
- package/dist/sync-engine.js +88 -35
- package/dist/sync-engine.js.map +1 -1
- package/package.json +13 -3
package/README.md
CHANGED
|
@@ -58,3 +58,8 @@ pnpm --filter @alfe.ai/openclaw-sync test
|
|
|
58
58
|
- **micromatch** — glob pattern matching
|
|
59
59
|
|
|
60
60
|
See [SKILL.md](./SKILL.md) for full CLI usage, storage classes, conflict resolution, and programmatic API docs.
|
|
61
|
+
|
|
62
|
+
## Links
|
|
63
|
+
|
|
64
|
+
- 🌐 Website: <https://alfe.ai>
|
|
65
|
+
- 📚 Docs: <https://docs.alfe.ai>
|
package/dist/cli/index.cjs
CHANGED
|
@@ -29,7 +29,8 @@ function buildClient() {
|
|
|
29
29
|
apiKey: config.apiKey,
|
|
30
30
|
apiUrl: config.apiUrl
|
|
31
31
|
}),
|
|
32
|
-
workspacePath: config.workspacePath
|
|
32
|
+
workspacePath: config.workspacePath,
|
|
33
|
+
runtime: config.runtime
|
|
33
34
|
};
|
|
34
35
|
}
|
|
35
36
|
const program = new commander.Command();
|
|
@@ -49,10 +50,11 @@ program.command("register").description("Register this agent with the sync servi
|
|
|
49
50
|
});
|
|
50
51
|
program.command("push").description("Push local changes to remote").option("-q, --quiet", "Suppress output").option("-f, --filter <prefix>", "Only push files matching this prefix").action(async (opts) => {
|
|
51
52
|
try {
|
|
52
|
-
const { client, workspacePath } = buildClient();
|
|
53
|
+
const { client, workspacePath, runtime } = buildClient();
|
|
53
54
|
await require_sync_engine.createSyncEngine({
|
|
54
55
|
workspacePath,
|
|
55
|
-
client
|
|
56
|
+
client,
|
|
57
|
+
runtime
|
|
56
58
|
}).push(void 0, {
|
|
57
59
|
quiet: opts.quiet,
|
|
58
60
|
filter: opts.filter
|
|
@@ -64,10 +66,11 @@ program.command("push").description("Push local changes to remote").option("-q,
|
|
|
64
66
|
});
|
|
65
67
|
program.command("pull").description("Pull remote changes to local").option("-q, --quiet", "Suppress output").action(async (opts) => {
|
|
66
68
|
try {
|
|
67
|
-
const { client, workspacePath } = buildClient();
|
|
69
|
+
const { client, workspacePath, runtime } = buildClient();
|
|
68
70
|
await require_sync_engine.createSyncEngine({
|
|
69
71
|
workspacePath,
|
|
70
|
-
client
|
|
72
|
+
client,
|
|
73
|
+
runtime
|
|
71
74
|
}).pull({ quiet: opts.quiet });
|
|
72
75
|
} catch (err) {
|
|
73
76
|
console.error(err instanceof Error ? err.message : String(err));
|
|
@@ -137,8 +140,8 @@ program.command("conflicts").description("List conflict files in the workspace")
|
|
|
137
140
|
});
|
|
138
141
|
program.command("prune").description("Delete cloud files matching .alfesyncignore. Dry-run by default; pass --yes to actually delete.").option("-y, --yes", "Actually delete files (default is dry-run)").action(async (opts) => {
|
|
139
142
|
try {
|
|
140
|
-
const { client, workspacePath } = buildClient();
|
|
141
|
-
const ignorePatterns = await require_sync_engine.loadIgnorePatterns(workspacePath);
|
|
143
|
+
const { client, workspacePath, runtime } = buildClient();
|
|
144
|
+
const ignorePatterns = await require_sync_engine.loadIgnorePatterns(workspacePath, runtime);
|
|
142
145
|
const remoteManifest = await client.syncGetManifest();
|
|
143
146
|
const ignoredPaths = [];
|
|
144
147
|
for (const [path, entry] of Object.entries(remoteManifest.files)) if (require_sync_engine.shouldIgnore(path, ignorePatterns)) ignoredPaths.push({
|
|
@@ -162,7 +165,8 @@ program.command("prune").description("Delete cloud files matching .alfesyncignor
|
|
|
162
165
|
console.log(`Deleting ${String(ignoredPaths.length)} file(s) from cloud (${formatBytes(totalSize)})...`);
|
|
163
166
|
const result = await require_sync_engine.createSyncEngine({
|
|
164
167
|
workspacePath,
|
|
165
|
-
client
|
|
168
|
+
client,
|
|
169
|
+
runtime
|
|
166
170
|
}).pushDeletes(ignoredPaths.map((e) => e.path), { quiet: true });
|
|
167
171
|
console.log(`Prune complete: ${String(result.pushed)} deleted, ${String(result.errors)} failed.`);
|
|
168
172
|
} catch (err) {
|
package/dist/cli/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { c as shouldIgnore, d as diffManifests, f as readManifest, s as loadIgnorePatterns, t as createSyncEngine } from "../sync-engine.js";
|
|
3
3
|
import { readdir } from "node:fs/promises";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { configExists, resolveConfig } from "@alfe.ai/config";
|
|
@@ -29,7 +29,8 @@ function buildClient() {
|
|
|
29
29
|
apiKey: config.apiKey,
|
|
30
30
|
apiUrl: config.apiUrl
|
|
31
31
|
}),
|
|
32
|
-
workspacePath: config.workspacePath
|
|
32
|
+
workspacePath: config.workspacePath,
|
|
33
|
+
runtime: config.runtime
|
|
33
34
|
};
|
|
34
35
|
}
|
|
35
36
|
const program = new Command();
|
|
@@ -49,10 +50,11 @@ program.command("register").description("Register this agent with the sync servi
|
|
|
49
50
|
});
|
|
50
51
|
program.command("push").description("Push local changes to remote").option("-q, --quiet", "Suppress output").option("-f, --filter <prefix>", "Only push files matching this prefix").action(async (opts) => {
|
|
51
52
|
try {
|
|
52
|
-
const { client, workspacePath } = buildClient();
|
|
53
|
+
const { client, workspacePath, runtime } = buildClient();
|
|
53
54
|
await createSyncEngine({
|
|
54
55
|
workspacePath,
|
|
55
|
-
client
|
|
56
|
+
client,
|
|
57
|
+
runtime
|
|
56
58
|
}).push(void 0, {
|
|
57
59
|
quiet: opts.quiet,
|
|
58
60
|
filter: opts.filter
|
|
@@ -64,10 +66,11 @@ program.command("push").description("Push local changes to remote").option("-q,
|
|
|
64
66
|
});
|
|
65
67
|
program.command("pull").description("Pull remote changes to local").option("-q, --quiet", "Suppress output").action(async (opts) => {
|
|
66
68
|
try {
|
|
67
|
-
const { client, workspacePath } = buildClient();
|
|
69
|
+
const { client, workspacePath, runtime } = buildClient();
|
|
68
70
|
await createSyncEngine({
|
|
69
71
|
workspacePath,
|
|
70
|
-
client
|
|
72
|
+
client,
|
|
73
|
+
runtime
|
|
71
74
|
}).pull({ quiet: opts.quiet });
|
|
72
75
|
} catch (err) {
|
|
73
76
|
console.error(err instanceof Error ? err.message : String(err));
|
|
@@ -137,8 +140,8 @@ program.command("conflicts").description("List conflict files in the workspace")
|
|
|
137
140
|
});
|
|
138
141
|
program.command("prune").description("Delete cloud files matching .alfesyncignore. Dry-run by default; pass --yes to actually delete.").option("-y, --yes", "Actually delete files (default is dry-run)").action(async (opts) => {
|
|
139
142
|
try {
|
|
140
|
-
const { client, workspacePath } = buildClient();
|
|
141
|
-
const ignorePatterns = await loadIgnorePatterns(workspacePath);
|
|
143
|
+
const { client, workspacePath, runtime } = buildClient();
|
|
144
|
+
const ignorePatterns = await loadIgnorePatterns(workspacePath, runtime);
|
|
142
145
|
const remoteManifest = await client.syncGetManifest();
|
|
143
146
|
const ignoredPaths = [];
|
|
144
147
|
for (const [path, entry] of Object.entries(remoteManifest.files)) if (shouldIgnore(path, ignorePatterns)) ignoredPaths.push({
|
|
@@ -162,7 +165,8 @@ program.command("prune").description("Delete cloud files matching .alfesyncignor
|
|
|
162
165
|
console.log(`Deleting ${String(ignoredPaths.length)} file(s) from cloud (${formatBytes(totalSize)})...`);
|
|
163
166
|
const result = await createSyncEngine({
|
|
164
167
|
workspacePath,
|
|
165
|
-
client
|
|
168
|
+
client,
|
|
169
|
+
runtime
|
|
166
170
|
}).pushDeletes(ignoredPaths.map((e) => e.path), { quiet: true });
|
|
167
171
|
console.log(`Prune complete: ${String(result.pushed)} deleted, ${String(result.errors)} failed.`);
|
|
168
172
|
} catch (err) {
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["resolveAlfeConfig"],"sources":["../../src/cli/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * AlfeSync CLI — `alfesync` command-line interface.\n *\n * Credentials come from `~/.alfe/config.toml` (set up via `alfe login`).\n * No separate sync init step is required.\n *\n * Commands:\n * register - Idempotently register this agent with the sync service\n * push - Push local changes to remote\n * pull - Pull remote changes to local\n * status - Show sync status and pending changes\n * conflicts - List conflict files\n * prune - Delete cloud files matching .alfesyncignore (dry-run by default)\n * restore - Restore agent workspace from remote\n */\n\nimport { Command } from \"commander\";\nimport { join } from \"node:path\";\nimport { readdir } from \"node:fs/promises\";\nimport { AgentApiClient } from \"@alfe.ai/agent-api-client\";\nimport { resolveConfig as resolveAlfeConfig, configExists } from \"@alfe.ai/config\";\nimport { createSyncEngine } from \"../sync-engine.js\";\nimport { readManifest, diffManifests } from \"../manifest.js\";\nimport { loadIgnorePatterns, shouldIgnore } from \"../ignore.js\";\n\nfunction buildClient(): { client: AgentApiClient; workspacePath: string } {\n if (!configExists()) {\n throw new Error(\"Alfe not configured — run `alfe login` first.\");\n }\n const config = resolveAlfeConfig();\n return {\n client: new AgentApiClient({ apiKey: config.apiKey, apiUrl: config.apiUrl }),\n workspacePath: config.workspacePath,\n };\n}\n\nconst program = new Command();\n\nprogram\n .name(\"alfesync\")\n .description(\"AlfeSync — agent workspace backup and sync\")\n .version(\"1.0.0\");\n\n// ─── register ─────────────────────────────────────────────\n\nprogram\n .command(\"register\")\n .description(\"Register this agent with the sync service (idempotent)\")\n .option(\"-n, --display-name <name>\", \"Display name for the agent\")\n .action(async (opts: { displayName?: string }) => {\n try {\n const { client, workspacePath } = buildClient();\n const result = await client.syncRegister(\n opts.displayName ? { displayName: opts.displayName } : undefined,\n );\n console.log(\"✓ Agent registered with AlfeSync\");\n console.log(` Agent: ${result.agent.agentId}`);\n console.log(` Org: ${result.agent.tenantId}`);\n console.log(` Workspace: ${workspacePath}`);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// ─── push ─────────────────────────────────────────────────\n\nprogram\n .command(\"push\")\n .description(\"Push local changes to remote\")\n .option(\"-q, --quiet\", \"Suppress output\")\n .option(\"-f, --filter <prefix>\", \"Only push files matching this prefix\")\n .action(async (opts: { quiet?: boolean; filter?: string }) => {\n try {\n const { client, workspacePath } = buildClient();\n const engine = createSyncEngine({ workspacePath, client });\n await engine.push(undefined, { quiet: opts.quiet, filter: opts.filter });\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// ─── pull ─────────────────────────────────────────────────\n\nprogram\n .command(\"pull\")\n .description(\"Pull remote changes to local\")\n .option(\"-q, --quiet\", \"Suppress output\")\n .action(async (opts: { quiet?: boolean }) => {\n try {\n const { client, workspacePath } = buildClient();\n const engine = createSyncEngine({ workspacePath, client });\n await engine.pull({ quiet: opts.quiet });\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// ─── status ───────────────────────────────────────────────\n\nprogram\n .command(\"status\")\n .description(\"Show sync status and pending changes\")\n .action(async () => {\n try {\n const { client, workspacePath } = buildClient();\n const [localManifest, remoteManifest, stats] = await Promise.all([\n readManifest(workspacePath),\n client.syncGetManifest(),\n client.syncGetStats(),\n ]);\n const diff = diffManifests(localManifest, remoteManifest);\n\n console.log(\"AlfeSync Status\");\n console.log(\"═══════════════\");\n console.log(`Agent: ${stats.agentId}`);\n console.log(`Workspace: ${workspacePath}`);\n console.log(\"\");\n\n console.log(\"Storage:\");\n console.log(` Standard: ${formatBytes(stats.standardBytes)}`);\n console.log(` Glacier IR: ${formatBytes(stats.glacierBytes)}`);\n console.log(` Total files: ${String(stats.fileCount)}`);\n console.log(` Last sync: ${stats.lastSyncAt ?? \"never\"}`);\n console.log(\"\");\n\n console.log(\"Pending Changes:\");\n console.log(` To push: ${String(diff.toPush.length)}`);\n console.log(` To pull: ${String(diff.toPull.length)}`);\n console.log(` Conflicts: ${String(diff.conflicts.length)}`);\n\n if (diff.toPush.length > 0) {\n console.log(\"\");\n console.log(\"Files to push:\");\n for (const p of diff.toPush.slice(0, 20)) console.log(` ↑ ${p}`);\n if (diff.toPush.length > 20) {\n console.log(` ... and ${String(diff.toPush.length - 20)} more`);\n }\n }\n\n if (diff.toPull.length > 0) {\n console.log(\"\");\n console.log(\"Files to pull:\");\n for (const p of diff.toPull.slice(0, 20)) console.log(` ↓ ${p}`);\n if (diff.toPull.length > 20) {\n console.log(` ... and ${String(diff.toPull.length - 20)} more`);\n }\n }\n\n if (diff.conflicts.length > 0) {\n console.log(\"\");\n console.log(\"Conflicts:\");\n for (const p of diff.conflicts) console.log(` ⚡ ${p}`);\n }\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// ─── conflicts ────────────────────────────────────────────\n\nprogram\n .command(\"conflicts\")\n .description(\"List conflict files in the workspace\")\n .action(async () => {\n try {\n const { workspacePath } = buildClient();\n const conflicts = await findConflictFiles(workspacePath);\n if (conflicts.length === 0) {\n console.log(\"No conflict files found.\");\n return;\n }\n console.log(`Found ${String(conflicts.length)} conflict file(s):`);\n for (const f of conflicts) console.log(` ⚡ ${f}`);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// ─── prune ────────────────────────────────────────────────\n\nprogram\n .command(\"prune\")\n .description(\n \"Delete cloud files matching .alfesyncignore. Dry-run by default; pass --yes to actually delete.\",\n )\n .option(\"-y, --yes\", \"Actually delete files (default is dry-run)\")\n .action(async (opts: { yes?: boolean }) => {\n try {\n const { client, workspacePath } = buildClient();\n const ignorePatterns = await loadIgnorePatterns(workspacePath);\n const remoteManifest = await client.syncGetManifest();\n\n const ignoredPaths: { path: string; size: number }[] = [];\n for (const [path, entry] of Object.entries(remoteManifest.files)) {\n if (shouldIgnore(path, ignorePatterns)) {\n ignoredPaths.push({ path, size: entry.size });\n }\n }\n\n if (ignoredPaths.length === 0) {\n console.log(\"Nothing to prune — no cloud files match .alfesyncignore.\");\n return;\n }\n\n const totalSize = ignoredPaths.reduce((s, e) => s + e.size, 0);\n\n if (!opts.yes) {\n console.log(\n `Dry-run: ${String(ignoredPaths.length)} cloud file(s) would be deleted (${formatBytes(totalSize)}).`,\n );\n console.log(\"\");\n for (const { path, size } of ignoredPaths.slice(0, 50)) {\n console.log(` ✗ ${path} (${formatBytes(size)})`);\n }\n if (ignoredPaths.length > 50) {\n console.log(` ... and ${String(ignoredPaths.length - 50)} more`);\n }\n console.log(\"\");\n console.log(\"Re-run with --yes to delete these files from the cloud.\");\n return;\n }\n\n console.log(\n `Deleting ${String(ignoredPaths.length)} file(s) from cloud (${formatBytes(totalSize)})...`,\n );\n const engine = createSyncEngine({ workspacePath, client });\n const result = await engine.pushDeletes(\n ignoredPaths.map((e) => e.path),\n { quiet: true },\n );\n console.log(\n `Prune complete: ${String(result.pushed)} deleted, ${String(result.errors)} failed.`,\n );\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// ─── restore ──────────────────────────────────────────────\n\nprogram\n .command(\"restore\")\n .description(\"Restore agent workspace from remote backup\")\n .option(\"-m, --mode <mode>\", \"Restore mode: full, active, memory\", \"full\")\n .option(\"-q, --quiet\", \"Suppress output\")\n .action(async (opts: { mode?: string; quiet?: boolean }) => {\n try {\n const { client, workspacePath } = buildClient();\n const mode = opts.mode as \"full\" | \"active\" | \"memory\";\n if (![\"full\", \"active\", \"memory\"].includes(mode)) {\n console.error(\"Error: mode must be full, active, or memory\");\n process.exit(1);\n }\n\n if (!opts.quiet) console.log(`Restoring workspace (mode: ${mode})...`);\n const bundle = await client.syncReconstruct({ mode });\n\n if (!opts.quiet) {\n console.log(\n `Downloading ${String(bundle.fileCount)} files (${formatBytes(bundle.totalSize)})...`,\n );\n }\n\n const { writeFile, mkdir } = await import(\"node:fs/promises\");\n const { dirname } = await import(\"node:path\");\n\n let downloaded = 0;\n let errors = 0;\n for (const file of bundle.files) {\n try {\n const response = await fetch(file.url);\n if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);\n const buffer = Buffer.from(await response.arrayBuffer());\n const absolutePath = join(workspacePath, file.path);\n await mkdir(dirname(absolutePath), { recursive: true });\n await writeFile(absolutePath, buffer);\n downloaded++;\n if (!opts.quiet) console.log(` ↓ ${file.path} (${formatBytes(file.size)})`);\n } catch (err) {\n errors++;\n if (!opts.quiet) {\n console.error(\n ` ✗ ${file.path}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n\n if (!opts.quiet) {\n console.log(\n `\\nRestore complete: ${String(downloaded)} files downloaded, ${String(errors)} errors.`,\n );\n }\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// ─── Helpers ──────────────────────────────────────────────\n\nasync function findConflictFiles(dir: string, base?: string): Promise<string[]> {\n const results: string[] = [];\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name === \"node_modules\" || entry.name === \".git\") continue;\n const fullPath = join(dir, entry.name);\n const relativePath = base ? join(base, entry.name) : entry.name;\n if (entry.isDirectory()) {\n const sub = await findConflictFiles(fullPath, relativePath);\n results.push(...sub);\n } else if (entry.name.includes(\".conflict-\")) {\n results.push(relativePath);\n }\n }\n return results;\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${String(bytes)} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;\n}\n\n// ─── Run ──────────────────────────────────────────────────\n\nprogram.parse();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["resolveAlfeConfig"],"sources":["../../src/cli/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * AlfeSync CLI — `alfesync` command-line interface.\n *\n * Credentials come from `~/.alfe/config.toml` (set up via `alfe login`).\n * No separate sync init step is required.\n *\n * Commands:\n * register - Idempotently register this agent with the sync service\n * push - Push local changes to remote\n * pull - Pull remote changes to local\n * status - Show sync status and pending changes\n * conflicts - List conflict files\n * prune - Delete cloud files matching .alfesyncignore (dry-run by default)\n * restore - Restore agent workspace from remote\n */\n\nimport { Command } from \"commander\";\nimport { join } from \"node:path\";\nimport { readdir } from \"node:fs/promises\";\nimport { AgentApiClient } from \"@alfe.ai/agent-api-client\";\nimport { resolveConfig as resolveAlfeConfig, configExists } from \"@alfe.ai/config\";\nimport { createSyncEngine } from \"../sync-engine.js\";\nimport { readManifest, diffManifests } from \"../manifest.js\";\nimport { loadIgnorePatterns, shouldIgnore } from \"../ignore.js\";\n\nfunction buildClient(): { client: AgentApiClient; workspacePath: string; runtime: string } {\n if (!configExists()) {\n throw new Error(\"Alfe not configured — run `alfe login` first.\");\n }\n const config = resolveAlfeConfig();\n return {\n client: new AgentApiClient({ apiKey: config.apiKey, apiUrl: config.apiUrl }),\n workspacePath: config.workspacePath,\n runtime: config.runtime,\n };\n}\n\nconst program = new Command();\n\nprogram\n .name(\"alfesync\")\n .description(\"AlfeSync — agent workspace backup and sync\")\n .version(\"1.0.0\");\n\n// ─── register ─────────────────────────────────────────────\n\nprogram\n .command(\"register\")\n .description(\"Register this agent with the sync service (idempotent)\")\n .option(\"-n, --display-name <name>\", \"Display name for the agent\")\n .action(async (opts: { displayName?: string }) => {\n try {\n const { client, workspacePath } = buildClient();\n const result = await client.syncRegister(\n opts.displayName ? { displayName: opts.displayName } : undefined,\n );\n console.log(\"✓ Agent registered with AlfeSync\");\n console.log(` Agent: ${result.agent.agentId}`);\n console.log(` Org: ${result.agent.tenantId}`);\n console.log(` Workspace: ${workspacePath}`);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// ─── push ─────────────────────────────────────────────────\n\nprogram\n .command(\"push\")\n .description(\"Push local changes to remote\")\n .option(\"-q, --quiet\", \"Suppress output\")\n .option(\"-f, --filter <prefix>\", \"Only push files matching this prefix\")\n .action(async (opts: { quiet?: boolean; filter?: string }) => {\n try {\n const { client, workspacePath, runtime } = buildClient();\n const engine = createSyncEngine({ workspacePath, client, runtime });\n await engine.push(undefined, { quiet: opts.quiet, filter: opts.filter });\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// ─── pull ─────────────────────────────────────────────────\n\nprogram\n .command(\"pull\")\n .description(\"Pull remote changes to local\")\n .option(\"-q, --quiet\", \"Suppress output\")\n .action(async (opts: { quiet?: boolean }) => {\n try {\n const { client, workspacePath, runtime } = buildClient();\n const engine = createSyncEngine({ workspacePath, client, runtime });\n await engine.pull({ quiet: opts.quiet });\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// ─── status ───────────────────────────────────────────────\n\nprogram\n .command(\"status\")\n .description(\"Show sync status and pending changes\")\n .action(async () => {\n try {\n const { client, workspacePath } = buildClient();\n const [localManifest, remoteManifest, stats] = await Promise.all([\n readManifest(workspacePath),\n client.syncGetManifest(),\n client.syncGetStats(),\n ]);\n const diff = diffManifests(localManifest, remoteManifest);\n\n console.log(\"AlfeSync Status\");\n console.log(\"═══════════════\");\n console.log(`Agent: ${stats.agentId}`);\n console.log(`Workspace: ${workspacePath}`);\n console.log(\"\");\n\n console.log(\"Storage:\");\n console.log(` Standard: ${formatBytes(stats.standardBytes)}`);\n console.log(` Glacier IR: ${formatBytes(stats.glacierBytes)}`);\n console.log(` Total files: ${String(stats.fileCount)}`);\n console.log(` Last sync: ${stats.lastSyncAt ?? \"never\"}`);\n console.log(\"\");\n\n console.log(\"Pending Changes:\");\n console.log(` To push: ${String(diff.toPush.length)}`);\n console.log(` To pull: ${String(diff.toPull.length)}`);\n console.log(` Conflicts: ${String(diff.conflicts.length)}`);\n\n if (diff.toPush.length > 0) {\n console.log(\"\");\n console.log(\"Files to push:\");\n for (const p of diff.toPush.slice(0, 20)) console.log(` ↑ ${p}`);\n if (diff.toPush.length > 20) {\n console.log(` ... and ${String(diff.toPush.length - 20)} more`);\n }\n }\n\n if (diff.toPull.length > 0) {\n console.log(\"\");\n console.log(\"Files to pull:\");\n for (const p of diff.toPull.slice(0, 20)) console.log(` ↓ ${p}`);\n if (diff.toPull.length > 20) {\n console.log(` ... and ${String(diff.toPull.length - 20)} more`);\n }\n }\n\n if (diff.conflicts.length > 0) {\n console.log(\"\");\n console.log(\"Conflicts:\");\n for (const p of diff.conflicts) console.log(` ⚡ ${p}`);\n }\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// ─── conflicts ────────────────────────────────────────────\n\nprogram\n .command(\"conflicts\")\n .description(\"List conflict files in the workspace\")\n .action(async () => {\n try {\n const { workspacePath } = buildClient();\n const conflicts = await findConflictFiles(workspacePath);\n if (conflicts.length === 0) {\n console.log(\"No conflict files found.\");\n return;\n }\n console.log(`Found ${String(conflicts.length)} conflict file(s):`);\n for (const f of conflicts) console.log(` ⚡ ${f}`);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// ─── prune ────────────────────────────────────────────────\n\nprogram\n .command(\"prune\")\n .description(\n \"Delete cloud files matching .alfesyncignore. Dry-run by default; pass --yes to actually delete.\",\n )\n .option(\"-y, --yes\", \"Actually delete files (default is dry-run)\")\n .action(async (opts: { yes?: boolean }) => {\n try {\n const { client, workspacePath, runtime } = buildClient();\n const ignorePatterns = await loadIgnorePatterns(workspacePath, runtime);\n const remoteManifest = await client.syncGetManifest();\n\n const ignoredPaths: { path: string; size: number }[] = [];\n for (const [path, entry] of Object.entries(remoteManifest.files)) {\n if (shouldIgnore(path, ignorePatterns)) {\n ignoredPaths.push({ path, size: entry.size });\n }\n }\n\n if (ignoredPaths.length === 0) {\n console.log(\"Nothing to prune — no cloud files match .alfesyncignore.\");\n return;\n }\n\n const totalSize = ignoredPaths.reduce((s, e) => s + e.size, 0);\n\n if (!opts.yes) {\n console.log(\n `Dry-run: ${String(ignoredPaths.length)} cloud file(s) would be deleted (${formatBytes(totalSize)}).`,\n );\n console.log(\"\");\n for (const { path, size } of ignoredPaths.slice(0, 50)) {\n console.log(` ✗ ${path} (${formatBytes(size)})`);\n }\n if (ignoredPaths.length > 50) {\n console.log(` ... and ${String(ignoredPaths.length - 50)} more`);\n }\n console.log(\"\");\n console.log(\"Re-run with --yes to delete these files from the cloud.\");\n return;\n }\n\n console.log(\n `Deleting ${String(ignoredPaths.length)} file(s) from cloud (${formatBytes(totalSize)})...`,\n );\n const engine = createSyncEngine({ workspacePath, client, runtime });\n const result = await engine.pushDeletes(\n ignoredPaths.map((e) => e.path),\n { quiet: true },\n );\n console.log(\n `Prune complete: ${String(result.pushed)} deleted, ${String(result.errors)} failed.`,\n );\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// ─── restore ──────────────────────────────────────────────\n\nprogram\n .command(\"restore\")\n .description(\"Restore agent workspace from remote backup\")\n .option(\"-m, --mode <mode>\", \"Restore mode: full, active, memory\", \"full\")\n .option(\"-q, --quiet\", \"Suppress output\")\n .action(async (opts: { mode?: string; quiet?: boolean }) => {\n try {\n const { client, workspacePath } = buildClient();\n const mode = opts.mode as \"full\" | \"active\" | \"memory\";\n if (![\"full\", \"active\", \"memory\"].includes(mode)) {\n console.error(\"Error: mode must be full, active, or memory\");\n process.exit(1);\n }\n\n if (!opts.quiet) console.log(`Restoring workspace (mode: ${mode})...`);\n const bundle = await client.syncReconstruct({ mode });\n\n if (!opts.quiet) {\n console.log(\n `Downloading ${String(bundle.fileCount)} files (${formatBytes(bundle.totalSize)})...`,\n );\n }\n\n const { writeFile, mkdir } = await import(\"node:fs/promises\");\n const { dirname } = await import(\"node:path\");\n\n let downloaded = 0;\n let errors = 0;\n for (const file of bundle.files) {\n try {\n const response = await fetch(file.url);\n if (!response.ok) throw new Error(`HTTP ${String(response.status)}`);\n const buffer = Buffer.from(await response.arrayBuffer());\n const absolutePath = join(workspacePath, file.path);\n await mkdir(dirname(absolutePath), { recursive: true });\n await writeFile(absolutePath, buffer);\n downloaded++;\n if (!opts.quiet) console.log(` ↓ ${file.path} (${formatBytes(file.size)})`);\n } catch (err) {\n errors++;\n if (!opts.quiet) {\n console.error(\n ` ✗ ${file.path}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n\n if (!opts.quiet) {\n console.log(\n `\\nRestore complete: ${String(downloaded)} files downloaded, ${String(errors)} errors.`,\n );\n }\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// ─── Helpers ──────────────────────────────────────────────\n\nasync function findConflictFiles(dir: string, base?: string): Promise<string[]> {\n const results: string[] = [];\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name === \"node_modules\" || entry.name === \".git\") continue;\n const fullPath = join(dir, entry.name);\n const relativePath = base ? join(base, entry.name) : entry.name;\n if (entry.isDirectory()) {\n const sub = await findConflictFiles(fullPath, relativePath);\n results.push(...sub);\n } else if (entry.name.includes(\".conflict-\")) {\n results.push(relativePath);\n }\n }\n return results;\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${String(bytes)} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;\n}\n\n// ─── Run ──────────────────────────────────────────────────\n\nprogram.parse();\n"],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# AlfeSync default ignores — applied to EVERY runtime.
|
|
2
|
+
#
|
|
3
|
+
# Source of truth for the sync's baseline ignore set (previously the hardcoded
|
|
4
|
+
# DEFAULT_IGNORES array). Entries are full micromatch globs, NOT gitignore
|
|
5
|
+
# shorthand — they are used verbatim (the workspace `.alfesyncignore` is the
|
|
6
|
+
# gitignore-shorthand surface). Match a name at any depth with a `**/` prefix;
|
|
7
|
+
# `matchBase` is never used (it breaks deep `**/X/**` in micromatch 4.x).
|
|
8
|
+
#
|
|
9
|
+
# Categories:
|
|
10
|
+
# VCS / build / package metadata; OS + editor noise; sync-internal backstop;
|
|
11
|
+
# secrets (never sync); OpenClaw config-rotation backups; Chromium/Electron
|
|
12
|
+
# browser caches (zero restore value, tens of MB); language churn.
|
|
13
|
+
|
|
14
|
+
**/.alfesync/**
|
|
15
|
+
# shared/ mirrors org/team/project files (OrgFilesBucket) into the workspace via
|
|
16
|
+
# shared-sync — the PRIVATE backup must not re-store them into SyncBucket, or a
|
|
17
|
+
# rebuild would restore stale shared files from the wrong bucket. Root-anchored
|
|
18
|
+
# to the runtime home; a nested user `workspace/shared/` still syncs.
|
|
19
|
+
shared/**
|
|
20
|
+
**/node_modules/**
|
|
21
|
+
**/*.tmp
|
|
22
|
+
**/.DS_Store
|
|
23
|
+
**/.git/**
|
|
24
|
+
**/.sst/**
|
|
25
|
+
**/.build/**
|
|
26
|
+
**/dist/**
|
|
27
|
+
**/.env
|
|
28
|
+
**/.env.*
|
|
29
|
+
**/openclaw.json.bak*
|
|
30
|
+
**/openclaw.json.clobbered.*
|
|
31
|
+
**/openclaw.json.preserve.*
|
|
32
|
+
**/Cache/**
|
|
33
|
+
**/Code Cache/**
|
|
34
|
+
**/GPUCache/**
|
|
35
|
+
**/CacheStorage/**
|
|
36
|
+
**/Service Worker/CacheStorage/**
|
|
37
|
+
**/blob_storage/**
|
|
38
|
+
**/Crashpad/**
|
|
39
|
+
**/ShaderCache/**
|
|
40
|
+
**/component_crx_cache/**
|
|
41
|
+
**/__pycache__/**
|
|
42
|
+
**/*.pyc
|
|
43
|
+
**/*.log
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# AlfeSync default ignores — Hermes runtime only.
|
|
2
|
+
#
|
|
3
|
+
# The sync watches the Hermes runtime HOME (~/.hermes), whose top level holds
|
|
4
|
+
# the Python venv and the installed agent code as siblings of user files.
|
|
5
|
+
# Large / high-churn / regenerable — never sync.
|
|
6
|
+
#
|
|
7
|
+
# `.venv/` is matched at any depth (nested venvs are common); `hermes-agent/`
|
|
8
|
+
# is root-anchored to the runtime home. Full micromatch globs, used verbatim.
|
|
9
|
+
# (`__pycache__` and `*.pyc` are already covered by the common set.)
|
|
10
|
+
|
|
11
|
+
# Python virtual environment
|
|
12
|
+
**/.venv/**
|
|
13
|
+
# Hermes runtime code installed by the installer: ~/.hermes/hermes-agent/...
|
|
14
|
+
hermes-agent/**
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# AlfeSync default ignores — OpenClaw runtime only.
|
|
2
|
+
#
|
|
3
|
+
# The sync watches the OpenClaw runtime HOME (~/.openclaw), whose top level
|
|
4
|
+
# holds runtime-internal dirs as siblings of the agent-owned `workspace/`.
|
|
5
|
+
# These are large, high-churn, and have zero restore value — if synced they
|
|
6
|
+
# exhaust the OS inotify watch limit and crash-loop the runtime.
|
|
7
|
+
#
|
|
8
|
+
# Root-anchored (no `**/` prefix) so they only match the runtime home's top
|
|
9
|
+
# level — a user dir named `plugins/` deeper in the workspace still syncs.
|
|
10
|
+
# Full micromatch globs, used verbatim.
|
|
11
|
+
|
|
12
|
+
# npm plugin registry (OpenClaw 2026.5+): ~/.openclaw/npm/node_modules/...
|
|
13
|
+
npm/**
|
|
14
|
+
# Plugin extension installs (OpenClaw 2026.4): ~/.openclaw/extensions/...
|
|
15
|
+
extensions/**
|
|
16
|
+
# Plugin install metadata (installs.json etc.): ~/.openclaw/plugins/...
|
|
17
|
+
plugins/**
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_sync_engine = require("./sync-engine.cjs");
|
|
3
3
|
const require_plugin = require("./plugin2.cjs");
|
|
4
|
+
exports.DEFAULT_IGNORES = require_sync_engine.DEFAULT_IGNORES;
|
|
4
5
|
exports.computeFileHash = require_sync_engine.computeFileHash;
|
|
5
6
|
exports.createSharedSyncEngine = require_plugin.createSharedSyncEngine;
|
|
6
7
|
exports.createSyncEngine = require_sync_engine.createSyncEngine;
|
|
@@ -12,6 +13,7 @@ exports.plugin = require_plugin.plugin;
|
|
|
12
13
|
exports.readManifest = require_sync_engine.readManifest;
|
|
13
14
|
exports.removeManifestEntry = require_sync_engine.removeManifestEntry;
|
|
14
15
|
exports.shouldIgnore = require_sync_engine.shouldIgnore;
|
|
16
|
+
exports.shouldIgnoreDir = require_sync_engine.shouldIgnoreDir;
|
|
15
17
|
exports.startWatcher = require_plugin.startWatcher;
|
|
16
18
|
exports.updateManifestEntry = require_sync_engine.updateManifestEntry;
|
|
17
19
|
exports.uploadFiles = require_sync_engine.uploadFiles;
|
package/dist/index.d.cts
CHANGED
|
@@ -81,8 +81,10 @@ declare function diffManifests(local: LocalManifest, remote: RemoteManifest): Ma
|
|
|
81
81
|
//# sourceMappingURL=manifest.d.ts.map
|
|
82
82
|
//#endregion
|
|
83
83
|
//#region src/ignore.d.ts
|
|
84
|
-
declare
|
|
84
|
+
declare const DEFAULT_IGNORES: string[];
|
|
85
|
+
declare function loadIgnorePatterns(workspacePath: string, runtime?: string): Promise<string[]>;
|
|
85
86
|
declare function shouldIgnore(relativePath: string, patterns: string[]): boolean;
|
|
87
|
+
declare function shouldIgnoreDir(relativeDir: string, patterns: string[]): boolean;
|
|
86
88
|
declare function filterIgnored(paths: string[], patterns: string[]): string[];
|
|
87
89
|
//# sourceMappingURL=ignore.d.ts.map
|
|
88
90
|
//#endregion
|
|
@@ -93,6 +95,15 @@ interface AgentApiClientConfig {
|
|
|
93
95
|
apiKey: string;
|
|
94
96
|
apiUrl: string;
|
|
95
97
|
}
|
|
98
|
+
interface RemoteSessionInfo {
|
|
99
|
+
sessionId: string;
|
|
100
|
+
agentId: string;
|
|
101
|
+
surface: "browser" | "terminal";
|
|
102
|
+
status: "agent_driving" | "awaiting_human" | "human_in_control" | "resuming" | "completed" | "expired" | "failed";
|
|
103
|
+
url?: string;
|
|
104
|
+
instructions?: string;
|
|
105
|
+
requestedAt?: string;
|
|
106
|
+
}
|
|
96
107
|
interface SyncAgentInfo {
|
|
97
108
|
agentId: string;
|
|
98
109
|
tenantId: string;
|
|
@@ -233,6 +244,79 @@ interface KnowledgeDoc {
|
|
|
233
244
|
createdAt: string;
|
|
234
245
|
updatedAt: string;
|
|
235
246
|
}
|
|
247
|
+
/** Voice settings — core agent config. Mirrors `VoiceConfig` in `@alfe/types`. */
|
|
248
|
+
interface AgentVoiceConfig {
|
|
249
|
+
/** ElevenLabs voice ID; platform default when unset. */
|
|
250
|
+
voiceId?: string;
|
|
251
|
+
ttsModel?: string;
|
|
252
|
+
enabled?: boolean;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* The agent's own public identity, as returned by `updateSelf`, `generateAvatar`,
|
|
256
|
+
* `presignAvatar`'s finalize (`finalizeAvatar`). This is the public agent
|
|
257
|
+
* projection; only the identity-relevant fields are typed here — the response
|
|
258
|
+
* carries the full public agent record.
|
|
259
|
+
*/
|
|
260
|
+
interface AgentSelf {
|
|
261
|
+
agentId: string;
|
|
262
|
+
tenantId: string;
|
|
263
|
+
name: string;
|
|
264
|
+
avatarUrl?: string;
|
|
265
|
+
voiceConfig?: AgentVoiceConfig;
|
|
266
|
+
status: string;
|
|
267
|
+
}
|
|
268
|
+
/** Result of `presignAvatar` — the agent PUTs bytes to `uploadUrl`, then finalizes with `s3Key`. */
|
|
269
|
+
interface AgentAvatarPresign {
|
|
270
|
+
/** Presigned PUT URL to upload the image bytes to. */
|
|
271
|
+
uploadUrl: string;
|
|
272
|
+
/** Object key — echoed back to `finalizeAvatar`. */
|
|
273
|
+
s3Key: string;
|
|
274
|
+
/** Stable public URL the avatar will be served from once finalized. */
|
|
275
|
+
publicUrl: string;
|
|
276
|
+
/** ISO expiry of the presigned PUT URL. */
|
|
277
|
+
expiresAt: string;
|
|
278
|
+
}
|
|
279
|
+
/** A voice in the platform catalogue (ElevenLabs), from `listVoices`. */
|
|
280
|
+
interface AgentVoice {
|
|
281
|
+
id: string;
|
|
282
|
+
name: string;
|
|
283
|
+
previewUrl: string;
|
|
284
|
+
description: string;
|
|
285
|
+
labels: Record<string, string>;
|
|
286
|
+
category: string;
|
|
287
|
+
}
|
|
288
|
+
/** The ElevenLabs models with a pricing row — the TTS endpoint rejects any other value. */
|
|
289
|
+
type VoiceTtsModel = "eleven_turbo_v2_5" | "eleven_multilingual_v2";
|
|
290
|
+
interface VoiceTtsArgs {
|
|
291
|
+
/** Text to synthesize (1–5000 chars — the endpoint enforces this). */
|
|
292
|
+
text: string;
|
|
293
|
+
/** ElevenLabs voice id; platform default when unset. */
|
|
294
|
+
voiceId?: string;
|
|
295
|
+
/** TTS model; `eleven_turbo_v2_5` (lower latency) when unset. */
|
|
296
|
+
model?: VoiceTtsModel;
|
|
297
|
+
}
|
|
298
|
+
/** Raw synthesized audio plus its PCM framing (from the response headers). */
|
|
299
|
+
interface VoiceTtsResult {
|
|
300
|
+
/** Raw little-endian PCM samples — no container. Wrap in WAV to make a playable file. */
|
|
301
|
+
audio: Buffer;
|
|
302
|
+
/** Samples per second (e.g. 24000). */
|
|
303
|
+
sampleRate: number;
|
|
304
|
+
/** Channel count (mono = 1). */
|
|
305
|
+
channels: number;
|
|
306
|
+
/** Bits per sample (e.g. 16). */
|
|
307
|
+
bitDepth: number;
|
|
308
|
+
}
|
|
309
|
+
interface VoiceSttArgs {
|
|
310
|
+
/** Raw linear16 (16-bit little-endian) mono PCM samples — no WAV/container header. */
|
|
311
|
+
audio: Uint8Array;
|
|
312
|
+
/** Sample rate of `audio` in Hz (8000–48000). */
|
|
313
|
+
sampleRate: number;
|
|
314
|
+
}
|
|
315
|
+
interface VoiceSttResult {
|
|
316
|
+
text: string;
|
|
317
|
+
/** Deepgram confidence in (0,1]. */
|
|
318
|
+
confidence: number;
|
|
319
|
+
}
|
|
236
320
|
declare class AgentApiClient {
|
|
237
321
|
private readonly apiKey;
|
|
238
322
|
private readonly apiUrl;
|
|
@@ -756,6 +840,35 @@ declare class AgentApiClient {
|
|
|
756
840
|
}): Promise<{
|
|
757
841
|
recorded: boolean;
|
|
758
842
|
}>;
|
|
843
|
+
/** Update the agent's own name and/or voice config. Returns the updated agent. */
|
|
844
|
+
updateSelf(update: {
|
|
845
|
+
name?: string;
|
|
846
|
+
voiceConfig?: AgentVoiceConfig;
|
|
847
|
+
}): Promise<AgentSelf>;
|
|
848
|
+
/**
|
|
849
|
+
* Generate the agent's own avatar from a text prompt. The image is generated,
|
|
850
|
+
* stored, and set on the agent server-side; returns the updated agent.
|
|
851
|
+
*/
|
|
852
|
+
generateAvatar(args: {
|
|
853
|
+
prompt: string;
|
|
854
|
+
}): Promise<AgentSelf>;
|
|
855
|
+
/**
|
|
856
|
+
* Get a presigned PUT URL to upload a new avatar image. Upload the bytes to
|
|
857
|
+
* `uploadUrl`, then call `finalizeAvatar(s3Key)` to set it on the agent.
|
|
858
|
+
*/
|
|
859
|
+
presignAvatar(args: {
|
|
860
|
+
mimeType: string;
|
|
861
|
+
size: number;
|
|
862
|
+
}): Promise<AgentAvatarPresign>;
|
|
863
|
+
/**
|
|
864
|
+
* Finalize an avatar upload — validates ownership + size, then sets the
|
|
865
|
+
* agent's `avatarUrl` server-side. Returns the updated agent.
|
|
866
|
+
*/
|
|
867
|
+
finalizeAvatar(s3Key: string): Promise<AgentSelf>;
|
|
868
|
+
/** List the platform voice catalogue (ElevenLabs) so the agent can pick its own voice. */
|
|
869
|
+
listVoices(): Promise<{
|
|
870
|
+
voices: AgentVoice[];
|
|
871
|
+
}>;
|
|
759
872
|
/**
|
|
760
873
|
* Mint a fresh AES-256 data key for a specific (secret, field) pair. The
|
|
761
874
|
* encryption context is rebuilt server-side from `auth.tenantId` + the body
|
|
@@ -1250,6 +1363,46 @@ declare class AgentApiClient {
|
|
|
1250
1363
|
operation: string;
|
|
1251
1364
|
summary?: string;
|
|
1252
1365
|
}): Promise<void>;
|
|
1366
|
+
requestBrowserTakeover(args: {
|
|
1367
|
+
instructions: string;
|
|
1368
|
+
url?: string;
|
|
1369
|
+
conversationId?: string;
|
|
1370
|
+
}): Promise<{
|
|
1371
|
+
sessionId: string;
|
|
1372
|
+
status: string;
|
|
1373
|
+
}>;
|
|
1374
|
+
getRemoteSession(sessionId: string): Promise<RemoteSessionInfo>;
|
|
1375
|
+
completeRemoteSession(sessionId: string): Promise<{
|
|
1376
|
+
ok: boolean;
|
|
1377
|
+
}>;
|
|
1378
|
+
/**
|
|
1379
|
+
* Issue a request that returns the raw `Response` (no JSON parsing, no
|
|
1380
|
+
* forced Content-Type). The caller sets `Content-Type`/`Accept` on `headers`
|
|
1381
|
+
* and reads the body itself (`arrayBuffer()` / `json()`).
|
|
1382
|
+
*
|
|
1383
|
+
* A single retry fires only on the same transient statuses `request()`
|
|
1384
|
+
* retries (authorizer-timeout 500 + LB 502/503/504) and transient network
|
|
1385
|
+
* errors — before the route handler runs — so re-issuing a POST does not
|
|
1386
|
+
* risk a duplicate side effect. Voice TTS/STT are effectively idempotent
|
|
1387
|
+
* (re-synthesize / re-transcribe) and meter server-side keyed on the
|
|
1388
|
+
* gateway requestId, so a retried transcription doesn't double-bill.
|
|
1389
|
+
*/
|
|
1390
|
+
private rawFetch;
|
|
1391
|
+
/**
|
|
1392
|
+
* Text-to-speech. Returns raw PCM audio bytes plus their framing — the
|
|
1393
|
+
* voice service defaults to 24 kHz / mono / 16-bit. Wrap in a WAV container
|
|
1394
|
+
* to produce a playable file. Metered per character against the tenant
|
|
1395
|
+
* credit pool server-side; TTS completes regardless of metering outcome.
|
|
1396
|
+
*/
|
|
1397
|
+
tts(args: VoiceTtsArgs): Promise<VoiceTtsResult>;
|
|
1398
|
+
/**
|
|
1399
|
+
* Speech-to-text. Accepts raw linear16 (16-bit LE) mono PCM — NOT a WAV or
|
|
1400
|
+
* other container (the endpoint transcribes with a fixed linear16 encoding,
|
|
1401
|
+
* so a container header would be transcribed as noise). Strip any WAV header
|
|
1402
|
+
* and pass `sampleRate` from it before calling. Metered by transcribed
|
|
1403
|
+
* duration against the tenant credit pool server-side.
|
|
1404
|
+
*/
|
|
1405
|
+
stt(args: VoiceSttArgs): Promise<VoiceSttResult>;
|
|
1253
1406
|
}
|
|
1254
1407
|
//# sourceMappingURL=index.d.ts.map
|
|
1255
1408
|
//#endregion
|
|
@@ -1264,6 +1417,11 @@ interface SyncResult {
|
|
|
1264
1417
|
interface SyncEngineOptions {
|
|
1265
1418
|
workspacePath: string;
|
|
1266
1419
|
client: AgentApiClient;
|
|
1420
|
+
/**
|
|
1421
|
+
* Active agent runtime — selects the per-runtime default ignore set used by
|
|
1422
|
+
* every scan (push / fullSync / firstRunReconcile). Default: "openclaw".
|
|
1423
|
+
*/
|
|
1424
|
+
runtime?: string;
|
|
1267
1425
|
}
|
|
1268
1426
|
/**
|
|
1269
1427
|
* Construct a sync engine bound to a workspace + agent API client.
|
|
@@ -1273,10 +1431,12 @@ interface SyncEngineOptions {
|
|
|
1273
1431
|
*/
|
|
1274
1432
|
declare function createSyncEngine({
|
|
1275
1433
|
workspacePath,
|
|
1276
|
-
client
|
|
1434
|
+
client,
|
|
1435
|
+
runtime
|
|
1277
1436
|
}: SyncEngineOptions): {
|
|
1278
1437
|
workspacePath: string;
|
|
1279
1438
|
client: AgentApiClient;
|
|
1439
|
+
runtime: string;
|
|
1280
1440
|
/**
|
|
1281
1441
|
* Upload changed files. Pass `paths` for an explicit list, or omit
|
|
1282
1442
|
* to scan the workspace for anything that drifted from the manifest.
|
|
@@ -1299,6 +1459,36 @@ declare function createSyncEngine({
|
|
|
1299
1459
|
fullSync(options?: {
|
|
1300
1460
|
quiet?: boolean;
|
|
1301
1461
|
}): Promise<SyncResult>;
|
|
1462
|
+
/**
|
|
1463
|
+
* First-run reconcile for realtime activation.
|
|
1464
|
+
*
|
|
1465
|
+
* Distinguishes a genuinely NEW agent (empty cloud state → push-only
|
|
1466
|
+
* seed, today's behaviour) from a REBUILD / reconnect (cloud already
|
|
1467
|
+
* holds this agent's last-synced state → restore cloud → local, cloud
|
|
1468
|
+
* wins, THEN seed only the files that are new locally).
|
|
1469
|
+
*
|
|
1470
|
+
* Why not `push(undefined)`? On a from-scratch VM rebuild the local
|
|
1471
|
+
* manifest is gone and `alfe setup` has just re-seeded the persona
|
|
1472
|
+
* templates (SOUL.md, IDENTITY.md, …) onto a fresh disk. With no
|
|
1473
|
+
* manifest, `detectLocalChanges()` classifies every seeded template as
|
|
1474
|
+
* "new", so a blind push uploads those fresh seeds OVER the agent's
|
|
1475
|
+
* edited cloud copy — the agent's edits are lost on every rebuild. This
|
|
1476
|
+
* is the persona-durability gap this method closes.
|
|
1477
|
+
*
|
|
1478
|
+
* Why not `fullSync()`? With an empty local manifest it double-counts
|
|
1479
|
+
* each on-disk seed as BOTH a push candidate (`detectLocalChanges`) and
|
|
1480
|
+
* a pull candidate (remote-only in `diffManifests`, since the local
|
|
1481
|
+
* manifest has no entry for it). fullSync pushes before it pulls, so it
|
|
1482
|
+
* would still clobber the cloud edit before restoring it locally.
|
|
1483
|
+
*
|
|
1484
|
+
* Conflict direction: for a rebuild the CLOUD copy is authoritative for
|
|
1485
|
+
* anything it holds. We do not write `.conflict-<ts>` markers here — a
|
|
1486
|
+
* fresh setup seed losing to the agent's own prior edit is the intended
|
|
1487
|
+
* outcome, not a conflict.
|
|
1488
|
+
*/
|
|
1489
|
+
firstRunReconcile(options?: {
|
|
1490
|
+
quiet?: boolean;
|
|
1491
|
+
}): Promise<SyncResult>;
|
|
1302
1492
|
/**
|
|
1303
1493
|
* Pull a known list of files (used for relay-driven notifications,
|
|
1304
1494
|
* where we already know which paths changed remotely).
|
|
@@ -1306,6 +1496,20 @@ declare function createSyncEngine({
|
|
|
1306
1496
|
pullFiles(paths: string[], options?: {
|
|
1307
1497
|
quiet?: boolean;
|
|
1308
1498
|
}): Promise<SyncResult>;
|
|
1499
|
+
/**
|
|
1500
|
+
* Purge cloud files that match the current (per-runtime) ignore set.
|
|
1501
|
+
*
|
|
1502
|
+
* Self-heals workspaces whose cloud copy still holds runtime-internal junk
|
|
1503
|
+
* (node_modules, the openclaw npm cache, …) that a pre-fix ignore engine
|
|
1504
|
+
* uploaded before it was correctly ignored. Bounded to ignored paths only,
|
|
1505
|
+
* so it can never delete a legitimately-synced file, and it deletes the
|
|
1506
|
+
* cloud copy directly (not via the watcher) so the rolling-window delete
|
|
1507
|
+
* brake — which guards against a buggy `rm -rf` — does not apply.
|
|
1508
|
+
*/
|
|
1509
|
+
pruneIgnored(options?: {
|
|
1510
|
+
quiet?: boolean;
|
|
1511
|
+
limit?: number;
|
|
1512
|
+
}): Promise<SyncResult>;
|
|
1309
1513
|
/**
|
|
1310
1514
|
* Delete a file locally and from the manifest. Used when the sync relay
|
|
1311
1515
|
* tells us a file was removed remotely.
|
|
@@ -1326,6 +1530,12 @@ type SyncEngine = ReturnType<typeof createSyncEngine>;
|
|
|
1326
1530
|
*/
|
|
1327
1531
|
interface WatcherOptions {
|
|
1328
1532
|
workspacePath: string;
|
|
1533
|
+
/**
|
|
1534
|
+
* Active agent runtime — selects the per-runtime default ignore set so the
|
|
1535
|
+
* watcher never descends into runtime-internal dirs (openclaw `npm/`,
|
|
1536
|
+
* hermes `.venv/`, …). Default: "openclaw".
|
|
1537
|
+
*/
|
|
1538
|
+
runtime?: string;
|
|
1329
1539
|
/** Debounce delay per file in milliseconds. Default: 2000 */
|
|
1330
1540
|
debounceMs?: number;
|
|
1331
1541
|
/** Callback invoked with batches of changed relative paths */
|
|
@@ -1411,5 +1621,5 @@ interface SharedSyncEngine {
|
|
|
1411
1621
|
}
|
|
1412
1622
|
declare function createSharedSyncEngine(config: SharedSyncConfig, log: PluginLogger): SharedSyncEngine;
|
|
1413
1623
|
//#endregion
|
|
1414
|
-
export { type DownloadResult, type LocalManifest, type ManifestDiff, type ManifestEntry, type RemoteManifest, type RetryOptions, type SharedScope, type SharedSyncConfig, type SharedSyncEngine, type SyncEngine, type SyncPluginConfig, type SyncResult, type UploadResult, type WatcherOptions, computeFileHash, createSharedSyncEngine, createSyncEngine, diffManifests, downloadFiles, filterIgnored, loadIgnorePatterns, plugin, readManifest, removeManifestEntry, shouldIgnore, startWatcher, updateManifestEntry, uploadFiles, withRetry, writeManifest };
|
|
1624
|
+
export { DEFAULT_IGNORES, type DownloadResult, type LocalManifest, type ManifestDiff, type ManifestEntry, type RemoteManifest, type RetryOptions, type SharedScope, type SharedSyncConfig, type SharedSyncEngine, type SyncEngine, type SyncPluginConfig, type SyncResult, type UploadResult, type WatcherOptions, computeFileHash, createSharedSyncEngine, createSyncEngine, diffManifests, downloadFiles, filterIgnored, loadIgnorePatterns, plugin, readManifest, removeManifestEntry, shouldIgnore, shouldIgnoreDir, startWatcher, updateManifestEntry, uploadFiles, withRetry, writeManifest };
|
|
1415
1625
|
//# sourceMappingURL=index.d.cts.map
|