@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.
- package/README.md +102 -206
- package/dist/cli.js +7 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/info.d.ts.map +1 -1
- package/dist/commands/info.js +35 -0
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +104 -27
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install.d.ts +6 -5
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +139 -74
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/lint.d.ts.map +1 -1
- package/dist/commands/lint.js +20 -1
- package/dist/commands/lint.js.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +34 -2
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/mcp.d.ts +11 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +90 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +38 -32
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +18 -19
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +122 -5
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/lib/registry.d.ts +1 -0
- package/dist/lib/registry.d.ts.map +1 -1
- package/dist/lib/registry.js +9 -14
- package/dist/lib/registry.js.map +1 -1
- package/dist/templates/python.d.ts +1 -24
- package/dist/templates/python.d.ts.map +1 -1
- package/dist/templates/python.js +2 -262
- package/dist/templates/python.js.map +1 -1
- package/dist/templates/typescript.d.ts +13 -11
- package/dist/templates/typescript.d.ts.map +1 -1
- package/dist/templates/typescript.js +219 -173
- package/dist/templates/typescript.js.map +1 -1
- package/package.json +5 -8
- package/dist/lib/validator.d.ts +0 -33
- package/dist/lib/validator.d.ts.map +0 -1
- package/dist/lib/validator.js +0 -133
- package/dist/lib/validator.js.map +0 -1
package/dist/commands/init.js
CHANGED
|
@@ -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
|
-
//
|
|
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
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
//
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
167
|
-
|
|
239
|
+
// Save author defaults for reuse
|
|
240
|
+
saveDefaults({ authorName, authorGithub });
|
|
241
|
+
// Show success message
|
|
168
242
|
console.log();
|
|
169
|
-
console.log(chalk.bold('
|
|
243
|
+
console.log(chalk.green.bold(' Your trik is ready!'));
|
|
170
244
|
console.log();
|
|
171
|
-
console.log(chalk.dim(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
console.log(
|
|
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(
|
|
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(
|
|
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":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;
|
|
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.
|
|
8
|
-
* 2.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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
|
|
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"}
|
package/dist/commands/install.js
CHANGED
|
@@ -4,13 +4,14 @@
|
|
|
4
4
|
* Installs a trik and registers it in .trikhub/config.json.
|
|
5
5
|
*
|
|
6
6
|
* Workflow:
|
|
7
|
-
* 1.
|
|
8
|
-
* 2.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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
|
|
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
|
-
//
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
//
|
|
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
|
-
|
|
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/
|
|
382
|
+
* Downloads to .trikhub/triks/ directory for non-JS triks in JS projects.
|
|
321
383
|
*/
|
|
322
|
-
async function
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
445
|
-
|
|
446
|
-
|
|
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
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
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
|
-
|
|
470
|
-
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
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.
|
|
505
|
-
|
|
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
|
-
|
|
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
|