clawsouls 0.2.0 → 0.2.1
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 +13 -9
- package/dist/bin/clawsouls.js +6 -0
- package/dist/bin/clawsouls.js.map +1 -1
- package/dist/commands/publish.js +8 -2
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/validate.d.ts +1 -0
- package/dist/commands/validate.js +132 -0
- package/dist/commands/validate.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# 🧠 ClawSouls CLI
|
|
1
|
+
# 🧠 ClawSouls CLI v0.2.0
|
|
2
2
|
|
|
3
3
|
**Give your AI a soul.** Install, manage, and switch AI agent personas for [OpenClaw](https://github.com/openclaw/openclaw).
|
|
4
4
|
|
|
@@ -14,8 +14,8 @@ Browse available souls at [clawsouls.ai](https://clawsouls.ai).
|
|
|
14
14
|
## Quick Start
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
# Install a soul
|
|
18
|
-
npx clawsouls install brad
|
|
17
|
+
# Install a soul (owner/name format)
|
|
18
|
+
npx clawsouls install clawsouls/brad
|
|
19
19
|
|
|
20
20
|
# Activate it (backs up your current workspace)
|
|
21
21
|
npx clawsouls use brad
|
|
@@ -47,14 +47,16 @@ clawsouls init my-soul
|
|
|
47
47
|
|
|
48
48
|
Creates a directory with `clawsoul.json`, `SOUL.md`, `IDENTITY.md`, `AGENTS.md`, `HEARTBEAT.md`, and `README.md` — ready for customization and publishing.
|
|
49
49
|
|
|
50
|
-
### `clawsouls install <name>`
|
|
50
|
+
### `clawsouls install <owner/name>`
|
|
51
51
|
|
|
52
|
-
Download and install a soul from the registry.
|
|
52
|
+
Download and install a soul from the registry. Uses `owner/name` format (e.g., `clawsouls/brad`).
|
|
53
|
+
|
|
54
|
+
The install command tries the API first (`/api/v1/souls/:owner/:name?files=true`), falls back to CDN if unavailable, and auto-generates `clawsoul.json` if missing from the response.
|
|
53
55
|
|
|
54
56
|
```bash
|
|
55
|
-
clawsouls install minimalist
|
|
56
|
-
clawsouls install devops-veteran
|
|
57
|
-
clawsouls install brad --force # overwrite existing
|
|
57
|
+
clawsouls install clawsouls/minimalist
|
|
58
|
+
clawsouls install clawsouls/devops-veteran
|
|
59
|
+
clawsouls install clawsouls/brad --force # overwrite existing
|
|
58
60
|
```
|
|
59
61
|
|
|
60
62
|
### `clawsouls use <name>`
|
|
@@ -95,7 +97,9 @@ export CLAWSOULS_TOKEN=<your-token>
|
|
|
95
97
|
clawsouls publish ./my-soul/
|
|
96
98
|
```
|
|
97
99
|
|
|
98
|
-
The directory must contain a valid `clawsoul.json`. All files in the directory are uploaded. A security scan runs automatically before publishing.
|
|
100
|
+
The directory must contain a valid `clawsoul.json`. All files in the directory are uploaded. A security scan runs automatically before publishing (blocks on dangerous patterns with 400 error).
|
|
101
|
+
|
|
102
|
+
**v0.2.0**: The `publish` command auto-prefixes the soul name with your username (e.g., publishing `my-soul` as user `TomLeeLive` creates `TomLeeLive/my-soul`).
|
|
99
103
|
|
|
100
104
|
### `clawsouls login`
|
|
101
105
|
|
package/dist/bin/clawsouls.js
CHANGED
|
@@ -7,6 +7,7 @@ import { restoreCommand } from '../commands/restore.js';
|
|
|
7
7
|
import { listCommand } from '../commands/list.js';
|
|
8
8
|
import { publishCommand, loginCommand } from '../commands/publish.js';
|
|
9
9
|
import { initCommand } from '../commands/init.js';
|
|
10
|
+
import { validateCommand } from '../commands/validate.js';
|
|
10
11
|
const require = createRequire(import.meta.url);
|
|
11
12
|
const { version } = require('../../package.json');
|
|
12
13
|
const program = new Command();
|
|
@@ -44,5 +45,10 @@ program
|
|
|
44
45
|
.command('init [name]')
|
|
45
46
|
.description('Scaffold a new soul directory')
|
|
46
47
|
.action((name) => initCommand(name));
|
|
48
|
+
program
|
|
49
|
+
.command('validate [dir]')
|
|
50
|
+
.alias('check')
|
|
51
|
+
.description('Validate a soul package against the spec')
|
|
52
|
+
.action((dir) => validateCommand(dir));
|
|
47
53
|
program.parse();
|
|
48
54
|
//# sourceMappingURL=clawsouls.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clawsouls.js","sourceRoot":"","sources":["../../src/bin/clawsouls.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"clawsouls.js","sourceRoot":"","sources":["../../src/bin/clawsouls.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAElD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,uCAAuC,CAAC;KACpD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,aAAa,EAAE,gCAAgC,CAAC;KACvD,MAAM,CAAC,cAAc,CAAC,CAAC;AAE1B,OAAO;KACJ,OAAO,CAAC,YAAY,CAAC;KACrB,WAAW,CAAC,yDAAyD,CAAC;KACtE,MAAM,CAAC,UAAU,CAAC,CAAC;AAEtB,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,0CAA0C,CAAC;KACvD,MAAM,CAAC,cAAc,CAAC,CAAC;AAE1B,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,KAAK,CAAC,IAAI,CAAC;KACX,WAAW,CAAC,sBAAsB,CAAC;KACnC,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,wCAAwC,CAAC;KACrD,MAAM,CAAC,cAAc,CAAC,CAAC;AAE1B,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,uDAAuD,CAAC;KACpE,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,+BAA+B,CAAC;KAC5C,MAAM,CAAC,CAAC,IAAa,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;AAEhD,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,KAAK,CAAC,OAAO,CAAC;KACd,WAAW,CAAC,0CAA0C,CAAC;KACvD,MAAM,CAAC,CAAC,GAAY,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;AAElD,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/dist/commands/publish.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFileSync, existsSync, readdirSync, statSync } from 'fs';
|
|
2
2
|
import { join } from 'path';
|
|
3
|
+
import { ClawSoulSchema } from '../utils/validate.js';
|
|
3
4
|
const API_BASE = 'https://clawsouls.ai/api/v1';
|
|
4
5
|
function getToken() {
|
|
5
6
|
if (process.env.CLAWSOULS_TOKEN)
|
|
@@ -42,8 +43,13 @@ export async function publishCommand(dir) {
|
|
|
42
43
|
console.error('Error: Invalid clawsoul.json');
|
|
43
44
|
process.exit(1);
|
|
44
45
|
}
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
// Validate against spec
|
|
47
|
+
const validation = ClawSoulSchema.safeParse(manifest);
|
|
48
|
+
if (!validation.success) {
|
|
49
|
+
console.error('Error: clawsoul.json validation failed:');
|
|
50
|
+
for (const issue of validation.error.issues) {
|
|
51
|
+
console.error(` - ${issue.path.join('.')}: ${issue.message}`);
|
|
52
|
+
}
|
|
47
53
|
process.exit(1);
|
|
48
54
|
}
|
|
49
55
|
const token = getToken();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACrE,OAAO,EAAE,IAAI,EAAY,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function validateCommand(dir?: string): Promise<void>;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { existsSync, readFileSync, readdirSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { ClawSoulSchema } from '../utils/validate.js';
|
|
5
|
+
export async function validateCommand(dir) {
|
|
6
|
+
const soulDir = dir || '.';
|
|
7
|
+
const manifestPath = join(soulDir, 'clawsoul.json');
|
|
8
|
+
console.log(chalk.bold(`Validating soul in ${soulDir}/\n`));
|
|
9
|
+
let hasError = false;
|
|
10
|
+
const pass = (msg) => console.log(chalk.green(' ✓ ') + msg);
|
|
11
|
+
const fail = (msg) => { console.log(chalk.red(' ✗ ') + msg); hasError = true; };
|
|
12
|
+
const warn = (msg) => console.log(chalk.yellow(' ⚠ ') + msg);
|
|
13
|
+
// 1. Check clawsoul.json exists
|
|
14
|
+
if (!existsSync(manifestPath)) {
|
|
15
|
+
fail('clawsoul.json not found');
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
pass('clawsoul.json exists');
|
|
19
|
+
// 2. Parse JSON
|
|
20
|
+
let raw;
|
|
21
|
+
try {
|
|
22
|
+
raw = JSON.parse(readFileSync(manifestPath, 'utf-8'));
|
|
23
|
+
pass('clawsoul.json is valid JSON');
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
fail(`clawsoul.json parse error: ${err.message}`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
// 3. Validate against schema
|
|
30
|
+
const result = ClawSoulSchema.safeParse(raw);
|
|
31
|
+
if (result.success) {
|
|
32
|
+
pass('Schema validation passed');
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
for (const issue of result.error.issues) {
|
|
36
|
+
fail(`${issue.path.join('.')}: ${issue.message}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// 4. Check required files exist
|
|
40
|
+
const files = raw.files || {};
|
|
41
|
+
const requiredFiles = [
|
|
42
|
+
['soul', 'SOUL.md'],
|
|
43
|
+
];
|
|
44
|
+
const optionalFiles = [
|
|
45
|
+
['identity', 'IDENTITY.md'],
|
|
46
|
+
['agents', 'AGENTS.md'],
|
|
47
|
+
['heartbeat', 'HEARTBEAT.md'],
|
|
48
|
+
['style', 'STYLE.md'],
|
|
49
|
+
];
|
|
50
|
+
for (const [key, defaultName] of requiredFiles) {
|
|
51
|
+
const filename = files[key] || defaultName;
|
|
52
|
+
if (existsSync(join(soulDir, filename))) {
|
|
53
|
+
pass(`${filename} exists`);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
fail(`${filename} missing (required)`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
for (const [key, defaultName] of optionalFiles) {
|
|
60
|
+
const filename = files[key] || defaultName;
|
|
61
|
+
if (existsSync(join(soulDir, filename))) {
|
|
62
|
+
pass(`${filename} exists`);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
warn(`${filename} not found (optional)`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// 5. Check README.md
|
|
69
|
+
if (existsSync(join(soulDir, 'README.md'))) {
|
|
70
|
+
pass('README.md exists');
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
warn('README.md not found (recommended)');
|
|
74
|
+
}
|
|
75
|
+
// 6. Content checks
|
|
76
|
+
if (files.soul) {
|
|
77
|
+
const soulContent = readFileSync(join(soulDir, files.soul), 'utf-8');
|
|
78
|
+
if (soulContent.length < 10) {
|
|
79
|
+
warn('SOUL.md is very short (< 10 chars)');
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
pass(`SOUL.md has content (${soulContent.length} chars)`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// 7. Security scan
|
|
86
|
+
const allFiles = readdirSync(soulDir, { recursive: true });
|
|
87
|
+
const dangerousExts = ['.exe', '.dll', '.so', '.dylib', '.sh', '.bat', '.cmd'];
|
|
88
|
+
const dangerousPatterns = ['eval(', 'exec(', 'Function(', 'require(', 'import('];
|
|
89
|
+
for (const file of allFiles) {
|
|
90
|
+
const filePath = String(file);
|
|
91
|
+
const ext = filePath.substring(filePath.lastIndexOf('.'));
|
|
92
|
+
if (dangerousExts.includes(ext)) {
|
|
93
|
+
fail(`Dangerous file extension: ${filePath}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Check text files for dangerous patterns
|
|
97
|
+
for (const file of allFiles) {
|
|
98
|
+
const filePath = join(soulDir, String(file));
|
|
99
|
+
try {
|
|
100
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
101
|
+
for (const pattern of dangerousPatterns) {
|
|
102
|
+
if (content.includes(pattern)) {
|
|
103
|
+
fail(`Dangerous pattern "${pattern}" in ${file}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// Binary file, skip
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// 8. Field-specific warnings
|
|
112
|
+
if (raw.name) {
|
|
113
|
+
if (raw.name.length > 40)
|
|
114
|
+
warn('Name is very long (> 40 chars)');
|
|
115
|
+
}
|
|
116
|
+
if (raw.description) {
|
|
117
|
+
if (raw.description.length < 10)
|
|
118
|
+
warn('Description is very short');
|
|
119
|
+
}
|
|
120
|
+
if (raw.tags && raw.tags.length === 0)
|
|
121
|
+
warn('No tags defined');
|
|
122
|
+
// Summary
|
|
123
|
+
console.log('');
|
|
124
|
+
if (hasError) {
|
|
125
|
+
console.log(chalk.red.bold('✗ Validation failed — fix errors above before publishing.'));
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
console.log(chalk.green.bold('✓ Soul is valid and ready to publish!'));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
|