sandstream-kit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +617 -0
- package/dist/adapters/api-key-adapter.d.ts +35 -0
- package/dist/adapters/api-key-adapter.js +46 -0
- package/dist/adapters/api-key-adapter.js.map +1 -0
- package/dist/adapters/clerk-auth.d.ts +6 -0
- package/dist/adapters/clerk-auth.js +20 -0
- package/dist/adapters/clerk-auth.js.map +1 -0
- package/dist/adapters/cloudflare-r2.d.ts +6 -0
- package/dist/adapters/cloudflare-r2.js +136 -0
- package/dist/adapters/cloudflare-r2.js.map +1 -0
- package/dist/adapters/expo-eas.d.ts +6 -0
- package/dist/adapters/expo-eas.js +129 -0
- package/dist/adapters/expo-eas.js.map +1 -0
- package/dist/adapters/flagsmith-flags.d.ts +5 -0
- package/dist/adapters/flagsmith-flags.js +20 -0
- package/dist/adapters/flagsmith-flags.js.map +1 -0
- package/dist/adapters/flyio-hosting.d.ts +2 -0
- package/dist/adapters/flyio-hosting.js +143 -0
- package/dist/adapters/flyio-hosting.js.map +1 -0
- package/dist/adapters/index.d.ts +6 -0
- package/dist/adapters/index.js +48 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/inngest-background.d.ts +5 -0
- package/dist/adapters/inngest-background.js +19 -0
- package/dist/adapters/inngest-background.js.map +1 -0
- package/dist/adapters/liveblocks-realtime.d.ts +11 -0
- package/dist/adapters/liveblocks-realtime.js +62 -0
- package/dist/adapters/liveblocks-realtime.js.map +1 -0
- package/dist/adapters/loops-email.d.ts +6 -0
- package/dist/adapters/loops-email.js +18 -0
- package/dist/adapters/loops-email.js.map +1 -0
- package/dist/adapters/neon-db.d.ts +10 -0
- package/dist/adapters/neon-db.js +94 -0
- package/dist/adapters/neon-db.js.map +1 -0
- package/dist/adapters/planetscale-db.d.ts +11 -0
- package/dist/adapters/planetscale-db.js +134 -0
- package/dist/adapters/planetscale-db.js.map +1 -0
- package/dist/adapters/posthog-analytics.d.ts +6 -0
- package/dist/adapters/posthog-analytics.js +22 -0
- package/dist/adapters/posthog-analytics.js.map +1 -0
- package/dist/adapters/railway-hosting.d.ts +2 -0
- package/dist/adapters/railway-hosting.js +136 -0
- package/dist/adapters/railway-hosting.js.map +1 -0
- package/dist/adapters/resend-email.d.ts +35 -0
- package/dist/adapters/resend-email.js +109 -0
- package/dist/adapters/resend-email.js.map +1 -0
- package/dist/adapters/searxng-instance.d.ts +6 -0
- package/dist/adapters/searxng-instance.js +240 -0
- package/dist/adapters/searxng-instance.js.map +1 -0
- package/dist/adapters/sentry-monitoring.d.ts +7 -0
- package/dist/adapters/sentry-monitoring.js +27 -0
- package/dist/adapters/sentry-monitoring.js.map +1 -0
- package/dist/adapters/stripe-payments.d.ts +6 -0
- package/dist/adapters/stripe-payments.js +134 -0
- package/dist/adapters/stripe-payments.js.map +1 -0
- package/dist/adapters/supabase-db.d.ts +6 -0
- package/dist/adapters/supabase-db.js +130 -0
- package/dist/adapters/supabase-db.js.map +1 -0
- package/dist/adapters/tinybird-analytics.d.ts +5 -0
- package/dist/adapters/tinybird-analytics.js +20 -0
- package/dist/adapters/tinybird-analytics.js.map +1 -0
- package/dist/adapters/trigger-background.d.ts +6 -0
- package/dist/adapters/trigger-background.js +20 -0
- package/dist/adapters/trigger-background.js.map +1 -0
- package/dist/adapters/types.d.ts +7 -0
- package/dist/adapters/types.js +2 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/adapters/upstash-redis.d.ts +6 -0
- package/dist/adapters/upstash-redis.js +88 -0
- package/dist/adapters/upstash-redis.js.map +1 -0
- package/dist/adapters/vercel-hosting.d.ts +6 -0
- package/dist/adapters/vercel-hosting.js +112 -0
- package/dist/adapters/vercel-hosting.js.map +1 -0
- package/dist/agent-adapter-model.d.ts +108 -0
- package/dist/agent-adapter-model.js +6 -0
- package/dist/agent-adapter-model.js.map +1 -0
- package/dist/agent-adapter-service.d.ts +67 -0
- package/dist/agent-adapter-service.js +299 -0
- package/dist/agent-adapter-service.js.map +1 -0
- package/dist/agent-config.d.ts +56 -0
- package/dist/agent-config.js +129 -0
- package/dist/agent-config.js.map +1 -0
- package/dist/agent-governance-model.d.ts +128 -0
- package/dist/agent-governance-model.js +6 -0
- package/dist/agent-governance-model.js.map +1 -0
- package/dist/agent-governance-service.d.ts +101 -0
- package/dist/agent-governance-service.js +319 -0
- package/dist/agent-governance-service.js.map +1 -0
- package/dist/alert-rules-engine.d.ts +102 -0
- package/dist/alert-rules-engine.js +210 -0
- package/dist/alert-rules-engine.js.map +1 -0
- package/dist/analytics-service.d.ts +126 -0
- package/dist/analytics-service.js +318 -0
- package/dist/analytics-service.js.map +1 -0
- package/dist/analyze.d.ts +19 -0
- package/dist/analyze.js +311 -0
- package/dist/analyze.js.map +1 -0
- package/dist/apm-instrumentor.d.ts +119 -0
- package/dist/apm-instrumentor.js +225 -0
- package/dist/apm-instrumentor.js.map +1 -0
- package/dist/approval-model.d.ts +82 -0
- package/dist/approval-model.js +6 -0
- package/dist/approval-model.js.map +1 -0
- package/dist/approval-service.d.ts +39 -0
- package/dist/approval-service.js +236 -0
- package/dist/approval-service.js.map +1 -0
- package/dist/approval.d.ts +22 -0
- package/dist/approval.js +148 -0
- package/dist/approval.js.map +1 -0
- package/dist/audit-logging-model.d.ts +157 -0
- package/dist/audit-logging-model.js +6 -0
- package/dist/audit-logging-model.js.map +1 -0
- package/dist/audit-logging-service.d.ts +89 -0
- package/dist/audit-logging-service.js +367 -0
- package/dist/audit-logging-service.js.map +1 -0
- package/dist/audit-secrets.d.ts +42 -0
- package/dist/audit-secrets.js +126 -0
- package/dist/audit-secrets.js.map +1 -0
- package/dist/audit.d.ts +43 -0
- package/dist/audit.js +286 -0
- package/dist/audit.js.map +1 -0
- package/dist/author-dashboard.d.ts +84 -0
- package/dist/author-dashboard.js +204 -0
- package/dist/author-dashboard.js.map +1 -0
- package/dist/author-notifications.d.ts +130 -0
- package/dist/author-notifications.js +261 -0
- package/dist/author-notifications.js.map +1 -0
- package/dist/author-verification.d.ts +79 -0
- package/dist/author-verification.js +257 -0
- package/dist/author-verification.js.map +1 -0
- package/dist/autonomous-setup-model.d.ts +117 -0
- package/dist/autonomous-setup-model.js +6 -0
- package/dist/autonomous-setup-model.js.map +1 -0
- package/dist/autonomous-setup-service.d.ts +74 -0
- package/dist/autonomous-setup-service.js +325 -0
- package/dist/autonomous-setup-service.js.map +1 -0
- package/dist/badge-system.d.ts +70 -0
- package/dist/badge-system.js +210 -0
- package/dist/badge-system.js.map +1 -0
- package/dist/baseline.d.ts +34 -0
- package/dist/baseline.js +78 -0
- package/dist/baseline.js.map +1 -0
- package/dist/beta-program-service.d.ts +112 -0
- package/dist/beta-program-service.js +240 -0
- package/dist/beta-program-service.js.map +1 -0
- package/dist/budget.d.ts +34 -0
- package/dist/budget.js +159 -0
- package/dist/budget.js.map +1 -0
- package/dist/bumblebee.d.ts +143 -0
- package/dist/bumblebee.js +384 -0
- package/dist/bumblebee.js.map +1 -0
- package/dist/cache-manager.d.ts +97 -0
- package/dist/cache-manager.js +244 -0
- package/dist/cache-manager.js.map +1 -0
- package/dist/cdn-adapter.d.ts +64 -0
- package/dist/cdn-adapter.js +263 -0
- package/dist/cdn-adapter.js.map +1 -0
- package/dist/certification-workflow-model.d.ts +95 -0
- package/dist/certification-workflow-model.js +6 -0
- package/dist/certification-workflow-model.js.map +1 -0
- package/dist/certification-workflow-service.d.ts +72 -0
- package/dist/certification-workflow-service.js +305 -0
- package/dist/certification-workflow-service.js.map +1 -0
- package/dist/check-design.d.ts +38 -0
- package/dist/check-design.js +256 -0
- package/dist/check-design.js.map +1 -0
- package/dist/check-gitignore.d.ts +39 -0
- package/dist/check-gitignore.js +156 -0
- package/dist/check-gitignore.js.map +1 -0
- package/dist/check-hooks.d.ts +15 -0
- package/dist/check-hooks.js +72 -0
- package/dist/check-hooks.js.map +1 -0
- package/dist/check-lock.d.ts +16 -0
- package/dist/check-lock.js +94 -0
- package/dist/check-lock.js.map +1 -0
- package/dist/check-secrets.d.ts +11 -0
- package/dist/check-secrets.js +320 -0
- package/dist/check-secrets.js.map +1 -0
- package/dist/check-security.d.ts +13 -0
- package/dist/check-security.js +887 -0
- package/dist/check-security.js.map +1 -0
- package/dist/check-services.d.ts +10 -0
- package/dist/check-services.js +44 -0
- package/dist/check-services.js.map +1 -0
- package/dist/check-skills.d.ts +8 -0
- package/dist/check-skills.js +26 -0
- package/dist/check-skills.js.map +1 -0
- package/dist/check-tests.d.ts +43 -0
- package/dist/check-tests.js +175 -0
- package/dist/check-tests.js.map +1 -0
- package/dist/check-tools.d.ts +8 -0
- package/dist/check-tools.js +42 -0
- package/dist/check-tools.js.map +1 -0
- package/dist/check-web-search.d.ts +12 -0
- package/dist/check-web-search.js +168 -0
- package/dist/check-web-search.js.map +1 -0
- package/dist/ci-cd-publisher.d.ts +162 -0
- package/dist/ci-cd-publisher.js +319 -0
- package/dist/ci-cd-publisher.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +4074 -0
- package/dist/cli.js.map +1 -0
- package/dist/clone.d.ts +25 -0
- package/dist/clone.js +73 -0
- package/dist/clone.js.map +1 -0
- package/dist/completions.d.ts +8 -0
- package/dist/completions.js +250 -0
- package/dist/completions.js.map +1 -0
- package/dist/compression-manager.d.ts +107 -0
- package/dist/compression-manager.js +250 -0
- package/dist/compression-manager.js.map +1 -0
- package/dist/config.d.ts +233 -0
- package/dist/config.js +255 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +38 -0
- package/dist/context.js +86 -0
- package/dist/context.js.map +1 -0
- package/dist/cost-monitor.d.ts +72 -0
- package/dist/cost-monitor.js +218 -0
- package/dist/cost-monitor.js.map +1 -0
- package/dist/create-plugin.d.ts +22 -0
- package/dist/create-plugin.js +266 -0
- package/dist/create-plugin.js.map +1 -0
- package/dist/database.d.ts +123 -0
- package/dist/database.js +354 -0
- package/dist/database.js.map +1 -0
- package/dist/datadog-adapter.d.ts +60 -0
- package/dist/datadog-adapter.js +245 -0
- package/dist/datadog-adapter.js.map +1 -0
- package/dist/doctor.d.ts +15 -0
- package/dist/doctor.js +131 -0
- package/dist/doctor.js.map +1 -0
- package/dist/documentation-generator.d.ts +226 -0
- package/dist/documentation-generator.js +348 -0
- package/dist/documentation-generator.js.map +1 -0
- package/dist/elevation-scopes.d.ts +40 -0
- package/dist/elevation-scopes.js +110 -0
- package/dist/elevation-scopes.js.map +1 -0
- package/dist/elevation.d.ts +102 -0
- package/dist/elevation.js +449 -0
- package/dist/elevation.js.map +1 -0
- package/dist/env-diff.d.ts +27 -0
- package/dist/env-diff.js +104 -0
- package/dist/env-diff.js.map +1 -0
- package/dist/env-inspect.d.ts +28 -0
- package/dist/env-inspect.js +81 -0
- package/dist/env-inspect.js.map +1 -0
- package/dist/env-switch.d.ts +37 -0
- package/dist/env-switch.js +102 -0
- package/dist/env-switch.js.map +1 -0
- package/dist/environment.d.ts +27 -0
- package/dist/environment.js +148 -0
- package/dist/environment.js.map +1 -0
- package/dist/error-tracker.d.ts +92 -0
- package/dist/error-tracker.js +206 -0
- package/dist/error-tracker.js.map +1 -0
- package/dist/escalate.d.ts +11 -0
- package/dist/escalate.js +73 -0
- package/dist/escalate.js.map +1 -0
- package/dist/event-stream.d.ts +81 -0
- package/dist/event-stream.js +161 -0
- package/dist/event-stream.js.map +1 -0
- package/dist/fix.d.ts +42 -0
- package/dist/fix.js +419 -0
- package/dist/fix.js.map +1 -0
- package/dist/governance-middleware.d.ts +22 -0
- package/dist/governance-middleware.js +173 -0
- package/dist/governance-middleware.js.map +1 -0
- package/dist/governance.d.ts +44 -0
- package/dist/governance.js +236 -0
- package/dist/governance.js.map +1 -0
- package/dist/hooks.d.ts +25 -0
- package/dist/hooks.js +281 -0
- package/dist/hooks.js.map +1 -0
- package/dist/id-generator.d.ts +43 -0
- package/dist/id-generator.js +47 -0
- package/dist/id-generator.js.map +1 -0
- package/dist/image-optimizer.d.ts +92 -0
- package/dist/image-optimizer.js +202 -0
- package/dist/image-optimizer.js.map +1 -0
- package/dist/install.d.ts +15 -0
- package/dist/install.js +59 -0
- package/dist/install.js.map +1 -0
- package/dist/lock.d.ts +82 -0
- package/dist/lock.js +264 -0
- package/dist/lock.js.map +1 -0
- package/dist/login.d.ts +23 -0
- package/dist/login.js +132 -0
- package/dist/login.js.map +1 -0
- package/dist/mcp-kit-tools-model.d.ts +195 -0
- package/dist/mcp-kit-tools-model.js +6 -0
- package/dist/mcp-kit-tools-model.js.map +1 -0
- package/dist/mcp-kit-tools-service.d.ts +127 -0
- package/dist/mcp-kit-tools-service.js +943 -0
- package/dist/mcp-kit-tools-service.js.map +1 -0
- package/dist/mcp-orchestrator.d.ts +70 -0
- package/dist/mcp-orchestrator.js +175 -0
- package/dist/mcp-orchestrator.js.map +1 -0
- package/dist/mcp-server.d.ts +3 -0
- package/dist/mcp-server.js +722 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/middleware/rate-limiter.d.ts +74 -0
- package/dist/middleware/rate-limiter.js +342 -0
- package/dist/middleware/rate-limiter.js.map +1 -0
- package/dist/migration-runner.d.ts +66 -0
- package/dist/migration-runner.js +192 -0
- package/dist/migration-runner.js.map +1 -0
- package/dist/migrations.d.ts +25 -0
- package/dist/migrations.js +530 -0
- package/dist/migrations.js.map +1 -0
- package/dist/moderation-system.d.ts +153 -0
- package/dist/moderation-system.js +338 -0
- package/dist/moderation-system.js.map +1 -0
- package/dist/multi-agent-workflow-model.d.ts +125 -0
- package/dist/multi-agent-workflow-model.js +6 -0
- package/dist/multi-agent-workflow-model.js.map +1 -0
- package/dist/multi-agent-workflow-service.d.ts +102 -0
- package/dist/multi-agent-workflow-service.js +452 -0
- package/dist/multi-agent-workflow-service.js.map +1 -0
- package/dist/onepassword.d.ts +75 -0
- package/dist/onepassword.js +140 -0
- package/dist/onepassword.js.map +1 -0
- package/dist/open.d.ts +30 -0
- package/dist/open.js +166 -0
- package/dist/open.js.map +1 -0
- package/dist/output.d.ts +32 -0
- package/dist/output.js +295 -0
- package/dist/output.js.map +1 -0
- package/dist/partner-service.d.ts +101 -0
- package/dist/partner-service.js +191 -0
- package/dist/partner-service.js.map +1 -0
- package/dist/payout-service.d.ts +136 -0
- package/dist/payout-service.js +293 -0
- package/dist/payout-service.js.map +1 -0
- package/dist/pkg.d.ts +30 -0
- package/dist/pkg.js +162 -0
- package/dist/pkg.js.map +1 -0
- package/dist/plugin-loader.d.ts +16 -0
- package/dist/plugin-loader.js +124 -0
- package/dist/plugin-loader.js.map +1 -0
- package/dist/plugin-registry-model.d.ts +133 -0
- package/dist/plugin-registry-model.js +6 -0
- package/dist/plugin-registry-model.js.map +1 -0
- package/dist/plugin-registry-service.d.ts +109 -0
- package/dist/plugin-registry-service.js +361 -0
- package/dist/plugin-registry-service.js.map +1 -0
- package/dist/plugin-registry.d.ts +58 -0
- package/dist/plugin-registry.js +108 -0
- package/dist/plugin-registry.js.map +1 -0
- package/dist/plugin-updates.d.ts +135 -0
- package/dist/plugin-updates.js +326 -0
- package/dist/plugin-updates.js.map +1 -0
- package/dist/plugins-cli.d.ts +7 -0
- package/dist/plugins-cli.js +157 -0
- package/dist/plugins-cli.js.map +1 -0
- package/dist/plugins.d.ts +88 -0
- package/dist/plugins.js +251 -0
- package/dist/plugins.js.map +1 -0
- package/dist/policy.d.ts +66 -0
- package/dist/policy.js +160 -0
- package/dist/policy.js.map +1 -0
- package/dist/post-pull-audit.d.ts +39 -0
- package/dist/post-pull-audit.js +151 -0
- package/dist/post-pull-audit.js.map +1 -0
- package/dist/provision.d.ts +17 -0
- package/dist/provision.js +147 -0
- package/dist/provision.js.map +1 -0
- package/dist/query-optimizer.d.ts +102 -0
- package/dist/query-optimizer.js +199 -0
- package/dist/query-optimizer.js.map +1 -0
- package/dist/read-only-mode.d.ts +46 -0
- package/dist/read-only-mode.js +71 -0
- package/dist/read-only-mode.js.map +1 -0
- package/dist/redis-adapter.d.ts +71 -0
- package/dist/redis-adapter.js +278 -0
- package/dist/redis-adapter.js.map +1 -0
- package/dist/resilience-tests.d.ts +120 -0
- package/dist/resilience-tests.js +293 -0
- package/dist/resilience-tests.js.map +1 -0
- package/dist/revocation.d.ts +22 -0
- package/dist/revocation.js +100 -0
- package/dist/revocation.js.map +1 -0
- package/dist/run.d.ts +21 -0
- package/dist/run.js +80 -0
- package/dist/run.js.map +1 -0
- package/dist/scan-build.d.ts +18 -0
- package/dist/scan-build.js +100 -0
- package/dist/scan-build.js.map +1 -0
- package/dist/scan-plaintext.d.ts +24 -0
- package/dist/scan-plaintext.js +147 -0
- package/dist/scan-plaintext.js.map +1 -0
- package/dist/scan-staged.d.ts +15 -0
- package/dist/scan-staged.js +70 -0
- package/dist/scan-staged.js.map +1 -0
- package/dist/scan-transcripts.d.ts +23 -0
- package/dist/scan-transcripts.js +93 -0
- package/dist/scan-transcripts.js.map +1 -0
- package/dist/secret-backends.d.ts +50 -0
- package/dist/secret-backends.js +510 -0
- package/dist/secret-backends.js.map +1 -0
- package/dist/secret-expiration.d.ts +46 -0
- package/dist/secret-expiration.js +172 -0
- package/dist/secret-expiration.js.map +1 -0
- package/dist/secrets-migrate.d.ts +75 -0
- package/dist/secrets-migrate.js +185 -0
- package/dist/secrets-migrate.js.map +1 -0
- package/dist/secrets-model.d.ts +77 -0
- package/dist/secrets-model.js +6 -0
- package/dist/secrets-model.js.map +1 -0
- package/dist/secrets-onecli.d.ts +65 -0
- package/dist/secrets-onecli.js +113 -0
- package/dist/secrets-onecli.js.map +1 -0
- package/dist/secrets-propagate.d.ts +48 -0
- package/dist/secrets-propagate.js +201 -0
- package/dist/secrets-propagate.js.map +1 -0
- package/dist/secrets-pull.d.ts +34 -0
- package/dist/secrets-pull.js +118 -0
- package/dist/secrets-pull.js.map +1 -0
- package/dist/secrets-purge-history.d.ts +53 -0
- package/dist/secrets-purge-history.js +144 -0
- package/dist/secrets-purge-history.js.map +1 -0
- package/dist/secrets-rotate-cli.d.ts +54 -0
- package/dist/secrets-rotate-cli.js +438 -0
- package/dist/secrets-rotate-cli.js.map +1 -0
- package/dist/secrets-rotate.d.ts +38 -0
- package/dist/secrets-rotate.js +65 -0
- package/dist/secrets-rotate.js.map +1 -0
- package/dist/secrets-service.d.ts +73 -0
- package/dist/secrets-service.js +283 -0
- package/dist/secrets-service.js.map +1 -0
- package/dist/secrets-set.d.ts +25 -0
- package/dist/secrets-set.js +33 -0
- package/dist/secrets-set.js.map +1 -0
- package/dist/secrets-sync.d.ts +21 -0
- package/dist/secrets-sync.js +215 -0
- package/dist/secrets-sync.js.map +1 -0
- package/dist/secrets-validate.d.ts +41 -0
- package/dist/secrets-validate.js +126 -0
- package/dist/secrets-validate.js.map +1 -0
- package/dist/secrets-vault-migrate.d.ts +71 -0
- package/dist/secrets-vault-migrate.js +258 -0
- package/dist/secrets-vault-migrate.js.map +1 -0
- package/dist/secrets.d.ts +16 -0
- package/dist/secrets.js +72 -0
- package/dist/secrets.js.map +1 -0
- package/dist/security-hardening.d.ts +150 -0
- package/dist/security-hardening.js +275 -0
- package/dist/security-hardening.js.map +1 -0
- package/dist/security-policy.d.ts +89 -0
- package/dist/security-policy.js +174 -0
- package/dist/security-policy.js.map +1 -0
- package/dist/security-prescan.d.ts +117 -0
- package/dist/security-prescan.js +566 -0
- package/dist/security-prescan.js.map +1 -0
- package/dist/sentry-adapter.d.ts +49 -0
- package/dist/sentry-adapter.js +227 -0
- package/dist/sentry-adapter.js.map +1 -0
- package/dist/service-adapter.d.ts +94 -0
- package/dist/service-adapter.js +162 -0
- package/dist/service-adapter.js.map +1 -0
- package/dist/skills.d.ts +13 -0
- package/dist/skills.js +17 -0
- package/dist/skills.js.map +1 -0
- package/dist/sla-monitor.d.ts +107 -0
- package/dist/sla-monitor.js +233 -0
- package/dist/sla-monitor.js.map +1 -0
- package/dist/stack-detector.d.ts +12 -0
- package/dist/stack-detector.js +251 -0
- package/dist/stack-detector.js.map +1 -0
- package/dist/team-model.d.ts +58 -0
- package/dist/team-model.js +83 -0
- package/dist/team-model.js.map +1 -0
- package/dist/team-service.d.ts +54 -0
- package/dist/team-service.js +206 -0
- package/dist/team-service.js.map +1 -0
- package/dist/toml-generator.d.ts +8 -0
- package/dist/toml-generator.js +223 -0
- package/dist/toml-generator.js.map +1 -0
- package/dist/triage-sandbox.d.ts +34 -0
- package/dist/triage-sandbox.js +167 -0
- package/dist/triage-sandbox.js.map +1 -0
- package/dist/triage.d.ts +30 -0
- package/dist/triage.js +79 -0
- package/dist/triage.js.map +1 -0
- package/dist/update-check.d.ts +13 -0
- package/dist/update-check.js +91 -0
- package/dist/update-check.js.map +1 -0
- package/dist/utils/colors.d.ts +14 -0
- package/dist/utils/colors.js +15 -0
- package/dist/utils/colors.js.map +1 -0
- package/dist/utils/didYouMean.d.ts +15 -0
- package/dist/utils/didYouMean.js +47 -0
- package/dist/utils/didYouMean.js.map +1 -0
- package/dist/utils/exec.d.ts +21 -0
- package/dist/utils/exec.js +23 -0
- package/dist/utils/exec.js.map +1 -0
- package/dist/utils/execFileNoThrow.d.ts +14 -0
- package/dist/utils/execFileNoThrow.js +29 -0
- package/dist/utils/execFileNoThrow.js.map +1 -0
- package/dist/utils/flags.d.ts +19 -0
- package/dist/utils/flags.js +36 -0
- package/dist/utils/flags.js.map +1 -0
- package/dist/utils/parseCommand.d.ts +16 -0
- package/dist/utils/parseCommand.js +13 -0
- package/dist/utils/parseCommand.js.map +1 -0
- package/dist/utils/prompt.d.ts +13 -0
- package/dist/utils/prompt.js +35 -0
- package/dist/utils/prompt.js.map +1 -0
- package/dist/utils/promptSelect.d.ts +19 -0
- package/dist/utils/promptSelect.js +89 -0
- package/dist/utils/promptSelect.js.map +1 -0
- package/dist/utils/redactSecrets.d.ts +24 -0
- package/dist/utils/redactSecrets.js +134 -0
- package/dist/utils/redactSecrets.js.map +1 -0
- package/dist/validation/dynamic-schema.d.ts +29 -0
- package/dist/validation/dynamic-schema.js +76 -0
- package/dist/validation/dynamic-schema.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Triage sandbox — behavioral analysis for npm packages without executing them.
|
|
3
|
+
*
|
|
4
|
+
* Complements the bumblebee catalog (known compromises) and the existing
|
|
5
|
+
* triage script (registry metadata). This module pulls the tarball, inspects
|
|
6
|
+
* it offline, and flags risk signals that frequently appear in supply-chain
|
|
7
|
+
* attacks but are absent from npm-registry metadata.
|
|
8
|
+
*
|
|
9
|
+
* Risk signals:
|
|
10
|
+
* - install scripts (preinstall / install / postinstall) — execution surface
|
|
11
|
+
* - postinstall content that resembles obfuscation, base64 blobs,
|
|
12
|
+
* network calls, or filesystem reads outside the package root
|
|
13
|
+
* - tarball entries that escape the package directory (path traversal)
|
|
14
|
+
* - tarball entries marked executable that shouldn't be
|
|
15
|
+
*
|
|
16
|
+
* No code from the package is ever executed. All work is read-only on the
|
|
17
|
+
* downloaded tarball.
|
|
18
|
+
*/
|
|
19
|
+
export interface SandboxFinding {
|
|
20
|
+
severity: "info" | "warn" | "critical";
|
|
21
|
+
signal: string;
|
|
22
|
+
detail: string;
|
|
23
|
+
}
|
|
24
|
+
export interface SandboxResult {
|
|
25
|
+
package: string;
|
|
26
|
+
version: string | null;
|
|
27
|
+
findings: SandboxFinding[];
|
|
28
|
+
hasInstallScripts: boolean;
|
|
29
|
+
tarballSize: number;
|
|
30
|
+
}
|
|
31
|
+
/** Inspect an npm package without executing any of its code. */
|
|
32
|
+
export declare function triageNpmSandbox(packageName: string, version?: string): Promise<SandboxResult>;
|
|
33
|
+
/** Cleanup helper if caller wants to drop the extraction tmpdir. */
|
|
34
|
+
export declare function cleanupSandbox(workDir: string): Promise<void>;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Triage sandbox — behavioral analysis for npm packages without executing them.
|
|
3
|
+
*
|
|
4
|
+
* Complements the bumblebee catalog (known compromises) and the existing
|
|
5
|
+
* triage script (registry metadata). This module pulls the tarball, inspects
|
|
6
|
+
* it offline, and flags risk signals that frequently appear in supply-chain
|
|
7
|
+
* attacks but are absent from npm-registry metadata.
|
|
8
|
+
*
|
|
9
|
+
* Risk signals:
|
|
10
|
+
* - install scripts (preinstall / install / postinstall) — execution surface
|
|
11
|
+
* - postinstall content that resembles obfuscation, base64 blobs,
|
|
12
|
+
* network calls, or filesystem reads outside the package root
|
|
13
|
+
* - tarball entries that escape the package directory (path traversal)
|
|
14
|
+
* - tarball entries marked executable that shouldn't be
|
|
15
|
+
*
|
|
16
|
+
* No code from the package is ever executed. All work is read-only on the
|
|
17
|
+
* downloaded tarball.
|
|
18
|
+
*/
|
|
19
|
+
import { execFile } from "node:child_process";
|
|
20
|
+
import { promisify } from "node:util";
|
|
21
|
+
import { readFile, mkdtemp, readdir, stat, rm } from "node:fs/promises";
|
|
22
|
+
import { join } from "node:path";
|
|
23
|
+
import { tmpdir } from "node:os";
|
|
24
|
+
const exec = promisify(execFile);
|
|
25
|
+
/** Patterns that frequently appear in malicious lifecycle scripts. */
|
|
26
|
+
const SUSPICIOUS_SCRIPT_PATTERNS = [
|
|
27
|
+
[/curl|wget|https?:\/\//i, "network call in install script"],
|
|
28
|
+
[/eval\s*\(/, "eval() in install script"],
|
|
29
|
+
[/Buffer\.from\([^,)]+,\s*['"]base64/, "base64 blob in install script"],
|
|
30
|
+
[/\\x[0-9a-f]{2}|\\u[0-9a-f]{4}/, "hex/unicode-escaped string in install script"],
|
|
31
|
+
[/\.ssh|\.aws|\.env|\.npmrc/, "reads sensitive file in install script"],
|
|
32
|
+
[/child_process|spawn|exec/, "spawns subprocess in install script"],
|
|
33
|
+
[/process\.env\.[A-Z]+_TOKEN|process\.env\.[A-Z]+_KEY/, "reads env credential in install script"],
|
|
34
|
+
];
|
|
35
|
+
/** Inspect an npm package without executing any of its code. */
|
|
36
|
+
export async function triageNpmSandbox(packageName, version) {
|
|
37
|
+
const findings = [];
|
|
38
|
+
const spec = version ? `${packageName}@${version}` : packageName;
|
|
39
|
+
// 1. Pull the tarball offline. npm pack writes to cwd; use a tmpdir so we
|
|
40
|
+
// can clean up cleanly.
|
|
41
|
+
const work = await mkdtemp(join(tmpdir(), "kit-triage-"));
|
|
42
|
+
let tarballPath = "";
|
|
43
|
+
let tarballSize = 0;
|
|
44
|
+
try {
|
|
45
|
+
const { stdout } = await exec("npm", ["pack", spec, "--json", "--silent"], {
|
|
46
|
+
cwd: work,
|
|
47
|
+
timeout: 60_000,
|
|
48
|
+
});
|
|
49
|
+
const meta = JSON.parse(stdout)[0];
|
|
50
|
+
tarballPath = join(work, meta.filename);
|
|
51
|
+
tarballSize = meta.size;
|
|
52
|
+
if (meta.version)
|
|
53
|
+
version = meta.version;
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
return {
|
|
57
|
+
package: packageName,
|
|
58
|
+
version: version ?? null,
|
|
59
|
+
findings: [
|
|
60
|
+
{
|
|
61
|
+
severity: "warn",
|
|
62
|
+
signal: "pack failed",
|
|
63
|
+
detail: `npm pack ${spec}: ${err instanceof Error ? err.message : String(err)}`,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
hasInstallScripts: false,
|
|
67
|
+
tarballSize: 0,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// 2. Extract into the same tmpdir for inspection.
|
|
71
|
+
await exec("tar", ["xzf", tarballPath, "-C", work], { timeout: 30_000 });
|
|
72
|
+
const pkgRoot = join(work, "package");
|
|
73
|
+
// 3. Path traversal check — npm packs everything under "package/", anything
|
|
74
|
+
// above is malicious.
|
|
75
|
+
const entries = (await exec("tar", ["tzf", tarballPath], { timeout: 10_000 })).stdout
|
|
76
|
+
.split("\n")
|
|
77
|
+
.filter(Boolean);
|
|
78
|
+
for (const entry of entries) {
|
|
79
|
+
if (entry.includes("..") || entry.startsWith("/")) {
|
|
80
|
+
findings.push({
|
|
81
|
+
severity: "critical",
|
|
82
|
+
signal: "path traversal",
|
|
83
|
+
detail: `tarball entry escapes package root: ${entry}`,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// 4. Parse package.json for install scripts.
|
|
88
|
+
let hasInstallScripts = false;
|
|
89
|
+
let pkgJson = {};
|
|
90
|
+
try {
|
|
91
|
+
pkgJson = JSON.parse(await readFile(join(pkgRoot, "package.json"), "utf-8"));
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
findings.push({
|
|
95
|
+
severity: "warn",
|
|
96
|
+
signal: "package.json unreadable",
|
|
97
|
+
detail: "couldn't parse extracted package.json",
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const lifecycleHooks = ["preinstall", "install", "postinstall"];
|
|
101
|
+
for (const hook of lifecycleHooks) {
|
|
102
|
+
const script = pkgJson.scripts?.[hook];
|
|
103
|
+
if (!script)
|
|
104
|
+
continue;
|
|
105
|
+
hasInstallScripts = true;
|
|
106
|
+
findings.push({
|
|
107
|
+
severity: "warn",
|
|
108
|
+
signal: `lifecycle: ${hook}`,
|
|
109
|
+
detail: `${hook}: ${script}`,
|
|
110
|
+
});
|
|
111
|
+
// 5. Scan the actual script file the hook invokes — `node foo.js` etc.
|
|
112
|
+
for (const [pattern, label] of SUSPICIOUS_SCRIPT_PATTERNS) {
|
|
113
|
+
if (pattern.test(script)) {
|
|
114
|
+
findings.push({
|
|
115
|
+
severity: "critical",
|
|
116
|
+
signal: label,
|
|
117
|
+
detail: `${hook} script matches: ${pattern}`,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// 6. World-readable, executable, oddly large files.
|
|
123
|
+
await walkAndCheck(pkgRoot, findings);
|
|
124
|
+
return {
|
|
125
|
+
package: packageName,
|
|
126
|
+
version: version ?? null,
|
|
127
|
+
findings,
|
|
128
|
+
hasInstallScripts,
|
|
129
|
+
tarballSize,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
async function walkAndCheck(dir, findings) {
|
|
133
|
+
for (const entry of await readdir(dir, { withFileTypes: true })) {
|
|
134
|
+
const full = join(dir, entry.name);
|
|
135
|
+
if (entry.isDirectory()) {
|
|
136
|
+
if (entry.name === "node_modules")
|
|
137
|
+
continue;
|
|
138
|
+
await walkAndCheck(full, findings);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (!entry.isFile())
|
|
142
|
+
continue;
|
|
143
|
+
const st = await stat(full);
|
|
144
|
+
// Bash/python/Perl scripts dropped at the package root are unusual for
|
|
145
|
+
// libraries — flag them.
|
|
146
|
+
if (/\.(sh|py|pl|rb)$/i.test(entry.name)) {
|
|
147
|
+
findings.push({
|
|
148
|
+
severity: "warn",
|
|
149
|
+
signal: "script in package",
|
|
150
|
+
detail: `${entry.name} (${st.size} bytes)`,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// 5MB+ single file in a tarball is unusual for JS libs.
|
|
154
|
+
if (st.size > 5 * 1024 * 1024) {
|
|
155
|
+
findings.push({
|
|
156
|
+
severity: "info",
|
|
157
|
+
signal: "large file",
|
|
158
|
+
detail: `${entry.name}: ${(st.size / 1024 / 1024).toFixed(1)} MB`,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/** Cleanup helper if caller wants to drop the extraction tmpdir. */
|
|
164
|
+
export async function cleanupSandbox(workDir) {
|
|
165
|
+
await rm(workDir, { recursive: true, force: true }).catch(() => { });
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=triage-sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triage-sandbox.js","sourceRoot":"","sources":["../src/triage-sandbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAgBjC,sEAAsE;AACtE,MAAM,0BAA0B,GAA4B;IAC1D,CAAC,wBAAwB,EAAE,gCAAgC,CAAC;IAC5D,CAAC,WAAW,EAAE,0BAA0B,CAAC;IACzC,CAAC,oCAAoC,EAAE,+BAA+B,CAAC;IACvE,CAAC,+BAA+B,EAAE,8CAA8C,CAAC;IACjF,CAAC,2BAA2B,EAAE,wCAAwC,CAAC;IACvE,CAAC,0BAA0B,EAAE,qCAAqC,CAAC;IACnE,CAAC,qDAAqD,EAAE,wCAAwC,CAAC;CAClG,CAAC;AAEF,gEAAgE;AAChE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,WAAmB,EACnB,OAAgB;IAEhB,MAAM,QAAQ,GAAqB,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,WAAW,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;IAEjE,0EAA0E;IAC1E,2BAA2B;IAC3B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC;IAC1D,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE;YACzE,GAAG,EAAE,IAAI;YACT,OAAO,EAAE,MAAM;SAChB,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAyD,CAAC;QAC3F,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC;QACxB,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,WAAW;YACpB,OAAO,EAAE,OAAO,IAAI,IAAI;YACxB,QAAQ,EAAE;gBACR;oBACE,QAAQ,EAAE,MAAM;oBAChB,MAAM,EAAE,aAAa;oBACrB,MAAM,EAAE,YAAY,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;iBAChF;aACF;YACD,iBAAiB,EAAE,KAAK;YACxB,WAAW,EAAE,CAAC;SACf,CAAC;IACJ,CAAC;IAED,kDAAkD;IAClD,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IACzE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAEtC,4EAA4E;IAC5E,yBAAyB;IACzB,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM;SAClF,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAClD,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,UAAU;gBACpB,MAAM,EAAE,gBAAgB;gBACxB,MAAM,EAAE,uCAAuC,KAAK,EAAE;aACvD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,6CAA6C;IAC7C,IAAI,iBAAiB,GAAG,KAAK,CAAC;IAC9B,IAAI,OAAO,GAAwD,EAAE,CAAC;IACtE,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/E,CAAC;IAAC,MAAM,CAAC;QACP,QAAQ,CAAC,IAAI,CAAC;YACZ,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,yBAAyB;YACjC,MAAM,EAAE,uCAAuC;SAChD,CAAC,CAAC;IACL,CAAC;IAED,MAAM,cAAc,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;IAChE,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,iBAAiB,GAAG,IAAI,CAAC;QACzB,QAAQ,CAAC,IAAI,CAAC;YACZ,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,cAAc,IAAI,EAAE;YAC5B,MAAM,EAAE,GAAG,IAAI,KAAK,MAAM,EAAE;SAC7B,CAAC,CAAC;QAEH,uEAAuE;QACvE,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,0BAA0B,EAAE,CAAC;YAC1D,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzB,QAAQ,CAAC,IAAI,CAAC;oBACZ,QAAQ,EAAE,UAAU;oBACpB,MAAM,EAAE,KAAK;oBACb,MAAM,EAAE,GAAG,IAAI,oBAAoB,OAAO,EAAE;iBAC7C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,oDAAoD;IACpD,MAAM,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAEtC,OAAO;QACL,OAAO,EAAE,WAAW;QACpB,OAAO,EAAE,OAAO,IAAI,IAAI;QACxB,QAAQ;QACR,iBAAiB;QACjB,WAAW;KACZ,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,QAA0B;IACjE,KAAK,MAAM,KAAK,IAAI,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;gBAAE,SAAS;YAC5C,MAAM,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACnC,SAAS;QACX,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAAE,SAAS;QAC9B,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,uEAAuE;QACvE,yBAAyB;QACzB,IAAI,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,MAAM;gBAChB,MAAM,EAAE,mBAAmB;gBAC3B,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,SAAS;aAC3C,CAAC,CAAC;QACL,CAAC;QACD,wDAAwD;QACxD,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,MAAM;gBAChB,MAAM,EAAE,YAAY;gBACpB,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;aAClE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AACH,CAAC;AAED,oEAAoE;AACpE,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAe;IAClD,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AACtE,CAAC"}
|
package/dist/triage.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Triage — Security evaluation for open source packages, Docker images, skills, and repos.
|
|
3
|
+
* Wraps the Python triage script and integrates with kit's check-security system.
|
|
4
|
+
*/
|
|
5
|
+
import { triageNpmSandbox, type SandboxResult } from "./triage-sandbox.js";
|
|
6
|
+
export type TriageType = "docker" | "npm" | "pip" | "repo" | "skill" | "all" | "tools";
|
|
7
|
+
export { triageNpmSandbox, type SandboxResult };
|
|
8
|
+
export interface TriageResult {
|
|
9
|
+
target: string;
|
|
10
|
+
type: TriageType;
|
|
11
|
+
passed: boolean;
|
|
12
|
+
output: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Run triage on a target
|
|
16
|
+
*/
|
|
17
|
+
export declare function runTriage(type: TriageType, target: string): Promise<TriageResult>;
|
|
18
|
+
/**
|
|
19
|
+
* List available security tools
|
|
20
|
+
*/
|
|
21
|
+
export declare function listTriageTools(): Promise<TriageResult>;
|
|
22
|
+
/**
|
|
23
|
+
* Parse the triage output for structured data
|
|
24
|
+
*/
|
|
25
|
+
export declare function parseTriageOutput(output: string): {
|
|
26
|
+
healthScore?: string;
|
|
27
|
+
criticalIssues: number;
|
|
28
|
+
warnings: number;
|
|
29
|
+
sections: string[];
|
|
30
|
+
};
|
package/dist/triage.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Triage — Security evaluation for open source packages, Docker images, skills, and repos.
|
|
3
|
+
* Wraps the Python triage script and integrates with kit's check-security system.
|
|
4
|
+
*/
|
|
5
|
+
import { access } from "node:fs/promises";
|
|
6
|
+
import { resolve } from "node:path";
|
|
7
|
+
import { triageNpmSandbox } from "./triage-sandbox.js";
|
|
8
|
+
import { exec } from "./utils/exec.js";
|
|
9
|
+
const TRIAGE_SCRIPT = resolve(process.env.HOME || "~", ".claude/skills/triage/scripts/triage.py");
|
|
10
|
+
export { triageNpmSandbox };
|
|
11
|
+
/**
|
|
12
|
+
* Check if the triage script exists
|
|
13
|
+
*/
|
|
14
|
+
async function ensureTriageScript() {
|
|
15
|
+
try {
|
|
16
|
+
await access(TRIAGE_SCRIPT);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Run triage on a target
|
|
25
|
+
*/
|
|
26
|
+
export async function runTriage(type, target) {
|
|
27
|
+
const scriptExists = await ensureTriageScript();
|
|
28
|
+
if (!scriptExists) {
|
|
29
|
+
return {
|
|
30
|
+
target,
|
|
31
|
+
type,
|
|
32
|
+
passed: false,
|
|
33
|
+
output: `Triage script not found at ${TRIAGE_SCRIPT}\nInstall: copy triage skill to ~/.claude/skills/triage/`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const { stdout, stderr } = await exec("python3", [TRIAGE_SCRIPT, type, target], { timeout: 300_000 } // 5 min for Docker pulls
|
|
38
|
+
);
|
|
39
|
+
const output = stdout + (stderr ? `\n${stderr}` : "");
|
|
40
|
+
const passed = output.includes("TRIAGE PASSED");
|
|
41
|
+
return { target, type, passed, output };
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
const err = error;
|
|
45
|
+
const output = (err.stdout || "") + (err.stderr || "") + (err.message || "");
|
|
46
|
+
return {
|
|
47
|
+
target,
|
|
48
|
+
type,
|
|
49
|
+
passed: false,
|
|
50
|
+
output: output || "Triage script execution failed",
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* List available security tools
|
|
56
|
+
*/
|
|
57
|
+
export async function listTriageTools() {
|
|
58
|
+
return runTriage("tools", "");
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Parse the triage output for structured data
|
|
62
|
+
*/
|
|
63
|
+
export function parseTriageOutput(output) {
|
|
64
|
+
const healthMatch = output.match(/Health score: (\d+\/\d+)/);
|
|
65
|
+
const criticalMatch = output.match(/Critical issues: (\d+)/);
|
|
66
|
+
const warningsMatch = output.match(/Warnings: (\d+)/);
|
|
67
|
+
const sections = output
|
|
68
|
+
.split("──────")
|
|
69
|
+
.filter((s) => s.trim())
|
|
70
|
+
.map((s) => s.trim().split("\n")[0]?.trim())
|
|
71
|
+
.filter(Boolean);
|
|
72
|
+
return {
|
|
73
|
+
healthScore: healthMatch?.[1],
|
|
74
|
+
criticalIssues: criticalMatch ? parseInt(criticalMatch[1]) : 0,
|
|
75
|
+
warnings: warningsMatch ? parseInt(warningsMatch[1]) : 0,
|
|
76
|
+
sections,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=triage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triage.js","sourceRoot":"","sources":["../src/triage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface UpdateInfo {
|
|
2
|
+
available: boolean;
|
|
3
|
+
latest: string;
|
|
4
|
+
current: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Check npm registry for a newer version of kit.
|
|
8
|
+
* Returns null if already on latest, check fails, or check is suppressed.
|
|
9
|
+
* Never throws — all errors are caught silently.
|
|
10
|
+
*/
|
|
11
|
+
export declare function checkForUpdate(currentVersion: string): Promise<UpdateInfo | null>;
|
|
12
|
+
/** Format and print the update notice after command output. */
|
|
13
|
+
export declare function printUpdateNotice(info: UpdateInfo): void;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
const PACKAGE_NAME = "sandstream-kit";
|
|
5
|
+
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
6
|
+
const CACHE_DIR = join(homedir(), ".kit");
|
|
7
|
+
const CACHE_FILE = join(CACHE_DIR, "last-update-check.json");
|
|
8
|
+
/**
|
|
9
|
+
* Check npm registry for a newer version of kit.
|
|
10
|
+
* Returns null if already on latest, check fails, or check is suppressed.
|
|
11
|
+
* Never throws — all errors are caught silently.
|
|
12
|
+
*/
|
|
13
|
+
export async function checkForUpdate(currentVersion) {
|
|
14
|
+
try {
|
|
15
|
+
// Suppression conditions
|
|
16
|
+
if (process.env.KIT_NO_UPDATE_CHECK === "1" ||
|
|
17
|
+
process.env.CI === "true" ||
|
|
18
|
+
process.env.GITHUB_ACTIONS === "true" ||
|
|
19
|
+
process.env.GITLAB_CI === "true") {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
// Read cache
|
|
23
|
+
let cache = null;
|
|
24
|
+
try {
|
|
25
|
+
const raw = await readFile(CACHE_FILE, "utf8");
|
|
26
|
+
cache = JSON.parse(raw);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// No cache yet
|
|
30
|
+
}
|
|
31
|
+
const now = Date.now();
|
|
32
|
+
// Use cached result if fresh
|
|
33
|
+
if (cache && now - cache.checkedAt < CHECK_INTERVAL_MS) {
|
|
34
|
+
const latest = cache.latestVersion;
|
|
35
|
+
if (isNewer(latest, currentVersion)) {
|
|
36
|
+
return { available: true, latest, current: currentVersion };
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
// Fetch latest from npm registry
|
|
41
|
+
const resp = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {
|
|
42
|
+
signal: AbortSignal.timeout(3_000),
|
|
43
|
+
headers: { Accept: "application/json" },
|
|
44
|
+
});
|
|
45
|
+
if (!resp.ok)
|
|
46
|
+
return null;
|
|
47
|
+
const data = (await resp.json());
|
|
48
|
+
const latest = data.version;
|
|
49
|
+
// Write cache
|
|
50
|
+
try {
|
|
51
|
+
await mkdir(CACHE_DIR, { recursive: true });
|
|
52
|
+
await writeFile(CACHE_FILE, JSON.stringify({ checkedAt: now, latestVersion: latest }), "utf8");
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Cache write failure is non-fatal
|
|
56
|
+
}
|
|
57
|
+
if (isNewer(latest, currentVersion)) {
|
|
58
|
+
return { available: true, latest, current: currentVersion };
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Returns true if `latest` is strictly newer than `current` (semver comparison). */
|
|
67
|
+
function isNewer(latest, current) {
|
|
68
|
+
try {
|
|
69
|
+
const parse = (v) => v.replace(/^v/, "").split(".").map(Number);
|
|
70
|
+
const [lMaj, lMin, lPatch] = parse(latest);
|
|
71
|
+
const [cMaj, cMin, cPatch] = parse(current);
|
|
72
|
+
if (lMaj !== cMaj)
|
|
73
|
+
return lMaj > cMaj;
|
|
74
|
+
if (lMin !== cMin)
|
|
75
|
+
return lMin > cMin;
|
|
76
|
+
return lPatch > cPatch;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Format and print the update notice after command output. */
|
|
83
|
+
export function printUpdateNotice(info) {
|
|
84
|
+
const dim = "\x1b[2m";
|
|
85
|
+
const reset = "\x1b[0m";
|
|
86
|
+
const yellow = "\x1b[33m";
|
|
87
|
+
const cyan = "\x1b[36m";
|
|
88
|
+
console.log(`\n ${dim}╰─${reset} ${yellow}Update available${reset}: ${dim}${info.current}${reset} → ${cyan}${info.latest}${reset} ` +
|
|
89
|
+
`${dim}npm install -g ${PACKAGE_NAME}${reset}`);
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=update-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared ANSI color codes. Single source of truth — cli.ts and output.ts
|
|
3
|
+
* previously each declared an identical private copy; extracted command
|
|
4
|
+
* modules import this one.
|
|
5
|
+
*/
|
|
6
|
+
export declare const c: {
|
|
7
|
+
readonly reset: "\u001B[0m";
|
|
8
|
+
readonly bold: "\u001B[1m";
|
|
9
|
+
readonly dim: "\u001B[2m";
|
|
10
|
+
readonly green: "\u001B[32m";
|
|
11
|
+
readonly red: "\u001B[31m";
|
|
12
|
+
readonly yellow: "\u001B[33m";
|
|
13
|
+
readonly cyan: "\u001B[36m";
|
|
14
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared ANSI color codes. Single source of truth — cli.ts and output.ts
|
|
3
|
+
* previously each declared an identical private copy; extracted command
|
|
4
|
+
* modules import this one.
|
|
5
|
+
*/
|
|
6
|
+
export const c = {
|
|
7
|
+
reset: "\x1b[0m",
|
|
8
|
+
bold: "\x1b[1m",
|
|
9
|
+
dim: "\x1b[2m",
|
|
10
|
+
green: "\x1b[32m",
|
|
11
|
+
red: "\x1b[31m",
|
|
12
|
+
yellow: "\x1b[33m",
|
|
13
|
+
cyan: "\x1b[36m",
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=colors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/utils/colors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,CAAC,GAAG;IACf,KAAK,EAAE,SAAS;IAChB,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,UAAU;IACjB,GAAG,EAAE,UAAU;IACf,MAAM,EAAE,UAAU;IAClB,IAAI,EAAE,UAAU;CACR,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Did you mean …?" suggestion for mistyped CLI subcommands.
|
|
3
|
+
*
|
|
4
|
+
* Plain Levenshtein with early-out on length difference. Suggestion
|
|
5
|
+
* threshold: distance <= 2 for short names, <= 3 for names longer than
|
|
6
|
+
* 8 chars — tight enough that unrelated commands never surface, loose
|
|
7
|
+
* enough to catch transpositions ("chekc"), drops ("screts") and fat
|
|
8
|
+
* fingers ("securty").
|
|
9
|
+
*/
|
|
10
|
+
export declare function levenshtein(a: string, b: string): number;
|
|
11
|
+
/**
|
|
12
|
+
* Return the closest candidates to `input`, best first. Empty array when
|
|
13
|
+
* nothing is within the distance threshold.
|
|
14
|
+
*/
|
|
15
|
+
export declare function didYouMean(input: string, candidates: string[]): string[];
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Did you mean …?" suggestion for mistyped CLI subcommands.
|
|
3
|
+
*
|
|
4
|
+
* Plain Levenshtein with early-out on length difference. Suggestion
|
|
5
|
+
* threshold: distance <= 2 for short names, <= 3 for names longer than
|
|
6
|
+
* 8 chars — tight enough that unrelated commands never surface, loose
|
|
7
|
+
* enough to catch transpositions ("chekc"), drops ("screts") and fat
|
|
8
|
+
* fingers ("securty").
|
|
9
|
+
*/
|
|
10
|
+
export function levenshtein(a, b) {
|
|
11
|
+
if (a === b)
|
|
12
|
+
return 0;
|
|
13
|
+
if (a.length === 0)
|
|
14
|
+
return b.length;
|
|
15
|
+
if (b.length === 0)
|
|
16
|
+
return a.length;
|
|
17
|
+
let prev = new Array(b.length + 1);
|
|
18
|
+
let curr = new Array(b.length + 1);
|
|
19
|
+
for (let j = 0; j <= b.length; j++)
|
|
20
|
+
prev[j] = j;
|
|
21
|
+
for (let i = 1; i <= a.length; i++) {
|
|
22
|
+
curr[0] = i;
|
|
23
|
+
for (let j = 1; j <= b.length; j++) {
|
|
24
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
25
|
+
curr[j] = Math.min(prev[j] + 1, // deletion
|
|
26
|
+
curr[j - 1] + 1, // insertion
|
|
27
|
+
prev[j - 1] + cost);
|
|
28
|
+
}
|
|
29
|
+
[prev, curr] = [curr, prev];
|
|
30
|
+
}
|
|
31
|
+
return prev[b.length];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Return the closest candidates to `input`, best first. Empty array when
|
|
35
|
+
* nothing is within the distance threshold.
|
|
36
|
+
*/
|
|
37
|
+
export function didYouMean(input, candidates) {
|
|
38
|
+
const lower = input.toLowerCase();
|
|
39
|
+
const maxDist = lower.length > 8 ? 3 : 2;
|
|
40
|
+
return candidates
|
|
41
|
+
.map((c) => ({ c, d: levenshtein(lower, c.toLowerCase()) }))
|
|
42
|
+
.filter(({ d }) => d > 0 && d <= maxDist)
|
|
43
|
+
.sort((x, y) => x.d - y.d)
|
|
44
|
+
.slice(0, 3)
|
|
45
|
+
.map(({ c }) => c);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=didYouMean.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"didYouMean.js","sourceRoot":"","sources":["../../src/utils/didYouMean.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,UAAU,WAAW,CAAC,CAAS,EAAE,CAAS;IAC9C,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtB,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,MAAM,CAAC;IAEpC,IAAI,IAAI,GAAG,IAAI,KAAK,CAAS,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3C,IAAI,IAAI,GAAG,IAAI,KAAK,CAAS,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAEhD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAChB,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAS,WAAW;YAC/B,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAK,YAAY;YAChC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CACnB,CAAC;QACJ,CAAC;QACD,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AACxB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,UAAoB;IAC5D,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,OAAO,UAAU;SACd,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;SAC3D,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC;SACxC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SACzB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { execFile as execFileCb } from "node:child_process";
|
|
2
|
+
/**
|
|
3
|
+
* Canonical promisified execFile for the whole codebase.
|
|
4
|
+
*
|
|
5
|
+
* Why a shared module: 30+ files previously declared their own
|
|
6
|
+
* `const exec = promisify(execFile)` — three lines of boilerplate per
|
|
7
|
+
* file, and a drift risk (anyone "simplifying" to `exec` from
|
|
8
|
+
* node:child_process reintroduces shell-injection surface). Import this
|
|
9
|
+
* instead:
|
|
10
|
+
*
|
|
11
|
+
* import { exec } from "./utils/exec.js";
|
|
12
|
+
*
|
|
13
|
+
* SECURITY INVARIANT: always pass arguments as an array. Never build a
|
|
14
|
+
* shell string. execFile does not spawn a shell, so metacharacters in
|
|
15
|
+
* arguments are inert.
|
|
16
|
+
*
|
|
17
|
+
* For a never-throwing variant returning { stdout, stderr, exitCode, ok },
|
|
18
|
+
* use execFileNoThrow from ./execFileNoThrow.js.
|
|
19
|
+
*/
|
|
20
|
+
export declare const exec: typeof execFileCb.__promisify__;
|
|
21
|
+
export { execFileNoThrow, type ExecResult } from "./execFileNoThrow.js";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { execFile as execFileCb } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
/**
|
|
4
|
+
* Canonical promisified execFile for the whole codebase.
|
|
5
|
+
*
|
|
6
|
+
* Why a shared module: 30+ files previously declared their own
|
|
7
|
+
* `const exec = promisify(execFile)` — three lines of boilerplate per
|
|
8
|
+
* file, and a drift risk (anyone "simplifying" to `exec` from
|
|
9
|
+
* node:child_process reintroduces shell-injection surface). Import this
|
|
10
|
+
* instead:
|
|
11
|
+
*
|
|
12
|
+
* import { exec } from "./utils/exec.js";
|
|
13
|
+
*
|
|
14
|
+
* SECURITY INVARIANT: always pass arguments as an array. Never build a
|
|
15
|
+
* shell string. execFile does not spawn a shell, so metacharacters in
|
|
16
|
+
* arguments are inert.
|
|
17
|
+
*
|
|
18
|
+
* For a never-throwing variant returning { stdout, stderr, exitCode, ok },
|
|
19
|
+
* use execFileNoThrow from ./execFileNoThrow.js.
|
|
20
|
+
*/
|
|
21
|
+
export const exec = promisify(execFileCb);
|
|
22
|
+
export { execFileNoThrow } from "./execFileNoThrow.js";
|
|
23
|
+
//# sourceMappingURL=exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAmB,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ExecResult {
|
|
2
|
+
stdout: string;
|
|
3
|
+
stderr: string;
|
|
4
|
+
exitCode: number;
|
|
5
|
+
ok: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Runs a command safely using execFile (no shell, no injection risk).
|
|
9
|
+
* Never throws — returns structured result with exitCode and ok flag.
|
|
10
|
+
*/
|
|
11
|
+
export declare function execFileNoThrow(command: string, args: string[], options?: {
|
|
12
|
+
timeout?: number;
|
|
13
|
+
env?: NodeJS.ProcessEnv;
|
|
14
|
+
}): Promise<ExecResult>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
const execFileAsync = promisify(execFile);
|
|
4
|
+
/**
|
|
5
|
+
* Runs a command safely using execFile (no shell, no injection risk).
|
|
6
|
+
* Never throws — returns structured result with exitCode and ok flag.
|
|
7
|
+
*/
|
|
8
|
+
export async function execFileNoThrow(command, args, options) {
|
|
9
|
+
try {
|
|
10
|
+
const { stdout, stderr } = await execFileAsync(command, args, {
|
|
11
|
+
timeout: options?.timeout ?? 30_000,
|
|
12
|
+
env: options?.env ?? process.env,
|
|
13
|
+
});
|
|
14
|
+
return { stdout, stderr, exitCode: 0, ok: true };
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
if (error && typeof error === "object") {
|
|
18
|
+
const e = error;
|
|
19
|
+
return {
|
|
20
|
+
stdout: e.stdout ?? "",
|
|
21
|
+
stderr: e.stderr ?? "",
|
|
22
|
+
exitCode: typeof e.code === "number" ? e.code : 1,
|
|
23
|
+
ok: false,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return { stdout: "", stderr: String(error), exitCode: 1, ok: false };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=execFileNoThrow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execFileNoThrow.js","sourceRoot":"","sources":["../../src/utils/execFileNoThrow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAS1C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAe,EACf,IAAc,EACd,OAAuD;IAEvD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE;YAC5D,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,MAAM;YACnC,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG;SACjC,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACnD,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvC,MAAM,CAAC,GAAG,KAAqE,CAAC;YAChF,OAAO;gBACL,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE;gBACtB,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE;gBACtB,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACjD,EAAE,EAAE,KAAK;aACV,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;IACvE,CAAC;AACH,CAAC"}
|