openkitt 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +236 -0
- package/dist/ast/engine.d.ts +26 -0
- package/dist/ast/engine.js +130 -0
- package/dist/ast/engine.js.map +1 -0
- package/dist/ast/operations.d.ts +13 -0
- package/dist/ast/operations.js +329 -0
- package/dist/ast/operations.js.map +1 -0
- package/dist/ast/validator.d.ts +19 -0
- package/dist/ast/validator.js +281 -0
- package/dist/ast/validator.js.map +1 -0
- package/dist/audit/logger.d.ts +14 -0
- package/dist/audit/logger.js +102 -0
- package/dist/audit/logger.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +401 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/create-confirm.d.ts +13 -0
- package/dist/commands/create-confirm.js +38 -0
- package/dist/commands/create-confirm.js.map +1 -0
- package/dist/commands/create-infra.d.ts +20 -0
- package/dist/commands/create-infra.js +63 -0
- package/dist/commands/create-infra.js.map +1 -0
- package/dist/commands/create-manifest.d.ts +10 -0
- package/dist/commands/create-manifest.js +21 -0
- package/dist/commands/create-manifest.js.map +1 -0
- package/dist/commands/create-packages.d.ts +17 -0
- package/dist/commands/create-packages.js +69 -0
- package/dist/commands/create-packages.js.map +1 -0
- package/dist/commands/create-pipeline.d.ts +15 -0
- package/dist/commands/create-pipeline.js +57 -0
- package/dist/commands/create-pipeline.js.map +1 -0
- package/dist/commands/create-scaffolding.d.ts +12 -0
- package/dist/commands/create-scaffolding.js +137 -0
- package/dist/commands/create-scaffolding.js.map +1 -0
- package/dist/commands/create-staging.d.ts +13 -0
- package/dist/commands/create-staging.js +17 -0
- package/dist/commands/create-staging.js.map +1 -0
- package/dist/commands/create-transforms.d.ts +10 -0
- package/dist/commands/create-transforms.js +33 -0
- package/dist/commands/create-transforms.js.map +1 -0
- package/dist/commands/create.d.ts +2 -0
- package/dist/commands/create.js +155 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/delete.d.ts +2 -0
- package/dist/commands/delete.js +83 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/deploy.d.ts +5 -0
- package/dist/commands/deploy.js +371 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/domain.d.ts +2 -0
- package/dist/commands/domain.js +90 -0
- package/dist/commands/domain.js.map +1 -0
- package/dist/commands/env.d.ts +2 -0
- package/dist/commands/env.js +153 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/help.d.ts +3 -0
- package/dist/commands/help.js +107 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +217 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/list.js +142 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +235 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logs.d.ts +2 -0
- package/dist/commands/logs.js +90 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/publish.d.ts +2 -0
- package/dist/commands/publish.js +113 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/run.d.ts +14 -0
- package/dist/commands/run.js +196 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/settings.d.ts +3 -0
- package/dist/commands/settings.js +278 -0
- package/dist/commands/settings.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +88 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/versions.d.ts +2 -0
- package/dist/commands/versions.js +242 -0
- package/dist/commands/versions.js.map +1 -0
- package/dist/credentials/config.d.ts +12 -0
- package/dist/credentials/config.js +196 -0
- package/dist/credentials/config.js.map +1 -0
- package/dist/credentials/encryption.d.ts +9 -0
- package/dist/credentials/encryption.js +100 -0
- package/dist/credentials/encryption.js.map +1 -0
- package/dist/credentials/keychain.d.ts +8 -0
- package/dist/credentials/keychain.js +236 -0
- package/dist/credentials/keychain.js.map +1 -0
- package/dist/credentials/railway.d.ts +9 -0
- package/dist/credentials/railway.js +69 -0
- package/dist/credentials/railway.js.map +1 -0
- package/dist/llm/client.d.ts +59 -0
- package/dist/llm/client.js +530 -0
- package/dist/llm/client.js.map +1 -0
- package/dist/llm/operations.d.ts +39 -0
- package/dist/llm/operations.js +131 -0
- package/dist/llm/operations.js.map +1 -0
- package/dist/llm/rate-limiter.d.ts +20 -0
- package/dist/llm/rate-limiter.js +57 -0
- package/dist/llm/rate-limiter.js.map +1 -0
- package/dist/llm/scaffolding.d.ts +51 -0
- package/dist/llm/scaffolding.js +118 -0
- package/dist/llm/scaffolding.js.map +1 -0
- package/dist/manifest/drift.d.ts +6 -0
- package/dist/manifest/drift.js +45 -0
- package/dist/manifest/drift.js.map +1 -0
- package/dist/manifest/reader.d.ts +12 -0
- package/dist/manifest/reader.js +99 -0
- package/dist/manifest/reader.js.map +1 -0
- package/dist/manifest/types.d.ts +31 -0
- package/dist/manifest/types.js +2 -0
- package/dist/manifest/types.js.map +1 -0
- package/dist/manifest/writer.d.ts +9 -0
- package/dist/manifest/writer.js +142 -0
- package/dist/manifest/writer.js.map +1 -0
- package/dist/mcp/client.d.ts +21 -0
- package/dist/mcp/client.js +213 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/lifecycle.d.ts +12 -0
- package/dist/mcp/lifecycle.js +149 -0
- package/dist/mcp/lifecycle.js.map +1 -0
- package/dist/mcp/project-guard.d.ts +14 -0
- package/dist/mcp/project-guard.js +27 -0
- package/dist/mcp/project-guard.js.map +1 -0
- package/dist/prompts/operations.d.ts +1 -0
- package/dist/prompts/operations.js +160 -0
- package/dist/prompts/operations.js.map +1 -0
- package/dist/prompts/scaffolding.d.ts +1 -0
- package/dist/prompts/scaffolding.js +331 -0
- package/dist/prompts/scaffolding.js.map +1 -0
- package/dist/prompts/version.d.ts +2 -0
- package/dist/prompts/version.js +3 -0
- package/dist/prompts/version.js.map +1 -0
- package/dist/sandbox/command-allowlist.d.ts +6 -0
- package/dist/sandbox/command-allowlist.js +103 -0
- package/dist/sandbox/command-allowlist.js.map +1 -0
- package/dist/sandbox/package-allowlist.d.ts +6 -0
- package/dist/sandbox/package-allowlist.js +49 -0
- package/dist/sandbox/package-allowlist.js.map +1 -0
- package/dist/sandbox/scanner.d.ts +25 -0
- package/dist/sandbox/scanner.js +196 -0
- package/dist/sandbox/scanner.js.map +1 -0
- package/dist/sandbox/staging.d.ts +12 -0
- package/dist/sandbox/staging.js +107 -0
- package/dist/sandbox/staging.js.map +1 -0
- package/dist/scaffold/frameworks/express.d.ts +3 -0
- package/dist/scaffold/frameworks/express.js +242 -0
- package/dist/scaffold/frameworks/express.js.map +1 -0
- package/dist/scaffold/frameworks/hono.d.ts +3 -0
- package/dist/scaffold/frameworks/hono.js +238 -0
- package/dist/scaffold/frameworks/hono.js.map +1 -0
- package/dist/scaffold/frameworks/nextjs.d.ts +3 -0
- package/dist/scaffold/frameworks/nextjs.js +447 -0
- package/dist/scaffold/frameworks/nextjs.js.map +1 -0
- package/dist/scaffold/frameworks/tanstack-start.d.ts +3 -0
- package/dist/scaffold/frameworks/tanstack-start.js +280 -0
- package/dist/scaffold/frameworks/tanstack-start.js.map +1 -0
- package/dist/scaffold/index.d.ts +4 -0
- package/dist/scaffold/index.js +138 -0
- package/dist/scaffold/index.js.map +1 -0
- package/dist/scaffold/integrations/backend.d.ts +3 -0
- package/dist/scaffold/integrations/backend.js +403 -0
- package/dist/scaffold/integrations/backend.js.map +1 -0
- package/dist/scaffold/integrations/posthog.d.ts +2 -0
- package/dist/scaffold/integrations/posthog.js +21 -0
- package/dist/scaffold/integrations/posthog.js.map +1 -0
- package/dist/scaffold/integrations/sentry.d.ts +2 -0
- package/dist/scaffold/integrations/sentry.js +16 -0
- package/dist/scaffold/integrations/sentry.js.map +1 -0
- package/dist/scaffold/integrations/storybook.d.ts +2 -0
- package/dist/scaffold/integrations/storybook.js +79 -0
- package/dist/scaffold/integrations/storybook.js.map +1 -0
- package/dist/scaffold/integrations/vitest.d.ts +2 -0
- package/dist/scaffold/integrations/vitest.js +37 -0
- package/dist/scaffold/integrations/vitest.js.map +1 -0
- package/dist/scaffold/package-builder.d.ts +3 -0
- package/dist/scaffold/package-builder.js +136 -0
- package/dist/scaffold/package-builder.js.map +1 -0
- package/dist/scaffold/packages.d.ts +4 -0
- package/dist/scaffold/packages.js +144 -0
- package/dist/scaffold/packages.js.map +1 -0
- package/dist/scaffold/types.d.ts +20 -0
- package/dist/scaffold/types.js +2 -0
- package/dist/scaffold/types.js.map +1 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/auth-guard.d.ts +5 -0
- package/dist/utils/auth-guard.js +52 -0
- package/dist/utils/auth-guard.js.map +1 -0
- package/dist/utils/cleanup.d.ts +2 -0
- package/dist/utils/cleanup.js +37 -0
- package/dist/utils/cleanup.js.map +1 -0
- package/dist/utils/constraints.d.ts +11 -0
- package/dist/utils/constraints.js +162 -0
- package/dist/utils/constraints.js.map +1 -0
- package/dist/utils/display.d.ts +32 -0
- package/dist/utils/display.js +103 -0
- package/dist/utils/display.js.map +1 -0
- package/dist/utils/global-config.d.ts +8 -0
- package/dist/utils/global-config.js +39 -0
- package/dist/utils/global-config.js.map +1 -0
- package/dist/utils/pm.d.ts +4 -0
- package/dist/utils/pm.js +40 -0
- package/dist/utils/pm.js.map +1 -0
- package/dist/utils/prerequisites.d.ts +9 -0
- package/dist/utils/prerequisites.js +96 -0
- package/dist/utils/prerequisites.js.map +1 -0
- package/dist/utils/prompts.d.ts +25 -0
- package/dist/utils/prompts.js +148 -0
- package/dist/utils/prompts.js.map +1 -0
- package/dist/utils/validation.d.ts +9 -0
- package/dist/utils/validation.js +38 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/versions/compat.d.ts +13 -0
- package/dist/versions/compat.js +127 -0
- package/dist/versions/compat.js.map +1 -0
- package/dist/versions/integrity.d.ts +9 -0
- package/dist/versions/integrity.js +60 -0
- package/dist/versions/integrity.js.map +1 -0
- package/dist/versions/parser.d.ts +13 -0
- package/dist/versions/parser.js +106 -0
- package/dist/versions/parser.js.map +1 -0
- package/dist/versions/registry.d.ts +30 -0
- package/dist/versions/registry.js +165 -0
- package/dist/versions/registry.js.map +1 -0
- package/package.json +58 -0
- package/scripts/publish.sh +254 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { createAuditLogger } from '../audit/logger.js';
|
|
2
|
+
import { getCommand } from '../utils/pm.js';
|
|
3
|
+
const auditLogger = createAuditLogger('.');
|
|
4
|
+
const SEMVER_PATTERN = String.raw `\d+\.\d+\.\d+`;
|
|
5
|
+
const PATH_PATTERN = String.raw `[A-Za-z0-9._/-]+`;
|
|
6
|
+
const PACKAGE_PATTERN = String.raw `(?:@[a-z0-9][a-z0-9-]*/)?[a-z0-9][a-z0-9._-]*`;
|
|
7
|
+
const COMPONENT_PATTERN = String.raw `[a-z0-9-]+`;
|
|
8
|
+
const APPROVED_PACKAGES = new Set([
|
|
9
|
+
'tailwindcss',
|
|
10
|
+
'@tailwindcss/vite',
|
|
11
|
+
'@tailwindcss/postcss',
|
|
12
|
+
'shadcn',
|
|
13
|
+
'storybook',
|
|
14
|
+
'@storybook/react-vite',
|
|
15
|
+
'@storybook/addon-essentials',
|
|
16
|
+
'drizzle-orm',
|
|
17
|
+
'drizzle-kit',
|
|
18
|
+
'prisma',
|
|
19
|
+
'@prisma/client',
|
|
20
|
+
'pg',
|
|
21
|
+
'@types/pg',
|
|
22
|
+
'postgres',
|
|
23
|
+
'mysql2',
|
|
24
|
+
'better-sqlite3',
|
|
25
|
+
'@types/better-sqlite3',
|
|
26
|
+
'ioredis',
|
|
27
|
+
'@types/ioredis',
|
|
28
|
+
'better-auth',
|
|
29
|
+
'stripe',
|
|
30
|
+
'@stripe/stripe-js',
|
|
31
|
+
'@polar-sh/sdk',
|
|
32
|
+
'resend',
|
|
33
|
+
'bullmq',
|
|
34
|
+
'@trigger.dev/sdk',
|
|
35
|
+
'@trigger.dev/react',
|
|
36
|
+
'posthog-js',
|
|
37
|
+
'posthog-node',
|
|
38
|
+
'@sentry/node',
|
|
39
|
+
'@sentry/react',
|
|
40
|
+
'@sentry/nextjs',
|
|
41
|
+
'@sentry/vite-plugin',
|
|
42
|
+
'vitest',
|
|
43
|
+
'@testing-library/react',
|
|
44
|
+
'@testing-library/jest-dom',
|
|
45
|
+
'@playwright/test',
|
|
46
|
+
'@tanstack/react-start',
|
|
47
|
+
'@tanstack/react-router',
|
|
48
|
+
'@tanstack/router-plugin',
|
|
49
|
+
'@tanstack/react-query',
|
|
50
|
+
'react',
|
|
51
|
+
'react-dom',
|
|
52
|
+
'@types/react',
|
|
53
|
+
'@types/react-dom',
|
|
54
|
+
'typescript',
|
|
55
|
+
'vite',
|
|
56
|
+
'vite-tsconfig-paths',
|
|
57
|
+
'@vitejs/plugin-react',
|
|
58
|
+
'next',
|
|
59
|
+
'express',
|
|
60
|
+
'@types/express',
|
|
61
|
+
'hono',
|
|
62
|
+
]);
|
|
63
|
+
function escapeRegex(value) {
|
|
64
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, String.raw `\$&`);
|
|
65
|
+
}
|
|
66
|
+
function blocked(command, reason) {
|
|
67
|
+
auditLogger.security('BLOCKED', `command: "${command}" (source: LLM)`);
|
|
68
|
+
return {
|
|
69
|
+
allowed: false,
|
|
70
|
+
reason,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export function validateCommand(command, packageManager) {
|
|
74
|
+
const executePrefix = escapeRegex(getCommand(packageManager, 'execute'));
|
|
75
|
+
const removePrefix = escapeRegex(getCommand(packageManager, 'remove'));
|
|
76
|
+
const packageWithVersion = `(${PACKAGE_PATTERN})@(${SEMVER_PATTERN})`;
|
|
77
|
+
const commandPatterns = [
|
|
78
|
+
new RegExp(`^${executePrefix} create-next-app@${SEMVER_PATTERN} ${PATH_PATTERN} --typescript$`),
|
|
79
|
+
new RegExp(`^${executePrefix} @tanstack/cli@${SEMVER_PATTERN} create ${PATH_PATTERN}(?: --framework [A-Za-z]+)?(?: --no-install)?(?: --no-examples)?(?: --package-manager ${PACKAGE_PATTERN})?(?: --deployment ${COMPONENT_PATTERN})?(?: --toolchain ${COMPONENT_PATTERN})?$`),
|
|
80
|
+
new RegExp(`^${removePrefix} ${PACKAGE_PATTERN}$`),
|
|
81
|
+
new RegExp(`^${executePrefix} shadcn@${SEMVER_PATTERN} init(?: --yes)?(?: --base-color [a-z]+)?(?: --cwd ${PATH_PATTERN})?$`),
|
|
82
|
+
new RegExp(`^${executePrefix} shadcn@${SEMVER_PATTERN} add ${COMPONENT_PATTERN}$`),
|
|
83
|
+
new RegExp(`^${executePrefix} storybook@${SEMVER_PATTERN} init$`),
|
|
84
|
+
new RegExp(`^${executePrefix} prisma init$`),
|
|
85
|
+
new RegExp(`^${executePrefix} prisma generate$`),
|
|
86
|
+
new RegExp(`^${executePrefix} drizzle-kit generate$`),
|
|
87
|
+
new RegExp(`^${executePrefix} playwright install$`),
|
|
88
|
+
];
|
|
89
|
+
const cdMatch = /^cd ([A-Za-z0-9._\/-]+) && (.+)$/.exec(command);
|
|
90
|
+
const bare = cdMatch ? cdMatch[2] : command;
|
|
91
|
+
const addPrefix = escapeRegex(getCommand(packageManager, 'add'));
|
|
92
|
+
const devFlag = String.raw `(?:(?:-D|-d|--dev|--save-dev) )?`;
|
|
93
|
+
const addRegex = new RegExp(`^${addPrefix} ${devFlag}${packageWithVersion}( ${packageWithVersion})*$`);
|
|
94
|
+
if (addRegex.test(bare)) {
|
|
95
|
+
return blocked(command, 'bun add commands are not allowed — all dependencies must be declared in package.json');
|
|
96
|
+
}
|
|
97
|
+
const allowed = commandPatterns.some((pattern) => pattern.test(bare));
|
|
98
|
+
if (allowed) {
|
|
99
|
+
return { allowed: true };
|
|
100
|
+
}
|
|
101
|
+
return blocked(command, 'Command does not match any allowed pattern');
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=command-allowlist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-allowlist.js","sourceRoot":"","sources":["../../src/sandbox/command-allowlist.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const INTEGRATION_PACKAGE_MAP: ReadonlyMap<string, readonly string[]>;
|
|
2
|
+
export declare const APPROVED_PACKAGES: ReadonlySet<string>;
|
|
3
|
+
export declare function isApprovedPackage(packageName: string): boolean;
|
|
4
|
+
export declare function getPackagesForIntegration(integration: string): string[];
|
|
5
|
+
export declare function isApprovedIntegration(integration: string): boolean;
|
|
6
|
+
export declare function getAllApprovedPackages(): string[];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export const INTEGRATION_PACKAGE_MAP = new Map([
|
|
2
|
+
["TailwindCSS v4", ["tailwindcss", "@tailwindcss/vite", "@tailwindcss/postcss"]],
|
|
3
|
+
["shadcn/ui", ["shadcn"]],
|
|
4
|
+
["Storybook", ["storybook", "@storybook/react-vite", "@storybook/addon-essentials"]],
|
|
5
|
+
["Drizzle", ["drizzle-orm", "drizzle-kit"]],
|
|
6
|
+
["Prisma", ["prisma", "@prisma/client"]],
|
|
7
|
+
["PostgreSQL", ["pg", "@types/pg", "postgres"]],
|
|
8
|
+
["MySQL", ["mysql2"]],
|
|
9
|
+
["SQLite", ["better-sqlite3", "@types/better-sqlite3"]],
|
|
10
|
+
["Redis", ["ioredis", "@types/ioredis"]],
|
|
11
|
+
["Better Auth", ["better-auth"]],
|
|
12
|
+
["Stripe", ["stripe", "@stripe/stripe-js"]],
|
|
13
|
+
["Polar", ["@polar-sh/sdk"]],
|
|
14
|
+
["Resend", ["resend"]],
|
|
15
|
+
["BullMQ", ["bullmq"]],
|
|
16
|
+
["Trigger.dev", ["@trigger.dev/sdk", "@trigger.dev/react"]],
|
|
17
|
+
["PostHog", ["posthog-js", "posthog-node"]],
|
|
18
|
+
["Sentry", ["@sentry/node", "@sentry/react", "@sentry/nextjs", "@sentry/vite-plugin"]],
|
|
19
|
+
["Vitest", ["vitest", "@testing-library/react", "@testing-library/jest-dom"]],
|
|
20
|
+
["Playwright", ["@playwright/test"]],
|
|
21
|
+
["TanStack Start", ["@tanstack/react-start", "@tanstack/react-router", "@tanstack/router-plugin", "react", "react-dom", "@types/react", "@types/react-dom", "typescript", "vite", "vite-tsconfig-paths", "@vitejs/plugin-react"]],
|
|
22
|
+
["TanStack Query", ["@tanstack/react-query"]],
|
|
23
|
+
["Next.js", ["next", "react", "react-dom", "@types/react", "@types/react-dom"]],
|
|
24
|
+
["Express.js", ["express", "@types/express"]],
|
|
25
|
+
["Hono", ["hono"]],
|
|
26
|
+
]);
|
|
27
|
+
export const APPROVED_PACKAGES = new Set(Array.from(INTEGRATION_PACKAGE_MAP.values()).flat());
|
|
28
|
+
function stripVersionSuffix(packageName) {
|
|
29
|
+
const versionSeparatorIndex = packageName.startsWith("@")
|
|
30
|
+
? packageName.indexOf("@", 1)
|
|
31
|
+
: packageName.indexOf("@");
|
|
32
|
+
return versionSeparatorIndex === -1
|
|
33
|
+
? packageName
|
|
34
|
+
: packageName.slice(0, versionSeparatorIndex);
|
|
35
|
+
}
|
|
36
|
+
export function isApprovedPackage(packageName) {
|
|
37
|
+
return APPROVED_PACKAGES.has(stripVersionSuffix(packageName));
|
|
38
|
+
}
|
|
39
|
+
export function getPackagesForIntegration(integration) {
|
|
40
|
+
const packages = INTEGRATION_PACKAGE_MAP.get(integration);
|
|
41
|
+
return packages ? [...packages] : [];
|
|
42
|
+
}
|
|
43
|
+
export function isApprovedIntegration(integration) {
|
|
44
|
+
return INTEGRATION_PACKAGE_MAP.has(integration);
|
|
45
|
+
}
|
|
46
|
+
export function getAllApprovedPackages() {
|
|
47
|
+
return [...APPROVED_PACKAGES].sort((a, b) => a.localeCompare(b));
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=package-allowlist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-allowlist.js","sourceRoot":"","sources":["../../src/sandbox/package-allowlist.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface ScanResult {
|
|
2
|
+
safe: boolean;
|
|
3
|
+
warnings: ScanWarning[];
|
|
4
|
+
}
|
|
5
|
+
export interface ScanWarning {
|
|
6
|
+
type: 'suspicious_pattern' | 'invalid_file_type' | 'path_traversal';
|
|
7
|
+
filePath: string;
|
|
8
|
+
detail: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function scanFileContent(filePath: string, content: string): ScanWarning[];
|
|
11
|
+
export declare function validateFilePath(filePath: string): ScanWarning[];
|
|
12
|
+
export declare function validateFileType(filePath: string): ScanWarning[];
|
|
13
|
+
export declare function scanStagedFiles(workspaceDir: string): ScanResult;
|
|
14
|
+
export interface SecretScanResult {
|
|
15
|
+
safe: boolean;
|
|
16
|
+
findings: SecretFinding[];
|
|
17
|
+
}
|
|
18
|
+
export interface SecretFinding {
|
|
19
|
+
filePath: string;
|
|
20
|
+
variableName: string;
|
|
21
|
+
}
|
|
22
|
+
export declare const SECRET_PATTERNS: readonly string[];
|
|
23
|
+
export declare function isSecretVariable(variableName: string): boolean;
|
|
24
|
+
export declare function maskSecretValue(value: string): string;
|
|
25
|
+
export declare function scanForSecrets(workspaceDir: string, filePaths: string[]): SecretScanResult;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { existsSync, lstatSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { extname, isAbsolute, join, normalize, resolve } from 'node:path';
|
|
3
|
+
import { createAuditLogger } from '../audit/logger.js';
|
|
4
|
+
import { listStagedFiles } from './staging.js';
|
|
5
|
+
const ALLOWED_EXTENSIONS = new Set([
|
|
6
|
+
'.ts',
|
|
7
|
+
'.tsx',
|
|
8
|
+
'.js',
|
|
9
|
+
'.mjs',
|
|
10
|
+
'.cjs',
|
|
11
|
+
'.jsx',
|
|
12
|
+
'.json',
|
|
13
|
+
'.css',
|
|
14
|
+
'.md',
|
|
15
|
+
'.toml',
|
|
16
|
+
'.prisma',
|
|
17
|
+
'.sql',
|
|
18
|
+
'.html',
|
|
19
|
+
]);
|
|
20
|
+
const SUSPICIOUS_CONTENT_PATTERNS = [
|
|
21
|
+
{ pattern: /\beval\s*\(/, detail: "Found 'eval(' - dynamic code execution is not allowed" },
|
|
22
|
+
{ pattern: /\bexec\s*\(/, detail: "Found 'exec(' - command execution is not allowed" },
|
|
23
|
+
{ pattern: /\bchild_process\b/, detail: "Found 'child_process' - process spawning module usage is not allowed" },
|
|
24
|
+
{ pattern: /\bspawn\s*\(/, detail: "Found 'spawn(' - process spawning is not allowed" },
|
|
25
|
+
{
|
|
26
|
+
pattern: /require\(\s*['"]http['"]\s*\)/,
|
|
27
|
+
detail: "Found 'require(\"http\")' - insecure HTTP imports are not allowed",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
pattern: /<script[^>]*\bsrc\s*=\s*['"]https?:\/\/[^'"]+['"][^>]*>/i,
|
|
31
|
+
detail: "Found external '<script src>' URL - remote script loading is not allowed",
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
function isDotEnvExampleFile(filePath) {
|
|
35
|
+
const normalizedPath = normalize(filePath);
|
|
36
|
+
const segments = normalizedPath.split(/[\\/]/);
|
|
37
|
+
const fileName = segments.at(-1) ?? normalizedPath;
|
|
38
|
+
return fileName === '.env.example';
|
|
39
|
+
}
|
|
40
|
+
export function scanFileContent(filePath, content) {
|
|
41
|
+
const warnings = [];
|
|
42
|
+
for (const entry of SUSPICIOUS_CONTENT_PATTERNS) {
|
|
43
|
+
if (!entry.pattern.test(content)) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
warnings.push({
|
|
47
|
+
type: 'suspicious_pattern',
|
|
48
|
+
filePath,
|
|
49
|
+
detail: entry.detail,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (filePath.endsWith('package.json') && /"(?:postinstall|preinstall)"\s*:/.test(content)) {
|
|
53
|
+
warnings.push({
|
|
54
|
+
type: 'suspicious_pattern',
|
|
55
|
+
filePath,
|
|
56
|
+
detail: "Found 'postinstall/preinstall' script in package.json - install hooks are not allowed",
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return warnings;
|
|
60
|
+
}
|
|
61
|
+
export function validateFilePath(filePath) {
|
|
62
|
+
const warnings = [];
|
|
63
|
+
const normalizedPath = normalize(filePath);
|
|
64
|
+
if (isAbsolute(filePath) || isAbsolute(normalizedPath)) {
|
|
65
|
+
warnings.push({
|
|
66
|
+
type: 'path_traversal',
|
|
67
|
+
filePath,
|
|
68
|
+
detail: 'Path must be relative and cannot be absolute',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const segments = normalizedPath.split(/[\\/]/).filter(Boolean);
|
|
72
|
+
if (segments.includes('..')) {
|
|
73
|
+
warnings.push({
|
|
74
|
+
type: 'path_traversal',
|
|
75
|
+
filePath,
|
|
76
|
+
detail: "Path contains '..' segments and may escape the workspace",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (existsSync(filePath)) {
|
|
80
|
+
const stats = lstatSync(filePath);
|
|
81
|
+
if (stats.isSymbolicLink()) {
|
|
82
|
+
warnings.push({
|
|
83
|
+
type: 'path_traversal',
|
|
84
|
+
filePath,
|
|
85
|
+
detail: 'Symbolic links are not allowed in staged paths',
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return warnings;
|
|
90
|
+
}
|
|
91
|
+
export function validateFileType(filePath) {
|
|
92
|
+
if (isDotEnvExampleFile(filePath)) {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
const extension = extname(filePath).toLowerCase();
|
|
96
|
+
if (ALLOWED_EXTENSIONS.has(extension)) {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
return [
|
|
100
|
+
{
|
|
101
|
+
type: 'invalid_file_type',
|
|
102
|
+
filePath,
|
|
103
|
+
detail: `File type '${extension}' is not in the allowed list`,
|
|
104
|
+
},
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
export function scanStagedFiles(workspaceDir) {
|
|
108
|
+
const auditLogger = createAuditLogger(workspaceDir);
|
|
109
|
+
const warnings = [];
|
|
110
|
+
const stagedFiles = listStagedFiles(workspaceDir);
|
|
111
|
+
const stagingRoot = resolve(workspaceDir, '.kitt/staging');
|
|
112
|
+
for (const stagedFile of stagedFiles) {
|
|
113
|
+
const filePathWarnings = validateFilePath(stagedFile.relativePath);
|
|
114
|
+
const fileTypeWarnings = validateFileType(stagedFile.relativePath);
|
|
115
|
+
warnings.push(...filePathWarnings, ...fileTypeWarnings);
|
|
116
|
+
const hasPathIssues = filePathWarnings.length > 0;
|
|
117
|
+
if (hasPathIssues) {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
const stagedAbsolutePath = resolve(stagingRoot, normalize(stagedFile.relativePath));
|
|
121
|
+
const stagedContent = readFileSync(stagedAbsolutePath, 'utf-8');
|
|
122
|
+
warnings.push(...scanFileContent(stagedFile.relativePath, stagedContent));
|
|
123
|
+
}
|
|
124
|
+
for (const warning of warnings) {
|
|
125
|
+
auditLogger.security('WARNING', `${warning.filePath}: ${warning.detail}`);
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
safe: warnings.length === 0,
|
|
129
|
+
warnings,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
export const SECRET_PATTERNS = [
|
|
133
|
+
'SECRET',
|
|
134
|
+
'KEY',
|
|
135
|
+
'TOKEN',
|
|
136
|
+
'PASSWORD',
|
|
137
|
+
'CREDENTIAL',
|
|
138
|
+
'PRIVATE',
|
|
139
|
+
'API_KEY',
|
|
140
|
+
'DATABASE_URL',
|
|
141
|
+
'REDIS_URL',
|
|
142
|
+
'DSN',
|
|
143
|
+
'CONNECTION_STRING',
|
|
144
|
+
];
|
|
145
|
+
const DEPLOY_SECRET_SCAN_IGNORED_DIRS = new Set(['.git', '.kitt', 'node_modules', 'dist', '.next', '.vinxi']);
|
|
146
|
+
function isIgnoredForDeploySecretScan(filePath) {
|
|
147
|
+
const normalizedPath = normalize(filePath);
|
|
148
|
+
const segments = normalizedPath.split(/[\\/]/).filter(Boolean);
|
|
149
|
+
return segments.some((segment) => DEPLOY_SECRET_SCAN_IGNORED_DIRS.has(segment));
|
|
150
|
+
}
|
|
151
|
+
export function isSecretVariable(variableName) {
|
|
152
|
+
const normalizedName = variableName.toUpperCase();
|
|
153
|
+
return SECRET_PATTERNS.some((pattern) => normalizedName.includes(pattern));
|
|
154
|
+
}
|
|
155
|
+
export function maskSecretValue(value) {
|
|
156
|
+
if (value.length > 8) {
|
|
157
|
+
return `${value.slice(0, 4)}****`;
|
|
158
|
+
}
|
|
159
|
+
return '****';
|
|
160
|
+
}
|
|
161
|
+
export function scanForSecrets(workspaceDir, filePaths) {
|
|
162
|
+
const auditLogger = createAuditLogger(workspaceDir);
|
|
163
|
+
const findings = [];
|
|
164
|
+
for (const filePath of filePaths) {
|
|
165
|
+
if (isIgnoredForDeploySecretScan(filePath)) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const normalizedPath = normalize(filePath);
|
|
169
|
+
const segments = normalizedPath.split(/[\\/]/).filter(Boolean);
|
|
170
|
+
const fileName = segments.at(-1) ?? normalizedPath;
|
|
171
|
+
if (fileName.startsWith('.env') && !isDotEnvExampleFile(filePath)) {
|
|
172
|
+
findings.push({ filePath, variableName: '(env file)' });
|
|
173
|
+
}
|
|
174
|
+
const absolutePath = join(workspaceDir, filePath);
|
|
175
|
+
if (!existsSync(absolutePath)) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
const content = readFileSync(absolutePath, 'utf-8');
|
|
179
|
+
const variableRegex = /^([A-Z_][A-Z0-9_]*)\s*=/gm;
|
|
180
|
+
for (const match of content.matchAll(variableRegex)) {
|
|
181
|
+
const variableName = match[1];
|
|
182
|
+
if (!isSecretVariable(variableName)) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
findings.push({ filePath, variableName });
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
for (const finding of findings) {
|
|
189
|
+
auditLogger.security('WARNING', `${finding.filePath} (contains ${finding.variableName})`);
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
safe: findings.length === 0,
|
|
193
|
+
findings,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/sandbox/scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface StagedFile {
|
|
2
|
+
relativePath: string;
|
|
3
|
+
lineCount: number;
|
|
4
|
+
isNew: boolean;
|
|
5
|
+
isModified: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function clearStaging(workspaceDir: string): void;
|
|
8
|
+
export declare function writeToStaging(workspaceDir: string, relativePath: string, content: string): void;
|
|
9
|
+
export declare function listStagedFiles(workspaceDir: string): StagedFile[];
|
|
10
|
+
export declare function generateDiffSummary(workspaceDir: string, stagedFiles: StagedFile[]): string[];
|
|
11
|
+
export declare function applyStagedChanges(workspaceDir: string, stagedFiles: StagedFile[]): void;
|
|
12
|
+
export declare function rejectStagedChanges(workspaceDir: string): void;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync, } from 'node:fs';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { dirname, join, relative } from 'node:path';
|
|
4
|
+
import { createAuditLogger } from '../audit/logger.js';
|
|
5
|
+
const KITT_DIR = '.kitt';
|
|
6
|
+
const STAGING_DIR = 'staging';
|
|
7
|
+
function getStagingDir(workspaceDir) {
|
|
8
|
+
return join(workspaceDir, KITT_DIR, STAGING_DIR);
|
|
9
|
+
}
|
|
10
|
+
function hashContent(content) {
|
|
11
|
+
return createHash('sha256').update(content).digest('hex');
|
|
12
|
+
}
|
|
13
|
+
function assertWithinWorkspace(workspaceDir, targetPath) {
|
|
14
|
+
const pathFromWorkspace = relative(workspaceDir, targetPath);
|
|
15
|
+
if (pathFromWorkspace === '..' || pathFromWorkspace.startsWith(`..${pathFromWorkspace.includes('\\') ? '\\' : '/'}`)) {
|
|
16
|
+
throw new Error(`Refusing to write outside workspace: ${targetPath}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function countLines(content) {
|
|
20
|
+
return content.match(/\n/g)?.length ?? 0;
|
|
21
|
+
}
|
|
22
|
+
function collectStagedFilePaths(stagingDir, currentDir, output) {
|
|
23
|
+
const entries = readdirSync(currentDir);
|
|
24
|
+
for (const entry of entries) {
|
|
25
|
+
const absolutePath = join(currentDir, entry);
|
|
26
|
+
const stats = statSync(absolutePath);
|
|
27
|
+
if (stats.isDirectory()) {
|
|
28
|
+
collectStagedFilePaths(stagingDir, absolutePath, output);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
const stagedRelativePath = relative(stagingDir, absolutePath);
|
|
32
|
+
output.push(stagedRelativePath);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export function clearStaging(workspaceDir) {
|
|
36
|
+
const logger = createAuditLogger(workspaceDir);
|
|
37
|
+
const stagingDir = getStagingDir(workspaceDir);
|
|
38
|
+
if (existsSync(stagingDir)) {
|
|
39
|
+
rmSync(stagingDir, { recursive: true, force: true });
|
|
40
|
+
}
|
|
41
|
+
mkdirSync(stagingDir, { recursive: true });
|
|
42
|
+
logger.staged(join(KITT_DIR, STAGING_DIR), 'cleared');
|
|
43
|
+
}
|
|
44
|
+
export function writeToStaging(workspaceDir, relativePath, content) {
|
|
45
|
+
const logger = createAuditLogger(workspaceDir);
|
|
46
|
+
const stagingDir = getStagingDir(workspaceDir);
|
|
47
|
+
const stagedPath = join(stagingDir, relativePath);
|
|
48
|
+
assertWithinWorkspace(stagingDir, stagedPath);
|
|
49
|
+
mkdirSync(dirname(stagedPath), { recursive: true });
|
|
50
|
+
writeFileSync(stagedPath, content, 'utf-8');
|
|
51
|
+
const hash = hashContent(content);
|
|
52
|
+
logger.staged(relativePath, 'written to staging');
|
|
53
|
+
logger.fileWrite(join(KITT_DIR, STAGING_DIR, relativePath), hash);
|
|
54
|
+
}
|
|
55
|
+
export function listStagedFiles(workspaceDir) {
|
|
56
|
+
const logger = createAuditLogger(workspaceDir);
|
|
57
|
+
const stagingDir = getStagingDir(workspaceDir);
|
|
58
|
+
if (!existsSync(stagingDir)) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
const filePaths = [];
|
|
62
|
+
collectStagedFilePaths(stagingDir, stagingDir, filePaths);
|
|
63
|
+
return filePaths
|
|
64
|
+
.sort((a, b) => a.localeCompare(b))
|
|
65
|
+
.map((stagedRelativePath) => {
|
|
66
|
+
const workspacePath = join(workspaceDir, stagedRelativePath);
|
|
67
|
+
assertWithinWorkspace(workspaceDir, workspacePath);
|
|
68
|
+
const content = readFileSync(join(stagingDir, stagedRelativePath), 'utf-8');
|
|
69
|
+
const isNew = !existsSync(workspacePath);
|
|
70
|
+
const isModified = !isNew;
|
|
71
|
+
logger.staged(stagedRelativePath, isNew ? 'new' : 'modified');
|
|
72
|
+
return {
|
|
73
|
+
relativePath: stagedRelativePath,
|
|
74
|
+
lineCount: countLines(content),
|
|
75
|
+
isNew,
|
|
76
|
+
isModified,
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
export function generateDiffSummary(workspaceDir, stagedFiles) {
|
|
81
|
+
void workspaceDir;
|
|
82
|
+
return stagedFiles.map((file) => {
|
|
83
|
+
if (file.isNew) {
|
|
84
|
+
return ` + ${file.relativePath} (${file.lineCount} lines, new)`;
|
|
85
|
+
}
|
|
86
|
+
return ` ~ ${file.relativePath} (modified)`;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
export function applyStagedChanges(workspaceDir, stagedFiles) {
|
|
90
|
+
const logger = createAuditLogger(workspaceDir);
|
|
91
|
+
const stagingDir = getStagingDir(workspaceDir);
|
|
92
|
+
for (const stagedFile of stagedFiles) {
|
|
93
|
+
const sourcePath = join(stagingDir, stagedFile.relativePath);
|
|
94
|
+
const destinationPath = join(workspaceDir, stagedFile.relativePath);
|
|
95
|
+
assertWithinWorkspace(workspaceDir, destinationPath);
|
|
96
|
+
mkdirSync(dirname(destinationPath), { recursive: true });
|
|
97
|
+
copyFileSync(sourcePath, destinationPath);
|
|
98
|
+
const content = readFileSync(destinationPath, 'utf-8');
|
|
99
|
+
logger.staged(stagedFile.relativePath, 'applied');
|
|
100
|
+
logger.fileWrite(stagedFile.relativePath, hashContent(content));
|
|
101
|
+
}
|
|
102
|
+
clearStaging(workspaceDir);
|
|
103
|
+
}
|
|
104
|
+
export function rejectStagedChanges(workspaceDir) {
|
|
105
|
+
clearStaging(workspaceDir);
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=staging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staging.js","sourceRoot":"","sources":["../../src/sandbox/staging.ts"],"names":[],"mappings":"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"}
|