agent-takkub 2.2.5 → 2.2.6
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
CHANGED
|
@@ -96,11 +96,12 @@ A role's own model wins over the provider default, so `backend` can run Codex on
|
|
|
96
96
|
## ⚡ Quick Start
|
|
97
97
|
|
|
98
98
|
```bash
|
|
99
|
-
# 1. Install the cockpit
|
|
99
|
+
# 1. Install the cockpit, plus Claude and Codex CLIs if missing
|
|
100
100
|
npm install -g agent-takkub
|
|
101
101
|
|
|
102
|
-
# 2. Authenticate with your Claude
|
|
102
|
+
# 2. Authenticate with your Claude and OpenAI accounts
|
|
103
103
|
claude login
|
|
104
|
+
codex login
|
|
104
105
|
|
|
105
106
|
# 3. Provision recommended plugins + browser-automation tools (idempotent)
|
|
106
107
|
takkub provision
|
|
@@ -117,7 +118,7 @@ agent-takkub
|
|
|
117
118
|
<table>
|
|
118
119
|
<tr><td>
|
|
119
120
|
|
|
120
|
-
**Requirements** — Node.js ≥ 18 and Python ≥ 3.11 already on your system.
|
|
121
|
+
**Requirements** — Node.js ≥ 18 and Python ≥ 3.11 already on your system. The installer creates an isolated Python runtime and Desktop launcher, and installs missing Claude and Codex CLIs into your npm global prefix. Existing provider installations are reused. Authenticate with `claude login` and `codex login` before using those providers.
|
|
121
122
|
|
|
122
123
|
**Optional: `graft` code-intelligence** needs Node ≥ 20 — stricter than the cockpit's own Node ≥ 18 floor. It's off until you run `takkub doctor --fix`; without it (or on Node 18–19), the cockpit runs exactly the same, just without the extra structural-search tools for code-reading roles.
|
|
123
124
|
|
|
Binary file
|
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
//
|
|
4
4
|
// SAFETY MODEL — check first, never clobber:
|
|
5
5
|
// • Detects what's already present (preflight.js, non-mutating) and REPORTS it.
|
|
6
|
-
// • Provisions
|
|
6
|
+
// • Provisions the Python runtime into the isolated AGENT_TAKKUB_HOME (default
|
|
7
7
|
// ~/.agent-takkub) — never a repo `.venv`, never shared user state.
|
|
8
8
|
// • REUSES an existing cockpit venv (upgrade in place) instead of wiping it.
|
|
9
|
-
// •
|
|
10
|
-
//
|
|
11
|
-
// `takkub doctor --fix` the user runs consciously.
|
|
9
|
+
// • Installs missing Claude and Codex CLIs; existing installations are reused.
|
|
10
|
+
// Plugins and account configuration are managed separately by provision/login.
|
|
12
11
|
// Cross-platform (win32 + darwin); idempotent; fails loudly on missing Python
|
|
13
12
|
// or a missing bundled wheel.
|
|
14
13
|
|
|
@@ -17,6 +16,7 @@ const fs = require('fs');
|
|
|
17
16
|
const path = require('path');
|
|
18
17
|
const { agentTakkubHome, venvDir, venvPython, findWheelForVersion } = require('./lib');
|
|
19
18
|
const preflight = require('./preflight');
|
|
19
|
+
const { ensureBaselineProviders } = require('./providers');
|
|
20
20
|
|
|
21
21
|
// The wheel matching THIS install's declared version (#340) — not the
|
|
22
22
|
// lexically-last filename in dist/. A string sort put "1.0.9" after
|
|
@@ -33,17 +33,6 @@ function run(cmd, args) {
|
|
|
33
33
|
return spawnSync(cmd, args, { stdio: 'inherit' }).status === 0;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
// Install the claude CLI only when it's missing — never overwrite an existing
|
|
37
|
-
// (possibly version-pinned) global install. Returns true if claude is available
|
|
38
|
-
// afterward. Best-effort: a failure just falls back to a "install it yourself"
|
|
39
|
-
// hint in the next-steps.
|
|
40
|
-
function ensureClaudeCli(present) {
|
|
41
|
-
if (present) return true;
|
|
42
|
-
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
43
|
-
console.log('[agent-takkub] claude CLI not found — installing @anthropic-ai/claude-code…');
|
|
44
|
-
return run(npm, ['install', '-g', '@anthropic-ai/claude-code']);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
36
|
// A local (non-global) install leaves a package that cannot work: the `takkub`
|
|
48
37
|
// / `agent-takkub` bin shims never land on PATH, and the PATH provisioning
|
|
49
38
|
// below targets the npm GLOBAL bin dir. Without this guard that failure is
|
|
@@ -114,7 +103,7 @@ function main() {
|
|
|
114
103
|
// already succeeded, so a hiccup here shouldn't fail the whole install.
|
|
115
104
|
run(vpy, ['-m', 'pip', 'install', '--force-reinstall', '--no-deps', wheel]);
|
|
116
105
|
|
|
117
|
-
const
|
|
106
|
+
const providers = ensureBaselineProviders(env);
|
|
118
107
|
|
|
119
108
|
// Keep the npm global bin dir on the persistent PATH — otherwise a broken
|
|
120
109
|
// PATH makes claude/takkub/agent-takkub "command not found" in new shells
|
|
@@ -124,7 +113,7 @@ function main() {
|
|
|
124
113
|
pathAdded = require('./pathfix').ensureGlobalBinOnPath();
|
|
125
114
|
if (pathAdded) {
|
|
126
115
|
console.log(
|
|
127
|
-
'[agent-takkub] ✓ npm global bin dir added to your PATH (open a NEW terminal to use takkub/claude).'
|
|
116
|
+
'[agent-takkub] ✓ npm global bin dir added to your PATH (open a NEW terminal to use takkub/claude/codex).'
|
|
128
117
|
);
|
|
129
118
|
}
|
|
130
119
|
} catch (_e) {
|
|
@@ -148,12 +137,16 @@ function main() {
|
|
|
148
137
|
);
|
|
149
138
|
console.log(' it backs up everything first, so this is safe to let run.');
|
|
150
139
|
console.log('\n Next steps:');
|
|
151
|
-
if (!
|
|
140
|
+
if (!providers.claude) {
|
|
152
141
|
console.log(' • install the claude CLI: npm i -g @anthropic-ai/claude-code');
|
|
153
142
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
143
|
+
if (!providers.codex) {
|
|
144
|
+
console.log(' • install the codex CLI: npm i -g @openai/codex');
|
|
145
|
+
}
|
|
146
|
+
console.log(' 1) claude login # authenticate your Claude account');
|
|
147
|
+
console.log(' 2) codex login # authenticate your OpenAI account');
|
|
148
|
+
console.log(' 3) takkub provision # install recommended plugins + browser MCPs (idempotent)');
|
|
149
|
+
console.log(' 4) double-click "Takkub Cockpit" on the Desktop (or run: agent-takkub)\n');
|
|
157
150
|
}
|
|
158
151
|
|
|
159
152
|
try {
|
package/npm/scripts/preflight.js
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
// Non-mutating environment detection. Runs ONLY `--version`-style probes and
|
|
3
3
|
// filesystem existence checks — nothing here installs, writes, or overwrites.
|
|
4
4
|
// This is what lets the installer "check first": report what's already present
|
|
5
|
-
// and provision ONLY the gaps, so a machine that already has Python /
|
|
5
|
+
// and provision ONLY the gaps, so a machine that already has Python / Claude / Codex /
|
|
6
6
|
// a cockpit venv is never clobbered.
|
|
7
7
|
|
|
8
8
|
const { spawnSync } = require('child_process');
|
|
9
9
|
const fs = require('fs');
|
|
10
10
|
const { venvPython, agentTakkubHome } = require('./lib');
|
|
11
|
+
const { probeCli } = require('./providers');
|
|
11
12
|
|
|
12
13
|
function probe(cmd, args) {
|
|
13
14
|
const r = spawnSync(cmd, args, { encoding: 'utf8' });
|
|
@@ -36,11 +37,13 @@ function detectPython() {
|
|
|
36
37
|
|
|
37
38
|
// Detect the whole environment without mutating anything.
|
|
38
39
|
function detect() {
|
|
39
|
-
const claude =
|
|
40
|
+
const claude = probeCli('claude');
|
|
41
|
+
const codex = probeCli('codex');
|
|
40
42
|
return {
|
|
41
43
|
python: detectPython(),
|
|
42
44
|
node: probe('node', ['--version']),
|
|
43
45
|
claudeCli: claude ? { present: true, version: claude } : { present: false },
|
|
46
|
+
codexCli: codex ? { present: true, version: codex } : { present: false },
|
|
44
47
|
venv: { present: fs.existsSync(venvPython()), path: venvPython() },
|
|
45
48
|
home: agentTakkubHome(),
|
|
46
49
|
};
|
|
@@ -51,6 +54,7 @@ function report(d) {
|
|
|
51
54
|
console.log(` Python >=3.11 : ${d.python.present ? '✓ ' + d.python.version + ' (reuse existing)' : '· missing'}`);
|
|
52
55
|
console.log(` Node : ${d.node ? '✓ ' + d.node : '· missing'}`);
|
|
53
56
|
console.log(` claude CLI : ${d.claudeCli.present ? '✓ ' + d.claudeCli.version + ' (kept as-is)' : '· not found'}`);
|
|
57
|
+
console.log(` codex CLI : ${d.codexCli.present ? '✓ ' + d.codexCli.version + ' (kept as-is)' : '· not found'}`);
|
|
54
58
|
console.log(` cockpit venv : ${d.venv.present ? '✓ exists (reuse/upgrade)' : '· will create'} — ${d.home}`);
|
|
55
59
|
}
|
|
56
60
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { spawnSync } = require('child_process');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
const BASELINE_PROVIDERS = {
|
|
8
|
+
claude: '@anthropic-ai/claude-code',
|
|
9
|
+
codex: '@openai/codex',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function providerEnv(env) {
|
|
13
|
+
const prefix = env.npm_config_prefix;
|
|
14
|
+
if (!prefix) return env;
|
|
15
|
+
const bin = process.platform === 'win32' ? prefix : path.join(prefix, 'bin');
|
|
16
|
+
const pathKey = Object.keys(env).find((key) => key.toUpperCase() === 'PATH') || 'PATH';
|
|
17
|
+
return { ...env, [pathKey]: bin + path.delimiter + (env[pathKey] || '') };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function probeCli(name, env = process.env) {
|
|
21
|
+
if (!Object.hasOwn(BASELINE_PROVIDERS, name)) throw new Error(`Unknown baseline provider: ${name}`);
|
|
22
|
+
// Node rejects direct .cmd execution on Windows (EINVAL). These commands
|
|
23
|
+
// are fixed provider names, with no user input interpolated into the shell.
|
|
24
|
+
const command = process.platform === 'win32' ? 'cmd.exe' : name;
|
|
25
|
+
const args = process.platform === 'win32' ? ['/d', '/s', '/c', `${name} --version`] : ['--version'];
|
|
26
|
+
const result = spawnSync(command, args, {
|
|
27
|
+
env: providerEnv(env), encoding: 'utf8', timeout: 30_000, windowsHide: true,
|
|
28
|
+
});
|
|
29
|
+
if (result.status !== 0) return null;
|
|
30
|
+
return ((result.stdout || '') + (result.stderr || '')).trim() || null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function npmInvocation(env) {
|
|
34
|
+
// Use the npm CLI that started this lifecycle, through Node rather than a
|
|
35
|
+
// .cmd shim. This also preserves custom prefixes and paths with spaces.
|
|
36
|
+
if (env.npm_execpath && fs.existsSync(env.npm_execpath) && /\.[cm]?js$/i.test(env.npm_execpath)) {
|
|
37
|
+
return [process.execPath, [env.npm_execpath]];
|
|
38
|
+
}
|
|
39
|
+
if (process.platform !== 'win32') return ['npm', []];
|
|
40
|
+
// The cockpit's repair/update flow can run postinstall directly, outside
|
|
41
|
+
// npm. Find its JS entry point without executing a batch shim.
|
|
42
|
+
const pathValue = Object.entries(env).find(([key]) => key.toUpperCase() === 'PATH')?.[1] || '';
|
|
43
|
+
for (const dir of [path.dirname(process.execPath), ...pathValue.split(path.delimiter)]) {
|
|
44
|
+
if (!dir) continue;
|
|
45
|
+
const cli = path.join(dir, 'node_modules', 'npm', 'bin', 'npm-cli.js');
|
|
46
|
+
if (fs.existsSync(cli)) return [process.execPath, [cli]];
|
|
47
|
+
}
|
|
48
|
+
throw new Error('npm CLI not found');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function ensureBaselineProviders(detected, { env = process.env, log = console.log, warn = console.warn } = {}) {
|
|
52
|
+
const available = {};
|
|
53
|
+
for (const [name, packageName] of Object.entries(BASELINE_PROVIDERS)) {
|
|
54
|
+
if (detected[`${name}Cli`]?.present) {
|
|
55
|
+
available[name] = true;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
log(`[agent-takkub] ${name} CLI not found — installing ${packageName}…`);
|
|
59
|
+
let failure;
|
|
60
|
+
try {
|
|
61
|
+
const [command, npmArgs] = npmInvocation(env);
|
|
62
|
+
const args = [...npmArgs, 'install', '-g', packageName];
|
|
63
|
+
if (env.npm_config_prefix) args.push('--prefix', env.npm_config_prefix);
|
|
64
|
+
const result = spawnSync(command, args, {
|
|
65
|
+
env: providerEnv(env), stdio: 'inherit', timeout: 300_000, windowsHide: true,
|
|
66
|
+
});
|
|
67
|
+
failure = result.error?.message || (result.status !== 0 ? `npm exited with status ${result.status}` : null);
|
|
68
|
+
available[name] = !failure && Boolean(probeCli(name, env));
|
|
69
|
+
if (!failure && !available[name]) failure = 'installed CLI could not be started';
|
|
70
|
+
} catch (error) {
|
|
71
|
+
failure = error.message;
|
|
72
|
+
available[name] = false;
|
|
73
|
+
}
|
|
74
|
+
if (available[name]) log(`[agent-takkub] ✓ ${name} CLI ready.`);
|
|
75
|
+
else warn(`[agent-takkub] ${name} installation failed: ${failure}. Retry: npm install -g ${packageName}`);
|
|
76
|
+
}
|
|
77
|
+
return available;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
module.exports = { probeCli, ensureBaselineProviders };
|
package/package.json
CHANGED