clawvault 2.3.0 → 2.4.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/bin/clawvault.js +6 -0
- package/bin/register-core-commands.js +25 -2
- package/bin/register-tailscale-commands.js +106 -0
- package/bin/register-task-commands.js +18 -2
- package/bin/register-task-commands.test.js +24 -0
- package/dist/{chunk-SOTWYGH7.js → chunk-33GW63WK.js} +4 -35
- package/dist/chunk-4GBPTBFJ.js +628 -0
- package/dist/{chunk-GQVYQCY5.js → chunk-AHGUJG76.js} +3 -3
- package/dist/{chunk-GJEGPO7U.js → chunk-BI6SGGZP.js} +1 -1
- package/dist/chunk-CLE2HHNT.js +513 -0
- package/dist/{chunk-NGVAEFT2.js → chunk-DEFBIVQ3.js} +21 -0
- package/dist/{chunk-DPS7NYIU.js → chunk-DHJPXGC7.js} +2 -2
- package/dist/{chunk-2HM7ZI4X.js → chunk-FEFPBHH4.js} +287 -12
- package/dist/{chunk-K6XHCUFL.js → chunk-FHFUXL6G.js} +8 -1
- package/dist/{chunk-6BBTI7NV.js → chunk-GBIDDDSL.js} +2 -2
- package/dist/{chunk-VR5NE7PZ.js → chunk-HVTTYDCJ.js} +1 -1
- package/dist/chunk-IFTEGE4D.js +361 -0
- package/dist/{chunk-5WR6RRPX.js → chunk-JXY6T5R7.js} +2 -2
- package/dist/chunk-L3DJ36BZ.js +40 -0
- package/dist/{chunk-Z2XBWN7A.js → chunk-NAMFB7ZA.js} +2 -0
- package/dist/chunk-NZ4ZZNSR.js +373 -0
- package/dist/{chunk-OTQW3OMC.js → chunk-Q3WBH4P4.js} +97 -0
- package/dist/{chunk-MQUJNOHK.js → chunk-QALB2V3E.js} +1 -1
- package/dist/{chunk-PTSEIWXZ.js → chunk-SNEMCQP7.js} +13 -6
- package/dist/commands/archive.js +3 -3
- package/dist/commands/backlog.js +9 -2
- package/dist/commands/blocked.js +9 -2
- package/dist/commands/canvas.d.ts +11 -3
- package/dist/commands/canvas.js +1333 -25
- package/dist/commands/context.js +5 -4
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/migrate-observations.js +3 -3
- package/dist/commands/observe.d.ts +1 -0
- package/dist/commands/observe.js +5 -4
- package/dist/commands/rebuild.js +5 -4
- package/dist/commands/reflect.js +5 -5
- package/dist/commands/replay.js +7 -6
- package/dist/commands/setup.d.ts +10 -2
- package/dist/commands/setup.js +1 -1
- package/dist/commands/sleep.js +7 -6
- package/dist/commands/status.js +1 -1
- package/dist/commands/tailscale.d.ts +52 -0
- package/dist/commands/tailscale.js +25 -0
- package/dist/commands/task.js +1 -1
- package/dist/commands/wake.js +4 -4
- package/dist/index.d.ts +9 -0
- package/dist/index.js +79 -15
- package/dist/lib/tailscale.d.ts +225 -0
- package/dist/lib/tailscale.js +49 -0
- package/dist/lib/task-utils.d.ts +13 -1
- package/dist/lib/task-utils.js +3 -1
- package/dist/lib/webdav.d.ts +109 -0
- package/dist/lib/webdav.js +34 -0
- package/package.json +2 -2
- package/dist/chunk-W463YRED.js +0 -97
package/bin/clawvault.js
CHANGED
|
@@ -16,7 +16,10 @@ import { registerResilienceCommands } from './register-resilience-commands.js';
|
|
|
16
16
|
import { registerSessionLifecycleCommands } from './register-session-lifecycle-commands.js';
|
|
17
17
|
import { registerTemplateCommands } from './register-template-commands.js';
|
|
18
18
|
import { registerVaultOperationsCommands } from './register-vault-operations-commands.js';
|
|
19
|
+
|
|
19
20
|
import { registerTaskCommands } from './register-task-commands.js';
|
|
21
|
+
|
|
22
|
+
import { registerTailscaleCommands } from './register-tailscale-commands.js';
|
|
20
23
|
import {
|
|
21
24
|
getVault,
|
|
22
25
|
resolveVaultPath,
|
|
@@ -83,10 +86,13 @@ registerVaultOperationsCommands(program, {
|
|
|
83
86
|
path
|
|
84
87
|
});
|
|
85
88
|
|
|
89
|
+
|
|
86
90
|
registerTaskCommands(program, {
|
|
87
91
|
chalk,
|
|
88
92
|
resolveVaultPath
|
|
89
93
|
});
|
|
90
94
|
|
|
95
|
+
registerTailscaleCommands(program, { chalk });
|
|
96
|
+
|
|
91
97
|
// Parse and run
|
|
92
98
|
program.parse();
|
|
@@ -13,6 +13,13 @@ export function registerCoreCommands(
|
|
|
13
13
|
.option('-n, --name <name>', 'Vault name')
|
|
14
14
|
.option('--qmd', 'Set up qmd semantic search collection')
|
|
15
15
|
.option('--qmd-collection <name>', 'qmd collection name (defaults to vault name)')
|
|
16
|
+
.option('--no-bases', 'Skip Obsidian Bases file generation')
|
|
17
|
+
.option('--no-tasks', 'Skip tasks/ and backlog/ directories')
|
|
18
|
+
.option('--no-graph', 'Skip initial graph build')
|
|
19
|
+
.option('--categories <list>', 'Comma-separated list of custom categories to create')
|
|
20
|
+
.option('--canvas <template>', 'Generate a canvas dashboard on init (default, brain, project-board, sprint)')
|
|
21
|
+
.option('--theme <style>', 'Graph color theme to apply (neural, minimal, none)', 'none')
|
|
22
|
+
.option('--minimal', 'Create minimal vault (memory categories only, no tasks/bases/graph)')
|
|
16
23
|
.action(async (vaultPath, options) => {
|
|
17
24
|
const targetPath = vaultPath || '.';
|
|
18
25
|
console.log(chalk.cyan(`\n🐘 Initializing ClawVault at ${path.resolve(targetPath)}...\n`));
|
|
@@ -67,10 +74,26 @@ export function registerCoreCommands(
|
|
|
67
74
|
program
|
|
68
75
|
.command('setup')
|
|
69
76
|
.description('Auto-discover and configure a ClawVault')
|
|
70
|
-
.
|
|
77
|
+
.option('--graph-colors', 'Set up graph color scheme for Obsidian')
|
|
78
|
+
.option('--no-graph-colors', 'Skip graph color configuration')
|
|
79
|
+
.option('--bases', 'Generate Obsidian Bases views for task management')
|
|
80
|
+
.option('--no-bases', 'Skip Bases file generation')
|
|
81
|
+
.option('--canvas [template]', 'Generate canvas dashboard (default, brain, project-board, sprint)')
|
|
82
|
+
.option('--no-canvas', 'Skip canvas generation')
|
|
83
|
+
.option('--theme <style>', 'Graph color theme (neural, minimal, none)', 'neural')
|
|
84
|
+
.option('--force', 'Overwrite existing configuration files')
|
|
85
|
+
.option('-v, --vault <path>', 'Vault path')
|
|
86
|
+
.action(async (options) => {
|
|
71
87
|
try {
|
|
72
88
|
const { setupCommand } = await import('../dist/commands/setup.js');
|
|
73
|
-
await setupCommand(
|
|
89
|
+
await setupCommand({
|
|
90
|
+
graphColors: options.graphColors,
|
|
91
|
+
bases: options.bases,
|
|
92
|
+
canvas: options.canvas,
|
|
93
|
+
theme: options.theme,
|
|
94
|
+
force: options.force,
|
|
95
|
+
vault: options.vault
|
|
96
|
+
});
|
|
74
97
|
} catch (err) {
|
|
75
98
|
console.error(chalk.red(`Error: ${err.message}`));
|
|
76
99
|
process.exit(1);
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tailscale networking command registrations.
|
|
3
|
+
* Provides vault synchronization over Tailscale networks.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export function registerTailscaleCommands(program, { chalk }) {
|
|
7
|
+
// === TAILSCALE-STATUS ===
|
|
8
|
+
program
|
|
9
|
+
.command('tailscale-status')
|
|
10
|
+
.alias('ts-status')
|
|
11
|
+
.description('Show Tailscale connection status and peers')
|
|
12
|
+
.option('--json', 'Output as JSON')
|
|
13
|
+
.option('--peers', 'Show all peers including offline')
|
|
14
|
+
.action(async (options) => {
|
|
15
|
+
try {
|
|
16
|
+
const { tailscaleStatusCommand } = await import('../dist/commands/tailscale.js');
|
|
17
|
+
await tailscaleStatusCommand({
|
|
18
|
+
json: options.json,
|
|
19
|
+
peers: options.peers
|
|
20
|
+
});
|
|
21
|
+
} catch (err) {
|
|
22
|
+
console.error(chalk.red(`Error: ${err.message}`));
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// === TAILSCALE-SYNC ===
|
|
28
|
+
program
|
|
29
|
+
.command('tailscale-sync')
|
|
30
|
+
.alias('ts-sync')
|
|
31
|
+
.description('Sync vault with a peer on the Tailscale network')
|
|
32
|
+
.requiredOption('--peer <hostname>', 'Peer hostname or IP to sync with')
|
|
33
|
+
.option('-v, --vault <path>', 'Vault path')
|
|
34
|
+
.option('--port <number>', 'Port on the peer (default: 8384)', parseInt)
|
|
35
|
+
.option('--direction <dir>', 'Sync direction: push, pull, or bidirectional', 'bidirectional')
|
|
36
|
+
.option('--dry-run', 'Show what would be synced without making changes')
|
|
37
|
+
.option('--delete-orphans', 'Delete files that exist locally but not on peer (pull only)')
|
|
38
|
+
.option('--categories <list>', 'Comma-separated list of categories to sync')
|
|
39
|
+
.option('--https', 'Use HTTPS for connection')
|
|
40
|
+
.option('--json', 'Output as JSON')
|
|
41
|
+
.action(async (options) => {
|
|
42
|
+
try {
|
|
43
|
+
const { tailscaleSyncCommand } = await import('../dist/commands/tailscale.js');
|
|
44
|
+
await tailscaleSyncCommand({
|
|
45
|
+
peer: options.peer,
|
|
46
|
+
vaultPath: options.vault,
|
|
47
|
+
port: options.port,
|
|
48
|
+
direction: options.direction,
|
|
49
|
+
dryRun: options.dryRun,
|
|
50
|
+
deleteOrphans: options.deleteOrphans,
|
|
51
|
+
categories: options.categories?.split(',').map(c => c.trim()),
|
|
52
|
+
https: options.https,
|
|
53
|
+
json: options.json
|
|
54
|
+
});
|
|
55
|
+
} catch (err) {
|
|
56
|
+
console.error(chalk.red(`Error: ${err.message}`));
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// === TAILSCALE-SERVE ===
|
|
62
|
+
program
|
|
63
|
+
.command('tailscale-serve')
|
|
64
|
+
.alias('ts-serve')
|
|
65
|
+
.description('Serve vault for sync over Tailscale')
|
|
66
|
+
.option('-v, --vault <path>', 'Vault path')
|
|
67
|
+
.option('--port <number>', 'Port to serve on (default: 8384)', parseInt)
|
|
68
|
+
.option('--funnel', 'Expose via Tailscale Funnel (public internet)')
|
|
69
|
+
.option('--background', 'Run in background')
|
|
70
|
+
.option('--stop', 'Stop serving')
|
|
71
|
+
.action(async (options) => {
|
|
72
|
+
try {
|
|
73
|
+
const { tailscaleServeCommand } = await import('../dist/commands/tailscale.js');
|
|
74
|
+
await tailscaleServeCommand({
|
|
75
|
+
vaultPath: options.vault,
|
|
76
|
+
port: options.port,
|
|
77
|
+
funnel: options.funnel,
|
|
78
|
+
background: options.background,
|
|
79
|
+
stop: options.stop
|
|
80
|
+
});
|
|
81
|
+
} catch (err) {
|
|
82
|
+
console.error(chalk.red(`Error: ${err.message}`));
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// === TAILSCALE-DISCOVER ===
|
|
88
|
+
program
|
|
89
|
+
.command('tailscale-discover')
|
|
90
|
+
.alias('ts-discover')
|
|
91
|
+
.description('Discover ClawVault peers on the Tailscale network')
|
|
92
|
+
.option('--port <number>', 'Port to check (default: 8384)', parseInt)
|
|
93
|
+
.option('--json', 'Output as JSON')
|
|
94
|
+
.action(async (options) => {
|
|
95
|
+
try {
|
|
96
|
+
const { tailscaleDiscoverCommand } = await import('../dist/commands/tailscale.js');
|
|
97
|
+
await tailscaleDiscoverCommand({
|
|
98
|
+
port: options.port,
|
|
99
|
+
json: options.json
|
|
100
|
+
});
|
|
101
|
+
} catch (err) {
|
|
102
|
+
console.error(chalk.red(`Error: ${err.message}`));
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
@@ -242,12 +242,28 @@ export function registerTaskCommands(
|
|
|
242
242
|
.description('Generate Obsidian canvas dashboard')
|
|
243
243
|
.option('-v, --vault <path>', 'Vault path')
|
|
244
244
|
.option('--output <path>', 'Output file path (default: dashboard.canvas)')
|
|
245
|
+
.option('--template <id>', 'Canvas template ID (default, project-board, brain, sprint)')
|
|
246
|
+
.option('--project <project>', 'Project filter for template-aware canvases')
|
|
247
|
+
.option('--owner <owner>', 'Filter tasks by owner (agent name or human)')
|
|
248
|
+
.option('--width <pixels>', 'Canvas width in pixels', parseInt)
|
|
249
|
+
.option('--height <pixels>', 'Canvas height in pixels', parseInt)
|
|
250
|
+
.option('--include-done', 'Include completed tasks (default: limited)')
|
|
251
|
+
.option('--list-templates', 'List available canvas templates and exit')
|
|
245
252
|
.action(async (options) => {
|
|
246
253
|
try {
|
|
247
|
-
const vaultPath =
|
|
254
|
+
const vaultPath = options.listTemplates
|
|
255
|
+
? (options.vault || '.')
|
|
256
|
+
: resolveVaultPath(options.vault);
|
|
248
257
|
const { canvasCommand } = await import('../dist/commands/canvas.js');
|
|
249
258
|
await canvasCommand(vaultPath, {
|
|
250
|
-
output: options.output
|
|
259
|
+
output: options.output,
|
|
260
|
+
template: options.template,
|
|
261
|
+
project: options.project,
|
|
262
|
+
owner: options.owner,
|
|
263
|
+
width: options.width,
|
|
264
|
+
height: options.height,
|
|
265
|
+
includeDone: options.includeDone,
|
|
266
|
+
listTemplates: options.listTemplates
|
|
251
267
|
});
|
|
252
268
|
} catch (err) {
|
|
253
269
|
console.error(chalk.red(`Error: ${err.message}`));
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { registerTaskCommands } from './register-task-commands.js';
|
|
4
|
+
import { chalkStub, stubResolveVaultPath } from './test-helpers/cli-command-fixtures.js';
|
|
5
|
+
|
|
6
|
+
describe('register-task-commands', () => {
|
|
7
|
+
it('adds canvas template and listing flags', () => {
|
|
8
|
+
const program = new Command();
|
|
9
|
+
registerTaskCommands(program, {
|
|
10
|
+
chalk: chalkStub,
|
|
11
|
+
resolveVaultPath: stubResolveVaultPath
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const canvasCommand = program.commands.find((command) => command.name() === 'canvas');
|
|
15
|
+
expect(canvasCommand).toBeDefined();
|
|
16
|
+
|
|
17
|
+
const optionFlags = canvasCommand?.options.map((option) => option.flags) ?? [];
|
|
18
|
+
expect(optionFlags).toEqual(expect.arrayContaining([
|
|
19
|
+
'--template <id>',
|
|
20
|
+
'--list-templates',
|
|
21
|
+
'--project <project>'
|
|
22
|
+
]));
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -1,48 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ClawVault
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Q3WBH4P4.js";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
parseObservationLines,
|
|
6
|
+
readObservations
|
|
7
|
+
} from "./chunk-L3DJ36BZ.js";
|
|
7
8
|
import {
|
|
8
9
|
getMemoryGraph
|
|
9
10
|
} from "./chunk-ZZA73MFY.js";
|
|
10
|
-
import {
|
|
11
|
-
listObservationFiles
|
|
12
|
-
} from "./chunk-Z2XBWN7A.js";
|
|
13
11
|
|
|
14
12
|
// src/commands/context.ts
|
|
15
13
|
import * as path from "path";
|
|
16
14
|
|
|
17
|
-
// src/lib/observation-reader.ts
|
|
18
|
-
import * as fs from "fs";
|
|
19
|
-
function readObservations(vaultPath, days = 7) {
|
|
20
|
-
const normalizedDays = Number.isFinite(days) ? Math.max(0, Math.floor(days)) : 0;
|
|
21
|
-
if (normalizedDays === 0) {
|
|
22
|
-
return "";
|
|
23
|
-
}
|
|
24
|
-
const files = listObservationFiles(vaultPath, {
|
|
25
|
-
includeLegacy: true,
|
|
26
|
-
includeArchive: false,
|
|
27
|
-
dedupeByDate: true
|
|
28
|
-
}).sort((left, right) => right.date.localeCompare(left.date)).slice(0, normalizedDays);
|
|
29
|
-
if (files.length === 0) {
|
|
30
|
-
return "";
|
|
31
|
-
}
|
|
32
|
-
return files.map((entry) => fs.readFileSync(entry.path, "utf-8").trim()).filter(Boolean).join("\n\n").trim();
|
|
33
|
-
}
|
|
34
|
-
function parseObservationLines(markdown) {
|
|
35
|
-
return parseObservationMarkdown(markdown).map((record) => ({
|
|
36
|
-
type: record.type,
|
|
37
|
-
confidence: record.confidence,
|
|
38
|
-
importance: record.importance,
|
|
39
|
-
content: record.content,
|
|
40
|
-
date: record.date,
|
|
41
|
-
format: record.format,
|
|
42
|
-
priority: record.priority
|
|
43
|
-
}));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
15
|
// src/lib/token-counter.ts
|
|
47
16
|
function estimateTokens(text) {
|
|
48
17
|
if (!text) {
|