@tankpkg/cli 0.7.0 → 0.9.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/dist/bin/tank.d.ts +1 -2
- package/dist/bin/tank.js +3517 -294
- package/dist/bin/tank.js.map +1 -1
- package/dist/debug-logger-BJzuguP3.js +140 -0
- package/dist/debug-logger-BJzuguP3.js.map +1 -0
- package/dist/index.d.ts +59 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +83 -4
- package/dist/index.js.map +1 -1
- package/dist/package.json +46 -0
- package/package.json +18 -12
- package/LICENSE +0 -21
- package/dist/commands/audit.d.ts +0 -5
- package/dist/commands/audit.js +0 -185
- package/dist/commands/audit.js.map +0 -1
- package/dist/commands/doctor.d.ts +0 -5
- package/dist/commands/doctor.js +0 -164
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/info.d.ts +0 -5
- package/dist/commands/info.js +0 -102
- package/dist/commands/info.js.map +0 -1
- package/dist/commands/init.d.ts +0 -11
- package/dist/commands/init.js +0 -140
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/install.d.ts +0 -24
- package/dist/commands/install.js +0 -517
- package/dist/commands/install.js.map +0 -1
- package/dist/commands/link.d.ts +0 -5
- package/dist/commands/link.js +0 -79
- package/dist/commands/link.js.map +0 -1
- package/dist/commands/login.d.ts +0 -14
- package/dist/commands/login.js +0 -87
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/logout.d.ts +0 -9
- package/dist/commands/logout.js +0 -20
- package/dist/commands/logout.js.map +0 -1
- package/dist/commands/permissions.d.ts +0 -4
- package/dist/commands/permissions.js +0 -199
- package/dist/commands/permissions.js.map +0 -1
- package/dist/commands/publish.d.ts +0 -25
- package/dist/commands/publish.js +0 -166
- package/dist/commands/publish.js.map +0 -1
- package/dist/commands/remove.d.ts +0 -7
- package/dist/commands/remove.js +0 -163
- package/dist/commands/remove.js.map +0 -1
- package/dist/commands/scan.d.ts +0 -5
- package/dist/commands/scan.js +0 -169
- package/dist/commands/scan.js.map +0 -1
- package/dist/commands/search.d.ts +0 -5
- package/dist/commands/search.js +0 -67
- package/dist/commands/search.js.map +0 -1
- package/dist/commands/unlink.d.ts +0 -5
- package/dist/commands/unlink.js +0 -42
- package/dist/commands/unlink.js.map +0 -1
- package/dist/commands/update.d.ts +0 -8
- package/dist/commands/update.js +0 -332
- package/dist/commands/update.js.map +0 -1
- package/dist/commands/upgrade.d.ts +0 -6
- package/dist/commands/upgrade.js +0 -111
- package/dist/commands/upgrade.js.map +0 -1
- package/dist/commands/verify.d.ts +0 -22
- package/dist/commands/verify.js +0 -63
- package/dist/commands/verify.js.map +0 -1
- package/dist/commands/whoami.d.ts +0 -4
- package/dist/commands/whoami.js +0 -57
- package/dist/commands/whoami.js.map +0 -1
- package/dist/lib/agents.d.ts +0 -19
- package/dist/lib/agents.js +0 -106
- package/dist/lib/agents.js.map +0 -1
- package/dist/lib/api-client.d.ts +0 -14
- package/dist/lib/api-client.js +0 -63
- package/dist/lib/api-client.js.map +0 -1
- package/dist/lib/config.d.ts +0 -29
- package/dist/lib/config.js +0 -66
- package/dist/lib/config.js.map +0 -1
- package/dist/lib/debug-logger.d.ts +0 -9
- package/dist/lib/debug-logger.js +0 -77
- package/dist/lib/debug-logger.js.map +0 -1
- package/dist/lib/dependency-resolver.d.ts +0 -51
- package/dist/lib/dependency-resolver.js +0 -181
- package/dist/lib/dependency-resolver.js.map +0 -1
- package/dist/lib/frontmatter.d.ts +0 -11
- package/dist/lib/frontmatter.js +0 -89
- package/dist/lib/frontmatter.js.map +0 -1
- package/dist/lib/install-pipeline.d.ts +0 -23
- package/dist/lib/install-pipeline.js +0 -181
- package/dist/lib/install-pipeline.js.map +0 -1
- package/dist/lib/linker.d.ts +0 -45
- package/dist/lib/linker.js +0 -137
- package/dist/lib/linker.js.map +0 -1
- package/dist/lib/links.d.ts +0 -20
- package/dist/lib/links.js +0 -105
- package/dist/lib/links.js.map +0 -1
- package/dist/lib/lockfile.d.ts +0 -24
- package/dist/lib/lockfile.js +0 -135
- package/dist/lib/lockfile.js.map +0 -1
- package/dist/lib/logger.d.ts +0 -6
- package/dist/lib/logger.js +0 -8
- package/dist/lib/logger.js.map +0 -1
- package/dist/lib/packer.d.ts +0 -41
- package/dist/lib/packer.js +0 -284
- package/dist/lib/packer.js.map +0 -1
- package/dist/lib/permission-checker.d.ts +0 -16
- package/dist/lib/permission-checker.js +0 -78
- package/dist/lib/permission-checker.js.map +0 -1
- package/dist/lib/upgrade-check.d.ts +0 -1
- package/dist/lib/upgrade-check.js +0 -59
- package/dist/lib/upgrade-check.js.map +0 -1
- package/dist/version.d.ts +0 -2
- package/dist/version.js +0 -4
- package/dist/version.js.map +0 -1
package/dist/lib/lockfile.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { SkillsLock, Permissions } from '@tank/shared';
|
|
2
|
-
/**
|
|
3
|
-
* Read and parse the lockfile from the given directory.
|
|
4
|
-
* Returns null if the file doesn't exist or is corrupt.
|
|
5
|
-
*/
|
|
6
|
-
export declare function readLockfile(directory?: string): SkillsLock | null;
|
|
7
|
-
/**
|
|
8
|
-
* Write a lockfile deterministically: sorted keys, consistent formatting, trailing newline.
|
|
9
|
-
*/
|
|
10
|
-
export declare function writeLockfile(lock: SkillsLock, directory?: string): void;
|
|
11
|
-
/**
|
|
12
|
-
* Compute the union of all skill permissions from a lockfile.
|
|
13
|
-
* Merges network outbound, filesystem read/write (deduped), and subprocess (OR).
|
|
14
|
-
*/
|
|
15
|
-
export declare function computeResolvedPermissions(lock: SkillsLock): Permissions;
|
|
16
|
-
/**
|
|
17
|
-
* Check if resolved permissions fit within the project's permission budget.
|
|
18
|
-
*
|
|
19
|
-
* Returns:
|
|
20
|
-
* - 'pass' if all resolved permissions are within budget
|
|
21
|
-
* - 'fail' if any resolved permission exceeds budget
|
|
22
|
-
* - 'no_budget' if no project permissions are defined
|
|
23
|
-
*/
|
|
24
|
-
export declare function computeBudgetCheck(resolvedPermissions: Permissions, projectPermissions: Permissions | undefined): 'pass' | 'fail' | 'no_budget';
|
package/dist/lib/lockfile.js
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
/**
|
|
4
|
-
* Read and parse the lockfile from the given directory.
|
|
5
|
-
* Returns null if the file doesn't exist or is corrupt.
|
|
6
|
-
*/
|
|
7
|
-
export function readLockfile(directory) {
|
|
8
|
-
const dir = directory ?? process.cwd();
|
|
9
|
-
const lockPath = path.join(dir, 'skills.lock');
|
|
10
|
-
if (!fs.existsSync(lockPath)) {
|
|
11
|
-
return null;
|
|
12
|
-
}
|
|
13
|
-
try {
|
|
14
|
-
const raw = fs.readFileSync(lockPath, 'utf-8');
|
|
15
|
-
return JSON.parse(raw);
|
|
16
|
-
}
|
|
17
|
-
catch {
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Write a lockfile deterministically: sorted keys, consistent formatting, trailing newline.
|
|
23
|
-
*/
|
|
24
|
-
export function writeLockfile(lock, directory) {
|
|
25
|
-
const dir = directory ?? process.cwd();
|
|
26
|
-
const lockPath = path.join(dir, 'skills.lock');
|
|
27
|
-
// Sort skill keys alphabetically for determinism
|
|
28
|
-
const sortedSkills = {};
|
|
29
|
-
for (const key of Object.keys(lock.skills).sort()) {
|
|
30
|
-
sortedSkills[key] = lock.skills[key];
|
|
31
|
-
}
|
|
32
|
-
const output = {
|
|
33
|
-
lockfileVersion: lock.lockfileVersion,
|
|
34
|
-
skills: sortedSkills,
|
|
35
|
-
};
|
|
36
|
-
fs.writeFileSync(lockPath, JSON.stringify(output, null, 2) + '\n');
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Compute the union of all skill permissions from a lockfile.
|
|
40
|
-
* Merges network outbound, filesystem read/write (deduped), and subprocess (OR).
|
|
41
|
-
*/
|
|
42
|
-
export function computeResolvedPermissions(lock) {
|
|
43
|
-
const entries = Object.values(lock.skills);
|
|
44
|
-
if (entries.length === 0) {
|
|
45
|
-
return {};
|
|
46
|
-
}
|
|
47
|
-
const outbound = new Set();
|
|
48
|
-
const fsRead = new Set();
|
|
49
|
-
const fsWrite = new Set();
|
|
50
|
-
let subprocess = false;
|
|
51
|
-
for (const entry of entries) {
|
|
52
|
-
const perms = entry.permissions;
|
|
53
|
-
if (perms.network?.outbound) {
|
|
54
|
-
for (const domain of perms.network.outbound) {
|
|
55
|
-
outbound.add(domain);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
if (perms.filesystem?.read) {
|
|
59
|
-
for (const pattern of perms.filesystem.read) {
|
|
60
|
-
fsRead.add(pattern);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if (perms.filesystem?.write) {
|
|
64
|
-
for (const pattern of perms.filesystem.write) {
|
|
65
|
-
fsWrite.add(pattern);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
if (perms.subprocess === true) {
|
|
69
|
-
subprocess = true;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
const result = {};
|
|
73
|
-
if (outbound.size > 0) {
|
|
74
|
-
result.network = { outbound: [...outbound].sort() };
|
|
75
|
-
}
|
|
76
|
-
if (fsRead.size > 0 || fsWrite.size > 0) {
|
|
77
|
-
result.filesystem = {};
|
|
78
|
-
if (fsRead.size > 0) {
|
|
79
|
-
result.filesystem.read = [...fsRead].sort();
|
|
80
|
-
}
|
|
81
|
-
if (fsWrite.size > 0) {
|
|
82
|
-
result.filesystem.write = [...fsWrite].sort();
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
if (subprocess) {
|
|
86
|
-
result.subprocess = true;
|
|
87
|
-
}
|
|
88
|
-
return result;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Check if resolved permissions fit within the project's permission budget.
|
|
92
|
-
*
|
|
93
|
-
* Returns:
|
|
94
|
-
* - 'pass' if all resolved permissions are within budget
|
|
95
|
-
* - 'fail' if any resolved permission exceeds budget
|
|
96
|
-
* - 'no_budget' if no project permissions are defined
|
|
97
|
-
*/
|
|
98
|
-
export function computeBudgetCheck(resolvedPermissions, projectPermissions) {
|
|
99
|
-
if (projectPermissions === undefined) {
|
|
100
|
-
return 'no_budget';
|
|
101
|
-
}
|
|
102
|
-
// Check subprocess
|
|
103
|
-
if (resolvedPermissions.subprocess === true && projectPermissions.subprocess === false) {
|
|
104
|
-
return 'fail';
|
|
105
|
-
}
|
|
106
|
-
// Check network outbound
|
|
107
|
-
if (resolvedPermissions.network?.outbound) {
|
|
108
|
-
const budgetOutbound = new Set(projectPermissions.network?.outbound ?? []);
|
|
109
|
-
for (const domain of resolvedPermissions.network.outbound) {
|
|
110
|
-
if (!budgetOutbound.has(domain)) {
|
|
111
|
-
return 'fail';
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
// Check filesystem read
|
|
116
|
-
if (resolvedPermissions.filesystem?.read) {
|
|
117
|
-
const budgetRead = new Set(projectPermissions.filesystem?.read ?? []);
|
|
118
|
-
for (const pattern of resolvedPermissions.filesystem.read) {
|
|
119
|
-
if (!budgetRead.has(pattern)) {
|
|
120
|
-
return 'fail';
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
// Check filesystem write
|
|
125
|
-
if (resolvedPermissions.filesystem?.write) {
|
|
126
|
-
const budgetWrite = new Set(projectPermissions.filesystem?.write ?? []);
|
|
127
|
-
for (const pattern of resolvedPermissions.filesystem.write) {
|
|
128
|
-
if (!budgetWrite.has(pattern)) {
|
|
129
|
-
return 'fail';
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return 'pass';
|
|
134
|
-
}
|
|
135
|
-
//# sourceMappingURL=lockfile.js.map
|
package/dist/lib/lockfile.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../../src/lib/lockfile.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/logger.d.ts
DELETED
package/dist/lib/logger.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
export const logger = {
|
|
3
|
-
info: (msg) => console.log(chalk.blue('ℹ'), msg),
|
|
4
|
-
success: (msg) => console.log(chalk.green('✓'), msg),
|
|
5
|
-
warn: (msg) => console.log(chalk.yellow('⚠'), msg),
|
|
6
|
-
error: (msg) => console.error(chalk.red('✗'), msg),
|
|
7
|
-
};
|
|
8
|
-
//# sourceMappingURL=logger.js.map
|
package/dist/lib/logger.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IACxD,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IAC5D,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IAC1D,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;CAC3D,CAAC"}
|
package/dist/lib/packer.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
export interface PackResult {
|
|
2
|
-
tarball: Buffer;
|
|
3
|
-
integrity: string;
|
|
4
|
-
fileCount: number;
|
|
5
|
-
totalSize: number;
|
|
6
|
-
readme: string;
|
|
7
|
-
files: string[];
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Pack a skill directory into a .tgz tarball with integrity hashing.
|
|
11
|
-
*
|
|
12
|
-
* Validates:
|
|
13
|
-
* - skills.json exists and is valid
|
|
14
|
-
* - SKILL.md exists
|
|
15
|
-
* - No symlinks or hardlinks
|
|
16
|
-
* - No path traversal (.. components)
|
|
17
|
-
* - No absolute paths
|
|
18
|
-
* - File count <= 1000
|
|
19
|
-
* - Tarball size <= 50MB
|
|
20
|
-
*/
|
|
21
|
-
export declare function pack(directory: string): Promise<PackResult>;
|
|
22
|
-
/**
|
|
23
|
-
* Pack a directory into a .tgz tarball for security scanning.
|
|
24
|
-
*
|
|
25
|
-
* Unlike pack(), this function does NOT require skills.json or SKILL.md.
|
|
26
|
-
* It applies the same security checks (no symlinks, no path traversal, etc.)
|
|
27
|
-
* and returns the same PackResult interface.
|
|
28
|
-
*
|
|
29
|
-
* Validates:
|
|
30
|
-
* - Directory exists
|
|
31
|
-
* - No symlinks or hardlinks
|
|
32
|
-
* - No path traversal (.. components)
|
|
33
|
-
* - No absolute paths
|
|
34
|
-
* - File count <= 1000
|
|
35
|
-
* - Tarball size <= 50MB
|
|
36
|
-
*
|
|
37
|
-
* Does NOT validate:
|
|
38
|
-
* - skills.json existence or validity
|
|
39
|
-
* - SKILL.md existence (but reads it if present)
|
|
40
|
-
*/
|
|
41
|
-
export declare function packForScan(directory: string): Promise<PackResult>;
|
package/dist/lib/packer.js
DELETED
|
@@ -1,284 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import crypto from 'node:crypto';
|
|
4
|
-
import { create } from 'tar';
|
|
5
|
-
import ignore from 'ignore';
|
|
6
|
-
import { skillsJsonSchema } from '@tank/shared';
|
|
7
|
-
// Limits
|
|
8
|
-
const MAX_PACKAGE_SIZE = 50 * 1024 * 1024; // 50MB
|
|
9
|
-
const MAX_FILE_COUNT = 1000;
|
|
10
|
-
// Default ignore patterns (used when no .tankignore or .gitignore exists)
|
|
11
|
-
const DEFAULT_IGNORES = [
|
|
12
|
-
'node_modules',
|
|
13
|
-
'.git',
|
|
14
|
-
'.env*',
|
|
15
|
-
'*.log',
|
|
16
|
-
'.tank',
|
|
17
|
-
'.DS_Store',
|
|
18
|
-
];
|
|
19
|
-
// Always ignored regardless of ignore file contents
|
|
20
|
-
const ALWAYS_IGNORED = [
|
|
21
|
-
'node_modules',
|
|
22
|
-
'.git',
|
|
23
|
-
];
|
|
24
|
-
// Ignore file names (not packed into tarball)
|
|
25
|
-
const IGNORE_FILES = ['.tankignore', '.gitignore'];
|
|
26
|
-
/**
|
|
27
|
-
* Pack a skill directory into a .tgz tarball with integrity hashing.
|
|
28
|
-
*
|
|
29
|
-
* Validates:
|
|
30
|
-
* - skills.json exists and is valid
|
|
31
|
-
* - SKILL.md exists
|
|
32
|
-
* - No symlinks or hardlinks
|
|
33
|
-
* - No path traversal (.. components)
|
|
34
|
-
* - No absolute paths
|
|
35
|
-
* - File count <= 1000
|
|
36
|
-
* - Tarball size <= 50MB
|
|
37
|
-
*/
|
|
38
|
-
export async function pack(directory) {
|
|
39
|
-
const absDir = path.resolve(directory);
|
|
40
|
-
// 1. Verify directory exists
|
|
41
|
-
if (!fs.existsSync(absDir)) {
|
|
42
|
-
throw new Error(`Directory does not exist: ${absDir}`);
|
|
43
|
-
}
|
|
44
|
-
const stat = fs.statSync(absDir);
|
|
45
|
-
if (!stat.isDirectory()) {
|
|
46
|
-
throw new Error(`Not a directory: ${absDir}`);
|
|
47
|
-
}
|
|
48
|
-
// 2. Verify skills.json exists and is valid
|
|
49
|
-
const skillsJsonPath = path.join(absDir, 'skills.json');
|
|
50
|
-
if (!fs.existsSync(skillsJsonPath)) {
|
|
51
|
-
throw new Error('Missing required file: skills.json');
|
|
52
|
-
}
|
|
53
|
-
let skillsJsonContent;
|
|
54
|
-
try {
|
|
55
|
-
skillsJsonContent = fs.readFileSync(skillsJsonPath, 'utf-8');
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
throw new Error('Failed to read skills.json');
|
|
59
|
-
}
|
|
60
|
-
let parsed;
|
|
61
|
-
try {
|
|
62
|
-
parsed = JSON.parse(skillsJsonContent);
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
throw new Error('Invalid skills.json: not valid JSON');
|
|
66
|
-
}
|
|
67
|
-
const validation = skillsJsonSchema.safeParse(parsed);
|
|
68
|
-
if (!validation.success) {
|
|
69
|
-
const issues = validation.error.issues
|
|
70
|
-
.map((i) => ` - ${i.path.join('.')}: ${i.message}`)
|
|
71
|
-
.join('\n');
|
|
72
|
-
throw new Error(`Invalid skills.json:\n${issues}`);
|
|
73
|
-
}
|
|
74
|
-
// 3. Verify SKILL.md exists and read its content
|
|
75
|
-
const skillMdPath = path.join(absDir, 'SKILL.md');
|
|
76
|
-
if (!fs.existsSync(skillMdPath)) {
|
|
77
|
-
throw new Error('Missing required file: SKILL.md');
|
|
78
|
-
}
|
|
79
|
-
let readmeContent;
|
|
80
|
-
try {
|
|
81
|
-
readmeContent = fs.readFileSync(skillMdPath, 'utf-8');
|
|
82
|
-
}
|
|
83
|
-
catch {
|
|
84
|
-
throw new Error('Failed to read SKILL.md');
|
|
85
|
-
}
|
|
86
|
-
// 4. Build ignore filter
|
|
87
|
-
const ig = buildIgnoreFilter(absDir);
|
|
88
|
-
// 5. Collect files with validation
|
|
89
|
-
const files = collectFiles(absDir, absDir, ig);
|
|
90
|
-
// 6. Enforce file count limit
|
|
91
|
-
if (files.length > MAX_FILE_COUNT) {
|
|
92
|
-
throw new Error(`Too many files: ${files.length} exceeds maximum of ${MAX_FILE_COUNT}`);
|
|
93
|
-
}
|
|
94
|
-
// 7. Calculate total size of source files
|
|
95
|
-
let totalSize = 0;
|
|
96
|
-
for (const file of files) {
|
|
97
|
-
const filePath = path.join(absDir, file);
|
|
98
|
-
const fileStat = fs.statSync(filePath);
|
|
99
|
-
totalSize += fileStat.size;
|
|
100
|
-
}
|
|
101
|
-
// 8. Create tarball
|
|
102
|
-
const tarball = await createTarball(absDir, files);
|
|
103
|
-
// 9. Enforce tarball size limit
|
|
104
|
-
if (tarball.length > MAX_PACKAGE_SIZE) {
|
|
105
|
-
throw new Error(`Tarball too large: ${tarball.length} bytes exceeds maximum of ${MAX_PACKAGE_SIZE} bytes (50MB)`);
|
|
106
|
-
}
|
|
107
|
-
// 10. Compute integrity hash
|
|
108
|
-
const hash = crypto.createHash('sha512').update(tarball).digest('base64');
|
|
109
|
-
const integrity = `sha512-${hash}`;
|
|
110
|
-
return {
|
|
111
|
-
tarball,
|
|
112
|
-
integrity,
|
|
113
|
-
fileCount: files.length,
|
|
114
|
-
totalSize,
|
|
115
|
-
readme: readmeContent,
|
|
116
|
-
files,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Pack a directory into a .tgz tarball for security scanning.
|
|
121
|
-
*
|
|
122
|
-
* Unlike pack(), this function does NOT require skills.json or SKILL.md.
|
|
123
|
-
* It applies the same security checks (no symlinks, no path traversal, etc.)
|
|
124
|
-
* and returns the same PackResult interface.
|
|
125
|
-
*
|
|
126
|
-
* Validates:
|
|
127
|
-
* - Directory exists
|
|
128
|
-
* - No symlinks or hardlinks
|
|
129
|
-
* - No path traversal (.. components)
|
|
130
|
-
* - No absolute paths
|
|
131
|
-
* - File count <= 1000
|
|
132
|
-
* - Tarball size <= 50MB
|
|
133
|
-
*
|
|
134
|
-
* Does NOT validate:
|
|
135
|
-
* - skills.json existence or validity
|
|
136
|
-
* - SKILL.md existence (but reads it if present)
|
|
137
|
-
*/
|
|
138
|
-
export async function packForScan(directory) {
|
|
139
|
-
const absDir = path.resolve(directory);
|
|
140
|
-
// 1. Verify directory exists
|
|
141
|
-
if (!fs.existsSync(absDir)) {
|
|
142
|
-
throw new Error(`Directory does not exist: ${absDir}`);
|
|
143
|
-
}
|
|
144
|
-
const stat = fs.statSync(absDir);
|
|
145
|
-
if (!stat.isDirectory()) {
|
|
146
|
-
throw new Error(`Not a directory: ${absDir}`);
|
|
147
|
-
}
|
|
148
|
-
// 2. Try to read SKILL.md if it exists (optional for scan)
|
|
149
|
-
let readmeContent = '';
|
|
150
|
-
const skillMdPath = path.join(absDir, 'SKILL.md');
|
|
151
|
-
if (fs.existsSync(skillMdPath)) {
|
|
152
|
-
try {
|
|
153
|
-
readmeContent = fs.readFileSync(skillMdPath, 'utf-8');
|
|
154
|
-
}
|
|
155
|
-
catch {
|
|
156
|
-
// If we can't read it, just use empty string
|
|
157
|
-
readmeContent = '';
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
// 3. Build ignore filter
|
|
161
|
-
const ig = buildIgnoreFilter(absDir);
|
|
162
|
-
// 4. Collect files with validation
|
|
163
|
-
const files = collectFiles(absDir, absDir, ig);
|
|
164
|
-
// 5. Enforce file count limit
|
|
165
|
-
if (files.length > MAX_FILE_COUNT) {
|
|
166
|
-
throw new Error(`Too many files: ${files.length} exceeds maximum of ${MAX_FILE_COUNT}`);
|
|
167
|
-
}
|
|
168
|
-
// 6. Calculate total size of source files
|
|
169
|
-
let totalSize = 0;
|
|
170
|
-
for (const file of files) {
|
|
171
|
-
const filePath = path.join(absDir, file);
|
|
172
|
-
const fileStat = fs.statSync(filePath);
|
|
173
|
-
totalSize += fileStat.size;
|
|
174
|
-
}
|
|
175
|
-
// 7. Create tarball
|
|
176
|
-
const tarball = await createTarball(absDir, files);
|
|
177
|
-
// 8. Enforce tarball size limit
|
|
178
|
-
if (tarball.length > MAX_PACKAGE_SIZE) {
|
|
179
|
-
throw new Error(`Tarball too large: ${tarball.length} bytes exceeds maximum of ${MAX_PACKAGE_SIZE} bytes (50MB)`);
|
|
180
|
-
}
|
|
181
|
-
// 9. Compute integrity hash
|
|
182
|
-
const hash = crypto.createHash('sha512').update(tarball).digest('base64');
|
|
183
|
-
const integrity = `sha512-${hash}`;
|
|
184
|
-
return {
|
|
185
|
-
tarball,
|
|
186
|
-
integrity,
|
|
187
|
-
fileCount: files.length,
|
|
188
|
-
totalSize,
|
|
189
|
-
readme: readmeContent,
|
|
190
|
-
files,
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
/**
|
|
194
|
-
* Build an ignore filter from .tankignore, .gitignore, or defaults.
|
|
195
|
-
*/
|
|
196
|
-
function buildIgnoreFilter(dir) {
|
|
197
|
-
const ig = ignore();
|
|
198
|
-
// Always add the forced ignores
|
|
199
|
-
ig.add(ALWAYS_IGNORED);
|
|
200
|
-
// Check for .tankignore first, then .gitignore, then defaults
|
|
201
|
-
const tankIgnorePath = path.join(dir, '.tankignore');
|
|
202
|
-
const gitIgnorePath = path.join(dir, '.gitignore');
|
|
203
|
-
if (fs.existsSync(tankIgnorePath)) {
|
|
204
|
-
const content = fs.readFileSync(tankIgnorePath, 'utf-8');
|
|
205
|
-
ig.add(content);
|
|
206
|
-
// Also ignore the ignore files themselves
|
|
207
|
-
ig.add(IGNORE_FILES);
|
|
208
|
-
}
|
|
209
|
-
else if (fs.existsSync(gitIgnorePath)) {
|
|
210
|
-
const content = fs.readFileSync(gitIgnorePath, 'utf-8');
|
|
211
|
-
ig.add(content);
|
|
212
|
-
ig.add(IGNORE_FILES);
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
ig.add(DEFAULT_IGNORES);
|
|
216
|
-
}
|
|
217
|
-
return ig;
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Recursively collect files from a directory, applying ignore rules and security checks.
|
|
221
|
-
*/
|
|
222
|
-
function collectFiles(baseDir, currentDir, ig) {
|
|
223
|
-
const files = [];
|
|
224
|
-
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
225
|
-
for (const entry of entries) {
|
|
226
|
-
const fullPath = path.join(currentDir, entry.name);
|
|
227
|
-
const relativePath = path.relative(baseDir, fullPath);
|
|
228
|
-
// Security: check for path traversal
|
|
229
|
-
if (relativePath.split(path.sep).includes('..')) {
|
|
230
|
-
throw new Error(`Path traversal detected: "${relativePath}" contains ".." component`);
|
|
231
|
-
}
|
|
232
|
-
// Security: check for absolute paths
|
|
233
|
-
if (path.isAbsolute(relativePath)) {
|
|
234
|
-
throw new Error(`Absolute path detected: "${relativePath}"`);
|
|
235
|
-
}
|
|
236
|
-
// Security: check for symlinks using lstat (not stat which follows symlinks)
|
|
237
|
-
const lstatResult = fs.lstatSync(fullPath);
|
|
238
|
-
if (lstatResult.isSymbolicLink()) {
|
|
239
|
-
throw new Error(`Symlink detected: "${relativePath}" — symlinks are not allowed in skill packages`);
|
|
240
|
-
}
|
|
241
|
-
// Check if this path should be ignored
|
|
242
|
-
// For directories, append '/' so ignore patterns like 'dir/' work correctly
|
|
243
|
-
const pathForIgnore = lstatResult.isDirectory()
|
|
244
|
-
? relativePath + '/'
|
|
245
|
-
: relativePath;
|
|
246
|
-
if (ig.ignores(pathForIgnore)) {
|
|
247
|
-
continue;
|
|
248
|
-
}
|
|
249
|
-
if (lstatResult.isDirectory()) {
|
|
250
|
-
// Recurse into subdirectory
|
|
251
|
-
const subFiles = collectFiles(baseDir, fullPath, ig);
|
|
252
|
-
files.push(...subFiles);
|
|
253
|
-
}
|
|
254
|
-
else if (lstatResult.isFile()) {
|
|
255
|
-
files.push(relativePath);
|
|
256
|
-
}
|
|
257
|
-
// Skip other types (block devices, character devices, FIFOs, sockets)
|
|
258
|
-
}
|
|
259
|
-
return files;
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* Create a gzipped tarball from the given files in the directory.
|
|
263
|
-
*/
|
|
264
|
-
async function createTarball(cwd, files) {
|
|
265
|
-
return new Promise((resolve, reject) => {
|
|
266
|
-
const chunks = [];
|
|
267
|
-
// tar.create without `file` returns a readable stream
|
|
268
|
-
const stream = create({
|
|
269
|
-
gzip: true,
|
|
270
|
-
cwd,
|
|
271
|
-
portable: true, // Omit system-specific metadata
|
|
272
|
-
}, files);
|
|
273
|
-
stream.on('data', (chunk) => {
|
|
274
|
-
chunks.push(chunk);
|
|
275
|
-
});
|
|
276
|
-
stream.on('end', () => {
|
|
277
|
-
resolve(Buffer.concat(chunks));
|
|
278
|
-
});
|
|
279
|
-
stream.on('error', (err) => {
|
|
280
|
-
reject(err);
|
|
281
|
-
});
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
//# sourceMappingURL=packer.js.map
|
package/dist/lib/packer.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"packer.js","sourceRoot":"","sources":["../../src/lib/packer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,SAAS;AACT,MAAM,gBAAgB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO;AAClD,MAAM,cAAc,GAAG,IAAI,CAAC;AAE5B,0EAA0E;AAC1E,MAAM,eAAe,GAAG;IACtB,cAAc;IACd,MAAM;IACN,OAAO;IACP,OAAO;IACP,OAAO;IACP,WAAW;CACZ,CAAC;AAEF,oDAAoD;AACpD,MAAM,cAAc,GAAG;IACrB,cAAc;IACd,MAAM;CACP,CAAC;AAEF,8CAA8C;AAC9C,MAAM,YAAY,GAAG,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;AAWnD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,SAAiB;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEvC,6BAA6B;IAC7B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,6BAA6B,MAAM,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,4CAA4C;IAC5C,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,iBAAyB,CAAC;IAC9B,IAAI,CAAC;QACH,iBAAiB,GAAG,EAAE,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,UAAU,GAAG,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACtD,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM;aACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;aACnD,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,yBAAyB,MAAM,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,iDAAiD;IACjD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,aAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,aAAa,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IAED,yBAAyB;IACzB,MAAM,EAAE,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAErC,mCAAmC;IACnC,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IAE/C,8BAA8B;IAC9B,IAAI,KAAK,CAAC,MAAM,GAAG,cAAc,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CACb,mBAAmB,KAAK,CAAC,MAAM,uBAAuB,cAAc,EAAE,CACvE,CAAC;IACJ,CAAC;IAED,0CAA0C;IAC1C,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACvC,SAAS,IAAI,QAAQ,CAAC,IAAI,CAAC;IAC7B,CAAC;IAED,oBAAoB;IACpB,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAEnD,gCAAgC;IAChC,IAAI,OAAO,CAAC,MAAM,GAAG,gBAAgB,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CACb,sBAAsB,OAAO,CAAC,MAAM,6BAA6B,gBAAgB,eAAe,CACjG,CAAC;IACJ,CAAC;IAED,6BAA6B;IAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC1E,MAAM,SAAS,GAAG,UAAU,IAAI,EAAE,CAAC;IAEnC,OAAO;QACL,OAAO;QACP,SAAS;QACT,SAAS,EAAE,KAAK,CAAC,MAAM;QACvB,SAAS;QACT,MAAM,EAAE,aAAa;QACrB,KAAK;KACN,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,SAAiB;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEvC,6BAA6B;IAC7B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,6BAA6B,MAAM,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,2DAA2D;IAC3D,IAAI,aAAa,GAAG,EAAE,CAAC;IACvB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAClD,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,aAAa,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACxD,CAAC;QAAC,MAAM,CAAC;YACP,6CAA6C;YAC7C,aAAa,GAAG,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,MAAM,EAAE,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAErC,mCAAmC;IACnC,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IAE/C,8BAA8B;IAC9B,IAAI,KAAK,CAAC,MAAM,GAAG,cAAc,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CACb,mBAAmB,KAAK,CAAC,MAAM,uBAAuB,cAAc,EAAE,CACvE,CAAC;IACJ,CAAC;IAED,0CAA0C;IAC1C,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACvC,SAAS,IAAI,QAAQ,CAAC,IAAI,CAAC;IAC7B,CAAC;IAED,oBAAoB;IACpB,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAEnD,gCAAgC;IAChC,IAAI,OAAO,CAAC,MAAM,GAAG,gBAAgB,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CACb,sBAAsB,OAAO,CAAC,MAAM,6BAA6B,gBAAgB,eAAe,CACjG,CAAC;IACJ,CAAC;IAED,4BAA4B;IAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC1E,MAAM,SAAS,GAAG,UAAU,IAAI,EAAE,CAAC;IAEnC,OAAO;QACL,OAAO;QACP,SAAS;QACT,SAAS,EAAE,KAAK,CAAC,MAAM;QACvB,SAAS;QACT,MAAM,EAAE,aAAa;QACrB,KAAK;KACN,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,GAAW;IACpC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IAEpB,gCAAgC;IAChC,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAEvB,8DAA8D;IAC9D,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IACrD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAEnD,IAAI,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACzD,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAChB,0CAA0C;QAC1C,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACvB,CAAC;SAAM,IAAI,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACxC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QACxD,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAChB,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACvB,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CACnB,OAAe,EACf,UAAkB,EAClB,EAA6B;IAE7B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAEtD,qCAAqC;QACrC,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CACb,6BAA6B,YAAY,2BAA2B,CACrE,CAAC;QACJ,CAAC;QAED,qCAAqC;QACrC,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,4BAA4B,YAAY,GAAG,CAAC,CAAC;QAC/D,CAAC;QAED,6EAA6E;QAC7E,MAAM,WAAW,GAAG,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAI,WAAW,CAAC,cAAc,EAAE,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CACb,sBAAsB,YAAY,gDAAgD,CACnF,CAAC;QACJ,CAAC;QAED,uCAAuC;QACvC,4EAA4E;QAC5E,MAAM,aAAa,GAAG,WAAW,CAAC,WAAW,EAAE;YAC7C,CAAC,CAAC,YAAY,GAAG,GAAG;YACpB,CAAC,CAAC,YAAY,CAAC;QAEjB,IAAI,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;YAC9B,SAAS;QACX,CAAC;QAED,IAAI,WAAW,CAAC,WAAW,EAAE,EAAE,CAAC;YAC9B,4BAA4B;YAC5B,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;YACrD,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;QAC1B,CAAC;aAAM,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3B,CAAC;QACD,sEAAsE;IACxE,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,aAAa,CAC1B,GAAW,EACX,KAAe;IAEf,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC7C,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,sDAAsD;QACtD,MAAM,MAAM,GAAG,MAAM,CACnB;YACE,IAAI,EAAE,IAAI;YACV,GAAG;YACH,QAAQ,EAAE,IAAI,EAAE,gCAAgC;SACjD,EACD,KAAK,CACiB,CAAC;QAEzB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAClC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACpB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YAChC,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { Permissions } from '@tank/shared';
|
|
2
|
-
/**
|
|
3
|
-
* Check if a skill's permissions fit within the project's permission budget.
|
|
4
|
-
* Throws if any permission exceeds the budget.
|
|
5
|
-
*/
|
|
6
|
-
export declare function checkPermissionBudget(budget: Permissions, skillPerms: Permissions | undefined, skillName: string): void;
|
|
7
|
-
/**
|
|
8
|
-
* Check if a domain is allowed by the budget's domain list.
|
|
9
|
-
* Supports wildcard matching: *.example.com matches sub.example.com
|
|
10
|
-
*/
|
|
11
|
-
export declare function isDomainAllowed(domain: string, allowedDomains: string[]): boolean;
|
|
12
|
-
/**
|
|
13
|
-
* Check if a path is allowed by the budget's path list.
|
|
14
|
-
* Simple subset check: skill path must match one of the budget paths.
|
|
15
|
-
*/
|
|
16
|
-
export declare function isPathAllowed(requestedPath: string, allowedPaths: string[]): boolean;
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Check if a skill's permissions fit within the project's permission budget.
|
|
3
|
-
* Throws if any permission exceeds the budget.
|
|
4
|
-
*/
|
|
5
|
-
export function checkPermissionBudget(budget, skillPerms, skillName) {
|
|
6
|
-
if (!skillPerms)
|
|
7
|
-
return;
|
|
8
|
-
// Check subprocess
|
|
9
|
-
if (skillPerms.subprocess === true && budget.subprocess !== true) {
|
|
10
|
-
throw new Error(`Permission denied: ${skillName} requires subprocess access, but project budget does not allow it`);
|
|
11
|
-
}
|
|
12
|
-
// Check network outbound
|
|
13
|
-
if (skillPerms.network?.outbound && skillPerms.network.outbound.length > 0) {
|
|
14
|
-
const budgetDomains = budget.network?.outbound ?? [];
|
|
15
|
-
for (const domain of skillPerms.network.outbound) {
|
|
16
|
-
if (!isDomainAllowed(domain, budgetDomains)) {
|
|
17
|
-
throw new Error(`Permission denied: ${skillName} requests network access to "${domain}", which is not in the project's permission budget`);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
// Check filesystem read
|
|
22
|
-
if (skillPerms.filesystem?.read && skillPerms.filesystem.read.length > 0) {
|
|
23
|
-
const budgetPaths = budget.filesystem?.read ?? [];
|
|
24
|
-
for (const p of skillPerms.filesystem.read) {
|
|
25
|
-
if (!isPathAllowed(p, budgetPaths)) {
|
|
26
|
-
throw new Error(`Permission denied: ${skillName} requests filesystem read access to "${p}", which is not in the project's permission budget`);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
// Check filesystem write
|
|
31
|
-
if (skillPerms.filesystem?.write && skillPerms.filesystem.write.length > 0) {
|
|
32
|
-
const budgetPaths = budget.filesystem?.write ?? [];
|
|
33
|
-
for (const p of skillPerms.filesystem.write) {
|
|
34
|
-
if (!isPathAllowed(p, budgetPaths)) {
|
|
35
|
-
throw new Error(`Permission denied: ${skillName} requests filesystem write access to "${p}", which is not in the project's permission budget`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Check if a domain is allowed by the budget's domain list.
|
|
42
|
-
* Supports wildcard matching: *.example.com matches sub.example.com
|
|
43
|
-
*/
|
|
44
|
-
export function isDomainAllowed(domain, allowedDomains) {
|
|
45
|
-
for (const allowed of allowedDomains) {
|
|
46
|
-
if (allowed === domain)
|
|
47
|
-
return true;
|
|
48
|
-
// Wildcard matching: *.example.com
|
|
49
|
-
if (allowed.startsWith('*.')) {
|
|
50
|
-
const suffix = allowed.slice(1); // .example.com
|
|
51
|
-
if (domain.endsWith(suffix) || domain === allowed.slice(2)) {
|
|
52
|
-
return true;
|
|
53
|
-
}
|
|
54
|
-
// Also match if the skill requests the same wildcard pattern
|
|
55
|
-
if (domain === allowed)
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Check if a path is allowed by the budget's path list.
|
|
63
|
-
* Simple subset check: skill path must match one of the budget paths.
|
|
64
|
-
*/
|
|
65
|
-
export function isPathAllowed(requestedPath, allowedPaths) {
|
|
66
|
-
for (const allowed of allowedPaths) {
|
|
67
|
-
if (allowed === requestedPath)
|
|
68
|
-
return true;
|
|
69
|
-
// If budget allows ./src/** and skill requests ./src/foo, it's allowed
|
|
70
|
-
if (allowed.endsWith('/**')) {
|
|
71
|
-
const prefix = allowed.slice(0, -3); // ./src
|
|
72
|
-
if (requestedPath.startsWith(prefix))
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return false;
|
|
77
|
-
}
|
|
78
|
-
//# sourceMappingURL=permission-checker.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"permission-checker.js","sourceRoot":"","sources":["../../src/lib/permission-checker.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAmB,EACnB,UAAmC,EACnC,SAAiB;IAEjB,IAAI,CAAC,UAAU;QAAE,OAAO;IAExB,mBAAmB;IACnB,IAAI,UAAU,CAAC,UAAU,KAAK,IAAI,IAAI,MAAM,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CACb,sBAAsB,SAAS,mEAAmE,CACnG,CAAC;IACJ,CAAC;IAED,yBAAyB;IACzB,IAAI,UAAU,CAAC,OAAO,EAAE,QAAQ,IAAI,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3E,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,EAAE,QAAQ,IAAI,EAAE,CAAC;QACrD,KAAK,MAAM,MAAM,IAAI,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YACjD,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,CAAC;gBAC5C,MAAM,IAAI,KAAK,CACb,sBAAsB,SAAS,gCAAgC,MAAM,oDAAoD,CAC1H,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,wBAAwB;IACxB,IAAI,UAAU,CAAC,UAAU,EAAE,IAAI,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzE,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC;QAClD,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;YAC3C,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CACb,sBAAsB,SAAS,wCAAwC,CAAC,oDAAoD,CAC7H,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,IAAI,UAAU,CAAC,UAAU,EAAE,KAAK,IAAI,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3E,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC;QACnD,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YAC5C,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CACb,sBAAsB,SAAS,yCAAyC,CAAC,oDAAoD,CAC9H,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,cAAwB;IACtE,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;QACrC,IAAI,OAAO,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QACpC,mCAAmC;QACnC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe;YAChD,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3D,OAAO,IAAI,CAAC;YACd,CAAC;YACD,6DAA6D;YAC7D,IAAI,MAAM,KAAK,OAAO;gBAAE,OAAO,IAAI,CAAC;QACtC,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,aAAqB,EAAE,YAAsB;IACzE,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;QACnC,IAAI,OAAO,KAAK,aAAa;YAAE,OAAO,IAAI,CAAC;QAC3C,uEAAuE;QACvE,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ;YAC7C,IAAI,aAAa,CAAC,UAAU,CAAC,MAAM,CAAC;gBAAE,OAAO,IAAI,CAAC;QACpD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function checkForUpgrade(configDir?: string): Promise<void>;
|