clawvault 2.3.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/clawvault.js +6 -0
- package/bin/register-tailscale-commands.js +106 -0
- package/dist/{chunk-2HM7ZI4X.js → chunk-2AYPFUGX.js} +1 -1
- package/dist/chunk-4GBPTBFJ.js +628 -0
- package/dist/{chunk-PTSEIWXZ.js → chunk-6AQZIPLV.js} +2 -2
- package/dist/chunk-CLE2HHNT.js +513 -0
- package/dist/{chunk-VR5NE7PZ.js → chunk-HVTTYDCJ.js} +1 -1
- package/dist/{chunk-GQVYQCY5.js → chunk-JVAWKNIZ.js} +2 -2
- package/dist/{chunk-Z2XBWN7A.js → chunk-NAMFB7ZA.js} +2 -0
- package/dist/chunk-NZ4ZZNSR.js +373 -0
- package/dist/{chunk-MQUJNOHK.js → chunk-QALB2V3E.js} +1 -1
- package/dist/{chunk-6BBTI7NV.js → chunk-RARDNTUP.js} +2 -2
- package/dist/{chunk-SOTWYGH7.js → chunk-TB3BM2PQ.js} +1 -1
- package/dist/{chunk-GJEGPO7U.js → chunk-TT3FXYCN.js} +1 -1
- package/dist/{chunk-DPS7NYIU.js → chunk-USZU5CBB.js} +2 -2
- package/dist/{chunk-5WR6RRPX.js → chunk-VBVEXNI5.js} +1 -1
- package/dist/commands/archive.js +3 -3
- package/dist/commands/canvas.js +386 -12
- package/dist/commands/context.js +2 -2
- package/dist/commands/migrate-observations.js +2 -2
- package/dist/commands/observe.js +3 -3
- package/dist/commands/rebuild.js +3 -3
- package/dist/commands/reflect.js +4 -4
- package/dist/commands/replay.js +5 -5
- package/dist/commands/sleep.js +4 -4
- package/dist/commands/tailscale.d.ts +52 -0
- package/dist/commands/tailscale.js +25 -0
- package/dist/commands/wake.js +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +74 -12
- package/dist/lib/tailscale.d.ts +225 -0
- package/dist/lib/tailscale.js +49 -0
- package/dist/lib/webdav.d.ts +109 -0
- package/dist/lib/webdav.js +34 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2,6 +2,39 @@ import {
|
|
|
2
2
|
registerSyncBdCommand,
|
|
3
3
|
syncBdCommand
|
|
4
4
|
} from "./chunk-MGDEINGP.js";
|
|
5
|
+
import {
|
|
6
|
+
registerTailscaleCommands,
|
|
7
|
+
registerTailscaleDiscoverCommand,
|
|
8
|
+
registerTailscaleServeCommand,
|
|
9
|
+
registerTailscaleStatusCommand,
|
|
10
|
+
registerTailscaleSyncCommand,
|
|
11
|
+
tailscaleDiscoverCommand,
|
|
12
|
+
tailscaleServeCommand,
|
|
13
|
+
tailscaleStatusCommand,
|
|
14
|
+
tailscaleSyncCommand
|
|
15
|
+
} from "./chunk-NZ4ZZNSR.js";
|
|
16
|
+
import {
|
|
17
|
+
CLAWVAULT_SERVE_PATH,
|
|
18
|
+
DEFAULT_SERVE_PORT,
|
|
19
|
+
checkPeerClawVault,
|
|
20
|
+
compareManifests,
|
|
21
|
+
configureTailscaleServe,
|
|
22
|
+
discoverClawVaultPeers,
|
|
23
|
+
fetchRemoteFile,
|
|
24
|
+
fetchRemoteManifest,
|
|
25
|
+
findPeer,
|
|
26
|
+
generateVaultManifest,
|
|
27
|
+
getOnlinePeers,
|
|
28
|
+
getTailscaleStatus,
|
|
29
|
+
getTailscaleVersion,
|
|
30
|
+
hasTailscale,
|
|
31
|
+
pushFileToRemote,
|
|
32
|
+
resolvePeerIP,
|
|
33
|
+
serveVault,
|
|
34
|
+
stopTailscaleServe,
|
|
35
|
+
syncWithPeer
|
|
36
|
+
} from "./chunk-4GBPTBFJ.js";
|
|
37
|
+
import "./chunk-CLE2HHNT.js";
|
|
5
38
|
import {
|
|
6
39
|
buildTemplateVariables,
|
|
7
40
|
renderTemplate
|
|
@@ -9,11 +42,11 @@ import {
|
|
|
9
42
|
import {
|
|
10
43
|
reflectCommand,
|
|
11
44
|
registerReflectCommand
|
|
12
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-TT3FXYCN.js";
|
|
13
46
|
import {
|
|
14
47
|
registerReplayCommand,
|
|
15
48
|
replayCommand
|
|
16
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-RARDNTUP.js";
|
|
17
50
|
import {
|
|
18
51
|
buildSessionRecap,
|
|
19
52
|
formatSessionRecapMarkdown,
|
|
@@ -24,7 +57,7 @@ import {
|
|
|
24
57
|
} from "./chunk-W463YRED.js";
|
|
25
58
|
import {
|
|
26
59
|
runReflection
|
|
27
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-JVAWKNIZ.js";
|
|
28
61
|
import {
|
|
29
62
|
graphCommand,
|
|
30
63
|
graphSummary
|
|
@@ -33,12 +66,12 @@ import {
|
|
|
33
66
|
migrateObservations,
|
|
34
67
|
migrateObservationsCommand,
|
|
35
68
|
registerMigrateObservationsCommand
|
|
36
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-VBVEXNI5.js";
|
|
37
70
|
import {
|
|
38
71
|
SessionWatcher,
|
|
39
72
|
observeCommand,
|
|
40
73
|
registerObserveCommand
|
|
41
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-6AQZIPLV.js";
|
|
42
75
|
import "./chunk-HRLWZGMA.js";
|
|
43
76
|
import {
|
|
44
77
|
parseSessionFile
|
|
@@ -46,19 +79,19 @@ import {
|
|
|
46
79
|
import {
|
|
47
80
|
rebuildCommand,
|
|
48
81
|
registerRebuildCommand
|
|
49
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-USZU5CBB.js";
|
|
50
83
|
import {
|
|
51
84
|
Compressor,
|
|
52
85
|
Observer,
|
|
53
86
|
Reflector
|
|
54
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-2AYPFUGX.js";
|
|
55
88
|
import {
|
|
56
89
|
archiveCommand,
|
|
57
90
|
registerArchiveCommand
|
|
58
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-HVTTYDCJ.js";
|
|
59
92
|
import {
|
|
60
93
|
archiveObservations
|
|
61
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-QALB2V3E.js";
|
|
62
95
|
import {
|
|
63
96
|
findNearestVaultPath,
|
|
64
97
|
getVaultPath,
|
|
@@ -77,7 +110,7 @@ import {
|
|
|
77
110
|
normalizeContextProfileInput,
|
|
78
111
|
registerContextCommand,
|
|
79
112
|
resolveContextProfile
|
|
80
|
-
} from "./chunk-
|
|
113
|
+
} from "./chunk-TB3BM2PQ.js";
|
|
81
114
|
import {
|
|
82
115
|
ClawVault,
|
|
83
116
|
createVault,
|
|
@@ -105,7 +138,7 @@ import {
|
|
|
105
138
|
getMemoryGraph,
|
|
106
139
|
loadMemoryGraphIndex
|
|
107
140
|
} from "./chunk-ZZA73MFY.js";
|
|
108
|
-
import "./chunk-
|
|
141
|
+
import "./chunk-NAMFB7ZA.js";
|
|
109
142
|
|
|
110
143
|
// src/index.ts
|
|
111
144
|
import * as fs from "fs";
|
|
@@ -123,13 +156,16 @@ function registerCommanderCommands(program) {
|
|
|
123
156
|
registerContextCommand(program);
|
|
124
157
|
registerObserveCommand(program);
|
|
125
158
|
registerReflectCommand(program);
|
|
159
|
+
registerTailscaleCommands(program);
|
|
126
160
|
return program;
|
|
127
161
|
}
|
|
128
162
|
export {
|
|
163
|
+
CLAWVAULT_SERVE_PATH,
|
|
129
164
|
ClawVault,
|
|
130
165
|
Compressor,
|
|
131
166
|
DEFAULT_CATEGORIES,
|
|
132
167
|
DEFAULT_CONFIG,
|
|
168
|
+
DEFAULT_SERVE_PORT,
|
|
133
169
|
MEMORY_GRAPH_SCHEMA_VERSION,
|
|
134
170
|
MEMORY_TYPES,
|
|
135
171
|
Observer,
|
|
@@ -148,21 +184,33 @@ export {
|
|
|
148
184
|
buildSessionRecap,
|
|
149
185
|
buildTemplateVariables,
|
|
150
186
|
checkOpenClawCompatibility,
|
|
187
|
+
checkPeerClawVault,
|
|
188
|
+
compareManifests,
|
|
151
189
|
compatCommand,
|
|
152
190
|
compatibilityExitCode,
|
|
191
|
+
configureTailscaleServe,
|
|
153
192
|
contextCommand,
|
|
154
193
|
createVault,
|
|
194
|
+
discoverClawVaultPeers,
|
|
155
195
|
extractTags,
|
|
156
196
|
extractWikiLinks,
|
|
197
|
+
fetchRemoteFile,
|
|
198
|
+
fetchRemoteManifest,
|
|
157
199
|
findNearestVaultPath,
|
|
200
|
+
findPeer,
|
|
158
201
|
findVault,
|
|
159
202
|
formatContextMarkdown,
|
|
160
203
|
formatSessionRecapMarkdown,
|
|
204
|
+
generateVaultManifest,
|
|
161
205
|
getMemoryGraph,
|
|
206
|
+
getOnlinePeers,
|
|
207
|
+
getTailscaleStatus,
|
|
208
|
+
getTailscaleVersion,
|
|
162
209
|
getVaultPath,
|
|
163
210
|
graphCommand,
|
|
164
211
|
graphSummary,
|
|
165
212
|
hasQmd,
|
|
213
|
+
hasTailscale,
|
|
166
214
|
inferContextProfile,
|
|
167
215
|
loadMemoryGraphIndex,
|
|
168
216
|
migrateObservations,
|
|
@@ -170,6 +218,7 @@ export {
|
|
|
170
218
|
normalizeContextProfileInput,
|
|
171
219
|
observeCommand,
|
|
172
220
|
parseSessionFile,
|
|
221
|
+
pushFileToRemote,
|
|
173
222
|
qmdEmbed,
|
|
174
223
|
qmdUpdate,
|
|
175
224
|
rebuildCommand,
|
|
@@ -183,12 +232,25 @@ export {
|
|
|
183
232
|
registerReflectCommand,
|
|
184
233
|
registerReplayCommand,
|
|
185
234
|
registerSyncBdCommand,
|
|
235
|
+
registerTailscaleCommands,
|
|
236
|
+
registerTailscaleDiscoverCommand,
|
|
237
|
+
registerTailscaleServeCommand,
|
|
238
|
+
registerTailscaleStatusCommand,
|
|
239
|
+
registerTailscaleSyncCommand,
|
|
186
240
|
renderTemplate,
|
|
187
241
|
replayCommand,
|
|
188
242
|
resolveContextProfile,
|
|
243
|
+
resolvePeerIP,
|
|
189
244
|
resolveVaultPath,
|
|
190
245
|
runReflection,
|
|
246
|
+
serveVault,
|
|
191
247
|
sessionRecapCommand,
|
|
192
248
|
setupCommand,
|
|
193
|
-
|
|
249
|
+
stopTailscaleServe,
|
|
250
|
+
syncBdCommand,
|
|
251
|
+
syncWithPeer,
|
|
252
|
+
tailscaleDiscoverCommand,
|
|
253
|
+
tailscaleServeCommand,
|
|
254
|
+
tailscaleStatusCommand,
|
|
255
|
+
tailscaleSyncCommand
|
|
194
256
|
};
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { ChildProcess } from 'child_process';
|
|
2
|
+
import * as http from 'http';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Tailscale Integration for ClawVault
|
|
6
|
+
*
|
|
7
|
+
* Provides native Tailscale networking capabilities for vault synchronization
|
|
8
|
+
* across devices on a Tailscale network (tailnet).
|
|
9
|
+
*
|
|
10
|
+
* Features:
|
|
11
|
+
* - Tailscale status detection and peer discovery
|
|
12
|
+
* - MagicDNS hostname resolution
|
|
13
|
+
* - Secure peer-to-peer vault sync
|
|
14
|
+
* - Tailscale Funnel/Serve integration for vault sharing
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
interface TailscaleStatus {
|
|
18
|
+
/** Whether Tailscale is installed */
|
|
19
|
+
installed: boolean;
|
|
20
|
+
/** Whether Tailscale daemon is running */
|
|
21
|
+
running: boolean;
|
|
22
|
+
/** Whether connected to tailnet */
|
|
23
|
+
connected: boolean;
|
|
24
|
+
/** Current device's Tailscale IP */
|
|
25
|
+
selfIP?: string;
|
|
26
|
+
/** Current device's MagicDNS hostname */
|
|
27
|
+
selfHostname?: string;
|
|
28
|
+
/** Current device's full domain name */
|
|
29
|
+
selfDNSName?: string;
|
|
30
|
+
/** Tailnet name */
|
|
31
|
+
tailnetName?: string;
|
|
32
|
+
/** Backend state (Running, Stopped, etc.) */
|
|
33
|
+
backendState?: string;
|
|
34
|
+
/** List of peers on the tailnet */
|
|
35
|
+
peers: TailscalePeer[];
|
|
36
|
+
/** Error message if any */
|
|
37
|
+
error?: string;
|
|
38
|
+
}
|
|
39
|
+
interface TailscalePeer {
|
|
40
|
+
/** Peer's hostname */
|
|
41
|
+
hostname: string;
|
|
42
|
+
/** Peer's MagicDNS name */
|
|
43
|
+
dnsName: string;
|
|
44
|
+
/** Peer's Tailscale IP addresses */
|
|
45
|
+
tailscaleIPs: string[];
|
|
46
|
+
/** Whether peer is currently online */
|
|
47
|
+
online: boolean;
|
|
48
|
+
/** Operating system */
|
|
49
|
+
os?: string;
|
|
50
|
+
/** Whether this peer is the exit node */
|
|
51
|
+
exitNode?: boolean;
|
|
52
|
+
/** Whether this peer is a tagged device */
|
|
53
|
+
tags?: string[];
|
|
54
|
+
/** Last seen timestamp */
|
|
55
|
+
lastSeen?: string;
|
|
56
|
+
/** Whether peer is running ClawVault serve */
|
|
57
|
+
clawvaultServing?: boolean;
|
|
58
|
+
/** ClawVault serve port if detected */
|
|
59
|
+
clawvaultPort?: number;
|
|
60
|
+
}
|
|
61
|
+
interface TailscaleServeConfig {
|
|
62
|
+
/** Port to serve on (default: 8384) */
|
|
63
|
+
port?: number;
|
|
64
|
+
/** Whether to use HTTPS (via Tailscale) */
|
|
65
|
+
https?: boolean;
|
|
66
|
+
/** Whether to expose via Tailscale Funnel (public internet) */
|
|
67
|
+
funnel?: boolean;
|
|
68
|
+
/** Path prefix for the serve endpoint */
|
|
69
|
+
pathPrefix?: string;
|
|
70
|
+
/** Optional WebDAV Basic Auth credentials */
|
|
71
|
+
webdavAuth?: {
|
|
72
|
+
username: string;
|
|
73
|
+
password: string;
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
interface TailscaleSyncOptions {
|
|
77
|
+
/** Target peer hostname or IP */
|
|
78
|
+
peer: string;
|
|
79
|
+
/** Port on the peer (default: 8384) */
|
|
80
|
+
port?: number;
|
|
81
|
+
/** Direction: push, pull, or bidirectional */
|
|
82
|
+
direction?: 'push' | 'pull' | 'bidirectional';
|
|
83
|
+
/** Dry run - don't actually sync */
|
|
84
|
+
dryRun?: boolean;
|
|
85
|
+
/** Delete files on target that don't exist on source */
|
|
86
|
+
deleteOrphans?: boolean;
|
|
87
|
+
/** Categories to sync (default: all) */
|
|
88
|
+
categories?: string[];
|
|
89
|
+
/** Use HTTPS for connection */
|
|
90
|
+
https?: boolean;
|
|
91
|
+
}
|
|
92
|
+
interface TailscaleSyncResult {
|
|
93
|
+
/** Files pushed to peer */
|
|
94
|
+
pushed: string[];
|
|
95
|
+
/** Files pulled from peer */
|
|
96
|
+
pulled: string[];
|
|
97
|
+
/** Files deleted */
|
|
98
|
+
deleted: string[];
|
|
99
|
+
/** Files unchanged */
|
|
100
|
+
unchanged: string[];
|
|
101
|
+
/** Errors encountered */
|
|
102
|
+
errors: string[];
|
|
103
|
+
/** Sync statistics */
|
|
104
|
+
stats: {
|
|
105
|
+
bytesTransferred: number;
|
|
106
|
+
filesProcessed: number;
|
|
107
|
+
duration: number;
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
interface VaultManifest {
|
|
111
|
+
/** Vault name */
|
|
112
|
+
name: string;
|
|
113
|
+
/** Vault version */
|
|
114
|
+
version: string;
|
|
115
|
+
/** Last updated timestamp */
|
|
116
|
+
lastUpdated: string;
|
|
117
|
+
/** File manifest with checksums */
|
|
118
|
+
files: VaultFileEntry[];
|
|
119
|
+
}
|
|
120
|
+
interface VaultFileEntry {
|
|
121
|
+
/** Relative path */
|
|
122
|
+
path: string;
|
|
123
|
+
/** File size in bytes */
|
|
124
|
+
size: number;
|
|
125
|
+
/** Last modified timestamp */
|
|
126
|
+
modified: string;
|
|
127
|
+
/** SHA-256 checksum */
|
|
128
|
+
checksum: string;
|
|
129
|
+
/** Category */
|
|
130
|
+
category: string;
|
|
131
|
+
}
|
|
132
|
+
declare const DEFAULT_SERVE_PORT = 8384;
|
|
133
|
+
declare const CLAWVAULT_SERVE_PATH = "/.clawvault";
|
|
134
|
+
declare const MANIFEST_ENDPOINT = "/.clawvault/manifest";
|
|
135
|
+
declare const SYNC_ENDPOINT = "/.clawvault/sync";
|
|
136
|
+
declare const FILE_ENDPOINT = "/.clawvault/files";
|
|
137
|
+
/**
|
|
138
|
+
* Check if Tailscale CLI is installed
|
|
139
|
+
*/
|
|
140
|
+
declare function hasTailscale(): boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Get Tailscale version
|
|
143
|
+
*/
|
|
144
|
+
declare function getTailscaleVersion(): string | null;
|
|
145
|
+
/**
|
|
146
|
+
* Get comprehensive Tailscale status
|
|
147
|
+
*/
|
|
148
|
+
declare function getTailscaleStatus(): TailscaleStatus;
|
|
149
|
+
/**
|
|
150
|
+
* Find a peer by hostname (partial match supported)
|
|
151
|
+
*/
|
|
152
|
+
declare function findPeer(hostname: string): TailscalePeer | null;
|
|
153
|
+
/**
|
|
154
|
+
* Get online peers only
|
|
155
|
+
*/
|
|
156
|
+
declare function getOnlinePeers(): TailscalePeer[];
|
|
157
|
+
/**
|
|
158
|
+
* Resolve a peer hostname to its Tailscale IP
|
|
159
|
+
*/
|
|
160
|
+
declare function resolvePeerIP(hostname: string): string | null;
|
|
161
|
+
/**
|
|
162
|
+
* Generate vault manifest for synchronization
|
|
163
|
+
*/
|
|
164
|
+
declare function generateVaultManifest(vaultPath: string): VaultManifest;
|
|
165
|
+
/**
|
|
166
|
+
* Compare two manifests and return differences
|
|
167
|
+
*/
|
|
168
|
+
declare function compareManifests(local: VaultManifest, remote: VaultManifest): {
|
|
169
|
+
toPush: VaultFileEntry[];
|
|
170
|
+
toPull: VaultFileEntry[];
|
|
171
|
+
conflicts: Array<{
|
|
172
|
+
path: string;
|
|
173
|
+
local: VaultFileEntry;
|
|
174
|
+
remote: VaultFileEntry;
|
|
175
|
+
}>;
|
|
176
|
+
unchanged: string[];
|
|
177
|
+
};
|
|
178
|
+
interface ServeInstance {
|
|
179
|
+
server: http.Server;
|
|
180
|
+
port: number;
|
|
181
|
+
stop: () => Promise<void>;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Start serving a vault over HTTP for Tailscale sync
|
|
185
|
+
* Includes WebDAV support at /webdav/ for Obsidian mobile sync
|
|
186
|
+
*/
|
|
187
|
+
declare function serveVault(vaultPath: string, options?: TailscaleServeConfig): ServeInstance;
|
|
188
|
+
/**
|
|
189
|
+
* Fetch remote vault manifest
|
|
190
|
+
*/
|
|
191
|
+
declare function fetchRemoteManifest(host: string, port?: number, useHttps?: boolean): Promise<VaultManifest>;
|
|
192
|
+
/**
|
|
193
|
+
* Fetch a file from remote vault
|
|
194
|
+
*/
|
|
195
|
+
declare function fetchRemoteFile(host: string, filePath: string, port?: number, useHttps?: boolean): Promise<string>;
|
|
196
|
+
/**
|
|
197
|
+
* Push a file to remote vault
|
|
198
|
+
*/
|
|
199
|
+
declare function pushFileToRemote(host: string, filePath: string, content: string, port?: number, useHttps?: boolean): Promise<void>;
|
|
200
|
+
/**
|
|
201
|
+
* Sync vault with a remote peer
|
|
202
|
+
*/
|
|
203
|
+
declare function syncWithPeer(vaultPath: string, options: TailscaleSyncOptions): Promise<TailscaleSyncResult>;
|
|
204
|
+
/**
|
|
205
|
+
* Configure Tailscale serve for the vault
|
|
206
|
+
* This uses `tailscale serve` to expose the vault server via Tailscale's HTTPS
|
|
207
|
+
*/
|
|
208
|
+
declare function configureTailscaleServe(localPort: number, options?: {
|
|
209
|
+
funnel?: boolean;
|
|
210
|
+
background?: boolean;
|
|
211
|
+
}): ChildProcess | null;
|
|
212
|
+
/**
|
|
213
|
+
* Stop Tailscale serve
|
|
214
|
+
*/
|
|
215
|
+
declare function stopTailscaleServe(): boolean;
|
|
216
|
+
/**
|
|
217
|
+
* Check if a peer is serving ClawVault
|
|
218
|
+
*/
|
|
219
|
+
declare function checkPeerClawVault(host: string, port?: number): Promise<boolean>;
|
|
220
|
+
/**
|
|
221
|
+
* Discover ClawVault peers on the tailnet
|
|
222
|
+
*/
|
|
223
|
+
declare function discoverClawVaultPeers(port?: number): Promise<TailscalePeer[]>;
|
|
224
|
+
|
|
225
|
+
export { CLAWVAULT_SERVE_PATH, DEFAULT_SERVE_PORT, FILE_ENDPOINT, MANIFEST_ENDPOINT, SYNC_ENDPOINT, type ServeInstance, type TailscalePeer, type TailscaleServeConfig, type TailscaleStatus, type TailscaleSyncOptions, type TailscaleSyncResult, type VaultFileEntry, type VaultManifest, checkPeerClawVault, compareManifests, configureTailscaleServe, discoverClawVaultPeers, fetchRemoteFile, fetchRemoteManifest, findPeer, generateVaultManifest, getOnlinePeers, getTailscaleStatus, getTailscaleVersion, hasTailscale, pushFileToRemote, resolvePeerIP, serveVault, stopTailscaleServe, syncWithPeer };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CLAWVAULT_SERVE_PATH,
|
|
3
|
+
DEFAULT_SERVE_PORT,
|
|
4
|
+
FILE_ENDPOINT,
|
|
5
|
+
MANIFEST_ENDPOINT,
|
|
6
|
+
SYNC_ENDPOINT,
|
|
7
|
+
checkPeerClawVault,
|
|
8
|
+
compareManifests,
|
|
9
|
+
configureTailscaleServe,
|
|
10
|
+
discoverClawVaultPeers,
|
|
11
|
+
fetchRemoteFile,
|
|
12
|
+
fetchRemoteManifest,
|
|
13
|
+
findPeer,
|
|
14
|
+
generateVaultManifest,
|
|
15
|
+
getOnlinePeers,
|
|
16
|
+
getTailscaleStatus,
|
|
17
|
+
getTailscaleVersion,
|
|
18
|
+
hasTailscale,
|
|
19
|
+
pushFileToRemote,
|
|
20
|
+
resolvePeerIP,
|
|
21
|
+
serveVault,
|
|
22
|
+
stopTailscaleServe,
|
|
23
|
+
syncWithPeer
|
|
24
|
+
} from "../chunk-4GBPTBFJ.js";
|
|
25
|
+
import "../chunk-CLE2HHNT.js";
|
|
26
|
+
export {
|
|
27
|
+
CLAWVAULT_SERVE_PATH,
|
|
28
|
+
DEFAULT_SERVE_PORT,
|
|
29
|
+
FILE_ENDPOINT,
|
|
30
|
+
MANIFEST_ENDPOINT,
|
|
31
|
+
SYNC_ENDPOINT,
|
|
32
|
+
checkPeerClawVault,
|
|
33
|
+
compareManifests,
|
|
34
|
+
configureTailscaleServe,
|
|
35
|
+
discoverClawVaultPeers,
|
|
36
|
+
fetchRemoteFile,
|
|
37
|
+
fetchRemoteManifest,
|
|
38
|
+
findPeer,
|
|
39
|
+
generateVaultManifest,
|
|
40
|
+
getOnlinePeers,
|
|
41
|
+
getTailscaleStatus,
|
|
42
|
+
getTailscaleVersion,
|
|
43
|
+
hasTailscale,
|
|
44
|
+
pushFileToRemote,
|
|
45
|
+
resolvePeerIP,
|
|
46
|
+
serveVault,
|
|
47
|
+
stopTailscaleServe,
|
|
48
|
+
syncWithPeer
|
|
49
|
+
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* WebDAV Handler for ClawVault
|
|
6
|
+
*
|
|
7
|
+
* Implements WebDAV protocol support for Obsidian mobile sync via Remotely Save plugin.
|
|
8
|
+
* Uses only Node built-in modules (http, fs, path) - zero external dependencies.
|
|
9
|
+
*
|
|
10
|
+
* Supported methods:
|
|
11
|
+
* - GET: Serve file contents
|
|
12
|
+
* - PUT: Write/create file (creates parent dirs if needed)
|
|
13
|
+
* - DELETE: Delete file or directory
|
|
14
|
+
* - MKCOL: Create directory
|
|
15
|
+
* - PROPFIND: List directory contents or file properties (XML response)
|
|
16
|
+
* - OPTIONS: Return allowed methods + DAV header
|
|
17
|
+
* - HEAD: File metadata without body
|
|
18
|
+
* - MOVE: Rename/move file (uses Destination header)
|
|
19
|
+
* - COPY: Copy file
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
interface WebDAVConfig {
|
|
23
|
+
/** Root path for WebDAV files (vault path) */
|
|
24
|
+
rootPath: string;
|
|
25
|
+
/** URL prefix for WebDAV routes (default: /webdav) */
|
|
26
|
+
prefix?: string;
|
|
27
|
+
/** Optional Basic Auth credentials */
|
|
28
|
+
auth?: {
|
|
29
|
+
username: string;
|
|
30
|
+
password: string;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
interface WebDAVRequest {
|
|
34
|
+
method: string;
|
|
35
|
+
path: string;
|
|
36
|
+
headers: Record<string, string | string[] | undefined>;
|
|
37
|
+
body?: string;
|
|
38
|
+
}
|
|
39
|
+
interface WebDAVResponse {
|
|
40
|
+
status: number;
|
|
41
|
+
headers: Record<string, string>;
|
|
42
|
+
body?: string;
|
|
43
|
+
}
|
|
44
|
+
declare const WEBDAV_PREFIX = "/webdav";
|
|
45
|
+
/**
|
|
46
|
+
* Check if a path is safe (no traversal attacks, not blocked)
|
|
47
|
+
*/
|
|
48
|
+
declare function isPathSafe(requestPath: string, rootPath: string): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Resolve a WebDAV path to filesystem path
|
|
51
|
+
*/
|
|
52
|
+
declare function resolveWebDAVPath(requestPath: string, rootPath: string): string | null;
|
|
53
|
+
/**
|
|
54
|
+
* Check Basic Auth credentials
|
|
55
|
+
*/
|
|
56
|
+
declare function checkAuth(req: IncomingMessage, auth?: {
|
|
57
|
+
username: string;
|
|
58
|
+
password: string;
|
|
59
|
+
}): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Generate full PROPFIND response XML
|
|
62
|
+
*/
|
|
63
|
+
declare function generatePropfindResponse(entries: Array<{
|
|
64
|
+
href: string;
|
|
65
|
+
stats: fs.Stats | null;
|
|
66
|
+
isCollection: boolean;
|
|
67
|
+
}>): string;
|
|
68
|
+
/**
|
|
69
|
+
* Handle OPTIONS request
|
|
70
|
+
*/
|
|
71
|
+
declare function handleOptions(res: ServerResponse, prefix: string): void;
|
|
72
|
+
/**
|
|
73
|
+
* Handle HEAD request
|
|
74
|
+
*/
|
|
75
|
+
declare function handleHead(res: ServerResponse, filePath: string): void;
|
|
76
|
+
/**
|
|
77
|
+
* Handle GET request
|
|
78
|
+
*/
|
|
79
|
+
declare function handleGet(res: ServerResponse, filePath: string): void;
|
|
80
|
+
/**
|
|
81
|
+
* Handle PUT request
|
|
82
|
+
*/
|
|
83
|
+
declare function handlePut(res: ServerResponse, filePath: string, body: Buffer): void;
|
|
84
|
+
/**
|
|
85
|
+
* Handle DELETE request
|
|
86
|
+
*/
|
|
87
|
+
declare function handleDelete(res: ServerResponse, filePath: string): void;
|
|
88
|
+
/**
|
|
89
|
+
* Handle MKCOL request (create directory)
|
|
90
|
+
*/
|
|
91
|
+
declare function handleMkcol(res: ServerResponse, filePath: string): void;
|
|
92
|
+
/**
|
|
93
|
+
* Handle PROPFIND request
|
|
94
|
+
*/
|
|
95
|
+
declare function handlePropfind(res: ServerResponse, filePath: string, webdavPath: string, prefix: string, depth: string): void;
|
|
96
|
+
/**
|
|
97
|
+
* Handle MOVE request
|
|
98
|
+
*/
|
|
99
|
+
declare function handleMove(res: ServerResponse, sourcePath: string, destinationPath: string | null, overwrite: boolean): void;
|
|
100
|
+
/**
|
|
101
|
+
* Handle COPY request
|
|
102
|
+
*/
|
|
103
|
+
declare function handleCopy(res: ServerResponse, sourcePath: string, destinationPath: string | null, overwrite: boolean): void;
|
|
104
|
+
/**
|
|
105
|
+
* Create WebDAV request handler
|
|
106
|
+
*/
|
|
107
|
+
declare function createWebDAVHandler(config: WebDAVConfig): (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
|
|
108
|
+
|
|
109
|
+
export { WEBDAV_PREFIX, type WebDAVConfig, type WebDAVRequest, type WebDAVResponse, checkAuth, createWebDAVHandler, generatePropfindResponse, handleCopy, handleDelete, handleGet, handleHead, handleMkcol, handleMove, handleOptions, handlePropfind, handlePut, isPathSafe, resolveWebDAVPath };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WEBDAV_PREFIX,
|
|
3
|
+
checkAuth,
|
|
4
|
+
createWebDAVHandler,
|
|
5
|
+
generatePropfindResponse,
|
|
6
|
+
handleCopy,
|
|
7
|
+
handleDelete,
|
|
8
|
+
handleGet,
|
|
9
|
+
handleHead,
|
|
10
|
+
handleMkcol,
|
|
11
|
+
handleMove,
|
|
12
|
+
handleOptions,
|
|
13
|
+
handlePropfind,
|
|
14
|
+
handlePut,
|
|
15
|
+
isPathSafe,
|
|
16
|
+
resolveWebDAVPath
|
|
17
|
+
} from "../chunk-CLE2HHNT.js";
|
|
18
|
+
export {
|
|
19
|
+
WEBDAV_PREFIX,
|
|
20
|
+
checkAuth,
|
|
21
|
+
createWebDAVHandler,
|
|
22
|
+
generatePropfindResponse,
|
|
23
|
+
handleCopy,
|
|
24
|
+
handleDelete,
|
|
25
|
+
handleGet,
|
|
26
|
+
handleHead,
|
|
27
|
+
handleMkcol,
|
|
28
|
+
handleMove,
|
|
29
|
+
handleOptions,
|
|
30
|
+
handlePropfind,
|
|
31
|
+
handlePut,
|
|
32
|
+
isPathSafe,
|
|
33
|
+
resolveWebDAVPath
|
|
34
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clawvault",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"description": "ClawVault™ - 🐘 An elephant never forgets. Structured memory for OpenClaw agents. Context death resilience, Obsidian-compatible markdown, local semantic search.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
]
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
|
-
"build": "tsup src/
|
|
32
|
+
"build": "tsup src/commands/archive.ts src/commands/backlog.ts src/commands/blocked.ts src/commands/canvas.ts src/commands/checkpoint.ts src/commands/compat.ts src/commands/context.ts src/commands/doctor.ts src/commands/entities.ts src/commands/graph.ts src/commands/link.ts src/commands/migrate-observations.ts src/commands/observe.ts src/commands/rebuild.ts src/commands/recover.ts src/commands/reflect.ts src/commands/repair-session.ts src/commands/replay.ts src/commands/session-recap.ts src/commands/setup.ts src/commands/shell-init.ts src/commands/sleep.ts src/commands/status.ts src/commands/sync-bd.ts src/commands/tailscale.ts src/commands/task.ts src/commands/template.ts src/commands/wake.ts src/index.ts src/lib/auto-linker.ts src/lib/canvas-layout.ts src/lib/config.ts src/lib/entity-index.ts src/lib/session-repair.ts src/lib/session-utils.ts src/lib/tailscale.ts src/lib/task-utils.ts src/lib/template-engine.ts src/lib/webdav.ts --format esm --dts --clean",
|
|
33
33
|
"dev": "tsup src/index.ts src/commands/*.ts src/lib/*.ts --format esm --dts --watch",
|
|
34
34
|
"lint": "eslint src",
|
|
35
35
|
"typecheck": "tsc --noEmit",
|