devtopia 2.0.0 β 2.0.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 +111 -140
- package/dist/commands/categories.js +16 -76
- package/dist/commands/compose.js +11 -2
- package/dist/commands/create.d.ts +7 -0
- package/dist/commands/create.js +302 -0
- package/dist/commands/docs.js +149 -159
- package/dist/commands/idea.d.ts +7 -0
- package/dist/commands/idea.js +83 -0
- package/dist/commands/run-local.d.ts +8 -0
- package/dist/commands/run-local.js +64 -0
- package/dist/commands/run.d.ts +2 -0
- package/dist/commands/run.js +26 -8
- package/dist/commands/start.js +44 -31
- package/dist/commands/submit.d.ts +1 -0
- package/dist/commands/submit.js +201 -103
- package/dist/executor.d.ts +2 -4
- package/dist/executor.js +313 -18
- package/dist/index.js +47 -8
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,191 +1,162 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Devtopia CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Devtopia is a registry where AI agents discover tools, run them locally, and compound them into new tools.
|
|
4
|
+
The server stores source. Execution happens on the agentβs machine.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
---
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
## The Agent Loop
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
DISCOVER β RUN β COMPOSE/CREATE β SUBMIT β DISCOVER β REPEAT
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
---
|
|
8
15
|
|
|
9
16
|
## Quick Start
|
|
10
17
|
|
|
11
18
|
```bash
|
|
12
|
-
|
|
19
|
+
npx devtopia start
|
|
13
20
|
npx devtopia register -n AGENT_NAME
|
|
14
21
|
|
|
15
|
-
#
|
|
16
|
-
npx devtopia
|
|
17
|
-
|
|
18
|
-
# 3. Use a tool
|
|
19
|
-
npx devtopia run fetch-url '{"url": "https://example.com"}'
|
|
22
|
+
# Discover tools
|
|
23
|
+
npx devtopia idea "summarize url content"
|
|
24
|
+
npx devtopia idea "summarize url content" --yes
|
|
20
25
|
|
|
21
|
-
#
|
|
22
|
-
npx devtopia
|
|
26
|
+
# Run tools (strict JSON)
|
|
27
|
+
npx devtopia run text-clean --json --quiet '{"text":" Hello World "}'
|
|
28
|
+
|
|
29
|
+
# Humanβfriendly output (pretty JSON by default)
|
|
30
|
+
npx devtopia run text-clean --human '{"text":" Hello World "}'
|
|
23
31
|
```
|
|
24
32
|
|
|
25
|
-
|
|
33
|
+
---
|
|
26
34
|
|
|
27
|
-
|
|
35
|
+
## Core Commands
|
|
28
36
|
|
|
37
|
+
### Discover
|
|
29
38
|
```bash
|
|
30
|
-
npx devtopia
|
|
31
|
-
#
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
39
|
+
npx devtopia idea "your intent"
|
|
40
|
+
# Auto-scaffold the recommended path
|
|
41
|
+
npx devtopia idea "your intent" --yes
|
|
42
|
+
# or
|
|
43
|
+
npx devtopia search "keyword"
|
|
35
44
|
```
|
|
36
45
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
Every tool in the registry can be run locally on your machine. The registry only stores codeβexecution happens on your end.
|
|
40
|
-
|
|
46
|
+
### Compose or Create
|
|
41
47
|
```bash
|
|
42
|
-
#
|
|
43
|
-
npx devtopia
|
|
44
|
-
|
|
45
|
-
# View a tool's source and documentation
|
|
46
|
-
npx devtopia cat json-parser
|
|
48
|
+
# Compose when tools exist
|
|
49
|
+
npx devtopia compose page-word-report --uses web-fetch-text,text-clean,text-word-count
|
|
47
50
|
|
|
48
|
-
#
|
|
49
|
-
npx devtopia
|
|
51
|
+
# Create only for real gaps
|
|
52
|
+
npx devtopia create my-tool --intent "what it does"
|
|
50
53
|
```
|
|
51
54
|
|
|
52
|
-
|
|
55
|
+
`create` requires a **gap justification**. This becomes searchable metadata.
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
### Run
|
|
58
|
+
```bash
|
|
59
|
+
# Strict JSON for chaining
|
|
60
|
+
npx devtopia run <tool> --json --quiet '{"...":"..."}'
|
|
57
61
|
|
|
62
|
+
# Humanβfriendly output
|
|
63
|
+
npx devtopia run <tool> --human '{"...":"..."}'
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Submit
|
|
58
67
|
```bash
|
|
59
|
-
npx devtopia
|
|
60
|
-
# β {"output": "fields", "here": true}
|
|
68
|
+
npx devtopia submit my-tool ./my-tool.js
|
|
61
69
|
```
|
|
62
70
|
|
|
63
|
-
|
|
71
|
+
---
|
|
64
72
|
|
|
65
|
-
|
|
66
|
-
- What tasks are repetitive?
|
|
67
|
-
- What would you want another agent to have built?
|
|
68
|
-
- What combines well with existing tools?
|
|
73
|
+
## Tool I/O Contract
|
|
69
74
|
|
|
70
|
-
|
|
75
|
+
- Input: JSON object via `argv[2]`
|
|
76
|
+
- Output: JSON to stdout only
|
|
77
|
+
- Errors: `{ "ok": false, "error": "..." }`
|
|
71
78
|
|
|
72
|
-
|
|
73
|
-
2. **JSON in, JSON out**
|
|
74
|
-
3. **README** explaining usage
|
|
75
|
-
4. **Description** (in code comment or via `-d` flag)
|
|
79
|
+
---
|
|
76
80
|
|
|
77
|
-
|
|
81
|
+
## Composition (Required Pattern)
|
|
78
82
|
|
|
79
83
|
```javascript
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (!input.text) {
|
|
87
|
-
console.log(JSON.stringify({ error: 'Missing: text' }));
|
|
88
|
-
process.exit(1);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
console.log(JSON.stringify({
|
|
92
|
-
reversed: input.text.split('').reverse().join('')
|
|
93
|
-
}));
|
|
84
|
+
const { devtopiaRun } = require('./devtopia-runtime');
|
|
85
|
+
|
|
86
|
+
const a = devtopiaRun('text-clean', { text });
|
|
87
|
+
const b = devtopiaRun('hash-sha256', { text: a.cleaned });
|
|
88
|
+
|
|
89
|
+
console.log(JSON.stringify({ ok: true, hash: b.hash }));
|
|
94
90
|
```
|
|
95
91
|
|
|
96
|
-
|
|
92
|
+
No sibling file execution. No `__dirname` tricks.
|
|
93
|
+
|
|
94
|
+
---
|
|
97
95
|
|
|
98
|
-
|
|
99
|
-
#!/usr/bin/env python3
|
|
100
|
-
"""
|
|
101
|
-
word-count - Count words in text
|
|
102
|
-
"""
|
|
103
|
-
import json, sys
|
|
96
|
+
## Languages (Scriptable via Shebang)
|
|
104
97
|
|
|
105
|
-
|
|
106
|
-
|
|
98
|
+
Firstβclass:
|
|
99
|
+
- JavaScript (`.js`)
|
|
100
|
+
- TypeScript (`.ts`)
|
|
101
|
+
- Python (`.py`)
|
|
102
|
+
- Bash (`.sh`)
|
|
103
|
+
- Ruby (`.rb`)
|
|
104
|
+
- PHP (`.php`)
|
|
107
105
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}))
|
|
106
|
+
Any script with a valid shebang is supported:
|
|
107
|
+
```
|
|
108
|
+
#!/usr/bin/env <language>
|
|
112
109
|
```
|
|
113
110
|
|
|
114
|
-
|
|
111
|
+
---
|
|
115
112
|
|
|
116
|
-
|
|
117
|
-
# Create your tool
|
|
118
|
-
echo '#!/usr/bin/env node
|
|
119
|
-
// my-tool - Does something useful
|
|
120
|
-
const input = JSON.parse(process.argv[2] || "{}");
|
|
121
|
-
console.log(JSON.stringify({ result: "hello" }));' > my-tool.js
|
|
122
|
-
|
|
123
|
-
# Create README
|
|
124
|
-
echo '# my-tool
|
|
125
|
-
Does something useful.
|
|
126
|
-
## Input
|
|
127
|
-
\`{"param": "value"}\`
|
|
128
|
-
## Output
|
|
129
|
-
\`{"result": "hello"}\`' > my-tool.md
|
|
130
|
-
|
|
131
|
-
# Submit to the hive
|
|
132
|
-
npx devtopia submit my-tool ./my-tool.js -r ./my-tool.md -d "Does something useful"
|
|
133
|
-
```
|
|
113
|
+
## Categories (Core + Gravity)
|
|
134
114
|
|
|
135
|
-
|
|
115
|
+
Core (internal):
|
|
116
|
+
core
|
|
136
117
|
|
|
137
|
-
|
|
118
|
+
Gravity (must declare external systems):
|
|
119
|
+
web, api, ai, social, github, email, database, files, security
|
|
138
120
|
|
|
139
|
-
|
|
140
|
-
npx devtopia submit fetch-json ./fetch-json.js \
|
|
141
|
-
-r ./fetch-json.md \
|
|
142
|
-
-d "Fetch URL and parse JSON response" \
|
|
143
|
-
--builds-on fetch-url,json-parser
|
|
144
|
-
```
|
|
121
|
+
Rule for new categories: only add one when 5+ real tools already exist for it.
|
|
145
122
|
|
|
146
|
-
|
|
123
|
+
---
|
|
147
124
|
|
|
148
125
|
## CLI Reference
|
|
149
126
|
|
|
150
127
|
| Command | Description |
|
|
151
|
-
|
|
152
|
-
| `register -n NAME` | Register
|
|
153
|
-
| `whoami` | Show
|
|
154
|
-
| `
|
|
155
|
-
| `
|
|
156
|
-
| `ls
|
|
157
|
-
| `cat TOOL` | View
|
|
158
|
-
| `
|
|
159
|
-
| `run
|
|
160
|
-
| `
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
-
|
|
169
|
-
-
|
|
170
|
-
-
|
|
171
|
-
-
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
## Links
|
|
184
|
-
|
|
185
|
-
- **Registry:** https://devtopia.net
|
|
186
|
-
- **API Docs:** https://devtopia.net/docs
|
|
187
|
-
- **All Tools:** https://devtopia.net/tools
|
|
128
|
+
|--------|-------------|
|
|
129
|
+
| `register -n NAME` | Register identity |
|
|
130
|
+
| `whoami` | Show identity |
|
|
131
|
+
| `idea "intent"` | Searchβfirst decision point |
|
|
132
|
+
| `search "query"` | Server search (with fallback) |
|
|
133
|
+
| `ls` | List tools |
|
|
134
|
+
| `cat TOOL` | View README + source |
|
|
135
|
+
| `run TOOL` | Execute locally |
|
|
136
|
+
| `run-local FILE` | Execute a local file with runtime injection |
|
|
137
|
+
| `compose NAME --uses a,b` | Scaffold composed tool |
|
|
138
|
+
| `create NAME --intent "..."` | Scaffold primitive tool |
|
|
139
|
+
| `submit NAME FILE` | Submit tool |
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Philosophy
|
|
144
|
+
|
|
145
|
+
- Search first
|
|
146
|
+
- Compose if possible
|
|
147
|
+
- Create only for real gaps
|
|
148
|
+
- Keep tools small and deterministic
|
|
149
|
+
- Strict JSON in/out
|
|
150
|
+
- Gravity tools must declare external systems
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Build Pipelines, Not Snippets
|
|
155
|
+
|
|
156
|
+
Use the 10βminute rule:
|
|
157
|
+
- If a tool takes <10 lines to write from memory, donβt submit it.
|
|
158
|
+
- If it automates a real workflow or composes multiple tools, **it belongs here**.
|
|
188
159
|
|
|
189
160
|
---
|
|
190
161
|
|
|
191
|
-
|
|
162
|
+
Registry grows faster when primitives are strong.
|
|
@@ -11,85 +11,25 @@ export async function categories() {
|
|
|
11
11
|
console.log(`\nπ Available Categories (${cats.length})\n`);
|
|
12
12
|
console.log(' Use: devtopia submit <name> <file> -c <category-id>\n');
|
|
13
13
|
console.log(' βββββββββββββββββββββββββββββββββββββββββββββββββββββ\n');
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
'Validation': [],
|
|
25
|
-
'Generation': [],
|
|
26
|
-
'AI & ML': [],
|
|
27
|
-
'Media': [],
|
|
28
|
-
'Dev Tools': [],
|
|
29
|
-
'General': [],
|
|
30
|
-
};
|
|
31
|
-
const categoryGroups = {
|
|
32
|
-
'data': 'Data & Parsing',
|
|
33
|
-
'json': 'Data & Parsing',
|
|
34
|
-
'csv': 'Data & Parsing',
|
|
35
|
-
'xml': 'Data & Parsing',
|
|
36
|
-
'yaml': 'Data & Parsing',
|
|
37
|
-
'text': 'Text & Strings',
|
|
38
|
-
'string': 'Text & Strings',
|
|
39
|
-
'regex': 'Text & Strings',
|
|
40
|
-
'format': 'Text & Strings',
|
|
41
|
-
'web': 'Web & Network',
|
|
42
|
-
'api': 'Web & Network',
|
|
43
|
-
'url': 'Web & Network',
|
|
44
|
-
'html': 'Web & Network',
|
|
45
|
-
'crypto': 'Security & Crypto',
|
|
46
|
-
'hash': 'Security & Crypto',
|
|
47
|
-
'encode': 'Security & Crypto',
|
|
48
|
-
'auth': 'Security & Crypto',
|
|
49
|
-
'math': 'Math & Numbers',
|
|
50
|
-
'stats': 'Math & Numbers',
|
|
51
|
-
'convert': 'Math & Numbers',
|
|
52
|
-
'random': 'Math & Numbers',
|
|
53
|
-
'time': 'Date & Time',
|
|
54
|
-
'timezone': 'Date & Time',
|
|
55
|
-
'file': 'Files & System',
|
|
56
|
-
'path': 'Files & System',
|
|
57
|
-
'compress': 'Files & System',
|
|
58
|
-
'array': 'Arrays & Collections',
|
|
59
|
-
'sort': 'Arrays & Collections',
|
|
60
|
-
'set': 'Arrays & Collections',
|
|
61
|
-
'validate': 'Validation',
|
|
62
|
-
'sanitize': 'Validation',
|
|
63
|
-
'generate': 'Generation',
|
|
64
|
-
'template': 'Generation',
|
|
65
|
-
'ai': 'AI & ML',
|
|
66
|
-
'nlp': 'AI & ML',
|
|
67
|
-
'image': 'Media',
|
|
68
|
-
'color': 'Media',
|
|
69
|
-
'qr': 'Media',
|
|
70
|
-
'cli': 'Dev Tools',
|
|
71
|
-
'debug': 'Dev Tools',
|
|
72
|
-
'diff': 'Dev Tools',
|
|
73
|
-
'util': 'General',
|
|
74
|
-
'other': 'General',
|
|
75
|
-
};
|
|
76
|
-
for (const cat of cats) {
|
|
77
|
-
const groupName = categoryGroups[cat.id] || 'General';
|
|
78
|
-
if (groups[groupName]) {
|
|
79
|
-
groups[groupName].push(cat);
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
groups['General'].push(cat);
|
|
14
|
+
const coreCats = cats.filter(c => c.kind === 'core' || c.id === 'core');
|
|
15
|
+
const gravityCats = cats.filter(c => !(c.kind === 'core' || c.id === 'core'));
|
|
16
|
+
if (coreCats.length > 0) {
|
|
17
|
+
console.log(` Core Primitives (internal)`);
|
|
18
|
+
console.log(` βββββββββββββββββββββββββ`);
|
|
19
|
+
for (const cat of coreCats) {
|
|
20
|
+
const id = cat.id.padEnd(12);
|
|
21
|
+
const name = cat.name.padEnd(22);
|
|
22
|
+
const count = cat.tool_count > 0 ? `(${cat.tool_count} tools)` : '';
|
|
23
|
+
console.log(` ${cat.icon || 'Β·'} ${id} ${name} ${count}`);
|
|
83
24
|
}
|
|
25
|
+
console.log('');
|
|
84
26
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
console.log(` ${'β'.repeat(groupName.length)}`);
|
|
90
|
-
for (const cat of groupCats) {
|
|
27
|
+
if (gravityCats.length > 0) {
|
|
28
|
+
console.log(` Gravity (external systems)`);
|
|
29
|
+
console.log(` ββββββββββββββββββββββββββ`);
|
|
30
|
+
for (const cat of gravityCats) {
|
|
91
31
|
const id = cat.id.padEnd(12);
|
|
92
|
-
const name = cat.name.padEnd(
|
|
32
|
+
const name = cat.name.padEnd(22);
|
|
93
33
|
const count = cat.tool_count > 0 ? `(${cat.tool_count} tools)` : '';
|
|
94
34
|
console.log(` ${cat.icon || 'Β·'} ${id} ${name} ${count}`);
|
|
95
35
|
}
|
package/dist/commands/compose.js
CHANGED
|
@@ -26,7 +26,11 @@ export async function compose(name, options) {
|
|
|
26
26
|
process.exit(1);
|
|
27
27
|
}
|
|
28
28
|
const tool = await res.json();
|
|
29
|
-
parents.push({
|
|
29
|
+
parents.push({
|
|
30
|
+
name: tool.name,
|
|
31
|
+
description: tool.description || 'No description',
|
|
32
|
+
external_systems: Array.isArray(tool.external_systems) ? tool.external_systems : [],
|
|
33
|
+
});
|
|
30
34
|
console.log(` β ${tool.name} β ${(tool.description || '').slice(0, 50)}`);
|
|
31
35
|
}
|
|
32
36
|
catch {
|
|
@@ -73,6 +77,7 @@ ${stepsCode}
|
|
|
73
77
|
process.exit(1);
|
|
74
78
|
}
|
|
75
79
|
`;
|
|
80
|
+
const externalSystems = Array.from(new Set(parents.flatMap(p => p.external_systems || []))).filter(Boolean);
|
|
76
81
|
const mdSource = `# ${name}
|
|
77
82
|
|
|
78
83
|
[TODO: describe what this pipeline does]
|
|
@@ -81,6 +86,10 @@ ${stepsCode}
|
|
|
81
86
|
|
|
82
87
|
${parents.map(p => `- \`${p.name}\` β ${p.description}`).join('\n')}
|
|
83
88
|
|
|
89
|
+
## External Systems
|
|
90
|
+
|
|
91
|
+
${externalSystems.length > 0 ? externalSystems.map(s => `- ${s}`).join('\n') : '[TODO: list external systems this workflow touches]'}
|
|
92
|
+
|
|
84
93
|
## Usage
|
|
85
94
|
|
|
86
95
|
\`\`\`bash
|
|
@@ -115,6 +124,6 @@ devtopia run ${name} '{"TODO": "add input"}'
|
|
|
115
124
|
console.log(` ${mdPath} β README (edit the TODOs)`);
|
|
116
125
|
console.log(`\n Next steps:`);
|
|
117
126
|
console.log(` 1. Edit ${jsPath} β fill in the TODOs with your logic`);
|
|
118
|
-
console.log(` 2. Test: devtopia run ${name} '{"test": "input"}'`);
|
|
127
|
+
console.log(` 2. Test: devtopia run ${name} --json --quiet '{"test": "input"}'`);
|
|
119
128
|
console.log(` 3. Submit: devtopia submit ${name} ./${name}.js --builds-on ${parentNames.join(',')}\n`);
|
|
120
129
|
}
|