@trikhub/cli 0.5.0 → 0.7.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.
Files changed (49) hide show
  1. package/README.md +102 -206
  2. package/dist/cli.js +7 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/info.d.ts.map +1 -1
  5. package/dist/commands/info.js +35 -0
  6. package/dist/commands/info.js.map +1 -1
  7. package/dist/commands/init.d.ts.map +1 -1
  8. package/dist/commands/init.js +104 -27
  9. package/dist/commands/init.js.map +1 -1
  10. package/dist/commands/install.d.ts +6 -5
  11. package/dist/commands/install.d.ts.map +1 -1
  12. package/dist/commands/install.js +139 -74
  13. package/dist/commands/install.js.map +1 -1
  14. package/dist/commands/lint.d.ts.map +1 -1
  15. package/dist/commands/lint.js +20 -1
  16. package/dist/commands/lint.js.map +1 -1
  17. package/dist/commands/list.d.ts.map +1 -1
  18. package/dist/commands/list.js +34 -2
  19. package/dist/commands/list.js.map +1 -1
  20. package/dist/commands/mcp.d.ts +11 -0
  21. package/dist/commands/mcp.d.ts.map +1 -0
  22. package/dist/commands/mcp.js +90 -0
  23. package/dist/commands/mcp.js.map +1 -0
  24. package/dist/commands/publish.d.ts.map +1 -1
  25. package/dist/commands/publish.js +38 -32
  26. package/dist/commands/publish.js.map +1 -1
  27. package/dist/commands/uninstall.d.ts.map +1 -1
  28. package/dist/commands/uninstall.js +18 -19
  29. package/dist/commands/uninstall.js.map +1 -1
  30. package/dist/commands/upgrade.d.ts.map +1 -1
  31. package/dist/commands/upgrade.js +122 -5
  32. package/dist/commands/upgrade.js.map +1 -1
  33. package/dist/lib/registry.d.ts +1 -0
  34. package/dist/lib/registry.d.ts.map +1 -1
  35. package/dist/lib/registry.js +9 -14
  36. package/dist/lib/registry.js.map +1 -1
  37. package/dist/templates/python.d.ts +1 -24
  38. package/dist/templates/python.d.ts.map +1 -1
  39. package/dist/templates/python.js +2 -262
  40. package/dist/templates/python.js.map +1 -1
  41. package/dist/templates/typescript.d.ts +13 -11
  42. package/dist/templates/typescript.d.ts.map +1 -1
  43. package/dist/templates/typescript.js +219 -173
  44. package/dist/templates/typescript.js.map +1 -1
  45. package/package.json +5 -8
  46. package/dist/lib/validator.d.ts +0 -33
  47. package/dist/lib/validator.d.ts.map +0 -1
  48. package/dist/lib/validator.js +0 -133
  49. package/dist/lib/validator.js.map +0 -1
@@ -11,7 +11,6 @@ import ora from 'ora';
11
11
  import { input, select, confirm } from '@inquirer/prompts';
12
12
  import { loadDefaults, saveDefaults } from '../lib/storage.js';
13
13
  import { generateTypescriptProject } from '../templates/typescript.js';
14
- import { generatePythonProject } from '../templates/python.js';
15
14
  const CATEGORIES = [
16
15
  { value: 'utilities', label: 'Utilities' },
17
16
  { value: 'productivity', label: 'Productivity' },
@@ -108,6 +107,58 @@ export async function initCommand(languageArg) {
108
107
  message: 'Enable configuration (env vars)?',
109
108
  default: false,
110
109
  });
110
+ // v2 agent prompts
111
+ const agentMode = await select({
112
+ message: 'Agent mode:',
113
+ choices: [
114
+ { value: 'conversational', name: 'Conversational (multi-turn ReAct agent)' },
115
+ { value: 'tool', name: 'Tool (export native tools to main agent)' },
116
+ ],
117
+ default: 'conversational',
118
+ });
119
+ // Handoff description only for conversational mode
120
+ let handoffDescription = '';
121
+ if (agentMode === 'conversational') {
122
+ handoffDescription = await input({
123
+ message: 'Handoff description (how should the main agent describe this trik?):',
124
+ validate: (value) => {
125
+ if (value.length < 10)
126
+ return 'Description must be at least 10 characters';
127
+ if (value.length > 500)
128
+ return 'Description must be at most 500 characters';
129
+ return true;
130
+ },
131
+ });
132
+ }
133
+ // Tool names for tool mode
134
+ let toolNames = [];
135
+ if (agentMode === 'tool') {
136
+ const toolNamesRaw = await input({
137
+ message: 'Tool names (comma-separated, camelCase, e.g. "getWeather, getForecast"):',
138
+ validate: (value) => {
139
+ const names = value.split(',').map((t) => t.trim()).filter(Boolean);
140
+ if (names.length === 0)
141
+ return 'At least one tool name is required';
142
+ for (const n of names) {
143
+ if (!/^[a-z][a-zA-Z0-9]*$/.test(n)) {
144
+ return `Invalid tool name "${n}": must be camelCase starting with a lowercase letter`;
145
+ }
146
+ }
147
+ return true;
148
+ },
149
+ });
150
+ toolNames = toolNamesRaw.split(',').map((t) => t.trim()).filter(Boolean);
151
+ }
152
+ const domainTagsRaw = await input({
153
+ message: 'Domain tags (comma-separated, e.g. "content curation, article writing"):',
154
+ validate: (value) => {
155
+ const tags = value.split(',').map((t) => t.trim()).filter(Boolean);
156
+ if (tags.length === 0)
157
+ return 'At least one domain tag is required';
158
+ return true;
159
+ },
160
+ });
161
+ const domainTags = domainTagsRaw.split(',').map((t) => t.trim()).filter(Boolean);
111
162
  // Path selection
112
163
  const pathChoice = await select({
113
164
  message: 'Where to create the trik?',
@@ -135,7 +186,7 @@ export async function initCommand(languageArg) {
135
186
  }
136
187
  console.log();
137
188
  spinner.start('Creating trik...');
138
- // Generate files
189
+ // Build full config
139
190
  const config = {
140
191
  name,
141
192
  displayName,
@@ -145,39 +196,65 @@ export async function initCommand(languageArg) {
145
196
  category,
146
197
  enableStorage,
147
198
  enableConfig,
199
+ agentMode,
200
+ handoffDescription,
201
+ domainTags,
202
+ toolNames,
148
203
  };
149
- const files = language === 'ts'
150
- ? generateTypescriptProject(config)
151
- : generatePythonProject(config);
152
- // Write files
153
- for (const file of files) {
154
- const filePath = join(targetDir, file.path);
155
- const dir = join(filePath, '..');
156
- await mkdir(dir, { recursive: true });
157
- await writeFile(filePath, file.content, 'utf-8');
204
+ // Only TypeScript is supported for now
205
+ if (language === 'py') {
206
+ spinner.stop();
207
+ console.log(chalk.yellow('\n Python trik init is not yet supported. Use TypeScript for now.\n'));
208
+ return;
158
209
  }
159
- // Save author defaults for next time
160
- if (authorName || authorGithub) {
161
- saveDefaults({
162
- authorName: authorName || defaults.authorName,
163
- authorGithub: authorGithub || defaults.authorGithub,
164
- });
210
+ // Generate project files
211
+ const files = generateTypescriptProject(config);
212
+ // Create target directory and write all files
213
+ await mkdir(targetDir, { recursive: true });
214
+ for (const [relativePath, content] of Object.entries(files)) {
215
+ const filePath = join(targetDir, relativePath);
216
+ const fileDir = join(filePath, '..');
217
+ await mkdir(fileDir, { recursive: true });
218
+ await writeFile(filePath, content, 'utf-8');
219
+ }
220
+ spinner.succeed('Trik created');
221
+ // Install dependencies
222
+ const { execSync } = await import('node:child_process');
223
+ let packageManager = 'npm';
224
+ try {
225
+ execSync('pnpm --version', { stdio: 'ignore' });
226
+ packageManager = 'pnpm';
227
+ }
228
+ catch {
229
+ // pnpm not available, use npm
230
+ }
231
+ spinner.start(`Installing dependencies with ${packageManager}...`);
232
+ try {
233
+ execSync(`${packageManager} install`, { cwd: targetDir, stdio: 'ignore' });
234
+ spinner.succeed('Dependencies installed');
235
+ }
236
+ catch {
237
+ spinner.warn(`Failed to install dependencies. Run \`${packageManager} install\` manually.`);
165
238
  }
166
- spinner.succeed(`Created trik: ${chalk.green(name)}`);
167
- // Print next steps
239
+ // Save author defaults for reuse
240
+ saveDefaults({ authorName, authorGithub });
241
+ // Show success message
168
242
  console.log();
169
- console.log(chalk.bold(' Next steps:'));
243
+ console.log(chalk.green.bold(' Your trik is ready!'));
170
244
  console.log();
171
- console.log(chalk.dim(` cd ${name}`));
172
- if (language === 'ts') {
173
- console.log(chalk.dim(' npm install'));
174
- console.log(chalk.dim(' npm run build'));
175
- console.log(chalk.dim(' npm test # Test your trik locally'));
245
+ console.log(chalk.dim(' Next steps:'));
246
+ console.log(` cd ${name}`);
247
+ if (agentMode === 'tool') {
248
+ console.log(' Edit src/agent.ts to implement your tool handlers');
176
249
  }
177
250
  else {
178
- console.log(chalk.dim(' python test.py # Test your trik locally'));
251
+ console.log(' Edit src/agent.ts to implement your agent logic');
252
+ console.log(' Add tools in src/tools/');
253
+ console.log(' Customize src/prompts/system.md');
179
254
  }
180
- console.log(chalk.dim(' trik publish # When ready to publish'));
255
+ console.log(` ${packageManager === 'pnpm' ? 'pnpm' : 'npm run'} build`);
256
+ console.log(' trik lint .');
257
+ console.log(' trik publish');
181
258
  console.log();
182
259
  }
183
260
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -4,11 +4,12 @@
4
4
  * Installs a trik and registers it in .trikhub/config.json.
5
5
  *
6
6
  * Workflow:
7
- * 1. Detect project type (node or python)
8
- * 2. Fetch trik info from TrikHub registry to get runtime
9
- * 3. If same runtime: use native package manager (npm/pip)
10
- * 4. If cross-language: download to .trikhub/triks/ directory
11
- * 5. Update .trikhub/config.json with the trik
7
+ * 1. Check TrikHub registry first (primary source)
8
+ * 2. If found on TrikHub:
9
+ * - Same runtime: add git URL to package.json + npm install (stays in node_modules)
10
+ * - Cross-language: download to .trikhub/triks/
11
+ * 3. If not on TrikHub: try npm as fallback for third-party packages
12
+ * 4. Update .trikhub/config.json with the trik
12
13
  */
13
14
  interface InstallOptions {
14
15
  version?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAiCH,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA2gBD,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,IAAI,CAAC,CA6If"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA4DH,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA0iBD,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,IAAI,CAAC,CAiJf"}
@@ -4,13 +4,14 @@
4
4
  * Installs a trik and registers it in .trikhub/config.json.
5
5
  *
6
6
  * Workflow:
7
- * 1. Detect project type (node or python)
8
- * 2. Fetch trik info from TrikHub registry to get runtime
9
- * 3. If same runtime: use native package manager (npm/pip)
10
- * 4. If cross-language: download to .trikhub/triks/ directory
11
- * 5. Update .trikhub/config.json with the trik
7
+ * 1. Check TrikHub registry first (primary source)
8
+ * 2. If found on TrikHub:
9
+ * - Same runtime: add git URL to package.json + npm install (stays in node_modules)
10
+ * - Cross-language: download to .trikhub/triks/
11
+ * 3. If not on TrikHub: try npm as fallback for third-party packages
12
+ * 4. Update .trikhub/config.json with the trik
12
13
  */
13
- import { existsSync, mkdirSync } from 'node:fs';
14
+ import { existsSync, mkdirSync, readFileSync } from 'node:fs';
14
15
  import { readFile, writeFile, mkdir } from 'node:fs/promises';
15
16
  import { join, dirname } from 'node:path';
16
17
  import { spawn } from 'node:child_process';
@@ -19,6 +20,32 @@ import ora from 'ora';
19
20
  import * as semver from 'semver';
20
21
  import { validateManifest } from '@trikhub/manifest';
21
22
  import { registry } from '../lib/registry.js';
23
+ /**
24
+ * Get mock repo path for E2E testing.
25
+ * When TRIKHUB_MOCK_REPOS_FILE is set, looks up the local bare repo path.
26
+ */
27
+ function getMockRepoPath(githubRepo) {
28
+ const mockReposFile = process.env.TRIKHUB_MOCK_REPOS_FILE;
29
+ if (!mockReposFile)
30
+ return null;
31
+ try {
32
+ const mapping = JSON.parse(readFileSync(mockReposFile, 'utf-8'));
33
+ return mapping[githubRepo] ?? null;
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ /**
40
+ * Get the clone URL for a repo - uses mock path in E2E tests
41
+ */
42
+ function getCloneUrl(githubRepo) {
43
+ const mockPath = getMockRepoPath(githubRepo);
44
+ if (mockPath) {
45
+ return mockPath;
46
+ }
47
+ return `https://github.com/${githubRepo}.git`;
48
+ }
22
49
  /**
23
50
  * Detect whether this is a Node.js or Python project
24
51
  */
@@ -158,8 +185,13 @@ async function addTrikToConfig(packageName, baseDir, trikhubVersion, runtime) {
158
185
  }
159
186
  /**
160
187
  * Verify that a GitHub tag points to the expected commit SHA
188
+ * Can be skipped with TRIKHUB_SKIP_TAG_CHECK=true (for E2E testing with mock repos)
161
189
  */
162
190
  async function verifyGitHubTagSha(githubRepo, gitTag, expectedSha) {
191
+ // Skip verification in test mode
192
+ if (process.env.TRIKHUB_SKIP_TAG_CHECK === 'true') {
193
+ return { valid: true };
194
+ }
163
195
  try {
164
196
  // Use GitHub API to get the tag reference
165
197
  const response = await fetch(`https://api.github.com/repos/${githubRepo}/git/refs/tags/${gitTag}`);
@@ -203,6 +235,16 @@ async function addToPackageJson(packageName, githubRepo, gitTag, baseDir) {
203
235
  pkg.dependencies[packageName] = `github:${githubRepo}#${gitTag}`;
204
236
  await writeFile(packageJsonPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
205
237
  }
238
+ /**
239
+ * Remove a package from node_modules to force fresh install
240
+ */
241
+ async function removeFromNodeModules(packageName, baseDir) {
242
+ const packagePath = join(baseDir, 'node_modules', ...packageName.split('/'));
243
+ if (existsSync(packagePath)) {
244
+ const { rm } = await import('node:fs/promises');
245
+ await rm(packagePath, { recursive: true, force: true });
246
+ }
247
+ }
206
248
  /**
207
249
  * Try to install from npm registry
208
250
  */
@@ -237,7 +279,8 @@ async function downloadToTriksDirectory(packageName, githubRepo, gitTag, baseDir
237
279
  }
238
280
  // Clone the repository at the specific tag
239
281
  spinner.text = `Downloading ${chalk.cyan(packageName)}...`;
240
- const cloneResult = await runCommand('git', ['clone', '--depth', '1', '--branch', gitTag, `https://github.com/${githubRepo}.git`, trikDir], baseDir, { silent: true });
282
+ const cloneUrl = getCloneUrl(githubRepo);
283
+ const cloneResult = await runCommand('git', ['clone', '--depth', '1', '--branch', gitTag, cloneUrl, trikDir], baseDir, { silent: true });
241
284
  if (cloneResult.code !== 0) {
242
285
  return { success: false, trikPath: trikDir };
243
286
  }
@@ -246,7 +289,8 @@ async function downloadToTriksDirectory(packageName, githubRepo, gitTag, baseDir
246
289
  return { success: true, trikPath: trikDir };
247
290
  }
248
291
  /**
249
- * Install from TrikHub registry using git URLs
292
+ * Install a JS trik from TrikHub registry using git URLs in package.json.
293
+ * This keeps JS triks in node_modules where they belong.
250
294
  */
251
295
  async function installFromTrikhub(packageName, requestedVersion, baseDir, pm, spinner) {
252
296
  // Fetch trik info from TrikHub registry
@@ -298,13 +342,31 @@ async function installFromTrikhub(packageName, requestedVersion, baseDir, pm, sp
298
342
  console.log(chalk.red('\nThis could indicate tampering. Aborting installation.'));
299
343
  return { success: false };
300
344
  }
301
- // Add to package.json using git URL format
302
- spinner.text = `Adding ${chalk.cyan(packageName)}@${versionToInstall} to package.json...`;
303
- await addToPackageJson(packageName, trikInfo.githubRepo, versionInfo.gitTag, baseDir);
304
- // Run package manager install
305
- // Use --prefix to explicitly set install directory (npm can ignore cwd in some contexts)
345
+ // IMPORTANT: Remove existing package from node_modules to force fresh install
346
+ // This fixes the issue where npm caches git dependencies
347
+ spinner.text = `Removing existing ${chalk.cyan(packageName)} from node_modules...`;
348
+ await removeFromNodeModules(packageName, baseDir);
349
+ // Install directly using the git URL to bypass npm cache
350
+ // This is more reliable than updating package.json + npm install
351
+ // Check for mock repo path (E2E testing) or use GitHub URL
352
+ const mockPath = getMockRepoPath(trikInfo.githubRepo);
353
+ const gitUrl = mockPath
354
+ ? `git+file://${mockPath}#${versionInfo.gitTag}`
355
+ : `github:${trikInfo.githubRepo}#${versionInfo.gitTag}`;
306
356
  spinner.text = `Installing ${chalk.cyan(packageName)}@${versionToInstall}...`;
307
- const installArgs = pm === 'npm' ? ['install', '--prefix', baseDir] : ['install'];
357
+ let installArgs;
358
+ if (pm === 'npm') {
359
+ // npm install <package-name>@<git-url> --prefix <dir>
360
+ installArgs = ['install', '--prefix', baseDir, `${packageName}@${gitUrl}`];
361
+ }
362
+ else if (pm === 'pnpm') {
363
+ // pnpm add <package-name>@<git-url>
364
+ installArgs = ['add', `${packageName}@${gitUrl}`];
365
+ }
366
+ else {
367
+ // yarn add <package-name>@<git-url>
368
+ installArgs = ['add', `${packageName}@${gitUrl}`];
369
+ }
308
370
  const installResult = await runCommand(pm, installArgs, baseDir, { silent: true });
309
371
  if (installResult.code !== 0) {
310
372
  spinner.fail(`Failed to install ${packageName}`);
@@ -317,9 +379,9 @@ async function installFromTrikhub(packageName, requestedVersion, baseDir, pm, sp
317
379
  }
318
380
  /**
319
381
  * Install a cross-language trik from TrikHub registry.
320
- * Downloads to .trikhub/triks/ instead of using npm.
382
+ * Downloads to .trikhub/triks/ directory for non-JS triks in JS projects.
321
383
  */
322
- async function installCrossLanguageFromTrikhub(packageName, requestedVersion, baseDir, spinner) {
384
+ async function installFromTrikhubRegistry(packageName, requestedVersion, baseDir, spinner) {
323
385
  // Fetch trik info from TrikHub registry
324
386
  spinner.text = `Fetching ${chalk.cyan(packageName)} from TrikHub registry...`;
325
387
  const trikInfo = await registry.getTrik(packageName);
@@ -433,45 +495,66 @@ export async function installCommand(trikInput, options) {
433
495
  let packageName = trikInput;
434
496
  let versionSpec = options.version;
435
497
  // Handle @scope/name@version format
498
+ // For scoped packages (@scope/name@version), the version @ comes after the /
436
499
  const atIndex = trikInput.lastIndexOf('@');
437
- if (atIndex > 0 && !trikInput.startsWith('@', atIndex)) {
500
+ const slashIndex = trikInput.indexOf('/');
501
+ const isVersionSuffix = atIndex > 0 && (!trikInput.startsWith('@') || atIndex > slashIndex);
502
+ if (isVersionSuffix) {
438
503
  packageName = trikInput.substring(0, atIndex);
439
504
  versionSpec = versionSpec ?? trikInput.substring(atIndex + 1);
440
505
  }
441
- // First, check TrikHub registry to get runtime info
506
+ // First, check TrikHub registry - this is the primary source for triks
442
507
  spinner.start(`Checking ${chalk.cyan(packageName)} on TrikHub registry...`);
443
508
  const trikInfo = await registry.getTrik(packageName);
444
- // Get runtime from latest version if available
445
- let trikRuntime = 'node'; // default
446
- if (trikInfo && trikInfo.versions.length > 0) {
509
+ if (trikInfo) {
510
+ // Found on TrikHub registry
511
+ let trikRuntime = 'node';
447
512
  const latestVersion = trikInfo.versions.find(v => v.version === trikInfo.latestVersion);
448
513
  if (latestVersion?.runtime) {
449
514
  trikRuntime = latestVersion.runtime;
450
515
  }
451
- }
452
- const isCrossLanguage = projectType !== trikRuntime;
453
- if (isCrossLanguage && trikInfo) {
454
- // Cross-language installation: download to .trikhub/triks/
455
- spinner.info(`Cross-language trik detected: ${chalk.cyan(trikRuntime)} trik in ${chalk.cyan(projectType)} project`);
456
- spinner.start(`Installing ${chalk.cyan(packageName)} to .trikhub/triks/...`);
457
- const crossResult = await installCrossLanguageFromTrikhub(packageName, versionSpec, baseDir, spinner);
458
- if (crossResult.success) {
459
- // Add to config with runtime for cross-language uninstall
460
- await addTrikToConfig(packageName, baseDir, crossResult.version, trikRuntime);
461
- spinner.succeed(`Installed ${chalk.green(packageName)}@${crossResult.version} (${trikRuntime} runtime)`);
462
- console.log();
463
- console.log(chalk.dim(` Downloaded to: .trikhub/triks/${packageName}`));
464
- console.log(chalk.dim(` Registered in: .trikhub/config.json`));
465
- console.log();
466
- console.log(chalk.dim('The trik will be available via the cross-language worker.'));
516
+ const isCrossLanguage = projectType !== trikRuntime;
517
+ if (isCrossLanguage) {
518
+ // Cross-language: download to .trikhub/triks/
519
+ spinner.info(`Cross-language trik: ${chalk.cyan(trikRuntime)} trik in ${chalk.cyan(projectType)} project`);
520
+ spinner.start(`Installing ${chalk.cyan(packageName)} to .trikhub/triks/...`);
521
+ const trikhubResult = await installFromTrikhubRegistry(packageName, versionSpec, baseDir, spinner);
522
+ if (trikhubResult.success) {
523
+ await addTrikToConfig(packageName, baseDir, trikhubResult.version, trikRuntime);
524
+ spinner.succeed(`Installed ${chalk.green(packageName)}@${trikhubResult.version} from TrikHub`);
525
+ console.log();
526
+ console.log(chalk.dim(` Downloaded to: .trikhub/triks/${packageName}`));
527
+ console.log(chalk.dim(` Registered in: .trikhub/config.json`));
528
+ console.log();
529
+ console.log(chalk.dim('The trik will run via the cross-language worker.'));
530
+ }
531
+ else {
532
+ spinner.fail(`Failed to install ${chalk.red(packageName)}`);
533
+ process.exit(1);
534
+ }
467
535
  }
468
536
  else {
469
- spinner.fail(`Failed to install ${chalk.red(packageName)}`);
470
- process.exit(1);
537
+ // Same language (JS trik in JS project): use git URL in package.json
538
+ spinner.info(`Found ${chalk.cyan(packageName)} on TrikHub registry`);
539
+ const pm = detectPackageManager(baseDir);
540
+ const trikhubResult = await installFromTrikhub(packageName, versionSpec, baseDir, pm, spinner);
541
+ if (trikhubResult.success) {
542
+ await addTrikToConfig(packageName, baseDir, trikhubResult.version);
543
+ spinner.succeed(`Installed ${chalk.green(packageName)}@${trikhubResult.version} from TrikHub`);
544
+ console.log();
545
+ console.log(chalk.dim(` Added to: package.json`));
546
+ console.log(chalk.dim(` Registered in: .trikhub/config.json`));
547
+ console.log();
548
+ console.log(chalk.dim('The trik will be available to your AI agent.'));
549
+ }
550
+ else {
551
+ spinner.fail(`Failed to install ${chalk.red(packageName)}`);
552
+ process.exit(1);
553
+ }
471
554
  }
472
555
  }
473
556
  else {
474
- // Same-language installation: use native package manager
557
+ // Not on TrikHub registry - try npm as fallback for third-party packages
475
558
  if (projectType === 'node') {
476
559
  // Ensure node_modules exists
477
560
  const nodeModulesPath = join(baseDir, 'node_modules');
@@ -480,53 +563,35 @@ export async function installCommand(trikInput, options) {
480
563
  }
481
564
  // Detect package manager
482
565
  const pm = detectPackageManager(baseDir);
566
+ spinner.info(`Not found on TrikHub, trying npm...`);
483
567
  spinner.info(`Using ${chalk.cyan(pm)} as package manager`);
484
568
  const packageSpec = versionSpec ? `${packageName}@${versionSpec}` : packageName;
485
- // First, try npm registry
569
+ // Try npm registry
486
570
  spinner.start(`Looking for ${chalk.cyan(packageSpec)} on npm...`);
487
571
  const npmResult = await tryNpmInstall(pm, packageSpec, baseDir);
488
- let installed = false;
489
- let installedVersion;
490
572
  if (npmResult.success) {
491
573
  spinner.succeed(`Installed ${chalk.green(packageName)} from npm`);
492
- installed = true;
493
- }
494
- else if (npmResult.notFound) {
495
- // Not on npm, try TrikHub registry
496
- spinner.text = `Not found on npm, checking TrikHub registry...`;
497
- const trikhubResult = await installFromTrikhub(packageName, versionSpec, baseDir, pm, spinner);
498
- if (trikhubResult.success) {
499
- spinner.succeed(`Installed ${chalk.green(packageName)}@${trikhubResult.version} from TrikHub`);
500
- installed = true;
501
- installedVersion = trikhubResult.version;
574
+ // Check if the installed package is a trik and register it
575
+ spinner.start('Checking if package is a trik...');
576
+ const packagePath = join(baseDir, 'node_modules', ...packageName.split('/'));
577
+ if (await isTrikPackage(packagePath)) {
578
+ await addTrikToConfig(packageName, baseDir);
579
+ spinner.succeed(`Registered ${chalk.green(packageName)} as a trik`);
580
+ console.log();
581
+ console.log(chalk.dim(` Added to: package.json`));
582
+ console.log(chalk.dim(` Registered in: .trikhub/config.json`));
583
+ console.log();
584
+ console.log(chalk.dim('The trik will be available to your AI agent.'));
502
585
  }
503
586
  else {
504
- spinner.fail(`${chalk.red(packageName)} not found on npm or TrikHub registry`);
505
- process.exit(1);
587
+ spinner.info(`${chalk.yellow(packageName)} installed but is not a trik (no manifest.json)`);
588
+ console.log(chalk.dim('\nThe package was added to your dependencies.'));
506
589
  }
507
590
  }
508
591
  else {
509
- // npm failed for other reasons
510
- spinner.fail(`Failed to install ${chalk.red(packageName)}`);
592
+ spinner.fail(`${chalk.red(packageName)} not found on TrikHub or npm`);
511
593
  process.exit(1);
512
594
  }
513
- // Check if the installed package is a trik and register it
514
- spinner.start('Checking if package is a trik...');
515
- const packagePath = join(baseDir, 'node_modules', ...packageName.split('/'));
516
- if (await isTrikPackage(packagePath)) {
517
- // Pass version for TrikHub packages (for sync/upgrade tracking)
518
- await addTrikToConfig(packageName, baseDir, installedVersion);
519
- spinner.succeed(`Registered ${chalk.green(packageName)} as a trik`);
520
- console.log();
521
- console.log(chalk.dim(` Added to: package.json`));
522
- console.log(chalk.dim(` Registered in: .trikhub/config.json`));
523
- console.log();
524
- console.log(chalk.dim('The trik will be available to your AI agent.'));
525
- }
526
- else {
527
- spinner.info(`${chalk.yellow(packageName)} installed but is not a trik (no manifest.json)`);
528
- console.log(chalk.dim('\nThe package was added to your dependencies.'));
529
- }
530
595
  }
531
596
  else {
532
597
  // Python project - not yet implemented