claude-autopm 3.23.2 → 3.24.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/autopm.js
CHANGED
|
@@ -208,6 +208,8 @@ function main() {
|
|
|
208
208
|
.command(require('../lib/cli/commands/agent'))
|
|
209
209
|
// Context management command (STANDALONE)
|
|
210
210
|
.command(require('../lib/cli/commands/context'))
|
|
211
|
+
// Obsidian vault integration (STANDALONE)
|
|
212
|
+
.command(require('../lib/cli/commands/obsidian'))
|
|
211
213
|
// Validation command
|
|
212
214
|
.command('validate', 'Validate ClaudeAutoPM configuration and setup',
|
|
213
215
|
(yargs) => {
|
package/install/install.js
CHANGED
|
@@ -127,6 +127,44 @@ class Installer {
|
|
|
127
127
|
console.log(`${this.colors.RED}✗${this.colors.NC} ${msg}`);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Print scenario-specific next steps after installation
|
|
132
|
+
*/
|
|
133
|
+
printScenarioNextSteps() {
|
|
134
|
+
const scenario = this.currentScenario;
|
|
135
|
+
if (!scenario) return;
|
|
136
|
+
|
|
137
|
+
console.log(`${this.colors.CYAN}📋 Next Steps for "${scenario}" scenario:${this.colors.NC}`);
|
|
138
|
+
console.log('');
|
|
139
|
+
|
|
140
|
+
if (scenario === 'obsidian') {
|
|
141
|
+
console.log(' 1. Configure your Obsidian vault:');
|
|
142
|
+
console.log(` ${this.colors.BOLD}autopm obsidian setup --vault-path "<your-vault-path>"${this.colors.NC}`);
|
|
143
|
+
console.log('');
|
|
144
|
+
console.log(` ${this.colors.DIM}Use quotes around the path. Examples per platform:${this.colors.NC}`);
|
|
145
|
+
console.log(` ${this.colors.DIM} WSL: --vault-path "/mnt/c/Users/You/Documents/My Vault"${this.colors.NC}`);
|
|
146
|
+
console.log(` ${this.colors.DIM} macOS: --vault-path "/Users/you/Documents/My Vault"${this.colors.NC}`);
|
|
147
|
+
console.log(` ${this.colors.DIM} Linux: --vault-path "/home/you/Obsidian/My Vault"${this.colors.NC}`);
|
|
148
|
+
console.log('');
|
|
149
|
+
console.log(' 2. Open the vault folder in Obsidian and install recommended plugins');
|
|
150
|
+
console.log(` ${this.colors.DIM}(Dataview, Templater, Excalidraw, Mermaid Tools)${this.colors.NC}`);
|
|
151
|
+
console.log('');
|
|
152
|
+
console.log(' 3. For continuous sync:');
|
|
153
|
+
console.log(` ${this.colors.BOLD}autopm obsidian sync --watch${this.colors.NC}`);
|
|
154
|
+
console.log('');
|
|
155
|
+
console.log(` ${this.colors.DIM}Verify setup: autopm validate${this.colors.NC}`);
|
|
156
|
+
console.log(` ${this.colors.DIM}Troubleshooting: autopm obsidian doctor${this.colors.NC}`);
|
|
157
|
+
console.log('');
|
|
158
|
+
} else {
|
|
159
|
+
console.log(' 1. Open your project in Claude Code:');
|
|
160
|
+
console.log(` ${this.colors.BOLD}cd your-project && claude${this.colors.NC}`);
|
|
161
|
+
console.log('');
|
|
162
|
+
console.log(' 2. Start working! Slash commands are available inside Claude Code.');
|
|
163
|
+
console.log(` ${this.colors.DIM}Example: /pm:status, /pm:next, /pm:help${this.colors.NC}`);
|
|
164
|
+
console.log('');
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
130
168
|
async confirm(prompt) {
|
|
131
169
|
// In test mode or auto-accept mode, auto-answer yes
|
|
132
170
|
if (process.env.AUTOPM_TEST_MODE === '1' || process.env.AUTOPM_AUTO_ACCEPT === '1') {
|
|
@@ -561,6 +599,7 @@ ${this.colors.BOLD}Select installation scenario:${this.colors.NC}
|
|
|
561
599
|
• Core + PM + Obsidian vault sync
|
|
562
600
|
• Unidirectional project → vault mirroring
|
|
563
601
|
• Best for: Knowledge management, documentation-heavy projects
|
|
602
|
+
• After install, run: ${this.colors.BOLD}autopm obsidian setup --vault-path "<path>"${this.colors.NC}
|
|
564
603
|
${this.colors.DIM}• Plugins: core, pm, obsidian (3 plugins)${this.colors.NC}
|
|
565
604
|
`);
|
|
566
605
|
|
|
@@ -1525,6 +1564,9 @@ See: https://github.com/rafeekpro/ClaudeAutoPM
|
|
|
1525
1564
|
this.printMsg('GREEN', '╚══════════════════════════════════════════╝');
|
|
1526
1565
|
console.log('');
|
|
1527
1566
|
|
|
1567
|
+
// Scenario-specific next steps
|
|
1568
|
+
this.printScenarioNextSteps();
|
|
1569
|
+
|
|
1528
1570
|
// Run post-installation configuration check
|
|
1529
1571
|
await this.runPostInstallCheck();
|
|
1530
1572
|
|
|
@@ -343,7 +343,7 @@ class PostInstallChecker {
|
|
|
343
343
|
checkObsidianVault() {
|
|
344
344
|
const configPath = path.join(this.projectRoot, '.claude', 'config.json');
|
|
345
345
|
let configured = false;
|
|
346
|
-
let message = 'Not configured — run: obsidian
|
|
346
|
+
let message = 'Not configured — run: autopm obsidian setup --vault-path "<path>"';
|
|
347
347
|
|
|
348
348
|
if (fs.existsSync(configPath)) {
|
|
349
349
|
try {
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Obsidian Commands
|
|
3
|
+
* Manage Obsidian vault integration — setup, sync, diagnostics
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { spawn } = require('child_process');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
|
|
10
|
+
const PLUGIN_DIR = 'packages/plugin-obsidian';
|
|
11
|
+
const SCRIPTS_DIR = path.join(PLUGIN_DIR, 'scripts', 'obsidian');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Find project root by walking up from cwd
|
|
15
|
+
*/
|
|
16
|
+
function findProjectRoot() {
|
|
17
|
+
let dir = process.cwd();
|
|
18
|
+
while (dir !== path.dirname(dir)) {
|
|
19
|
+
if (fs.existsSync(path.join(dir, '.claude', 'config.json')) ||
|
|
20
|
+
fs.existsSync(path.join(dir, 'CLAUDE.md'))) {
|
|
21
|
+
return dir;
|
|
22
|
+
}
|
|
23
|
+
dir = path.dirname(dir);
|
|
24
|
+
}
|
|
25
|
+
return process.cwd();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Check if plugin-obsidian is installed
|
|
30
|
+
*/
|
|
31
|
+
function checkPlugin(root) {
|
|
32
|
+
const pluginJson = path.join(root, PLUGIN_DIR, 'plugin.json');
|
|
33
|
+
if (!fs.existsSync(pluginJson)) {
|
|
34
|
+
console.error('❌ plugin-obsidian not installed.');
|
|
35
|
+
console.error(' Run: autopm install --scenario=obsidian');
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* autopm obsidian setup
|
|
42
|
+
*/
|
|
43
|
+
async function obsidianSetup(argv) {
|
|
44
|
+
const root = findProjectRoot();
|
|
45
|
+
checkPlugin(root);
|
|
46
|
+
|
|
47
|
+
const scriptPath = path.join(root, SCRIPTS_DIR, 'setup.js');
|
|
48
|
+
if (!fs.existsSync(scriptPath)) {
|
|
49
|
+
console.error('❌ Setup script not found:', scriptPath);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const args = [];
|
|
54
|
+
if (argv.vaultPath) args.push('--vault-path', argv.vaultPath);
|
|
55
|
+
if (argv.prefix) args.push('--prefix', argv.prefix);
|
|
56
|
+
if (argv.watch === true) args.push('--watch');
|
|
57
|
+
if (argv.watch === false) args.push('--no-watch');
|
|
58
|
+
args.push('--project-root', root);
|
|
59
|
+
|
|
60
|
+
const child = spawn('node', [scriptPath, ...args], {
|
|
61
|
+
stdio: 'inherit',
|
|
62
|
+
cwd: root
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
child.on('close', (code) => process.exit(code || 0));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* autopm obsidian sync
|
|
70
|
+
*/
|
|
71
|
+
async function obsidianSync(argv) {
|
|
72
|
+
const root = findProjectRoot();
|
|
73
|
+
checkPlugin(root);
|
|
74
|
+
|
|
75
|
+
// Prefer shell script, fall back to Node
|
|
76
|
+
const shPath = path.join(root, SCRIPTS_DIR, 'sync-to-obsidian.sh');
|
|
77
|
+
const jsPath = path.join(root, SCRIPTS_DIR, 'sync-to-obsidian.js');
|
|
78
|
+
|
|
79
|
+
const args = [];
|
|
80
|
+
if (argv.watch) args.push('--watch');
|
|
81
|
+
if (argv.check) args.push('--check');
|
|
82
|
+
if (argv.safeMode) args.push('--safe-mode');
|
|
83
|
+
args.push('--project-root', root);
|
|
84
|
+
|
|
85
|
+
let cmd, cmdArgs;
|
|
86
|
+
if (fs.existsSync(shPath)) {
|
|
87
|
+
cmd = 'bash';
|
|
88
|
+
cmdArgs = [shPath, ...args];
|
|
89
|
+
} else if (fs.existsSync(jsPath)) {
|
|
90
|
+
cmd = 'node';
|
|
91
|
+
cmdArgs = [jsPath, ...args];
|
|
92
|
+
} else {
|
|
93
|
+
console.error('❌ Sync script not found. Reinstall plugin-obsidian.');
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const child = spawn(cmd, cmdArgs, {
|
|
98
|
+
stdio: 'inherit',
|
|
99
|
+
cwd: root
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
child.on('close', (code) => process.exit(code || 0));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* autopm obsidian doctor
|
|
107
|
+
*/
|
|
108
|
+
async function obsidianDoctor(argv) {
|
|
109
|
+
const root = findProjectRoot();
|
|
110
|
+
checkPlugin(root);
|
|
111
|
+
|
|
112
|
+
const scriptPath = path.join(root, SCRIPTS_DIR, 'doctor.js');
|
|
113
|
+
if (!fs.existsSync(scriptPath)) {
|
|
114
|
+
console.error('❌ Doctor script not found:', scriptPath);
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const args = ['--project-root', root];
|
|
119
|
+
|
|
120
|
+
const child = spawn('node', [scriptPath, ...args], {
|
|
121
|
+
stdio: 'inherit',
|
|
122
|
+
cwd: root
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
child.on('close', (code) => process.exit(code || 0));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Command builder — registers subcommands
|
|
130
|
+
*/
|
|
131
|
+
function builder(yargs) {
|
|
132
|
+
return yargs
|
|
133
|
+
.command(
|
|
134
|
+
'setup',
|
|
135
|
+
'Configure Obsidian vault integration',
|
|
136
|
+
(yargs) => {
|
|
137
|
+
return yargs
|
|
138
|
+
.option('vault-path', {
|
|
139
|
+
describe: 'Path to your Obsidian vault folder (use quotes if path has spaces)',
|
|
140
|
+
type: 'string',
|
|
141
|
+
demandOption: true
|
|
142
|
+
})
|
|
143
|
+
.option('prefix', {
|
|
144
|
+
describe: 'Subfolder name in vault (default: project directory name)',
|
|
145
|
+
type: 'string'
|
|
146
|
+
})
|
|
147
|
+
.option('watch', {
|
|
148
|
+
describe: 'Enable continuous sync after setup',
|
|
149
|
+
type: 'boolean'
|
|
150
|
+
})
|
|
151
|
+
.example('autopm obsidian setup --vault-path "/mnt/c/Users/You/My Vault"', 'WSL')
|
|
152
|
+
.example('autopm obsidian setup --vault-path "/Users/you/My Vault"', 'macOS')
|
|
153
|
+
.example('autopm obsidian setup --vault-path "/home/you/My Vault" --prefix my-project', 'Linux with prefix');
|
|
154
|
+
},
|
|
155
|
+
obsidianSetup
|
|
156
|
+
)
|
|
157
|
+
.command(
|
|
158
|
+
'sync',
|
|
159
|
+
'Sync project files to Obsidian vault',
|
|
160
|
+
(yargs) => {
|
|
161
|
+
return yargs
|
|
162
|
+
.option('watch', {
|
|
163
|
+
describe: 'Continuous sync on file changes',
|
|
164
|
+
type: 'boolean',
|
|
165
|
+
default: false
|
|
166
|
+
})
|
|
167
|
+
.option('check', {
|
|
168
|
+
describe: 'Dry-run: show what would be synced',
|
|
169
|
+
type: 'boolean',
|
|
170
|
+
default: false
|
|
171
|
+
})
|
|
172
|
+
.option('safe-mode', {
|
|
173
|
+
describe: 'Never delete vault files (omit --delete from rsync)',
|
|
174
|
+
type: 'boolean',
|
|
175
|
+
default: false
|
|
176
|
+
})
|
|
177
|
+
.example('autopm obsidian sync', 'One-shot sync')
|
|
178
|
+
.example('autopm obsidian sync --watch', 'Continuous sync')
|
|
179
|
+
.example('autopm obsidian sync --check', 'Dry-run');
|
|
180
|
+
},
|
|
181
|
+
obsidianSync
|
|
182
|
+
)
|
|
183
|
+
.command(
|
|
184
|
+
'doctor',
|
|
185
|
+
'Diagnose common Obsidian integration issues',
|
|
186
|
+
(yargs) => {
|
|
187
|
+
return yargs
|
|
188
|
+
.example('autopm obsidian doctor', 'Run all diagnostic checks');
|
|
189
|
+
},
|
|
190
|
+
obsidianDoctor
|
|
191
|
+
)
|
|
192
|
+
.demandCommand(1, 'You must specify an obsidian command')
|
|
193
|
+
.strictCommands()
|
|
194
|
+
.help();
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
module.exports = {
|
|
198
|
+
command: 'obsidian',
|
|
199
|
+
describe: 'Manage Obsidian vault integration (setup, sync, diagnostics)',
|
|
200
|
+
builder,
|
|
201
|
+
handler: (argv) => {
|
|
202
|
+
console.log('\nUsage: autopm obsidian <command>\n');
|
|
203
|
+
console.log('Commands:');
|
|
204
|
+
console.log(' setup Configure Obsidian vault integration');
|
|
205
|
+
console.log(' sync Sync project files to Obsidian vault');
|
|
206
|
+
console.log(' doctor Diagnose common integration issues');
|
|
207
|
+
console.log('\nRun autopm obsidian <command> --help for details\n');
|
|
208
|
+
}
|
|
209
|
+
};
|
package/package.json
CHANGED
|
@@ -50,26 +50,32 @@ autopm install
|
|
|
50
50
|
|
|
51
51
|
## Commands
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
Available from your terminal via `autopm obsidian <command>` and as `/obsidian:<command>` slash commands inside Claude Code.
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
### `autopm obsidian setup`
|
|
56
|
+
|
|
57
|
+
Configure your Obsidian vault. Run once after install:
|
|
56
58
|
|
|
57
59
|
```bash
|
|
58
|
-
|
|
60
|
+
autopm obsidian setup --vault-path "/path/to/your vault" --prefix my-project
|
|
61
|
+
|
|
62
|
+
# WSL: --vault-path "/mnt/c/Users/You/Documents/My Vault"
|
|
63
|
+
# macOS: --vault-path "/Users/you/Documents/My Vault"
|
|
64
|
+
# Linux: --vault-path "/home/you/Obsidian/My Vault"
|
|
59
65
|
```
|
|
60
66
|
|
|
61
|
-
### `obsidian
|
|
67
|
+
### `autopm obsidian sync`
|
|
62
68
|
|
|
63
69
|
Sync project files to the Obsidian vault.
|
|
64
70
|
|
|
65
71
|
```bash
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
autopm obsidian sync # One-shot sync
|
|
73
|
+
autopm obsidian sync --watch # Continuous sync on file changes
|
|
74
|
+
autopm obsidian sync --check # Dry-run (show what would sync)
|
|
75
|
+
autopm obsidian sync --safe-mode # Don't delete vault files
|
|
70
76
|
```
|
|
71
77
|
|
|
72
|
-
### `obsidian
|
|
78
|
+
### `autopm obsidian doctor`
|
|
73
79
|
|
|
74
80
|
Diagnose common integration problems:
|
|
75
81
|
|
|
@@ -36,27 +36,27 @@ describe('plugin-obsidian documentation', () => {
|
|
|
36
36
|
describe('packages/plugin-obsidian/README.md', () => {
|
|
37
37
|
const readmePath = resolve(root, 'packages', 'plugin-obsidian', 'README.md');
|
|
38
38
|
|
|
39
|
-
it('mentions obsidian
|
|
39
|
+
it('mentions obsidian setup command', () => {
|
|
40
40
|
const content = readFileSync(readmePath, 'utf8');
|
|
41
41
|
assert.ok(
|
|
42
|
-
content.includes('obsidian
|
|
43
|
-
'README must mention obsidian
|
|
42
|
+
content.includes('obsidian setup'),
|
|
43
|
+
'README must mention obsidian setup'
|
|
44
44
|
);
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
it('mentions obsidian
|
|
47
|
+
it('mentions obsidian sync command', () => {
|
|
48
48
|
const content = readFileSync(readmePath, 'utf8');
|
|
49
49
|
assert.ok(
|
|
50
|
-
content.includes('obsidian
|
|
51
|
-
'README must mention obsidian
|
|
50
|
+
content.includes('obsidian sync'),
|
|
51
|
+
'README must mention obsidian sync'
|
|
52
52
|
);
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
it('mentions obsidian
|
|
55
|
+
it('mentions obsidian doctor command', () => {
|
|
56
56
|
const content = readFileSync(readmePath, 'utf8');
|
|
57
57
|
assert.ok(
|
|
58
|
-
content.includes('obsidian
|
|
59
|
-
'README must mention obsidian
|
|
58
|
+
content.includes('obsidian doctor'),
|
|
59
|
+
'README must mention obsidian doctor'
|
|
60
60
|
);
|
|
61
61
|
});
|
|
62
62
|
});
|
|
@@ -64,21 +64,11 @@ describe('plugin-obsidian documentation', () => {
|
|
|
64
64
|
describe('CHANGELOG.md', () => {
|
|
65
65
|
const changelogPath = resolve(root, 'CHANGELOG.md');
|
|
66
66
|
|
|
67
|
-
it('mentions plugin-obsidian
|
|
67
|
+
it('mentions plugin-obsidian', () => {
|
|
68
68
|
const content = readFileSync(changelogPath, 'utf8');
|
|
69
|
-
const unreleasedIdx = content.indexOf('## [Unreleased]');
|
|
70
|
-
assert.ok(unreleasedIdx !== -1, 'CHANGELOG must have an [Unreleased] section');
|
|
71
|
-
|
|
72
|
-
// Find the next version heading after Unreleased
|
|
73
|
-
const afterUnreleased = content.slice(unreleasedIdx + '## [Unreleased]'.length);
|
|
74
|
-
const nextVersionIdx = afterUnreleased.indexOf('\n## [');
|
|
75
|
-
const unreleasedSection = nextVersionIdx !== -1
|
|
76
|
-
? afterUnreleased.slice(0, nextVersionIdx)
|
|
77
|
-
: afterUnreleased;
|
|
78
|
-
|
|
79
69
|
assert.ok(
|
|
80
|
-
|
|
81
|
-
'
|
|
70
|
+
content.includes('plugin-obsidian'),
|
|
71
|
+
'CHANGELOG must mention plugin-obsidian'
|
|
82
72
|
);
|
|
83
73
|
});
|
|
84
74
|
});
|