@robbiesrobotics/alice-agents 1.3.2 → 1.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/alice-install.mjs +7 -0
- package/lib/colors.mjs +102 -0
- package/lib/doctor.mjs +61 -16
- package/lib/installer.mjs +351 -93
- package/lib/skills.mjs +310 -0
- package/package.json +1 -1
- package/templates/workspaces/aiden/SOUL.md +39 -0
- package/templates/workspaces/aiden/TOOLS.md +57 -0
- package/templates/workspaces/alex/SOUL.md +40 -0
- package/templates/workspaces/alex/TOOLS.md +56 -0
- package/templates/workspaces/audrey/SOUL.md +39 -0
- package/templates/workspaces/avery/SOUL.md +40 -0
- package/templates/workspaces/avery/TOOLS.md +47 -0
- package/templates/workspaces/caleb/SOUL.md +39 -0
- package/templates/workspaces/clara/SOUL.md +39 -0
- package/templates/workspaces/daphne/SOUL.md +39 -0
- package/templates/workspaces/darius/SOUL.md +40 -0
- package/templates/workspaces/darius/TOOLS.md +57 -0
- package/templates/workspaces/devon/SOUL.md +40 -0
- package/templates/workspaces/devon/TOOLS.md +49 -0
- package/templates/workspaces/dylan/SOUL.md +42 -0
- package/templates/workspaces/dylan/TOOLS.md +43 -0
- package/templates/workspaces/elena/SOUL.md +39 -0
- package/templates/workspaces/eva/SOUL.md +39 -0
- package/templates/workspaces/felix/SOUL.md +40 -0
- package/templates/workspaces/felix/TOOLS.md +57 -0
- package/templates/workspaces/hannah/SOUL.md +39 -0
- package/templates/workspaces/isaac/SOUL.md +40 -0
- package/templates/workspaces/isaac/TOOLS.md +52 -0
- package/templates/workspaces/logan/SOUL.md +39 -0
- package/templates/workspaces/morgan/SOUL.md +39 -0
- package/templates/workspaces/nadia/SOUL.md +39 -0
- package/templates/workspaces/olivia/SOUL.md +40 -0
- package/templates/workspaces/owen/SOUL.md +39 -0
- package/templates/workspaces/parker/SOUL.md +39 -0
- package/templates/workspaces/quinn/SOUL.md +40 -0
- package/templates/workspaces/quinn/TOOLS.md +50 -0
- package/templates/workspaces/rowan/SOUL.md +40 -0
- package/templates/workspaces/rowan/TOOLS.md +59 -0
- package/templates/workspaces/selena/SOUL.md +40 -0
- package/templates/workspaces/selena/TOOLS.md +47 -0
- package/templates/workspaces/sloane/SOUL.md +39 -0
- package/templates/workspaces/sophie/SOUL.md +39 -0
- package/templates/workspaces/tommy/SOUL.md +39 -0
- package/templates/workspaces/uma/SOUL.md +39 -0
package/bin/alice-install.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import { readFileSync } from 'node:fs';
|
|
|
4
4
|
import { createRequire } from 'node:module';
|
|
5
5
|
import { runInstall, runUninstall } from '../lib/installer.mjs';
|
|
6
6
|
import { runDoctor } from '../lib/doctor.mjs';
|
|
7
|
+
import { runSkillsManager } from '../lib/skills.mjs';
|
|
7
8
|
|
|
8
9
|
const args = process.argv.slice(2);
|
|
9
10
|
const flags = new Set(args);
|
|
@@ -24,6 +25,7 @@ if (flags.has('--help') || flags.has('-h')) {
|
|
|
24
25
|
npx @robbiesrobotics/alice-agents --update Non-interactive upgrade to latest agents
|
|
25
26
|
npx @robbiesrobotics/alice-agents --uninstall Remove A.L.I.C.E. agents from config
|
|
26
27
|
npx @robbiesrobotics/alice-agents --doctor Run diagnostics on your A.L.I.C.E. install
|
|
28
|
+
npx @robbiesrobotics/alice-agents --skills Manage skills (install, remove, browse)
|
|
27
29
|
npx @robbiesrobotics/alice-agents --version Show version
|
|
28
30
|
npx @robbiesrobotics/alice-agents --help Show this help
|
|
29
31
|
|
|
@@ -47,6 +49,11 @@ if (flags.has('--doctor')) {
|
|
|
47
49
|
console.error(' ❌ Update failed:', err.message);
|
|
48
50
|
process.exit(1);
|
|
49
51
|
});
|
|
52
|
+
} else if (flags.has('--skills')) {
|
|
53
|
+
runSkillsManager().catch((err) => {
|
|
54
|
+
console.error(` ✗ Skills manager failed: ${err.message}`);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
});
|
|
50
57
|
} else if (flags.has('--uninstall')) {
|
|
51
58
|
runUninstall({ yes: flags.has('--yes') }).catch((err) => {
|
|
52
59
|
console.error(' ❌ Uninstall failed:', err.message);
|
package/lib/colors.mjs
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// lib/colors.mjs
|
|
2
|
+
// ANSI color helper — no external deps, NO_COLOR + non-TTY safe
|
|
3
|
+
// Brand: A.L.I.C.E. / NemoClaw green (#76b900 → \x1b[92m bright green)
|
|
4
|
+
|
|
5
|
+
const enabled =
|
|
6
|
+
process.stdout.isTTY &&
|
|
7
|
+
!process.env.NO_COLOR &&
|
|
8
|
+
process.env.TERM !== 'dumb';
|
|
9
|
+
|
|
10
|
+
const esc = (code) => (str) => enabled ? `\x1b[${code}m${str}\x1b[0m` : str;
|
|
11
|
+
|
|
12
|
+
export const c = {
|
|
13
|
+
green: esc('92'),
|
|
14
|
+
greenDim: esc('32'),
|
|
15
|
+
success: esc('92'),
|
|
16
|
+
error: esc('91'),
|
|
17
|
+
warning: esc('93'),
|
|
18
|
+
info: esc('96'),
|
|
19
|
+
accent: esc('95'),
|
|
20
|
+
bold: esc('1'),
|
|
21
|
+
dim: esc('2'),
|
|
22
|
+
italic: esc('3'),
|
|
23
|
+
underline:esc('4'),
|
|
24
|
+
white: esc('97'),
|
|
25
|
+
gray: esc('90'),
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const bold = (s) => c.bold(s);
|
|
29
|
+
export const dim = (s) => c.dim(s);
|
|
30
|
+
export const green = (s) => c.green(s);
|
|
31
|
+
export const greenBold = (s) => enabled ? `\x1b[1m\x1b[92m${s}\x1b[0m` : s;
|
|
32
|
+
export const red = (s) => c.error(s);
|
|
33
|
+
export const yellow = (s) => c.warning(s);
|
|
34
|
+
export const cyan = (s) => c.info(s);
|
|
35
|
+
export const gray = (s) => c.gray(s);
|
|
36
|
+
export const white = (s) => c.white(s);
|
|
37
|
+
|
|
38
|
+
export const icons = {
|
|
39
|
+
ok: green('✔'),
|
|
40
|
+
fail: red('✗'),
|
|
41
|
+
warn: yellow('⚠'),
|
|
42
|
+
info: cyan('ℹ'),
|
|
43
|
+
pkg: '📦',
|
|
44
|
+
arrow: dim('›'),
|
|
45
|
+
bullet:dim('·'),
|
|
46
|
+
check: green('✓'),
|
|
47
|
+
cross: red('✗'),
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const SEP_WIDTH = 50;
|
|
51
|
+
const SEP_CHAR = '─';
|
|
52
|
+
|
|
53
|
+
export function separator() {
|
|
54
|
+
return dim(SEP_CHAR.repeat(SEP_WIDTH));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function printSection(title) {
|
|
58
|
+
const totalDashes = SEP_WIDTH - title.length - 4;
|
|
59
|
+
const left = SEP_CHAR.repeat(2);
|
|
60
|
+
const right = SEP_CHAR.repeat(Math.max(0, totalDashes));
|
|
61
|
+
console.log(`\n ${dim(left)} ${greenBold(title)} ${dim(right)}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function printSeparator() {
|
|
65
|
+
console.log(` ${separator()}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const stripAnsi = (s) => s.replace(/\x1b\[[0-9;]*m/g, '');
|
|
69
|
+
|
|
70
|
+
export function printBox(lines, { title = null, padding = 1 } = {}) {
|
|
71
|
+
const innerWidth = Math.max(...lines.map(l => stripAnsi(l).length)) + padding * 2;
|
|
72
|
+
const w = innerWidth;
|
|
73
|
+
const TL = '╭', TR = '╮', BL = '╰', BR = '╯', H = '─', V = '│';
|
|
74
|
+
|
|
75
|
+
const topBar = title
|
|
76
|
+
? `${TL}${H} ${greenBold(title)} ${H.repeat(Math.max(0, w - stripAnsi(title).length - 4))}${TR}`
|
|
77
|
+
: `${TL}${H.repeat(w + 2)}${TR}`;
|
|
78
|
+
|
|
79
|
+
console.log(` ${dim(topBar)}`);
|
|
80
|
+
lines.forEach(line => {
|
|
81
|
+
const pad = ' '.repeat(padding);
|
|
82
|
+
const raw = stripAnsi(line);
|
|
83
|
+
const trail = ' '.repeat(Math.max(0, w - raw.length - padding));
|
|
84
|
+
console.log(` ${dim(V)}${pad}${line}${trail}${dim(V)}`);
|
|
85
|
+
});
|
|
86
|
+
console.log(` ${dim(`${BL}${H.repeat(w + 2)}${BR}`)}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function printStepDone(label, detail = '') {
|
|
90
|
+
const suffix = detail ? ` ${dim(detail)}` : '';
|
|
91
|
+
console.log(` ${icons.ok} ${label}${suffix}`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function printStepFail(label, reason = '') {
|
|
95
|
+
const suffix = reason ? ` ${red(reason)}` : '';
|
|
96
|
+
console.log(` ${icons.fail} ${label}${suffix}`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function printStepSkip(label, reason = '') {
|
|
100
|
+
const suffix = reason ? ` ${dim(reason)}` : '';
|
|
101
|
+
console.log(` ${dim('–')} ${dim(label)}${suffix}`);
|
|
102
|
+
}
|
package/lib/doctor.mjs
CHANGED
|
@@ -3,9 +3,21 @@ import { join, dirname } from 'node:path';
|
|
|
3
3
|
import { homedir, platform } from 'node:os';
|
|
4
4
|
import { execSync } from 'node:child_process';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { icons, greenBold, green, red, yellow, cyan, dim, bold,
|
|
7
|
+
printSection, printSeparator, separator } from './colors.mjs';
|
|
6
8
|
|
|
7
9
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
10
|
const HOME = homedir();
|
|
11
|
+
|
|
12
|
+
function commandExists(cmd) {
|
|
13
|
+
const probe = process.platform === 'win32' ? 'where' : 'which';
|
|
14
|
+
try {
|
|
15
|
+
execSync(`${probe} ${cmd}`, { stdio: 'pipe' });
|
|
16
|
+
return true;
|
|
17
|
+
} catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
9
21
|
const OPENCLAW_DIR = join(HOME, '.openclaw');
|
|
10
22
|
|
|
11
23
|
const STARTER_AGENTS = [
|
|
@@ -14,9 +26,9 @@ const STARTER_AGENTS = [
|
|
|
14
26
|
];
|
|
15
27
|
|
|
16
28
|
function check(label, ok, hint) {
|
|
17
|
-
const icon = ok ?
|
|
18
|
-
console.log(` ${icon} ${label}`);
|
|
19
|
-
if (!ok && hint) console.log(` → ${hint}`);
|
|
29
|
+
const icon = ok ? icons.ok : icons.fail;
|
|
30
|
+
console.log(` ${icon} ${ok ? green(label) : red(label)}`);
|
|
31
|
+
if (!ok && hint) console.log(` ${dim('→')} ${dim(hint)}`);
|
|
20
32
|
return ok;
|
|
21
33
|
}
|
|
22
34
|
|
|
@@ -51,12 +63,7 @@ function checkDockerEnvironment() {
|
|
|
51
63
|
const isLinux = platform() === 'linux';
|
|
52
64
|
|
|
53
65
|
// Check if docker binary exists at all
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
execSync('which docker', { stdio: 'pipe' });
|
|
57
|
-
dockerInstalled = true;
|
|
58
|
-
} catch {
|
|
59
|
-
// Docker not installed — not a blocker unless openclaw needs it
|
|
66
|
+
if (!commandExists('docker')) {
|
|
60
67
|
return { present: false, accessible: false, needsSudo: false, hint: null };
|
|
61
68
|
}
|
|
62
69
|
|
|
@@ -109,7 +116,10 @@ function checkDockerEnvironment() {
|
|
|
109
116
|
}
|
|
110
117
|
|
|
111
118
|
export async function runDoctor() {
|
|
112
|
-
console.log('
|
|
119
|
+
console.log('');
|
|
120
|
+
printSection('A.L.I.C.E. Doctor');
|
|
121
|
+
console.log(` ${dim('Diagnostic Report')}`);
|
|
122
|
+
console.log('');
|
|
113
123
|
let allOk = true;
|
|
114
124
|
|
|
115
125
|
// 1. Runtime check
|
|
@@ -130,7 +140,7 @@ export async function runDoctor() {
|
|
|
130
140
|
|
|
131
141
|
if (!configExists) {
|
|
132
142
|
allOk = false;
|
|
133
|
-
console.log(
|
|
143
|
+
console.log(`\n ${icons.warn} ${yellow('Cannot continue checks — openclaw.json missing.')}\n`);
|
|
134
144
|
return false;
|
|
135
145
|
}
|
|
136
146
|
|
|
@@ -143,7 +153,7 @@ export async function runDoctor() {
|
|
|
143
153
|
);
|
|
144
154
|
if (!configValid) {
|
|
145
155
|
allOk = false;
|
|
146
|
-
console.log(
|
|
156
|
+
console.log(`\n ${icons.warn} ${yellow('Cannot continue checks — config is invalid JSON.')}\n`);
|
|
147
157
|
return false;
|
|
148
158
|
}
|
|
149
159
|
|
|
@@ -236,11 +246,16 @@ export async function runDoctor() {
|
|
|
236
246
|
);
|
|
237
247
|
// Docker permission issue is a warning, not a hard failure for A.L.I.C.E. itself
|
|
238
248
|
// but it will break OpenClaw's own Docker features
|
|
239
|
-
console.log(
|
|
249
|
+
console.log(` ${icons.info} ${dim('This will affect OpenClaw features that use Docker.')}\n`);
|
|
240
250
|
} else {
|
|
241
251
|
check('Docker daemon not running or not accessible', false, docker.hint);
|
|
242
252
|
}
|
|
243
253
|
}
|
|
254
|
+
|
|
255
|
+
const isWSL = !!process.env.WSL_DISTRO_NAME || !!process.env.WSLENV;
|
|
256
|
+
if (isWSL && docker.present) {
|
|
257
|
+
console.log(" ℹ️ WSL2 detected. If Docker has cgroup issues, run: nemoclaw setup-spark\n");
|
|
258
|
+
}
|
|
244
259
|
// If docker not present at all, skip silently — not required for all setups
|
|
245
260
|
|
|
246
261
|
// 7. License check
|
|
@@ -276,13 +291,43 @@ export async function runDoctor() {
|
|
|
276
291
|
check('License: Starter tier (no license required)', true);
|
|
277
292
|
}
|
|
278
293
|
|
|
294
|
+
// 8. Skills disk check
|
|
295
|
+
const skillsManifestPath = join(OPENCLAW_DIR, '.alice-manifest.json');
|
|
296
|
+
const skillsManifestData = (() => {
|
|
297
|
+
try {
|
|
298
|
+
if (!existsSync(skillsManifestPath)) return null;
|
|
299
|
+
return JSON.parse(readFileSync(skillsManifestPath, 'utf8'));
|
|
300
|
+
} catch { return null; }
|
|
301
|
+
})();
|
|
302
|
+
|
|
303
|
+
const installedSkills = skillsManifestData?.skills || [];
|
|
304
|
+
if (installedSkills.length > 0) {
|
|
305
|
+
const missingSkills = installedSkills.filter(
|
|
306
|
+
id => !existsSync(join(HOME, '.openclaw', 'skills', id))
|
|
307
|
+
);
|
|
308
|
+
if (missingSkills.length > 0) {
|
|
309
|
+
check(
|
|
310
|
+
`Skills missing on disk: ${missingSkills.join(', ')}`,
|
|
311
|
+
false,
|
|
312
|
+
'Run: npx @robbiesrobotics/alice-agents --skills to reinstall'
|
|
313
|
+
);
|
|
314
|
+
allOk = false;
|
|
315
|
+
} else {
|
|
316
|
+
check(`Skills installed (${installedSkills.length}): ${installedSkills.join(', ')}`, true);
|
|
317
|
+
}
|
|
318
|
+
} else {
|
|
319
|
+
console.log(` ${dim('–')} ${dim('No skills installed (optional)')}`);
|
|
320
|
+
}
|
|
321
|
+
|
|
279
322
|
// Summary
|
|
280
|
-
console.log();
|
|
323
|
+
console.log('');
|
|
281
324
|
if (allOk) {
|
|
282
|
-
console.log(
|
|
325
|
+
console.log(` ${icons.ok} ${greenBold('A.L.I.C.E. is healthy!')}`);
|
|
283
326
|
} else {
|
|
284
|
-
console.log('
|
|
327
|
+
console.log(` ${icons.warn} ${yellow('Issues found')} ${dim('─ follow the hints above to fix them.')}`);
|
|
285
328
|
}
|
|
329
|
+
printSeparator();
|
|
330
|
+
console.log('');
|
|
286
331
|
|
|
287
332
|
return allOk;
|
|
288
333
|
}
|