@trikhub/linter 0.1.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Muffles
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env node
2
+ import { resolve } from 'node:path';
3
+ import { TrikLinter } from './linter.js';
4
+ async function main() {
5
+ const args = process.argv.slice(2);
6
+ if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
7
+ console.log(`
8
+ Usage: trik-lint <trik-path> [options]
9
+
10
+ Arguments:
11
+ trik-path Path to the trik directory containing manifest.json
12
+
13
+ Options:
14
+ --warnings-as-errors Treat warnings as errors
15
+ --skip <rule> Skip a specific rule (can be used multiple times)
16
+ --help, -h Show this help message
17
+
18
+ Rules:
19
+ valid-manifest Manifest must be valid JSON and match schema
20
+ manifest-completeness Check for recommended manifest fields
21
+ has-source-files Trik must have TypeScript source files
22
+ entry-point-exists Entry point in manifest must exist
23
+ no-forbidden-imports Block dangerous Node.js modules
24
+ no-dynamic-code Block eval() and Function constructor
25
+ undeclared-tool Tools used must be declared in manifest
26
+ no-process-env Warn on process.env access
27
+ `);
28
+ process.exit(0);
29
+ }
30
+ const trikPath = resolve(args[0]);
31
+ const warningsAsErrors = args.includes('--warnings-as-errors');
32
+ const skipRules = [];
33
+ for (let i = 0; i < args.length; i++) {
34
+ if (args[i] === '--skip' && args[i + 1]) {
35
+ skipRules.push(args[i + 1]);
36
+ i++;
37
+ }
38
+ }
39
+ const linter = new TrikLinter({
40
+ warningsAsErrors,
41
+ skipRules,
42
+ });
43
+ console.log(`Linting trik at: ${trikPath}\n`);
44
+ try {
45
+ const results = await linter.lint(trikPath);
46
+ console.log(linter.formatResults(results));
47
+ if (linter.hasErrors(results)) {
48
+ process.exit(1);
49
+ }
50
+ }
51
+ catch (error) {
52
+ console.error('Error:', error instanceof Error ? error.message : error);
53
+ process.exit(1);
54
+ }
55
+ }
56
+ main();
57
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;CAoBf,CAAC,CAAC;QACC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACxC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC5B,CAAC,EAAE,CAAC;QACN,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC;QAC5B,gBAAgB;QAChB,SAAS;KACV,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,oBAAoB,QAAQ,IAAI,CAAC,CAAC;IAE9C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;QAE3C,IAAI,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { TrikLinter, type LinterConfig } from './linter.js';
2
+ export { type LintResult, type LintSeverity, FORBIDDEN_IMPORTS, FORBIDDEN_CALLS, getImports, checkForbiddenImports, checkDynamicCodeExecution, checkUndeclaredTools, checkProcessEnvAccess, findToolUsage, ALLOWED_AGENT_STRING_FORMATS, schemaHasNoUnconstrainedStrings, checkNoFreeStringsInAgentData, extractTemplatePlaceholders, getSchemaFieldNames, checkTemplateFieldsExist, checkHasResponseTemplates, checkDefaultTemplateRecommended, } from './rules.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,EAEb,4BAA4B,EAC5B,+BAA+B,EAC/B,6BAA6B,EAC7B,2BAA2B,EAC3B,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,EACzB,+BAA+B,GAChC,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { TrikLinter } from './linter.js';
2
+ export { FORBIDDEN_IMPORTS, FORBIDDEN_CALLS, getImports, checkForbiddenImports, checkDynamicCodeExecution, checkUndeclaredTools, checkProcessEnvAccess, findToolUsage,
3
+ // V2 rules
4
+ ALLOWED_AGENT_STRING_FORMATS, schemaHasNoUnconstrainedStrings, checkNoFreeStringsInAgentData, extractTemplatePlaceholders, getSchemaFieldNames, checkTemplateFieldsExist, checkHasResponseTemplates, checkDefaultTemplateRecommended, } from './rules.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAqB,MAAM,aAAa,CAAC;AAC5D,OAAO,EAGL,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,aAAa;AACb,WAAW;AACX,4BAA4B,EAC5B,+BAA+B,EAC/B,6BAA6B,EAC7B,2BAA2B,EAC3B,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,EACzB,+BAA+B,GAChC,MAAM,YAAY,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { type LintResult } from './rules.js';
2
+ /**
3
+ * Linter configuration
4
+ */
5
+ export interface LinterConfig {
6
+ /** Additional forbidden imports */
7
+ forbiddenImports?: string[];
8
+ /** Skip certain rules */
9
+ skipRules?: string[];
10
+ /** Treat warnings as errors */
11
+ warningsAsErrors?: boolean;
12
+ }
13
+ /**
14
+ * Linter for trik validation
15
+ */
16
+ export declare class TrikLinter {
17
+ private config;
18
+ constructor(config?: LinterConfig);
19
+ /**
20
+ * Parse a TypeScript file into a source file
21
+ */
22
+ private parseTypeScript;
23
+ /**
24
+ * Load and parse the manifest
25
+ */
26
+ private loadManifest;
27
+ /**
28
+ * Find all TypeScript files in the trik directory
29
+ */
30
+ private findSourceFiles;
31
+ /**
32
+ * Check if a rule should be skipped
33
+ */
34
+ private shouldSkipRule;
35
+ /**
36
+ * Lint only the manifest (for downloaded/compiled triks without TypeScript source)
37
+ *
38
+ * This validates:
39
+ * - Manifest structure and required fields
40
+ * - Privilege separation rules (no free strings in agentData)
41
+ * - Template field existence
42
+ * - Response templates presence
43
+ *
44
+ * This does NOT validate:
45
+ * - Source code (forbidden imports, eval, etc.)
46
+ * - Entry point existence as TypeScript
47
+ */
48
+ lintManifestOnly(trikPath: string): Promise<LintResult[]>;
49
+ /**
50
+ * Lint a trik
51
+ */
52
+ lint(trikPath: string): Promise<LintResult[]>;
53
+ /**
54
+ * Lint manifest with privilege separation rules
55
+ */
56
+ private lintManifest;
57
+ /**
58
+ * Check manifest has all recommended fields
59
+ */
60
+ private checkManifestCompleteness;
61
+ /**
62
+ * Format lint results for console output
63
+ */
64
+ formatResults(results: LintResult[]): string;
65
+ /**
66
+ * Check if lint results have any errors
67
+ */
68
+ hasErrors(results: LintResult[]): boolean;
69
+ }
70
+ //# sourceMappingURL=linter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linter.d.ts","sourceRoot":"","sources":["../src/linter.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,KAAK,UAAU,EAUhB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,+BAA+B;IAC/B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,GAAE,YAAiB;IAIrC;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;YACW,YAAY;IAa1B;;OAEG;YACW,eAAe;IAiB7B;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;;;;;;;;;;;OAYG;IACG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAsC/D;;OAEG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAwFnD;;OAEG;IACH,OAAO,CAAC,YAAY;IA0BpB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA2CjC;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM;IAyB5C;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO;CAG1C"}
package/dist/linter.js ADDED
@@ -0,0 +1,275 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import ts from 'typescript';
4
+ import { validateManifest, } from '@trikhub/manifest';
5
+ import { checkForbiddenImports, checkDynamicCodeExecution, checkUndeclaredTools, checkProcessEnvAccess,
6
+ // Privilege separation rules
7
+ checkNoFreeStringsInAgentData, checkTemplateFieldsExist, checkHasResponseTemplates, checkDefaultTemplateRecommended, } from './rules.js';
8
+ /**
9
+ * Linter for trik validation
10
+ */
11
+ export class TrikLinter {
12
+ config;
13
+ constructor(config = {}) {
14
+ this.config = config;
15
+ }
16
+ /**
17
+ * Parse a TypeScript file into a source file
18
+ */
19
+ parseTypeScript(filePath, content) {
20
+ return ts.createSourceFile(filePath, content, ts.ScriptTarget.ESNext, true, ts.ScriptKind.TS);
21
+ }
22
+ /**
23
+ * Load and parse the manifest
24
+ */
25
+ async loadManifest(trikPath) {
26
+ const manifestPath = join(trikPath, 'manifest.json');
27
+ const content = await readFile(manifestPath, 'utf-8');
28
+ const data = JSON.parse(content);
29
+ const validation = validateManifest(data);
30
+ if (!validation.valid) {
31
+ throw new Error(`Invalid manifest: ${validation.errors?.join(', ')}`);
32
+ }
33
+ return data;
34
+ }
35
+ /**
36
+ * Find all TypeScript files in the trik directory
37
+ */
38
+ async findSourceFiles(trikPath) {
39
+ const fs = await import('node:fs/promises');
40
+ const entries = await fs.readdir(trikPath, { withFileTypes: true });
41
+ const tsFiles = [];
42
+ for (const entry of entries) {
43
+ if (entry.isFile() && (entry.name.endsWith('.ts') || entry.name.endsWith('.tsx'))) {
44
+ // Skip test files and declaration files
45
+ if (!entry.name.includes('.test.') && !entry.name.includes('.spec.') && !entry.name.endsWith('.d.ts')) {
46
+ tsFiles.push(join(trikPath, entry.name));
47
+ }
48
+ }
49
+ }
50
+ return tsFiles;
51
+ }
52
+ /**
53
+ * Check if a rule should be skipped
54
+ */
55
+ shouldSkipRule(ruleName) {
56
+ return this.config.skipRules?.includes(ruleName) ?? false;
57
+ }
58
+ /**
59
+ * Lint only the manifest (for downloaded/compiled triks without TypeScript source)
60
+ *
61
+ * This validates:
62
+ * - Manifest structure and required fields
63
+ * - Privilege separation rules (no free strings in agentData)
64
+ * - Template field existence
65
+ * - Response templates presence
66
+ *
67
+ * This does NOT validate:
68
+ * - Source code (forbidden imports, eval, etc.)
69
+ * - Entry point existence as TypeScript
70
+ */
71
+ async lintManifestOnly(trikPath) {
72
+ const results = [];
73
+ const manifestPath = join(trikPath, 'manifest.json');
74
+ // 1. Load and validate manifest
75
+ let manifest;
76
+ try {
77
+ manifest = await this.loadManifest(trikPath);
78
+ }
79
+ catch (error) {
80
+ results.push({
81
+ rule: 'valid-manifest',
82
+ severity: 'error',
83
+ message: error instanceof Error ? error.message : 'Failed to load manifest',
84
+ file: manifestPath,
85
+ });
86
+ return results;
87
+ }
88
+ // 2. Apply manifest-specific rules (privilege separation)
89
+ results.push(...this.lintManifest(manifest, manifestPath));
90
+ // 3. Check manifest completeness
91
+ if (!this.shouldSkipRule('manifest-completeness')) {
92
+ results.push(...this.checkManifestCompleteness(manifest, trikPath));
93
+ }
94
+ // Apply warningsAsErrors if configured
95
+ if (this.config.warningsAsErrors) {
96
+ for (const result of results) {
97
+ if (result.severity === 'warning') {
98
+ result.severity = 'error';
99
+ }
100
+ }
101
+ }
102
+ return results;
103
+ }
104
+ /**
105
+ * Lint a trik
106
+ */
107
+ async lint(trikPath) {
108
+ const results = [];
109
+ const manifestPath = join(trikPath, 'manifest.json');
110
+ // 1. Load and validate manifest
111
+ let manifest;
112
+ try {
113
+ manifest = await this.loadManifest(trikPath);
114
+ }
115
+ catch (error) {
116
+ results.push({
117
+ rule: 'valid-manifest',
118
+ severity: 'error',
119
+ message: error instanceof Error ? error.message : 'Failed to load manifest',
120
+ file: manifestPath,
121
+ });
122
+ return results;
123
+ }
124
+ // 2. Apply manifest-specific rules (privilege separation)
125
+ results.push(...this.lintManifest(manifest, manifestPath));
126
+ // 3. Check manifest completeness
127
+ if (!this.shouldSkipRule('manifest-completeness')) {
128
+ results.push(...this.checkManifestCompleteness(manifest, trikPath));
129
+ }
130
+ // 4. Find and analyze source files
131
+ const sourceFiles = await this.findSourceFiles(trikPath);
132
+ if (sourceFiles.length === 0) {
133
+ results.push({
134
+ rule: 'has-source-files',
135
+ severity: 'error',
136
+ message: 'No TypeScript source files found in trik directory',
137
+ file: trikPath,
138
+ });
139
+ return results;
140
+ }
141
+ // 5. Check entry point exists
142
+ const entryPath = join(trikPath, manifest.entry.module.replace('.js', '.ts'));
143
+ if (!sourceFiles.some((f) => f.endsWith(entryPath.split('/').pop().replace('.js', '.ts')))) {
144
+ results.push({
145
+ rule: 'entry-point-exists',
146
+ severity: 'warning',
147
+ message: `Entry point "${manifest.entry.module}" not found as TypeScript source`,
148
+ file: trikPath,
149
+ });
150
+ }
151
+ // 6. Analyze each source file
152
+ for (const filePath of sourceFiles) {
153
+ const content = await readFile(filePath, 'utf-8');
154
+ const sourceFile = this.parseTypeScript(filePath, content);
155
+ // Check forbidden imports
156
+ if (!this.shouldSkipRule('no-forbidden-imports')) {
157
+ results.push(...checkForbiddenImports(sourceFile, this.config.forbiddenImports));
158
+ }
159
+ // Check dynamic code execution
160
+ if (!this.shouldSkipRule('no-dynamic-code')) {
161
+ results.push(...checkDynamicCodeExecution(sourceFile));
162
+ }
163
+ // Check undeclared tools
164
+ if (!this.shouldSkipRule('undeclared-tool')) {
165
+ results.push(...checkUndeclaredTools(sourceFile, manifest.capabilities.tools));
166
+ }
167
+ // Check process.env access
168
+ if (!this.shouldSkipRule('no-process-env')) {
169
+ results.push(...checkProcessEnvAccess(sourceFile));
170
+ }
171
+ }
172
+ // Apply warningsAsErrors if configured
173
+ if (this.config.warningsAsErrors) {
174
+ for (const result of results) {
175
+ if (result.severity === 'warning') {
176
+ result.severity = 'error';
177
+ }
178
+ }
179
+ }
180
+ return results;
181
+ }
182
+ /**
183
+ * Lint manifest with privilege separation rules
184
+ */
185
+ lintManifest(manifest, manifestPath) {
186
+ const results = [];
187
+ // Core security rule: no free-form strings in agentDataSchema
188
+ if (!this.shouldSkipRule('no-free-strings-in-agent-data')) {
189
+ results.push(...checkNoFreeStringsInAgentData(manifest, manifestPath));
190
+ }
191
+ // Validate template placeholders reference real fields
192
+ if (!this.shouldSkipRule('template-fields-exist')) {
193
+ results.push(...checkTemplateFieldsExist(manifest, manifestPath));
194
+ }
195
+ // Ensure actions have response templates
196
+ if (!this.shouldSkipRule('has-response-templates')) {
197
+ results.push(...checkHasResponseTemplates(manifest, manifestPath));
198
+ }
199
+ // Recommend having a default/success template
200
+ if (!this.shouldSkipRule('default-template-recommended')) {
201
+ results.push(...checkDefaultTemplateRecommended(manifest, manifestPath));
202
+ }
203
+ return results;
204
+ }
205
+ /**
206
+ * Check manifest has all recommended fields
207
+ */
208
+ checkManifestCompleteness(manifest, trikPath) {
209
+ const results = [];
210
+ const manifestPath = join(trikPath, 'manifest.json');
211
+ if (!manifest.author) {
212
+ results.push({
213
+ rule: 'manifest-completeness',
214
+ severity: 'info',
215
+ message: 'Manifest is missing optional "author" field',
216
+ file: manifestPath,
217
+ });
218
+ }
219
+ if (!manifest.repository) {
220
+ results.push({
221
+ rule: 'manifest-completeness',
222
+ severity: 'info',
223
+ message: 'Manifest is missing optional "repository" field',
224
+ file: manifestPath,
225
+ });
226
+ }
227
+ if (!manifest.license) {
228
+ results.push({
229
+ rule: 'manifest-completeness',
230
+ severity: 'info',
231
+ message: 'Manifest is missing optional "license" field',
232
+ file: manifestPath,
233
+ });
234
+ }
235
+ if (manifest.limits.maxExecutionTimeMs > 60000) {
236
+ results.push({
237
+ rule: 'manifest-completeness',
238
+ severity: 'warning',
239
+ message: 'maxExecutionTimeMs is very high (>60s) - consider reducing',
240
+ file: manifestPath,
241
+ });
242
+ }
243
+ return results;
244
+ }
245
+ /**
246
+ * Format lint results for console output
247
+ */
248
+ formatResults(results) {
249
+ if (results.length === 0) {
250
+ return '✓ No issues found';
251
+ }
252
+ const lines = [];
253
+ const errors = results.filter((r) => r.severity === 'error');
254
+ const warnings = results.filter((r) => r.severity === 'warning');
255
+ const infos = results.filter((r) => r.severity === 'info');
256
+ for (const result of results) {
257
+ const icon = result.severity === 'error' ? '✗' : result.severity === 'warning' ? '⚠' : 'ℹ';
258
+ const location = result.line ? `${result.file}:${result.line}:${result.column}` : result.file;
259
+ lines.push(`${icon} [${result.rule}] ${result.message}`);
260
+ if (location) {
261
+ lines.push(` at ${location}`);
262
+ }
263
+ }
264
+ lines.push('');
265
+ lines.push(`${errors.length} error(s), ${warnings.length} warning(s), ${infos.length} info`);
266
+ return lines.join('\n');
267
+ }
268
+ /**
269
+ * Check if lint results have any errors
270
+ */
271
+ hasErrors(results) {
272
+ return results.some((r) => r.severity === 'error');
273
+ }
274
+ }
275
+ //# sourceMappingURL=linter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linter.js","sourceRoot":"","sources":["../src/linter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ import ts from 'typescript';
2
+ /**
3
+ * Lint result severity
4
+ */
5
+ export type LintSeverity = 'error' | 'warning' | 'info';
6
+ /**
7
+ * A single lint result
8
+ */
9
+ export interface LintResult {
10
+ rule: string;
11
+ severity: LintSeverity;
12
+ message: string;
13
+ file?: string;
14
+ line?: number;
15
+ column?: number;
16
+ }
17
+ /**
18
+ * List of forbidden Node.js core modules
19
+ */
20
+ export declare const FORBIDDEN_IMPORTS: string[];
21
+ /**
22
+ * List of forbidden global function calls
23
+ */
24
+ export declare const FORBIDDEN_CALLS: string[];
25
+ /**
26
+ * Extract all import specifiers from a source file
27
+ */
28
+ export declare function getImports(sourceFile: ts.SourceFile): string[];
29
+ /**
30
+ * Check for forbidden imports
31
+ */
32
+ export declare function checkForbiddenImports(sourceFile: ts.SourceFile, forbiddenList?: string[]): LintResult[];
33
+ /**
34
+ * Check for dynamic code execution (eval, Function constructor)
35
+ */
36
+ export declare function checkDynamicCodeExecution(sourceFile: ts.SourceFile): LintResult[];
37
+ /**
38
+ * Find tool usages in the source file
39
+ * This is a heuristic - looks for common LangGraph tool patterns
40
+ */
41
+ export declare function findToolUsage(sourceFile: ts.SourceFile): string[];
42
+ /**
43
+ * Check that all tools used are declared in manifest
44
+ */
45
+ export declare function checkUndeclaredTools(sourceFile: ts.SourceFile, declaredTools: string[]): LintResult[];
46
+ /**
47
+ * Check for process.env access (potential secret leakage)
48
+ */
49
+ export declare function checkProcessEnvAccess(sourceFile: ts.SourceFile): LintResult[];
50
+ import type { JSONSchema, TrikManifest } from '@trikhub/manifest';
51
+ /**
52
+ * Allowed string formats in agentDataSchema.
53
+ * These are safe because they have constrained, predictable values.
54
+ */
55
+ export declare const ALLOWED_AGENT_STRING_FORMATS: string[];
56
+ /**
57
+ * Recursively check if a schema contains unconstrained strings.
58
+ * Returns array of paths where unconstrained strings are found.
59
+ */
60
+ export declare function schemaHasNoUnconstrainedStrings(schema: JSONSchema, path?: string): string[];
61
+ /**
62
+ * Check that agentDataSchema contains no free-form strings.
63
+ * This is the core security rule for type-directed privilege separation.
64
+ */
65
+ export declare function checkNoFreeStringsInAgentData(manifest: TrikManifest, manifestPath: string): LintResult[];
66
+ /**
67
+ * Extract placeholder names from template text.
68
+ * Placeholders use {{fieldName}} syntax.
69
+ */
70
+ export declare function extractTemplatePlaceholders(templateText: string): string[];
71
+ /**
72
+ * Get all top-level field names from a schema
73
+ */
74
+ export declare function getSchemaFieldNames(schema: JSONSchema): string[];
75
+ /**
76
+ * Check that all template placeholders reference fields in agentDataSchema.
77
+ */
78
+ export declare function checkTemplateFieldsExist(manifest: TrikManifest, manifestPath: string): LintResult[];
79
+ /**
80
+ * Check that template mode V2 actions have at least one response template.
81
+ */
82
+ export declare function checkHasResponseTemplates(manifest: TrikManifest, manifestPath: string): LintResult[];
83
+ /**
84
+ * Check that template mode V2 actions have a "default" or commonly expected template.
85
+ */
86
+ export declare function checkDefaultTemplateRecommended(manifest: TrikManifest, manifestPath: string): LintResult[];
87
+ //# sourceMappingURL=rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,UAc7B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,UAAuB,CAAC;AAEpD;;GAEG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,MAAM,EAAE,CAwB9D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,EAAE,CAAC,UAAU,EACzB,aAAa,GAAE,MAAM,EAAsB,GAC1C,UAAU,EAAE,CAmBd;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,UAAU,EAAE,CAyCjF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,MAAM,EAAE,CA8CjE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,EAAE,CAAC,UAAU,EACzB,aAAa,EAAE,MAAM,EAAE,GACtB,UAAU,EAAE,CAgBd;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,UAAU,EAAE,CA8B7E;AAMD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,4BAA4B,UAAsD,CAAC;AAEhG;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,UAAU,EAClB,IAAI,GAAE,MAAe,GACpB,MAAM,EAAE,CA6CV;AA6BD;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,YAAY,EACtB,YAAY,EAAE,MAAM,GACnB,UAAU,EAAE,CAwBd;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAU1E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,EAAE,CAQhE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,YAAY,EACtB,YAAY,EAAE,MAAM,GACnB,UAAU,EAAE,CA6Bd;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,YAAY,EACtB,YAAY,EAAE,MAAM,GACnB,UAAU,EAAE,CAuBd;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,YAAY,EACtB,YAAY,EAAE,MAAM,GACnB,UAAU,EAAE,CAyBd"}
package/dist/rules.js ADDED
@@ -0,0 +1,397 @@
1
+ import ts from 'typescript';
2
+ /**
3
+ * List of forbidden Node.js core modules
4
+ */
5
+ export const FORBIDDEN_IMPORTS = [
6
+ 'fs',
7
+ 'fs/promises',
8
+ 'child_process',
9
+ 'net',
10
+ 'http',
11
+ 'https',
12
+ 'dgram',
13
+ 'dns',
14
+ 'tls',
15
+ 'cluster',
16
+ 'worker_threads',
17
+ 'vm',
18
+ 'process',
19
+ ];
20
+ /**
21
+ * List of forbidden global function calls
22
+ */
23
+ export const FORBIDDEN_CALLS = ['eval', 'Function'];
24
+ /**
25
+ * Extract all import specifiers from a source file
26
+ */
27
+ export function getImports(sourceFile) {
28
+ const imports = [];
29
+ function visit(node) {
30
+ if (ts.isImportDeclaration(node)) {
31
+ const moduleSpecifier = node.moduleSpecifier;
32
+ if (ts.isStringLiteral(moduleSpecifier)) {
33
+ imports.push(moduleSpecifier.text);
34
+ }
35
+ }
36
+ // Also check for dynamic imports
37
+ if (ts.isCallExpression(node)) {
38
+ if (node.expression.kind === ts.SyntaxKind.ImportKeyword) {
39
+ const arg = node.arguments[0];
40
+ if (arg && ts.isStringLiteral(arg)) {
41
+ imports.push(arg.text);
42
+ }
43
+ }
44
+ }
45
+ ts.forEachChild(node, visit);
46
+ }
47
+ visit(sourceFile);
48
+ return imports;
49
+ }
50
+ /**
51
+ * Check for forbidden imports
52
+ */
53
+ export function checkForbiddenImports(sourceFile, forbiddenList = FORBIDDEN_IMPORTS) {
54
+ const results = [];
55
+ const imports = getImports(sourceFile);
56
+ for (const imp of imports) {
57
+ // Check direct matches and node: prefix
58
+ const normalizedImport = imp.startsWith('node:') ? imp.slice(5) : imp;
59
+ if (forbiddenList.includes(normalizedImport)) {
60
+ results.push({
61
+ rule: 'no-forbidden-imports',
62
+ severity: 'error',
63
+ message: `Forbidden import: "${imp}" - triks cannot use this module`,
64
+ file: sourceFile.fileName,
65
+ });
66
+ }
67
+ }
68
+ return results;
69
+ }
70
+ /**
71
+ * Check for dynamic code execution (eval, Function constructor)
72
+ */
73
+ export function checkDynamicCodeExecution(sourceFile) {
74
+ const results = [];
75
+ function visit(node) {
76
+ // Check for eval()
77
+ if (ts.isCallExpression(node)) {
78
+ const callee = node.expression;
79
+ if (ts.isIdentifier(callee) && callee.text === 'eval') {
80
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
81
+ results.push({
82
+ rule: 'no-dynamic-code',
83
+ severity: 'error',
84
+ message: 'Use of eval() is forbidden in triks',
85
+ file: sourceFile.fileName,
86
+ line: line + 1,
87
+ column: character + 1,
88
+ });
89
+ }
90
+ }
91
+ // Check for new Function()
92
+ if (ts.isNewExpression(node)) {
93
+ const expression = node.expression;
94
+ if (ts.isIdentifier(expression) && expression.text === 'Function') {
95
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
96
+ results.push({
97
+ rule: 'no-dynamic-code',
98
+ severity: 'error',
99
+ message: 'Use of Function constructor is forbidden in triks',
100
+ file: sourceFile.fileName,
101
+ line: line + 1,
102
+ column: character + 1,
103
+ });
104
+ }
105
+ }
106
+ ts.forEachChild(node, visit);
107
+ }
108
+ visit(sourceFile);
109
+ return results;
110
+ }
111
+ /**
112
+ * Find tool usages in the source file
113
+ * This is a heuristic - looks for common LangGraph tool patterns
114
+ */
115
+ export function findToolUsage(sourceFile) {
116
+ const tools = [];
117
+ function visit(node) {
118
+ // Look for @tool decorator or tool() calls
119
+ if (ts.isCallExpression(node)) {
120
+ const callee = node.expression;
121
+ if (ts.isIdentifier(callee) && callee.text === 'tool') {
122
+ // tool("name", ...) pattern
123
+ const firstArg = node.arguments[0];
124
+ if (firstArg && ts.isStringLiteral(firstArg)) {
125
+ tools.push(firstArg.text);
126
+ }
127
+ }
128
+ }
129
+ // Look for StructuredTool class definitions
130
+ if (ts.isClassDeclaration(node)) {
131
+ const heritage = node.heritageClauses;
132
+ if (heritage) {
133
+ for (const clause of heritage) {
134
+ for (const type of clause.types) {
135
+ if (ts.isIdentifier(type.expression) && type.expression.text === 'StructuredTool') {
136
+ // Get the name property
137
+ for (const member of node.members) {
138
+ if (ts.isPropertyDeclaration(member)) {
139
+ const name = member.name;
140
+ if (ts.isIdentifier(name) && name.text === 'name') {
141
+ const initializer = member.initializer;
142
+ if (initializer && ts.isStringLiteral(initializer)) {
143
+ tools.push(initializer.text);
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+ }
153
+ ts.forEachChild(node, visit);
154
+ }
155
+ visit(sourceFile);
156
+ return tools;
157
+ }
158
+ /**
159
+ * Check that all tools used are declared in manifest
160
+ */
161
+ export function checkUndeclaredTools(sourceFile, declaredTools) {
162
+ const results = [];
163
+ const usedTools = findToolUsage(sourceFile);
164
+ for (const tool of usedTools) {
165
+ if (!declaredTools.includes(tool)) {
166
+ results.push({
167
+ rule: 'undeclared-tool',
168
+ severity: 'error',
169
+ message: `Tool "${tool}" is used but not declared in manifest.capabilities.tools`,
170
+ file: sourceFile.fileName,
171
+ });
172
+ }
173
+ }
174
+ return results;
175
+ }
176
+ /**
177
+ * Check for process.env access (potential secret leakage)
178
+ */
179
+ export function checkProcessEnvAccess(sourceFile) {
180
+ const results = [];
181
+ function visit(node) {
182
+ if (ts.isPropertyAccessExpression(node)) {
183
+ // Check for process.env
184
+ if (ts.isPropertyAccessExpression(node.expression) &&
185
+ ts.isIdentifier(node.expression.expression) &&
186
+ node.expression.expression.text === 'process' &&
187
+ ts.isIdentifier(node.expression.name) &&
188
+ node.expression.name.text === 'env') {
189
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
190
+ results.push({
191
+ rule: 'no-process-env',
192
+ severity: 'warning',
193
+ message: 'Accessing process.env - ensure no secrets are leaked in trik output',
194
+ file: sourceFile.fileName,
195
+ line: line + 1,
196
+ column: character + 1,
197
+ });
198
+ }
199
+ }
200
+ ts.forEachChild(node, visit);
201
+ }
202
+ visit(sourceFile);
203
+ return results;
204
+ }
205
+ /**
206
+ * Allowed string formats in agentDataSchema.
207
+ * These are safe because they have constrained, predictable values.
208
+ */
209
+ export const ALLOWED_AGENT_STRING_FORMATS = ['id', 'date', 'date-time', 'uuid', 'email', 'url'];
210
+ /**
211
+ * Recursively check if a schema contains unconstrained strings.
212
+ * Returns array of paths where unconstrained strings are found.
213
+ */
214
+ export function schemaHasNoUnconstrainedStrings(schema, path = 'root') {
215
+ const violations = [];
216
+ // Handle array type
217
+ if (Array.isArray(schema.type)) {
218
+ if (schema.type.includes('string')) {
219
+ // String is one of the allowed types - check if constrained
220
+ if (!isConstrainedString(schema)) {
221
+ violations.push(path);
222
+ }
223
+ }
224
+ }
225
+ else if (schema.type === 'string') {
226
+ // Direct string type - must be constrained
227
+ if (!isConstrainedString(schema)) {
228
+ violations.push(path);
229
+ }
230
+ }
231
+ // Recursively check properties
232
+ if (schema.properties) {
233
+ for (const [key, propSchema] of Object.entries(schema.properties)) {
234
+ violations.push(...schemaHasNoUnconstrainedStrings(propSchema, `${path}.${key}`));
235
+ }
236
+ }
237
+ // Recursively check array items
238
+ if (schema.items) {
239
+ violations.push(...schemaHasNoUnconstrainedStrings(schema.items, `${path}[]`));
240
+ }
241
+ // Check additionalProperties if it's a schema
242
+ if (schema.additionalProperties && typeof schema.additionalProperties === 'object') {
243
+ violations.push(...schemaHasNoUnconstrainedStrings(schema.additionalProperties, `${path}[additionalProperties]`));
244
+ }
245
+ // Check $defs
246
+ if (schema.$defs) {
247
+ for (const [key, defSchema] of Object.entries(schema.$defs)) {
248
+ violations.push(...schemaHasNoUnconstrainedStrings(defSchema, `${path}.$defs.${key}`));
249
+ }
250
+ }
251
+ return violations;
252
+ }
253
+ /**
254
+ * Check if a string schema is properly constrained
255
+ */
256
+ function isConstrainedString(schema) {
257
+ // Has enum constraint
258
+ if (schema.enum && Array.isArray(schema.enum) && schema.enum.length > 0) {
259
+ return true;
260
+ }
261
+ // Has const constraint
262
+ if (schema.const !== undefined) {
263
+ return true;
264
+ }
265
+ // Has pattern constraint
266
+ if (schema.pattern && typeof schema.pattern === 'string') {
267
+ return true;
268
+ }
269
+ // Has allowed format constraint
270
+ if (schema.format && ALLOWED_AGENT_STRING_FORMATS.includes(schema.format)) {
271
+ return true;
272
+ }
273
+ return false;
274
+ }
275
+ /**
276
+ * Check that agentDataSchema contains no free-form strings.
277
+ * This is the core security rule for type-directed privilege separation.
278
+ */
279
+ export function checkNoFreeStringsInAgentData(manifest, manifestPath) {
280
+ const results = [];
281
+ for (const [actionName, action] of Object.entries(manifest.actions)) {
282
+ // Only check agentDataSchema for template mode actions
283
+ if (action.responseMode === 'template' && action.agentDataSchema) {
284
+ const violations = schemaHasNoUnconstrainedStrings(action.agentDataSchema, `actions.${actionName}.agentDataSchema`);
285
+ for (const violationPath of violations) {
286
+ results.push({
287
+ rule: 'no-free-strings-in-agent-data',
288
+ severity: 'error',
289
+ message: `Unconstrained string found at ${violationPath}. ` +
290
+ `Strings in agentDataSchema must have: enum, const, pattern, or format (${ALLOWED_AGENT_STRING_FORMATS.join(', ')})`,
291
+ file: manifestPath,
292
+ });
293
+ }
294
+ }
295
+ }
296
+ return results;
297
+ }
298
+ /**
299
+ * Extract placeholder names from template text.
300
+ * Placeholders use {{fieldName}} syntax.
301
+ */
302
+ export function extractTemplatePlaceholders(templateText) {
303
+ const regex = /\{\{(\w+)\}\}/g;
304
+ const placeholders = [];
305
+ let match;
306
+ while ((match = regex.exec(templateText)) !== null) {
307
+ placeholders.push(match[1]);
308
+ }
309
+ return placeholders;
310
+ }
311
+ /**
312
+ * Get all top-level field names from a schema
313
+ */
314
+ export function getSchemaFieldNames(schema) {
315
+ const fields = [];
316
+ if (schema.properties) {
317
+ fields.push(...Object.keys(schema.properties));
318
+ }
319
+ return fields;
320
+ }
321
+ /**
322
+ * Check that all template placeholders reference fields in agentDataSchema.
323
+ */
324
+ export function checkTemplateFieldsExist(manifest, manifestPath) {
325
+ const results = [];
326
+ for (const [actionName, action] of Object.entries(manifest.actions)) {
327
+ // Only check template fields for template mode actions with schemas and templates
328
+ if (action.responseMode !== 'template' || !action.agentDataSchema || !action.responseTemplates) {
329
+ continue;
330
+ }
331
+ const schemaFields = getSchemaFieldNames(action.agentDataSchema);
332
+ for (const [templateId, template] of Object.entries(action.responseTemplates)) {
333
+ const placeholders = extractTemplatePlaceholders(template.text);
334
+ for (const placeholder of placeholders) {
335
+ if (!schemaFields.includes(placeholder)) {
336
+ results.push({
337
+ rule: 'template-fields-exist',
338
+ severity: 'error',
339
+ message: `Template "${templateId}" in action "${actionName}" references field "{{${placeholder}}}" ` +
340
+ `which does not exist in agentDataSchema. Available fields: ${schemaFields.join(', ') || 'none'}`,
341
+ file: manifestPath,
342
+ });
343
+ }
344
+ }
345
+ }
346
+ }
347
+ return results;
348
+ }
349
+ /**
350
+ * Check that template mode V2 actions have at least one response template.
351
+ */
352
+ export function checkHasResponseTemplates(manifest, manifestPath) {
353
+ const results = [];
354
+ for (const [actionName, action] of Object.entries(manifest.actions)) {
355
+ // Only check template mode actions
356
+ if (action.responseMode !== 'template') {
357
+ continue;
358
+ }
359
+ const templateCount = action.responseTemplates ? Object.keys(action.responseTemplates).length : 0;
360
+ if (templateCount === 0) {
361
+ results.push({
362
+ rule: 'has-response-templates',
363
+ severity: 'error',
364
+ message: `Template mode action "${actionName}" has no response templates. ` +
365
+ `Template mode actions must define at least one response template.`,
366
+ file: manifestPath,
367
+ });
368
+ }
369
+ }
370
+ return results;
371
+ }
372
+ /**
373
+ * Check that template mode V2 actions have a "default" or commonly expected template.
374
+ */
375
+ export function checkDefaultTemplateRecommended(manifest, manifestPath) {
376
+ const results = [];
377
+ const commonTemplates = ['default', 'success', 'result'];
378
+ for (const [actionName, action] of Object.entries(manifest.actions)) {
379
+ // Only check template mode actions with templates
380
+ if (action.responseMode !== 'template' || !action.responseTemplates) {
381
+ continue;
382
+ }
383
+ const templateIds = Object.keys(action.responseTemplates);
384
+ const hasCommon = templateIds.some((id) => commonTemplates.includes(id));
385
+ if (!hasCommon && templateIds.length > 0) {
386
+ results.push({
387
+ rule: 'default-template-recommended',
388
+ severity: 'warning',
389
+ message: `Action "${actionName}" has no common template (${commonTemplates.join(', ')}). ` +
390
+ `Consider adding a "success" or "default" template for clarity.`,
391
+ file: manifestPath,
392
+ });
393
+ }
394
+ }
395
+ return results;
396
+ }
397
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@trikhub/linter",
3
+ "version": "0.1.0",
4
+ "description": "Linter and validator for trik manifests and handlers",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "trik-lint": "./dist/cli.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.js",
14
+ "types": "./dist/index.d.ts"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md",
20
+ "LICENSE"
21
+ ],
22
+ "keywords": [
23
+ "ai",
24
+ "agent",
25
+ "trik",
26
+ "linter",
27
+ "validator",
28
+ "cli",
29
+ "typescript",
30
+ "trikhub"
31
+ ],
32
+ "author": "Muffles",
33
+ "license": "MIT",
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/Muffles/trikhub.git",
37
+ "directory": "packages/trik-linter"
38
+ },
39
+ "bugs": {
40
+ "url": "https://github.com/Muffles/trikhub/issues"
41
+ },
42
+ "homepage": "https://github.com/Muffles/trikhub/tree/main/packages/trik-linter#readme",
43
+ "publishConfig": {
44
+ "access": "public"
45
+ },
46
+ "engines": {
47
+ "node": ">=18.0.0"
48
+ },
49
+ "dependencies": {
50
+ "typescript": "^5.5.0",
51
+ "@trikhub/manifest": "0.1.0"
52
+ },
53
+ "scripts": {
54
+ "build": "tsc",
55
+ "clean": "rm -rf dist *.tsbuildinfo"
56
+ }
57
+ }