@trikhub/cli 0.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/LICENSE +21 -0
- package/README.md +389 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +105 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/info.d.ts +11 -0
- package/dist/commands/info.d.ts.map +1 -0
- package/dist/commands/info.js +101 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/install.d.ts +17 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +358 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/list.d.ts +11 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +96 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/login.d.ts +19 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +154 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/publish.d.ts +13 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +285 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/search.d.ts +12 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +60 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/sync.d.ts +19 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +193 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/uninstall.d.ts +11 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +153 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/upgrade.d.ts +15 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +144 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +79 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +202 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/registry.d.ts +90 -0
- package/dist/lib/registry.d.ts.map +1 -0
- package/dist/lib/registry.js +294 -0
- package/dist/lib/registry.js.map +1 -0
- package/dist/lib/storage.d.ts +82 -0
- package/dist/lib/storage.d.ts.map +1 -0
- package/dist/lib/storage.js +177 -0
- package/dist/lib/storage.js.map +1 -0
- package/dist/lib/validator.d.ts +24 -0
- package/dist/lib/validator.d.ts.map +1 -0
- package/dist/lib/validator.js +181 -0
- package/dist/lib/validator.js.map +1 -0
- package/dist/types.d.ts +187 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +36 -0
- package/dist/types.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/lib/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage and configuration management for TrikHub CLI
|
|
3
|
+
*
|
|
4
|
+
* This module handles trik installation paths and lockfile management.
|
|
5
|
+
* All functions now work with ConfigContext for local/global support.
|
|
6
|
+
*/
|
|
7
|
+
import { TrikConfig, TrikLockfile, InstalledTrik } from '../types.js';
|
|
8
|
+
import { ConfigContext } from './config.js';
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated Use ConfigContext instead. This is kept for backwards compatibility.
|
|
11
|
+
*/
|
|
12
|
+
export declare const TRIKHUB_DIR: string;
|
|
13
|
+
/**
|
|
14
|
+
* @deprecated Use ConfigContext.configPath instead.
|
|
15
|
+
*/
|
|
16
|
+
export declare const CONFIG_PATH: string;
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated Use ConfigContext.lockfilePath instead.
|
|
19
|
+
*/
|
|
20
|
+
export declare const LOCKFILE_PATH: string;
|
|
21
|
+
/**
|
|
22
|
+
* @deprecated Use ConfigContext.triksDir instead.
|
|
23
|
+
*/
|
|
24
|
+
export declare const TRIKS_DIR: string;
|
|
25
|
+
/**
|
|
26
|
+
* Ensure the TrikHub directory structure exists for a context
|
|
27
|
+
*/
|
|
28
|
+
export declare function ensureDirectories(ctx?: ConfigContext): void;
|
|
29
|
+
/**
|
|
30
|
+
* Ensure parent directory exists for a path
|
|
31
|
+
*/
|
|
32
|
+
export declare function ensureParentDir(filePath: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* Load the CLI configuration
|
|
35
|
+
* @deprecated Use resolveConfig() from config.ts for full local/global support
|
|
36
|
+
*/
|
|
37
|
+
export declare function loadConfig(): TrikConfig;
|
|
38
|
+
/**
|
|
39
|
+
* Save the CLI configuration
|
|
40
|
+
* @deprecated Use saveConfig() from config.ts with a ConfigContext
|
|
41
|
+
*/
|
|
42
|
+
export declare function saveConfig(config: TrikConfig): void;
|
|
43
|
+
/**
|
|
44
|
+
* Load the lockfile for a context
|
|
45
|
+
*/
|
|
46
|
+
export declare function loadLockfile(ctx?: ConfigContext): TrikLockfile;
|
|
47
|
+
/**
|
|
48
|
+
* Save the lockfile for a context
|
|
49
|
+
*/
|
|
50
|
+
export declare function saveLockfile(lockfile: TrikLockfile, ctx?: ConfigContext): void;
|
|
51
|
+
/**
|
|
52
|
+
* Add or update a trik in the lockfile
|
|
53
|
+
*/
|
|
54
|
+
export declare function addToLockfile(trik: InstalledTrik, ctx?: ConfigContext): void;
|
|
55
|
+
/**
|
|
56
|
+
* Remove a trik from the lockfile
|
|
57
|
+
*/
|
|
58
|
+
export declare function removeFromLockfile(fullName: string, ctx?: ConfigContext): void;
|
|
59
|
+
/**
|
|
60
|
+
* Get the installation path for a trik
|
|
61
|
+
*
|
|
62
|
+
* @example getTrikPath("@acme/article-search") => "~/.trikhub/triks/@acme/article-search"
|
|
63
|
+
* @example getTrikPath("@acme/article-search", localCtx) => "./.trikhub/triks/@acme/article-search"
|
|
64
|
+
*/
|
|
65
|
+
export declare function getTrikPath(fullName: string, ctx?: ConfigContext): string;
|
|
66
|
+
/**
|
|
67
|
+
* Get the triks directory for a context
|
|
68
|
+
*/
|
|
69
|
+
export declare function getTriksDir(ctx?: ConfigContext): string;
|
|
70
|
+
/**
|
|
71
|
+
* Check if a trik is installed
|
|
72
|
+
*/
|
|
73
|
+
export declare function isTrikInstalled(fullName: string, ctx?: ConfigContext): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Get installed trik info
|
|
76
|
+
*/
|
|
77
|
+
export declare function getInstalledTrik(fullName: string, ctx?: ConfigContext): InstalledTrik | null;
|
|
78
|
+
/**
|
|
79
|
+
* Get all installed triks
|
|
80
|
+
*/
|
|
81
|
+
export declare function getInstalledTriks(ctx?: ConfigContext): InstalledTrik[];
|
|
82
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/lib/storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EACL,UAAU,EACV,YAAY,EACZ,aAAa,EAEd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAoB,MAAM,aAAa,CAAC;AAO9D;;GAEG;AACH,eAAO,MAAM,WAAW,QAA8B,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,WAAW,QAAmC,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,aAAa,QAAkC,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,SAAS,QAA6B,CAAC;AAMpD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,CAAC,EAAE,aAAa,GAAG,IAAI,CAS3D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAKtD;AAMD;;;GAGG;AACH,wBAAgB,UAAU,IAAI,UAAU,CAGvC;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAInD;AAMD;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,aAAa,GAAG,YAAY,CAsB9D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,aAAa,GAAG,IAAI,CAI9E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,aAAa,GAAG,IAAI,CAK5E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,aAAa,GAAG,IAAI,CAK9E;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,aAAa,GAAG,MAAM,CAIzE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,CAAC,EAAE,aAAa,GAAG,MAAM,CAGvD;AAMD;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,aAAa,GAAG,OAAO,CAI9E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,aAAa,GAAG,aAAa,GAAG,IAAI,CAI5F;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,CAAC,EAAE,aAAa,GAAG,aAAa,EAAE,CAItE"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage and configuration management for TrikHub CLI
|
|
3
|
+
*
|
|
4
|
+
* This module handles trik installation paths and lockfile management.
|
|
5
|
+
* All functions now work with ConfigContext for local/global support.
|
|
6
|
+
*/
|
|
7
|
+
import { homedir } from 'node:os';
|
|
8
|
+
import { join, dirname } from 'node:path';
|
|
9
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
10
|
+
import { getConfigContext } from './config.js';
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Legacy exports for backwards compatibility
|
|
13
|
+
// These use the default (global) config context
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* @deprecated Use ConfigContext instead. This is kept for backwards compatibility.
|
|
17
|
+
*/
|
|
18
|
+
export const TRIKHUB_DIR = join(homedir(), '.trikhub');
|
|
19
|
+
/**
|
|
20
|
+
* @deprecated Use ConfigContext.configPath instead.
|
|
21
|
+
*/
|
|
22
|
+
export const CONFIG_PATH = join(TRIKHUB_DIR, 'config.json');
|
|
23
|
+
/**
|
|
24
|
+
* @deprecated Use ConfigContext.lockfilePath instead.
|
|
25
|
+
*/
|
|
26
|
+
export const LOCKFILE_PATH = join(TRIKHUB_DIR, 'triks.lock');
|
|
27
|
+
/**
|
|
28
|
+
* @deprecated Use ConfigContext.triksDir instead.
|
|
29
|
+
*/
|
|
30
|
+
export const TRIKS_DIR = join(TRIKHUB_DIR, 'triks');
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// Directory Management
|
|
33
|
+
// ============================================================================
|
|
34
|
+
/**
|
|
35
|
+
* Ensure the TrikHub directory structure exists for a context
|
|
36
|
+
*/
|
|
37
|
+
export function ensureDirectories(ctx) {
|
|
38
|
+
const context = ctx ?? getConfigContext();
|
|
39
|
+
if (!existsSync(context.trikhubDir)) {
|
|
40
|
+
mkdirSync(context.trikhubDir, { recursive: true });
|
|
41
|
+
}
|
|
42
|
+
if (!existsSync(context.triksDir)) {
|
|
43
|
+
mkdirSync(context.triksDir, { recursive: true });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Ensure parent directory exists for a path
|
|
48
|
+
*/
|
|
49
|
+
export function ensureParentDir(filePath) {
|
|
50
|
+
const dir = dirname(filePath);
|
|
51
|
+
if (!existsSync(dir)) {
|
|
52
|
+
mkdirSync(dir, { recursive: true });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// ============================================================================
|
|
56
|
+
// Config Management (Legacy - prefer using config.ts directly)
|
|
57
|
+
// ============================================================================
|
|
58
|
+
/**
|
|
59
|
+
* Load the CLI configuration
|
|
60
|
+
* @deprecated Use resolveConfig() from config.ts for full local/global support
|
|
61
|
+
*/
|
|
62
|
+
export function loadConfig() {
|
|
63
|
+
const ctx = getConfigContext();
|
|
64
|
+
return ctx.config;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Save the CLI configuration
|
|
68
|
+
* @deprecated Use saveConfig() from config.ts with a ConfigContext
|
|
69
|
+
*/
|
|
70
|
+
export function saveConfig(config) {
|
|
71
|
+
const ctx = getConfigContext();
|
|
72
|
+
ensureDirectories(ctx);
|
|
73
|
+
writeFileSync(ctx.configPath, JSON.stringify(config, null, 2));
|
|
74
|
+
}
|
|
75
|
+
// ============================================================================
|
|
76
|
+
// Lockfile Management
|
|
77
|
+
// ============================================================================
|
|
78
|
+
/**
|
|
79
|
+
* Load the lockfile for a context
|
|
80
|
+
*/
|
|
81
|
+
export function loadLockfile(ctx) {
|
|
82
|
+
const context = ctx ?? getConfigContext();
|
|
83
|
+
ensureDirectories(context);
|
|
84
|
+
if (!existsSync(context.lockfilePath)) {
|
|
85
|
+
const empty = {
|
|
86
|
+
lockfileVersion: 1,
|
|
87
|
+
triks: {},
|
|
88
|
+
};
|
|
89
|
+
saveLockfile(empty, context);
|
|
90
|
+
return empty;
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
const content = readFileSync(context.lockfilePath, 'utf-8');
|
|
94
|
+
return JSON.parse(content);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return {
|
|
98
|
+
lockfileVersion: 1,
|
|
99
|
+
triks: {},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Save the lockfile for a context
|
|
105
|
+
*/
|
|
106
|
+
export function saveLockfile(lockfile, ctx) {
|
|
107
|
+
const context = ctx ?? getConfigContext();
|
|
108
|
+
ensureDirectories(context);
|
|
109
|
+
writeFileSync(context.lockfilePath, JSON.stringify(lockfile, null, 2));
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Add or update a trik in the lockfile
|
|
113
|
+
*/
|
|
114
|
+
export function addToLockfile(trik, ctx) {
|
|
115
|
+
const context = ctx ?? getConfigContext();
|
|
116
|
+
const lockfile = loadLockfile(context);
|
|
117
|
+
lockfile.triks[trik.fullName] = trik;
|
|
118
|
+
saveLockfile(lockfile, context);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Remove a trik from the lockfile
|
|
122
|
+
*/
|
|
123
|
+
export function removeFromLockfile(fullName, ctx) {
|
|
124
|
+
const context = ctx ?? getConfigContext();
|
|
125
|
+
const lockfile = loadLockfile(context);
|
|
126
|
+
delete lockfile.triks[fullName];
|
|
127
|
+
saveLockfile(lockfile, context);
|
|
128
|
+
}
|
|
129
|
+
// ============================================================================
|
|
130
|
+
// Trik Path Management
|
|
131
|
+
// ============================================================================
|
|
132
|
+
/**
|
|
133
|
+
* Get the installation path for a trik
|
|
134
|
+
*
|
|
135
|
+
* @example getTrikPath("@acme/article-search") => "~/.trikhub/triks/@acme/article-search"
|
|
136
|
+
* @example getTrikPath("@acme/article-search", localCtx) => "./.trikhub/triks/@acme/article-search"
|
|
137
|
+
*/
|
|
138
|
+
export function getTrikPath(fullName, ctx) {
|
|
139
|
+
const context = ctx ?? getConfigContext();
|
|
140
|
+
// fullName is like "@acme/article-search"
|
|
141
|
+
return join(context.triksDir, fullName);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Get the triks directory for a context
|
|
145
|
+
*/
|
|
146
|
+
export function getTriksDir(ctx) {
|
|
147
|
+
const context = ctx ?? getConfigContext();
|
|
148
|
+
return context.triksDir;
|
|
149
|
+
}
|
|
150
|
+
// ============================================================================
|
|
151
|
+
// Trik Status Queries
|
|
152
|
+
// ============================================================================
|
|
153
|
+
/**
|
|
154
|
+
* Check if a trik is installed
|
|
155
|
+
*/
|
|
156
|
+
export function isTrikInstalled(fullName, ctx) {
|
|
157
|
+
const context = ctx ?? getConfigContext();
|
|
158
|
+
const lockfile = loadLockfile(context);
|
|
159
|
+
return fullName in lockfile.triks;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get installed trik info
|
|
163
|
+
*/
|
|
164
|
+
export function getInstalledTrik(fullName, ctx) {
|
|
165
|
+
const context = ctx ?? getConfigContext();
|
|
166
|
+
const lockfile = loadLockfile(context);
|
|
167
|
+
return lockfile.triks[fullName] ?? null;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get all installed triks
|
|
171
|
+
*/
|
|
172
|
+
export function getInstalledTriks(ctx) {
|
|
173
|
+
const context = ctx ?? getConfigContext();
|
|
174
|
+
const lockfile = loadLockfile(context);
|
|
175
|
+
return Object.values(lockfile.triks);
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/lib/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trik Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates downloaded triks before installation.
|
|
5
|
+
* This is a lightweight validator for the CLI - the full linter
|
|
6
|
+
* is available in @saaas-sdk/linter for skill development.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Validation result
|
|
10
|
+
*/
|
|
11
|
+
export interface ValidationResult {
|
|
12
|
+
valid: boolean;
|
|
13
|
+
errors: string[];
|
|
14
|
+
warnings: string[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Validate a trik at the given path
|
|
18
|
+
*/
|
|
19
|
+
export declare function validateTrik(trikPath: string): ValidationResult;
|
|
20
|
+
/**
|
|
21
|
+
* Format validation result for display
|
|
22
|
+
*/
|
|
23
|
+
export declare function formatValidationResult(result: ValidationResult): string;
|
|
24
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/lib/validator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAoGD;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CA4G/D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAkBvE"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trik Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates downloaded triks before installation.
|
|
5
|
+
* This is a lightweight validator for the CLI - the full linter
|
|
6
|
+
* is available in @saaas-sdk/linter for skill development.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
/**
|
|
11
|
+
* Allowed string formats in agentDataSchema
|
|
12
|
+
* Free-form strings without these constraints are security risks
|
|
13
|
+
*/
|
|
14
|
+
const ALLOWED_STRING_FORMATS = ['date', 'date-time', 'time', 'email', 'uri', 'uuid', 'id'];
|
|
15
|
+
/**
|
|
16
|
+
* Check if a JSON Schema allows unconstrained strings
|
|
17
|
+
*
|
|
18
|
+
* Unconstrained strings in agentData can lead to prompt injection
|
|
19
|
+
* because the agent's output would flow directly to the user.
|
|
20
|
+
*/
|
|
21
|
+
function hasUnconstrainedStrings(schema, path = '') {
|
|
22
|
+
const issues = [];
|
|
23
|
+
if (!schema || typeof schema !== 'object') {
|
|
24
|
+
return issues;
|
|
25
|
+
}
|
|
26
|
+
const s = schema;
|
|
27
|
+
// Check if this is a string type
|
|
28
|
+
if (s.type === 'string') {
|
|
29
|
+
const hasEnum = Array.isArray(s.enum) && s.enum.length > 0;
|
|
30
|
+
const hasConst = s.const !== undefined;
|
|
31
|
+
const hasPattern = typeof s.pattern === 'string';
|
|
32
|
+
const hasAllowedFormat = ALLOWED_STRING_FORMATS.includes(s.format);
|
|
33
|
+
if (!hasEnum && !hasConst && !hasPattern && !hasAllowedFormat) {
|
|
34
|
+
issues.push(`${path || 'root'}: Unconstrained string type. ` +
|
|
35
|
+
`Use enum, const, pattern, or format (${ALLOWED_STRING_FORMATS.join(', ')}) to constrain.`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Recurse into object properties
|
|
39
|
+
if (s.properties && typeof s.properties === 'object') {
|
|
40
|
+
for (const [key, value] of Object.entries(s.properties)) {
|
|
41
|
+
issues.push(...hasUnconstrainedStrings(value, `${path}.${key}`));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Recurse into array items
|
|
45
|
+
if (s.items) {
|
|
46
|
+
issues.push(...hasUnconstrainedStrings(s.items, `${path}[]`));
|
|
47
|
+
}
|
|
48
|
+
// Check additionalProperties
|
|
49
|
+
if (s.additionalProperties && typeof s.additionalProperties === 'object') {
|
|
50
|
+
issues.push(...hasUnconstrainedStrings(s.additionalProperties, `${path}[*]`));
|
|
51
|
+
}
|
|
52
|
+
// Check anyOf, oneOf, allOf
|
|
53
|
+
for (const combinator of ['anyOf', 'oneOf', 'allOf']) {
|
|
54
|
+
if (Array.isArray(s[combinator])) {
|
|
55
|
+
s[combinator].forEach((subSchema, i) => {
|
|
56
|
+
issues.push(...hasUnconstrainedStrings(subSchema, `${path}(${combinator}[${i}])`));
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return issues;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Validate a trik at the given path
|
|
64
|
+
*/
|
|
65
|
+
export function validateTrik(trikPath) {
|
|
66
|
+
const errors = [];
|
|
67
|
+
const warnings = [];
|
|
68
|
+
// 1. Check manifest.json exists
|
|
69
|
+
const manifestPath = join(trikPath, 'manifest.json');
|
|
70
|
+
if (!existsSync(manifestPath)) {
|
|
71
|
+
return {
|
|
72
|
+
valid: false,
|
|
73
|
+
errors: ['Missing manifest.json'],
|
|
74
|
+
warnings: [],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// 2. Parse manifest
|
|
78
|
+
let manifest;
|
|
79
|
+
try {
|
|
80
|
+
const content = readFileSync(manifestPath, 'utf-8');
|
|
81
|
+
manifest = JSON.parse(content);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
return {
|
|
85
|
+
valid: false,
|
|
86
|
+
errors: [`Invalid manifest.json: ${error instanceof Error ? error.message : 'Parse error'}`],
|
|
87
|
+
warnings: [],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
// 3. Validate required fields
|
|
91
|
+
const requiredFields = ['id', 'name', 'version', 'description', 'entry', 'actions', 'capabilities', 'limits'];
|
|
92
|
+
for (const field of requiredFields) {
|
|
93
|
+
if (!(field in manifest)) {
|
|
94
|
+
errors.push(`Missing required field: ${field}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (errors.length > 0) {
|
|
98
|
+
return { valid: false, errors, warnings };
|
|
99
|
+
}
|
|
100
|
+
// 4. Validate entry point
|
|
101
|
+
if (!manifest.entry?.module || !manifest.entry?.export) {
|
|
102
|
+
errors.push('Invalid entry: must have module and export');
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const entryPath = join(trikPath, manifest.entry.module);
|
|
106
|
+
if (!existsSync(entryPath)) {
|
|
107
|
+
errors.push(`Entry point not found: ${manifest.entry.module}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// 5. Validate actions
|
|
111
|
+
if (!manifest.actions || Object.keys(manifest.actions).length === 0) {
|
|
112
|
+
errors.push('Manifest must define at least one action');
|
|
113
|
+
}
|
|
114
|
+
// 6. Check each action for privilege separation
|
|
115
|
+
for (const [actionName, action] of Object.entries(manifest.actions || {})) {
|
|
116
|
+
// Validate responseMode
|
|
117
|
+
if (!['template', 'passthrough'].includes(action.responseMode)) {
|
|
118
|
+
errors.push(`Action "${actionName}": Invalid responseMode "${action.responseMode}"`);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
// Template mode: must have agentDataSchema and responseTemplates
|
|
122
|
+
if (action.responseMode === 'template') {
|
|
123
|
+
if (!action.agentDataSchema) {
|
|
124
|
+
errors.push(`Action "${actionName}": Template mode requires agentDataSchema`);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
// Check for unconstrained strings in agentDataSchema
|
|
128
|
+
const stringIssues = hasUnconstrainedStrings(action.agentDataSchema, `actions.${actionName}.agentDataSchema`);
|
|
129
|
+
for (const issue of stringIssues) {
|
|
130
|
+
errors.push(`Action "${actionName}": ${issue}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (!action.responseTemplates || Object.keys(action.responseTemplates).length === 0) {
|
|
134
|
+
errors.push(`Action "${actionName}": Template mode requires responseTemplates`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Passthrough mode: must have userContentSchema
|
|
138
|
+
if (action.responseMode === 'passthrough') {
|
|
139
|
+
if (!action.userContentSchema) {
|
|
140
|
+
errors.push(`Action "${actionName}": Passthrough mode requires userContentSchema`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// 7. Validate limits
|
|
145
|
+
if (manifest.limits) {
|
|
146
|
+
if (manifest.limits.maxExecutionTimeMs > 120000) {
|
|
147
|
+
warnings.push('maxExecutionTimeMs is very high (>2min)');
|
|
148
|
+
}
|
|
149
|
+
if (manifest.limits.maxLlmCalls > 50) {
|
|
150
|
+
warnings.push('maxLlmCalls is very high (>50)');
|
|
151
|
+
}
|
|
152
|
+
if (manifest.limits.maxToolCalls > 100) {
|
|
153
|
+
warnings.push('maxToolCalls is very high (>100)');
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
valid: errors.length === 0,
|
|
158
|
+
errors,
|
|
159
|
+
warnings,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Format validation result for display
|
|
164
|
+
*/
|
|
165
|
+
export function formatValidationResult(result) {
|
|
166
|
+
const lines = [];
|
|
167
|
+
if (result.valid) {
|
|
168
|
+
lines.push('Validation passed');
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
lines.push('Validation failed');
|
|
172
|
+
}
|
|
173
|
+
for (const error of result.errors) {
|
|
174
|
+
lines.push(` [error] ${error}`);
|
|
175
|
+
}
|
|
176
|
+
for (const warning of result.warnings) {
|
|
177
|
+
lines.push(` [warn] ${warning}`);
|
|
178
|
+
}
|
|
179
|
+
return lines.join('\n');
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/lib/validator.ts"],"names":[],"mappings":"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"}
|