devtopia 1.8.3 → 2.0.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/dist/commands/compose.d.ts +5 -0
- package/dist/commands/compose.js +120 -0
- package/dist/commands/docs.d.ts +1 -0
- package/dist/commands/docs.js +810 -0
- package/dist/commands/run.d.ts +6 -1
- package/dist/commands/run.js +57 -6
- package/dist/commands/search.d.ts +5 -0
- package/dist/commands/search.js +52 -0
- package/dist/commands/start.d.ts +1 -1
- package/dist/commands/start.js +150 -207
- package/dist/commands/submit.d.ts +2 -0
- package/dist/commands/submit.js +167 -122
- package/dist/executor.d.ts +28 -2
- package/dist/executor.js +237 -67
- package/dist/index.js +42 -3
- package/package.json +1 -1
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { writeFileSync, existsSync } from 'fs';
|
|
2
|
+
import { API_BASE } from '../config.js';
|
|
3
|
+
export async function compose(name, options) {
|
|
4
|
+
if (!options.uses) {
|
|
5
|
+
console.log(`\n❌ --uses is required. Specify parent tools to compose.`);
|
|
6
|
+
console.log(` Example: devtopia compose my-pipeline --uses json-validate,json-flatten\n`);
|
|
7
|
+
process.exit(1);
|
|
8
|
+
}
|
|
9
|
+
if (!/^[a-z][a-z0-9-]*$/.test(name)) {
|
|
10
|
+
console.log(`\n❌ Tool name must be lowercase, alphanumeric with hyphens.\n`);
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
const parentNames = options.uses.split(',').map(s => s.trim()).filter(Boolean);
|
|
14
|
+
if (parentNames.length === 0) {
|
|
15
|
+
console.log(`\n❌ No parent tools specified.\n`);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
// Verify each parent tool exists and fetch descriptions
|
|
19
|
+
console.log(`\n Verifying parent tools...`);
|
|
20
|
+
const parents = [];
|
|
21
|
+
for (const parentName of parentNames) {
|
|
22
|
+
try {
|
|
23
|
+
const res = await fetch(`${API_BASE}/api/tools/${parentName}`);
|
|
24
|
+
if (!res.ok) {
|
|
25
|
+
console.log(` ❌ Tool "${parentName}" not found in registry.`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const tool = await res.json();
|
|
29
|
+
parents.push({ name: tool.name, description: tool.description || 'No description' });
|
|
30
|
+
console.log(` ✓ ${tool.name} — ${(tool.description || '').slice(0, 50)}`);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
console.log(` ❌ Could not verify "${parentName}" — server unreachable.`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Generate scaffold JS
|
|
38
|
+
const stepsCode = parents.map((p, i) => {
|
|
39
|
+
const varName = p.name.replace(/-/g, '_');
|
|
40
|
+
return ` // Step ${i + 1}: ${p.description}
|
|
41
|
+
const ${varName}_result = devtopiaRun('${p.name}', { /* TODO: pass input */ });`;
|
|
42
|
+
}).join('\n\n');
|
|
43
|
+
const jsSource = `/**
|
|
44
|
+
* ${name} - [TODO: describe what this pipeline does]
|
|
45
|
+
* Builds on: ${parentNames.join(', ')} (via devtopia-runtime)
|
|
46
|
+
*
|
|
47
|
+
${parents.map(p => ` * Composes ${p.name}: ${p.description}`).join('\n')}
|
|
48
|
+
*
|
|
49
|
+
* @param {Object} params
|
|
50
|
+
* @returns {Object} Pipeline result
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
const { devtopiaRun } = require('./devtopia-runtime');
|
|
54
|
+
const input = JSON.parse(process.argv[2] || '{}');
|
|
55
|
+
|
|
56
|
+
// TODO: validate required input fields
|
|
57
|
+
// if (!input.someField) {
|
|
58
|
+
// console.log(JSON.stringify({ error: 'Missing required field: someField' }));
|
|
59
|
+
// process.exit(1);
|
|
60
|
+
// }
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
${stepsCode}
|
|
64
|
+
|
|
65
|
+
// TODO: combine results and produce final output
|
|
66
|
+
console.log(JSON.stringify({
|
|
67
|
+
success: true,
|
|
68
|
+
// result: ...,
|
|
69
|
+
steps: ${JSON.stringify(parentNames)},
|
|
70
|
+
}));
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.log(JSON.stringify({ error: error.message }));
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
`;
|
|
76
|
+
const mdSource = `# ${name}
|
|
77
|
+
|
|
78
|
+
[TODO: describe what this pipeline does]
|
|
79
|
+
|
|
80
|
+
## Composes
|
|
81
|
+
|
|
82
|
+
${parents.map(p => `- \`${p.name}\` — ${p.description}`).join('\n')}
|
|
83
|
+
|
|
84
|
+
## Usage
|
|
85
|
+
|
|
86
|
+
\`\`\`bash
|
|
87
|
+
devtopia run ${name} '{"TODO": "add input"}'
|
|
88
|
+
\`\`\`
|
|
89
|
+
|
|
90
|
+
## Input
|
|
91
|
+
|
|
92
|
+
[TODO: document input fields]
|
|
93
|
+
|
|
94
|
+
## Output
|
|
95
|
+
|
|
96
|
+
\`\`\`json
|
|
97
|
+
{
|
|
98
|
+
"success": true,
|
|
99
|
+
"steps": ${JSON.stringify(parentNames)}
|
|
100
|
+
}
|
|
101
|
+
\`\`\`
|
|
102
|
+
`;
|
|
103
|
+
// Write files
|
|
104
|
+
const jsPath = `./${name}.js`;
|
|
105
|
+
const mdPath = `./${name}.md`;
|
|
106
|
+
if (existsSync(jsPath)) {
|
|
107
|
+
console.log(`\n⚠️ ${jsPath} already exists. Not overwriting.\n`);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
writeFileSync(jsPath, jsSource);
|
|
111
|
+
writeFileSync(mdPath, mdSource);
|
|
112
|
+
console.log(`\n✅ Scaffold generated!`);
|
|
113
|
+
console.log(`\n Files created:`);
|
|
114
|
+
console.log(` ${jsPath} — Tool source (edit the TODOs)`);
|
|
115
|
+
console.log(` ${mdPath} — README (edit the TODOs)`);
|
|
116
|
+
console.log(`\n Next steps:`);
|
|
117
|
+
console.log(` 1. Edit ${jsPath} — fill in the TODOs with your logic`);
|
|
118
|
+
console.log(` 2. Test: devtopia run ${name} '{"test": "input"}'`);
|
|
119
|
+
console.log(` 3. Submit: devtopia submit ${name} ./${name}.js --builds-on ${parentNames.join(',')}\n`);
|
|
120
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function showDocs(docName?: string): void;
|