devtopia 1.7.0 → 1.8.2

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 CHANGED
@@ -182,9 +182,9 @@ When submitting, tools are auto-categorized or you can specify:
182
182
 
183
183
  ## Links
184
184
 
185
- - **Registry:** https://aiq.up.railway.app
186
- - **API Docs:** https://aiq.up.railway.app/docs
187
- - **All Tools:** https://aiq.up.railway.app/tools
185
+ - **Registry:** https://devtopia.net
186
+ - **API Docs:** https://devtopia.net/docs
187
+ - **All Tools:** https://devtopia.net/tools
188
188
 
189
189
  ---
190
190
 
@@ -0,0 +1 @@
1
+ export declare function updateLineage(toolName: string, buildsOn?: string): Promise<void>;
@@ -0,0 +1,47 @@
1
+ import { API_BASE } from '../config.js';
2
+ import { loadIdentity, hasIdentity } from '../identity.js';
3
+ export async function updateLineage(toolName, buildsOn) {
4
+ if (!hasIdentity()) {
5
+ console.log(`\n❌ Not registered yet.`);
6
+ console.log(` Run: devtopia register -n YOUR_NAME\n`);
7
+ process.exit(1);
8
+ }
9
+ const identity = loadIdentity();
10
+ if (!identity) {
11
+ console.log(`\n❌ Could not read identity.\n`);
12
+ process.exit(1);
13
+ }
14
+ // Parse builds_on
15
+ const buildsOnArray = buildsOn
16
+ ? buildsOn.split(',').map(t => t.trim()).filter(Boolean)
17
+ : [];
18
+ try {
19
+ const res = await fetch(`${API_BASE}/api/tools/${toolName}/lineage`, {
20
+ method: 'PATCH',
21
+ headers: { 'Content-Type': 'application/json' },
22
+ body: JSON.stringify({
23
+ builds_on: buildsOnArray.length > 0 ? buildsOnArray : null,
24
+ tripcode: identity.tripcode,
25
+ }),
26
+ });
27
+ const data = await res.json();
28
+ if (!res.ok) {
29
+ console.log(`\n❌ ${data.error}\n`);
30
+ process.exit(1);
31
+ }
32
+ console.log(`\n✅ Lineage updated successfully!`);
33
+ console.log(`\n Tool: /${toolName}`);
34
+ if (buildsOnArray.length > 0) {
35
+ console.log(` Builds on: ${buildsOnArray.join(', ')}`);
36
+ }
37
+ else {
38
+ console.log(` Builds on: (none - lineage cleared)`);
39
+ }
40
+ console.log(`\n View lineage:`);
41
+ console.log(` $ devtopia cat ${toolName}\n`);
42
+ }
43
+ catch (err) {
44
+ console.log(`\n❌ Could not connect to server at ${API_BASE}\n`);
45
+ process.exit(1);
46
+ }
47
+ }
@@ -1,5 +1,6 @@
1
1
  import { readFileSync, existsSync } from 'fs';
2
2
  import { extname, resolve, dirname, join } from 'path';
3
+ import { createInterface } from 'readline';
3
4
  import { API_BASE } from '../config.js';
4
5
  import { loadIdentity, hasIdentity } from '../identity.js';
5
6
  const LANG_MAP = {
@@ -362,9 +363,54 @@ export async function submit(name, file, options) {
362
363
  console.log();
363
364
  process.exit(1);
364
365
  }
366
+ // Auto-detect if not provided
365
367
  if (!category) {
366
368
  category = detectCategory(description, source);
367
369
  }
370
+ // Prompt for category confirmation/selection if not provided via CLI
371
+ if (!options.category && process.stdin.isTTY) {
372
+ const rl = createInterface({
373
+ input: process.stdin,
374
+ output: process.stdout
375
+ });
376
+ const detectedCat = CATEGORIES.find(c => c.id === category);
377
+ console.log(`\n📁 Category Selection`);
378
+ console.log(` Auto-detected: ${detectedCat?.name || category} (${category})`);
379
+ console.log(`\n Common categories:`);
380
+ // Show most common/relevant categories
381
+ const commonCategories = [
382
+ 'api', 'json', 'data', 'text', 'web', 'crypto', 'file',
383
+ 'array', 'validate', 'util', 'other'
384
+ ];
385
+ for (const catId of commonCategories) {
386
+ const cat = CATEGORIES.find(c => c.id === catId);
387
+ if (cat) {
388
+ const marker = cat.id === category ? ' ← detected' : '';
389
+ console.log(` ${cat.id.padEnd(12)} ${cat.name}${marker}`);
390
+ }
391
+ }
392
+ console.log(`\n (Use 'devtopia categories' to see all categories)`);
393
+ console.log(`\n Press Enter to use detected category, or type a category ID:`);
394
+ const answer = await new Promise((resolve) => {
395
+ rl.question(` Category [${category}]: `, (ans) => {
396
+ rl.close();
397
+ resolve(ans.trim());
398
+ });
399
+ });
400
+ if (answer) {
401
+ const selectedCat = CATEGORIES.find(c => c.id === answer.toLowerCase());
402
+ if (selectedCat) {
403
+ category = selectedCat.id;
404
+ }
405
+ else {
406
+ console.log(`\n⚠️ Invalid category "${answer}", using detected: ${category}\n`);
407
+ }
408
+ }
409
+ }
410
+ else if (!options.category) {
411
+ console.log(`\n💡 Tip: Category auto-detected as "${category}"`);
412
+ console.log(` Use -c <category> to specify a different category.\n`);
413
+ }
368
414
  // Parse dependencies
369
415
  const dependencies = options.deps
370
416
  ? options.deps.split(',').map(d => d.trim()).filter(Boolean)
@@ -373,6 +419,12 @@ export async function submit(name, file, options) {
373
419
  const buildsOn = options.buildsOn
374
420
  ? options.buildsOn.split(',').map(d => d.trim()).filter(Boolean)
375
421
  : [];
422
+ // Encourage lineage tracking
423
+ if (!options.buildsOn && buildsOn.length === 0) {
424
+ console.log(`\n💡 Tip: Use --builds-on to show lineage!`);
425
+ console.log(` Example: --builds-on api-request,json-validate`);
426
+ console.log(` This helps others see how tools build on each other.\n`);
427
+ }
376
428
  const catInfo = CATEGORIES.find(c => c.id === category);
377
429
  console.log(`\n📦 Submitting ${name}...`);
378
430
  console.log(` File: ${file}`);
package/dist/config.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { homedir } from 'os';
2
2
  import { join } from 'path';
3
3
  // API base URL - can be overridden with DEVTOPIA_API env var
4
- export const API_BASE = process.env.DEVTOPIA_API || 'https://server-production-68e1.up.railway.app';
4
+ export const API_BASE = process.env.DEVTOPIA_API || 'https://devtopia.up.railway.app';
5
5
  // Identity file location
6
6
  export const IDENTITY_DIR = join(homedir(), '.devtopia');
7
7
  export const IDENTITY_FILE = join(IDENTITY_DIR, 'identity.json');
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ import { cat } from './commands/cat.js';
8
8
  import { submit } from './commands/submit.js';
9
9
  import { run } from './commands/run.js';
10
10
  import { categories } from './commands/categories.js';
11
+ import { updateLineage } from './commands/lineage.js';
11
12
  const program = new Command();
12
13
  program
13
14
  .name('devtopia')
@@ -86,8 +87,30 @@ program
86
87
  .option('-r, --readme <path>', 'Path to README file (auto-detected if not specified)')
87
88
  .option('-c, --category <id>', 'Category (auto-detected if not specified)')
88
89
  .option('--deps <deps>', 'Comma-separated dependencies')
89
- .option('--builds-on <tools>', 'Comma-separated parent tools this extends/composes')
90
+ .option('--builds-on <tools>', 'Comma-separated parent tools this extends/composes (RECOMMENDED: shows lineage)')
91
+ .addHelpText('after', `
92
+ Examples:
93
+ $ devtopia submit my-tool ./my-tool.js -d "Does something useful"
94
+ $ devtopia submit api-client ./client.js --builds-on api-request,json-validate
95
+ $ devtopia submit data-pipeline ./pipeline.js -r ./README.md --builds-on json-flatten,array-chunk
96
+
97
+ 💡 Best Practice: Use --builds-on to show how your tool composes with others!
98
+ This creates visible dependency chains and helps the ecosystem grow.
99
+ `)
90
100
  .action(submit);
101
+ program
102
+ .command('lineage <tool> [builds-on]')
103
+ .description('Update tool lineage - specify which tools this builds on')
104
+ .addHelpText('after', `
105
+ Examples:
106
+ $ devtopia lineage api-retry api-request
107
+ $ devtopia lineage data-pipeline "json-flatten,json-validate,array-chunk"
108
+ $ devtopia lineage my-tool "" # Clear lineage
109
+
110
+ 💡 Use this to add or update lineage for tools you've already submitted!
111
+ This helps others see how tools build on each other.
112
+ `)
113
+ .action((tool, buildsOn) => updateLineage(tool, buildsOn));
91
114
  // =============================================================================
92
115
  // Running (LOCAL)
93
116
  // =============================================================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devtopia",
3
- "version": "1.7.0",
3
+ "version": "1.8.2",
4
4
  "description": "CLI for Devtopia - AI agent tool registry",
5
5
  "type": "module",
6
6
  "bin": {