create-openthrottle 1.1.0 → 1.2.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/index.mjs +33 -77
- package/package.json +1 -2
package/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// Usage: npx create-openthrottle
|
|
6
6
|
//
|
|
7
7
|
// Detects the project, prompts for config, generates .openthrottle.yml +
|
|
8
|
-
// wake-sandbox.yml,
|
|
8
|
+
// wake-sandbox.yml, copies Daytona runtime files, and prints next steps.
|
|
9
9
|
// =============================================================================
|
|
10
10
|
|
|
11
11
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, copyFileSync, readdirSync, statSync } from 'node:fs';
|
|
@@ -14,7 +14,6 @@ import { execFileSync } from 'node:child_process';
|
|
|
14
14
|
import { fileURLToPath } from 'node:url';
|
|
15
15
|
import prompts from 'prompts';
|
|
16
16
|
import { stringify } from 'yaml';
|
|
17
|
-
import { Daytona } from '@daytonaio/sdk';
|
|
18
17
|
|
|
19
18
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
19
|
const cwd = process.cwd();
|
|
@@ -109,14 +108,6 @@ async function promptConfig(detected) {
|
|
|
109
108
|
name: 'maxRounds', message: 'Max review rounds', initial: 3, min: 1, max: 10,
|
|
110
109
|
},
|
|
111
110
|
{ type: 'text', name: 'snapshotName', message: 'Daytona snapshot name', initial: 'openthrottle' },
|
|
112
|
-
{
|
|
113
|
-
type: 'select', name: 'snapshotMode', message: 'Snapshot source',
|
|
114
|
-
choices: [
|
|
115
|
-
{ title: 'Pre-built image (faster, recommended)', value: 'image' },
|
|
116
|
-
{ title: 'Build from Dockerfile (customizable)', value: 'dockerfile' },
|
|
117
|
-
],
|
|
118
|
-
initial: 0,
|
|
119
|
-
},
|
|
120
111
|
], { onCancel: () => { console.log('\nCancelled.'); process.exit(0); } });
|
|
121
112
|
|
|
122
113
|
return { ...detected, ...response };
|
|
@@ -174,76 +165,33 @@ function copyWorkflow() {
|
|
|
174
165
|
}
|
|
175
166
|
|
|
176
167
|
// ---------------------------------------------------------------------------
|
|
177
|
-
// 5
|
|
168
|
+
// 5. Copy Daytona runtime files
|
|
178
169
|
// ---------------------------------------------------------------------------
|
|
179
170
|
|
|
180
|
-
|
|
181
|
-
const apiKey = process.env.DAYTONA_API_KEY;
|
|
182
|
-
if (!apiKey) {
|
|
183
|
-
console.error('\n Missing DAYTONA_API_KEY env var. Get one at https://daytona.io/dashboard\n');
|
|
184
|
-
process.exit(1);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const daytona = new Daytona();
|
|
171
|
+
function setupDaytona(config) {
|
|
188
172
|
const snapshotName = config.snapshotName || 'openthrottle';
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const stat = statSync(src);
|
|
203
|
-
if (stat.isDirectory()) {
|
|
204
|
-
mkdirSync(dest, { recursive: true });
|
|
205
|
-
} else {
|
|
206
|
-
mkdirSync(dirname(dest), { recursive: true });
|
|
207
|
-
copyFileSync(src, dest);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
console.log(' ✓ Copied Dockerfile + runtime to .openthrottle/docker/');
|
|
212
|
-
console.log(' Customize the Dockerfile, then create snapshot:');
|
|
213
|
-
console.log(` daytona snapshot create ${snapshotName} --dockerfile .openthrottle/docker/Dockerfile --build-arg AGENT=${config.agent}`);
|
|
214
|
-
} else {
|
|
215
|
-
const image = `ghcr.io/openthrottle/doer-${config.agent}:node-1.0.0`;
|
|
216
|
-
try {
|
|
217
|
-
await daytona.snapshot.create({
|
|
218
|
-
name: snapshotName,
|
|
219
|
-
image,
|
|
220
|
-
resources: { cpu: 2, memory: 4, disk: 10 },
|
|
221
|
-
});
|
|
222
|
-
console.log(` ✓ Created Daytona snapshot: ${snapshotName}`);
|
|
223
|
-
} catch (err) {
|
|
224
|
-
if (err.status === 409 || err.message?.includes('already exists')) {
|
|
225
|
-
console.log(` ✓ Snapshot already exists: ${snapshotName}`);
|
|
173
|
+
|
|
174
|
+
// Copy Dockerfile + runtime scripts into user's project
|
|
175
|
+
const dockerDir = join(cwd, '.openthrottle', 'docker');
|
|
176
|
+
mkdirSync(dockerDir, { recursive: true });
|
|
177
|
+
|
|
178
|
+
const templateDir = join(__dirname, 'templates', 'docker');
|
|
179
|
+
if (existsSync(templateDir)) {
|
|
180
|
+
for (const file of readdirSync(templateDir, { recursive: true })) {
|
|
181
|
+
const src = join(templateDir, file);
|
|
182
|
+
const dest = join(dockerDir, file);
|
|
183
|
+
const stat = statSync(src);
|
|
184
|
+
if (stat.isDirectory()) {
|
|
185
|
+
mkdirSync(dest, { recursive: true });
|
|
226
186
|
} else {
|
|
227
|
-
|
|
228
|
-
|
|
187
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
188
|
+
copyFileSync(src, dest);
|
|
229
189
|
}
|
|
230
190
|
}
|
|
231
191
|
}
|
|
192
|
+
console.log(' ✓ Copied Dockerfile + runtime to .openthrottle/docker/');
|
|
232
193
|
|
|
233
|
-
|
|
234
|
-
try {
|
|
235
|
-
await daytona.volume.create({ name: volumeName });
|
|
236
|
-
console.log(` ✓ Created Daytona volume: ${volumeName}`);
|
|
237
|
-
} catch (err) {
|
|
238
|
-
if (err.status === 409 || err.message?.includes('already exists')) {
|
|
239
|
-
console.log(` ✓ Volume already exists: ${volumeName}`);
|
|
240
|
-
} else {
|
|
241
|
-
console.error(` ✗ Failed to create volume: ${err.message}`);
|
|
242
|
-
process.exit(1);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
return { snapshotName, volumeName };
|
|
194
|
+
return { snapshotName };
|
|
247
195
|
}
|
|
248
196
|
|
|
249
197
|
// ---------------------------------------------------------------------------
|
|
@@ -262,20 +210,28 @@ function printNextSteps(config) {
|
|
|
262
210
|
agentSecret,
|
|
263
211
|
];
|
|
264
212
|
|
|
213
|
+
const snapshotName = config.snapshotName || 'openthrottle';
|
|
214
|
+
|
|
265
215
|
console.log(`
|
|
266
216
|
Next steps:
|
|
267
217
|
|
|
268
|
-
1.
|
|
218
|
+
1. Create your Daytona snapshot:
|
|
219
|
+
cd .openthrottle/docker
|
|
220
|
+
daytona snapshot create ${snapshotName} \\
|
|
221
|
+
--dockerfile ./Dockerfile --context . \\
|
|
222
|
+
--cpu 2 --memory 4 --disk 10
|
|
223
|
+
|
|
224
|
+
2. Set GitHub repo secrets:
|
|
269
225
|
${secrets.join('\n')}
|
|
270
226
|
TELEGRAM_BOT_TOKEN ← optional (notifications)
|
|
271
227
|
TELEGRAM_CHAT_ID ← optional (notifications)
|
|
272
228
|
|
|
273
|
-
|
|
229
|
+
3. Commit and push:
|
|
274
230
|
git add .openthrottle.yml .github/workflows/wake-sandbox.yml
|
|
275
231
|
git commit -m "feat: add openthrottle config"
|
|
276
232
|
git push
|
|
277
233
|
|
|
278
|
-
|
|
234
|
+
4. Ship your first prompt:
|
|
279
235
|
gh issue create --title "My first feature" \\
|
|
280
236
|
--body-file docs/prds/my-feature.md \\
|
|
281
237
|
--label prd-queued
|
|
@@ -323,8 +279,8 @@ async function main() {
|
|
|
323
279
|
console.log(' ✓ Copied .github/workflows/wake-sandbox.yml');
|
|
324
280
|
}
|
|
325
281
|
|
|
326
|
-
//
|
|
327
|
-
|
|
282
|
+
// Step 5: Copy Daytona runtime files
|
|
283
|
+
setupDaytona(config);
|
|
328
284
|
|
|
329
285
|
// Step 7: Next steps
|
|
330
286
|
printNextSteps(config);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-openthrottle",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Set up openthrottle in any Node.js project — agent-agnostic, config-driven.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
"templates/"
|
|
12
12
|
],
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@daytonaio/sdk": "^0.153.0",
|
|
15
14
|
"prompts": "^2.4.2",
|
|
16
15
|
"yaml": "^2.4.0"
|
|
17
16
|
},
|