@buffbirb/unclaude 1.0.1 → 1.0.3
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 +2 -2
- package/dist/cli.js +36 -6
- package/dist/install.js +4 -1
- package/dist/uninstall.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,13 +13,13 @@ I also added a few broadly useful tools to cut tokens and leverage SDD, which I
|
|
|
13
13
|
Recommended for local installs, launch the TUI:
|
|
14
14
|
|
|
15
15
|
```sh
|
|
16
|
-
npx unclaude
|
|
16
|
+
npx @buffbirb/unclaude
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Recommended for cloud pre-session installs, run in CLI mode:
|
|
20
20
|
|
|
21
21
|
```sh
|
|
22
|
-
npx unclaude install --git-user "Your Name" --git-email "you@example.com"
|
|
22
|
+
npx @buffbirb/unclaude install --git-user "Your Name" --git-email "you@example.com"
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
If the cloud agent doesn't support pre-session scripts, run locally with `.gitignore` disabled and commit to the repo.
|
package/dist/cli.js
CHANGED
|
@@ -5,6 +5,8 @@ import { Command } from 'commander';
|
|
|
5
5
|
import { App } from './install.js';
|
|
6
6
|
import { runInstall } from './install.js';
|
|
7
7
|
import { runUninstall } from './uninstall.js';
|
|
8
|
+
import { writeFileSync, appendFileSync } from 'fs';
|
|
9
|
+
import { resolve } from 'path';
|
|
8
10
|
import { FEATURE_ORDER, DEFAULT_FEATURES, addGitignoreEntries, removeGitignoreEntries } from './common.js';
|
|
9
11
|
const AGENTS = ['claudeCode', 'openCode'];
|
|
10
12
|
const SCOPES = ['global', 'project'];
|
|
@@ -39,6 +41,20 @@ function consoleUpdateStep(id, update) {
|
|
|
39
41
|
console.log(` ${update.line}`);
|
|
40
42
|
}
|
|
41
43
|
}
|
|
44
|
+
function makeUpdateStep(logPath) {
|
|
45
|
+
if (logPath)
|
|
46
|
+
writeFileSync(logPath, '');
|
|
47
|
+
return (id, update) => {
|
|
48
|
+
consoleUpdateStep(id, update);
|
|
49
|
+
if (!logPath)
|
|
50
|
+
return;
|
|
51
|
+
const ts = new Date().toISOString();
|
|
52
|
+
if (update.status)
|
|
53
|
+
appendFileSync(logPath, `${ts} [${id}] ${update.status}\n`);
|
|
54
|
+
if (update.line)
|
|
55
|
+
appendFileSync(logPath, `${ts} [${id}] ${update.line}\n`);
|
|
56
|
+
};
|
|
57
|
+
}
|
|
42
58
|
const program = new Command();
|
|
43
59
|
program
|
|
44
60
|
.command('install')
|
|
@@ -50,6 +66,7 @@ program
|
|
|
50
66
|
.option('--git-user <name>', 'git user.name to embed in hooks and agent md files')
|
|
51
67
|
.option('--git-email <email>', 'git user.email to embed in hooks and agent md files')
|
|
52
68
|
.option('--branch-prefix <prefix>', 'prefix for renamed claude/* branches')
|
|
69
|
+
.option('--debug', 'write timestamped log to unclaude-debug.log')
|
|
53
70
|
.action((opts, cmd) => {
|
|
54
71
|
let selection;
|
|
55
72
|
try {
|
|
@@ -58,16 +75,22 @@ program
|
|
|
58
75
|
catch (e) {
|
|
59
76
|
cmd.error(String(e instanceof Error ? e.message : e));
|
|
60
77
|
}
|
|
78
|
+
const logPath = opts.debug ? resolve('unclaude-debug.log') : false;
|
|
61
79
|
const personalize = !!(opts.gitUser || opts.gitEmail || opts.branchPrefix);
|
|
62
80
|
const formState = { personalize, gitUser: opts.gitUser ?? '', gitEmail: opts.gitEmail ?? '', branchPrefix: opts.branchPrefix ?? '' };
|
|
63
|
-
runInstall(selection, formState,
|
|
81
|
+
runInstall(selection, formState, makeUpdateStep(logPath))
|
|
64
82
|
.then(() => {
|
|
65
83
|
if (opts.gitignore)
|
|
66
84
|
addGitignoreEntries(selection.features);
|
|
67
85
|
console.log('Install complete.');
|
|
68
|
-
process.
|
|
86
|
+
process.exitCode = 0;
|
|
69
87
|
})
|
|
70
|
-
.catch((e) => {
|
|
88
|
+
.catch((e) => {
|
|
89
|
+
if (logPath)
|
|
90
|
+
appendFileSync(logPath, `${new Date().toISOString()} ERROR: ${e}\n`);
|
|
91
|
+
console.error(e);
|
|
92
|
+
process.exitCode = 1;
|
|
93
|
+
});
|
|
71
94
|
});
|
|
72
95
|
program
|
|
73
96
|
.command('uninstall')
|
|
@@ -76,6 +99,7 @@ program
|
|
|
76
99
|
.option('--scopes <list>', `comma-separated scopes (default: all) — ${SCOPES.join(', ')}`)
|
|
77
100
|
.option('--features <list>', `comma-separated features (default: all) — ${FEATURES.join(', ')}`)
|
|
78
101
|
.option('--no-gitignore', 'skip removing generated project-scope files from .gitignore')
|
|
102
|
+
.option('--debug', 'write timestamped log to unclaude-debug.log')
|
|
79
103
|
.action((opts, cmd) => {
|
|
80
104
|
let selection;
|
|
81
105
|
try {
|
|
@@ -84,14 +108,20 @@ program
|
|
|
84
108
|
catch (e) {
|
|
85
109
|
cmd.error(String(e instanceof Error ? e.message : e));
|
|
86
110
|
}
|
|
87
|
-
|
|
111
|
+
const logPath = opts.debug ? resolve('unclaude-debug.log') : false;
|
|
112
|
+
runUninstall(selection, makeUpdateStep(logPath))
|
|
88
113
|
.then(() => {
|
|
89
114
|
if (opts.gitignore)
|
|
90
115
|
removeGitignoreEntries();
|
|
91
116
|
console.log('Uninstall complete.');
|
|
92
|
-
process.
|
|
117
|
+
process.exitCode = 0;
|
|
93
118
|
})
|
|
94
|
-
.catch((e) => {
|
|
119
|
+
.catch((e) => {
|
|
120
|
+
if (logPath)
|
|
121
|
+
appendFileSync(logPath, `${new Date().toISOString()} ERROR: ${e}\n`);
|
|
122
|
+
console.error(e);
|
|
123
|
+
process.exitCode = 1;
|
|
124
|
+
});
|
|
95
125
|
});
|
|
96
126
|
if (process.argv.length <= 2) {
|
|
97
127
|
render(_jsx(App, {}));
|
package/dist/install.js
CHANGED
|
@@ -246,9 +246,12 @@ export async function runInstall(selection, formState, updateStep) {
|
|
|
246
246
|
}
|
|
247
247
|
else {
|
|
248
248
|
scopes.delete('project');
|
|
249
|
+
if (scopes.size === 0) {
|
|
250
|
+
throw new Error('Project scope requested but no git repo found in cwd or any subdirectory with a .git dir touched in the last 120s.');
|
|
251
|
+
}
|
|
249
252
|
}
|
|
250
253
|
}
|
|
251
|
-
const scopeOk = (feat) =>
|
|
254
|
+
const scopeOk = (feat) => FEATURE_SCOPES[feat].some(s => scopes.has(s));
|
|
252
255
|
const tasks = [];
|
|
253
256
|
if (features.has('headroom') && scopeOk('headroom'))
|
|
254
257
|
tasks.push(['headroom', () => installHeadroom(l => updateStep('headroom', { line: l }))]);
|
package/dist/uninstall.js
CHANGED
|
@@ -286,7 +286,7 @@ async function uninstallOpenspec(scopes, onLine) {
|
|
|
286
286
|
// ── Orchestrator ──────────────────────────────────────────────────────────────
|
|
287
287
|
export async function runUninstall(selection, updateStep) {
|
|
288
288
|
const { features, scopes, agents, lspLanguages } = selection;
|
|
289
|
-
const scopeOk = (feat) =>
|
|
289
|
+
const scopeOk = (feat) => FEATURE_SCOPES[feat].some(s => scopes.has(s));
|
|
290
290
|
const tasks = [];
|
|
291
291
|
if (features.has('headroom') && scopeOk('headroom'))
|
|
292
292
|
tasks.push(['headroom', () => uninstallHeadroom(l => updateStep('headroom', { line: l }))]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buffbirb/unclaude",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "An opinionated AI dev tool setup script with a terminal UI. Configure privacy, code intelligence, and tool wrappers for Claude Code and OpenCode.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|