torusguard 1.3.0 → 1.3.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/.torusguard/.manifest.json +113 -9
- package/.torusguard/rules/README.md +93 -62
- package/.torusguard/rules/TG-AUTH-001-weak-password-storage.md +103 -0
- package/.torusguard/rules/TG-AUTH-002-client-only-authorization.md +85 -0
- package/.torusguard/rules/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/.torusguard/rules/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/.torusguard/rules/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/.torusguard/rules/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/.torusguard/rules/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/.torusguard/rules/TG-DB-001-frontend-database-query.md +83 -0
- package/.torusguard/rules/TG-DB-002-privileged-database-credential.md +86 -0
- package/.torusguard/rules/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/.torusguard/rules/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/.torusguard/rules/TG-INPUT-001-missing-server-validation.md +98 -0
- package/.torusguard/rules/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/.torusguard/rules/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/.torusguard/rules/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/.torusguard/rules/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/.torusguard/rules/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/.torusguard/rules/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/.torusguard/rules/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/.torusguard/rules/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/.torusguard/rules/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/.torusguard/rules/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/.torusguard/rules/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/.torusguard/rules/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/.torusguard/rules/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/.torusguard/rules/TG-SEC-002-public-environment-secrets.md +83 -0
- package/.torusguard/rules/TG-SEC-003-tracked-env-file.md +79 -0
- package/.torusguard/rules/TG-SEC-004-sensitive-logging.md +83 -0
- package/.torusguard/rules/active/TG-AUTH-001-weak-password-storage.md +103 -0
- package/.torusguard/rules/active/TG-AUTH-002-client-only-authorization.md +85 -0
- package/.torusguard/rules/active/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/.torusguard/rules/active/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/.torusguard/rules/active/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/.torusguard/rules/active/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/.torusguard/rules/active/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/.torusguard/rules/active/TG-DB-001-frontend-database-query.md +83 -0
- package/.torusguard/rules/active/TG-DB-002-privileged-database-credential.md +86 -0
- package/.torusguard/rules/active/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/.torusguard/rules/active/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/.torusguard/rules/active/TG-INPUT-001-missing-server-validation.md +98 -0
- package/.torusguard/rules/active/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/.torusguard/rules/active/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/.torusguard/rules/active/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/.torusguard/rules/active/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/.torusguard/rules/active/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/.torusguard/rules/active/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/.torusguard/rules/active/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/.torusguard/rules/active/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/.torusguard/rules/active/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/.torusguard/rules/active/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/.torusguard/rules/active/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/.torusguard/rules/active/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/.torusguard/rules/active/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/.torusguard/rules/active/TG-SEC-002-public-environment-secrets.md +83 -0
- package/.torusguard/rules/active/TG-SEC-003-tracked-env-file.md +79 -0
- package/.torusguard/rules/active/TG-SEC-004-sensitive-logging.md +83 -0
- package/.torusguard/rules/agent/TG-AGENT-001-prompt-injection-system-context.md +56 -0
- package/.torusguard/rules/agent/TG-AGENT-002-unsafe-tool-dispatch-unsandboxed-execution.md +68 -0
- package/.torusguard/rules/agent/TG-AGENT-003-broad-mcp-tool-scoping.md +53 -0
- package/.torusguard/rules/agent/TG-AGENT-004-persistent-memory-cross-session-leakage.md +67 -0
- package/.torusguard/rules/authorization/TG-AUTH-006-mass-assignment.md +70 -0
- package/.torusguard/rules/authorization/TG-AUTH-007-missing-property-level-authorization.md +71 -0
- package/.torusguard/rules/authorization/TG-AUTH-008-untrusted-role-header-injection.md +112 -0
- package/.torusguard/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +37 -0
- package/.torusguard/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +37 -0
- package/.torusguard/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +37 -0
- package/.torusguard/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +37 -0
- package/.torusguard/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +37 -0
- package/.torusguard/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +37 -0
- package/.torusguard/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +37 -0
- package/.torusguard/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +37 -0
- package/.torusguard/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +37 -0
- package/.torusguard/rules/edge/TG-EDGE-001-serverless-global-state-leak.md +83 -0
- package/.torusguard/rules/edge/TG-EDGE-003-aws-lambda-ephemeral-cold-start.md +76 -0
- package/.torusguard/rules/graphql/TG-GQL-001-missing-query-depth-or-complexity-limits.md +64 -0
- package/.torusguard/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +37 -0
- package/.torusguard/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +37 -0
- package/.torusguard/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +37 -0
- package/.torusguard/rules/secrets/TG-SEC-005-secret-in-git-history.md +37 -0
- package/.torusguard/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +37 -0
- package/.torusguard/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +37 -0
- package/.torusguard/rules/ssrf/TG-SSRF-001-user-controlled-server-side-url-fetch.md +68 -0
- package/.torusguard/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +37 -0
- package/.torusguard/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +37 -0
- package/.torusguard/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-002-vulnerable-dependency-review-missing.md +94 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-006-container-build-secret-persistence.md +61 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +37 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +37 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +37 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +37 -0
- package/.torusguard/rules/websocket/TG-WS-001-unauthenticated-websocket-handshake.md +82 -0
- package/.torusguard/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +37 -0
- package/.torusguard/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +37 -0
- package/.torusguard/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +37 -0
- package/.torusguard/runs/report-latest.html +62 -20
- package/.torusguard/runs/run-20260908-112648-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-112648-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-112648-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260908-112648-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-112722-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-112722-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-112722-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260908-112722-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-113004-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-113004-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-113004-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260908-113004-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-113127-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-113127-audit/manifest.json +13 -0
- package/.torusguard/runs/run-20260908-113127-audit/remediation.md +262 -0
- package/.torusguard/runs/run-20260908-113127-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-115240-audit/apply_plan.md +6 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/diff_summary.md +221 -0
- package/.torusguard/runs/run-20260908-115240-audit/findings.json +1553 -0
- package/.torusguard/runs/run-20260908-115240-audit/findings.md +572 -0
- package/.torusguard/runs/run-20260908-115240-audit/manifest.json +14 -0
- package/.torusguard/runs/run-20260908-115240-audit/recheck.md +91 -0
- package/.torusguard/runs/run-20260908-115240-audit/remediation.md +278 -0
- package/.torusguard/runs/run-20260908-115240-audit/summary.md +5 -0
- package/.torusguard/scripts/__pycache__/audit_runner.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/finding_scorer.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/memory_engine.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/monorepo_detector.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/run_manager.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/stack_detect.cpython-311.pyc +0 -0
- package/.torusguard/scripts/apply_runner.py +339 -0
- package/.torusguard/scripts/audit_runner.py +550 -0
- package/.torusguard/scripts/diff_guard.py +52 -4
- package/.torusguard/scripts/finding_scorer.py +58 -0
- package/.torusguard/scripts/harden_runner.py +375 -0
- package/.torusguard/scripts/html_reporter.py +25 -10
- package/.torusguard/scripts/manifest_builder.py +2 -0
- package/.torusguard/scripts/memory_engine.py +4 -0
- package/.torusguard/scripts/recheck_runner.py +221 -0
- package/.torusguard/scripts/recipes_runner.py +130 -0
- package/.torusguard/scripts/run_manager.py +17 -5
- package/.torusguard/skills/torusguard/SKILL.md +42 -42
- package/.torusguard/skills/torusguard/bootstrap.py +149 -70
- package/.torusguard/snapshots/run-20260908-115240-audit/examples/vulnerable-react-express/client/src/App.jsx.bak +63 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/examples/vulnerable-react-express/server/index.js.bak +82 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/engine/fixture_manager.py.bak +245 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/master_validation.py.bak +698 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/runner.py.bak +551 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_e2e.py.bak +498 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_qa_v0_6_0.py.bak +572 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_1_scale.py.bak +371 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_2_modern_stacks.py.bak +462 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_3_hardening.py.bak +444 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v1_0_0_memory.py.bak +302 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v1_1_0_advanced_memory.py.bak +342 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/skills/torusguard/payload/scripts/harden_runner.py.bak +353 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/tests/test_v0_6_0_governed_remediation.py.bak +353 -0
- package/README.md +70 -33
- package/bin/torusguard.js +92 -22
- package/package.json +1 -1
- package/skills/torusguard/SKILL.md +42 -42
- package/skills/torusguard/bootstrap.py +147 -68
- package/skills/torusguard/payload/.manifest.json +113 -9
- package/skills/torusguard/payload/rules/README.md +93 -62
- package/skills/torusguard/payload/rules/TG-AUTH-001-weak-password-storage.md +103 -0
- package/skills/torusguard/payload/rules/TG-AUTH-002-client-only-authorization.md +85 -0
- package/skills/torusguard/payload/rules/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/skills/torusguard/payload/rules/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/skills/torusguard/payload/rules/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/skills/torusguard/payload/rules/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/skills/torusguard/payload/rules/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/skills/torusguard/payload/rules/TG-DB-001-frontend-database-query.md +83 -0
- package/skills/torusguard/payload/rules/TG-DB-002-privileged-database-credential.md +86 -0
- package/skills/torusguard/payload/rules/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/skills/torusguard/payload/rules/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/skills/torusguard/payload/rules/TG-INPUT-001-missing-server-validation.md +98 -0
- package/skills/torusguard/payload/rules/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/skills/torusguard/payload/rules/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/skills/torusguard/payload/rules/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/skills/torusguard/payload/rules/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/skills/torusguard/payload/rules/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/skills/torusguard/payload/rules/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/skills/torusguard/payload/rules/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/skills/torusguard/payload/rules/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/skills/torusguard/payload/rules/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/skills/torusguard/payload/rules/TG-SEC-002-public-environment-secrets.md +83 -0
- package/skills/torusguard/payload/rules/TG-SEC-003-tracked-env-file.md +79 -0
- package/skills/torusguard/payload/rules/TG-SEC-004-sensitive-logging.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-001-weak-password-storage.md +103 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-002-client-only-authorization.md +85 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/skills/torusguard/payload/rules/active/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-DB-001-frontend-database-query.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-DB-002-privileged-database-credential.md +86 -0
- package/skills/torusguard/payload/rules/active/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/skills/torusguard/payload/rules/active/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-001-missing-server-validation.md +98 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/skills/torusguard/payload/rules/active/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/skills/torusguard/payload/rules/active/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-002-public-environment-secrets.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-003-tracked-env-file.md +79 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-004-sensitive-logging.md +83 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-001-prompt-injection-system-context.md +56 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-002-unsafe-tool-dispatch-unsandboxed-execution.md +68 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-003-broad-mcp-tool-scoping.md +53 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-004-persistent-memory-cross-session-leakage.md +67 -0
- package/skills/torusguard/payload/rules/authorization/TG-AUTH-006-mass-assignment.md +70 -0
- package/skills/torusguard/payload/rules/authorization/TG-AUTH-007-missing-property-level-authorization.md +71 -0
- package/skills/torusguard/payload/rules/authorization/TG-AUTH-008-untrusted-role-header-injection.md +112 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +37 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +37 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +37 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +37 -0
- package/skills/torusguard/payload/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +37 -0
- package/skills/torusguard/payload/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +37 -0
- package/skills/torusguard/payload/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +37 -0
- package/skills/torusguard/payload/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +37 -0
- package/skills/torusguard/payload/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +37 -0
- package/skills/torusguard/payload/rules/edge/TG-EDGE-001-serverless-global-state-leak.md +83 -0
- package/skills/torusguard/payload/rules/edge/TG-EDGE-003-aws-lambda-ephemeral-cold-start.md +76 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-001-missing-query-depth-or-complexity-limits.md +64 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +37 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +37 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +37 -0
- package/skills/torusguard/payload/rules/secrets/TG-SEC-005-secret-in-git-history.md +37 -0
- package/skills/torusguard/payload/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +37 -0
- package/skills/torusguard/payload/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +37 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-001-user-controlled-server-side-url-fetch.md +68 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +37 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +37 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-002-vulnerable-dependency-review-missing.md +94 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-006-container-build-secret-persistence.md +61 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +37 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +37 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +37 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +37 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-001-unauthenticated-websocket-handshake.md +82 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +37 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +37 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +37 -0
- package/skills/torusguard/payload/scripts/apply_runner.py +339 -0
- package/skills/torusguard/payload/scripts/audit_runner.py +550 -0
- package/skills/torusguard/payload/scripts/diff_guard.py +52 -4
- package/skills/torusguard/payload/scripts/finding_scorer.py +58 -0
- package/skills/torusguard/payload/scripts/harden_runner.py +375 -0
- package/skills/torusguard/payload/scripts/html_reporter.py +25 -10
- package/skills/torusguard/payload/scripts/manifest_builder.py +2 -0
- package/skills/torusguard/payload/scripts/memory_engine.py +4 -0
- package/skills/torusguard/payload/scripts/recheck_runner.py +221 -0
- package/skills/torusguard/payload/scripts/recipes_runner.py +130 -0
- package/skills/torusguard/payload/scripts/run_manager.py +17 -5
- package/skills/torusguard/payload/skills/torusguard/SKILL.md +42 -42
- package/skills/torusguard/payload/skills/torusguard/bootstrap.py +147 -68
package/bin/torusguard.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* TorusGuard CLI Runner (NPM Distribution)
|
|
@@ -49,7 +49,7 @@ function printHelp() {
|
|
|
49
49
|
console.log(`
|
|
50
50
|
${CYAN}╭─────────────────────────────────────────────────────────────────────────╮${RESET}
|
|
51
51
|
${CYAN}│${RESET} ${CYAN}│${RESET}
|
|
52
|
-
${CYAN}│${RESET} ${BOLD}${WHITE}🛡️ T O R U S G U A R D C L I${RESET} ${GRAY}v1.3.
|
|
52
|
+
${CYAN}│${RESET} ${BOLD}${WHITE}🛡️ T O R U S G U A R D C L I${RESET} ${GRAY}v1.3.2${RESET} ${CYAN}│${RESET}
|
|
53
53
|
${CYAN}│${RESET} ${DIM}Autonomous Security Engine for AI-Built Applications${RESET} ${CYAN}│${RESET}
|
|
54
54
|
${CYAN}│${RESET} ${CYAN}│${RESET}
|
|
55
55
|
${CYAN}╰─────────────────────────────────────────────────────────────────────────╯${RESET}
|
|
@@ -64,6 +64,11 @@ function printHelp() {
|
|
|
64
64
|
${CYAN}│${RESET} ${GREEN}rules${RESET} Auto-sync memory to AI IDE rules (.cursorrules, CLAUDE.md) ${CYAN}│${RESET}
|
|
65
65
|
${CYAN}│${RESET} ${GREEN}memory${RESET} Manage persistent security memory (export, hook, learn) ${CYAN}│${RESET}
|
|
66
66
|
${CYAN}│${RESET} ${GREEN}audit${RESET} Run static AST security scan on the target project ${CYAN}│${RESET}
|
|
67
|
+
${CYAN}│${RESET} ${GREEN}harden${RESET} Formulate minimal candidate patches (Ponytail bounded) ${CYAN}│${RESET}
|
|
68
|
+
${CYAN}│${RESET} ${GREEN}apply${RESET} Apply candidate patches with automatic .bak snapshots ${CYAN}│${RESET}
|
|
69
|
+
${CYAN}│${RESET} ${GREEN}recheck${RESET} Targeted differential verification of applied fixes ${CYAN}│${RESET}
|
|
70
|
+
${CYAN}│${RESET} ${GREEN}recipes${RESET} List & inspect distilled Golden Fix Recipes in memory ${CYAN}│${RESET}
|
|
71
|
+
${CYAN}│${RESET} ${GREEN}rollback${RESET} Instantly revert files from latest pre-apply snapshot ${CYAN}│${RESET}
|
|
67
72
|
${CYAN}│${RESET} ${GREEN}report${RESET} Export OASIS SARIF v2.1.0 or single-file visual HTML report ${CYAN}│${RESET}
|
|
68
73
|
${CYAN}│${RESET} ${GREEN}diff-guard${RESET} Scan diffs or wire pre-commit hook (--install-hook) ${CYAN}│${RESET}
|
|
69
74
|
${CYAN}│${RESET} ${GREEN}help${RESET} Show this interactive command guide ${CYAN}│${RESET}
|
|
@@ -137,7 +142,7 @@ if (command === 'status') {
|
|
|
137
142
|
console.log(`
|
|
138
143
|
${CYAN}╭─────────────────────────────────────────────────────────────────────────╮${RESET}
|
|
139
144
|
${CYAN}│${RESET} ${CYAN}│${RESET}
|
|
140
|
-
${CYAN}│${RESET} ${BOLD}${WHITE}🛡️ TORUSGUARD SECURITY POSTURE${RESET} ${GRAY}v1.3.
|
|
145
|
+
${CYAN}│${RESET} ${BOLD}${WHITE}🛡️ TORUSGUARD SECURITY POSTURE${RESET} ${GRAY}v1.3.2${RESET} ${CYAN}│${RESET}
|
|
141
146
|
${CYAN}│${RESET} ${CYAN}│${RESET}
|
|
142
147
|
${CYAN}╰─────────────────────────────────────────────────────────────────────────╯${RESET}
|
|
143
148
|
|
|
@@ -287,7 +292,7 @@ if (command === 'memory') {
|
|
|
287
292
|
if (command === 'diff-guard') {
|
|
288
293
|
const diffScript = path.join(cwd, '.torusguard', 'scripts', 'diff_guard.py');
|
|
289
294
|
const fallbackDiffScript = path.join(rootDir, '.torusguard', 'scripts', 'diff_guard.py');
|
|
290
|
-
const actualDiffScript = fs.existsSync(
|
|
295
|
+
const actualDiffScript = fs.existsSync(fallbackDiffScript) ? fallbackDiffScript : diffScript;
|
|
291
296
|
|
|
292
297
|
const proc = spawnSync(pythonCmd, [actualDiffScript, ...args.slice(1)], { stdio: 'inherit', cwd });
|
|
293
298
|
process.exit(proc.status !== null ? proc.status : 0);
|
|
@@ -298,7 +303,7 @@ if (command === 'rules') {
|
|
|
298
303
|
const sub = args[1] || 'sync';
|
|
299
304
|
const rulesScript = path.join(cwd, '.torusguard', 'scripts', 'rules_sync.py');
|
|
300
305
|
const fallbackRulesScript = path.join(rootDir, '.torusguard', 'scripts', 'rules_sync.py');
|
|
301
|
-
const actualRulesScript = fs.existsSync(
|
|
306
|
+
const actualRulesScript = fs.existsSync(fallbackRulesScript) ? fallbackRulesScript : rulesScript;
|
|
302
307
|
|
|
303
308
|
let pyArgs = [actualRulesScript];
|
|
304
309
|
if (sub === 'sync') {
|
|
@@ -321,12 +326,22 @@ if (command === 'rules') {
|
|
|
321
326
|
process.exit(proc.status !== null ? proc.status : 0);
|
|
322
327
|
}
|
|
323
328
|
|
|
329
|
+
// Subcommand: audit
|
|
330
|
+
if (command === 'audit') {
|
|
331
|
+
const auditScript = path.join(cwd, '.torusguard', 'scripts', 'audit_runner.py');
|
|
332
|
+
const fallbackAuditScript = path.join(rootDir, '.torusguard', 'scripts', 'audit_runner.py');
|
|
333
|
+
const actualAuditScript = fs.existsSync(fallbackAuditScript) ? fallbackAuditScript : auditScript;
|
|
334
|
+
|
|
335
|
+
const proc = spawnSync(pythonCmd, [actualAuditScript, ...args.slice(1)], { stdio: 'inherit', cwd });
|
|
336
|
+
process.exit(proc.status !== null ? proc.status : 0);
|
|
337
|
+
}
|
|
338
|
+
|
|
324
339
|
// Subcommand: report
|
|
325
340
|
if (command === 'report') {
|
|
326
341
|
if (args.includes('--html') || args[1] === 'html') {
|
|
327
342
|
const htmlScript = path.join(cwd, '.torusguard', 'scripts', 'html_reporter.py');
|
|
328
343
|
const fallbackHtmlScript = path.join(rootDir, '.torusguard', 'scripts', 'html_reporter.py');
|
|
329
|
-
const actualHtmlScript = fs.existsSync(
|
|
344
|
+
const actualHtmlScript = fs.existsSync(fallbackHtmlScript) ? fallbackHtmlScript : htmlScript;
|
|
330
345
|
|
|
331
346
|
let pyArgs = [actualHtmlScript];
|
|
332
347
|
const outIdx = args.indexOf('--out');
|
|
@@ -343,26 +358,81 @@ if (command === 'report') {
|
|
|
343
358
|
|
|
344
359
|
const proc = spawnSync(pythonCmd, pyArgs, { stdio: 'inherit', cwd });
|
|
345
360
|
process.exit(proc.status !== null ? proc.status : 0);
|
|
361
|
+
} else {
|
|
362
|
+
const sarifScript = path.join(cwd, '.torusguard', 'scripts', 'sarif_exporter.py');
|
|
363
|
+
const fallbackSarifScript = path.join(rootDir, '.torusguard', 'scripts', 'sarif_exporter.py');
|
|
364
|
+
const actualSarifScript = fs.existsSync(fallbackSarifScript) ? fallbackSarifScript : sarifScript;
|
|
365
|
+
|
|
366
|
+
const proc = spawnSync(pythonCmd, [actualSarifScript, ...args.slice(1)], { stdio: 'inherit', cwd });
|
|
367
|
+
process.exit(proc.status !== null ? proc.status : 0);
|
|
346
368
|
}
|
|
347
369
|
}
|
|
348
370
|
|
|
349
|
-
//
|
|
350
|
-
|
|
351
|
-
const
|
|
352
|
-
const
|
|
371
|
+
// Subcommand: harden
|
|
372
|
+
if (command === 'harden') {
|
|
373
|
+
const scriptPath = path.join(cwd, '.torusguard', 'scripts', 'harden_runner.py');
|
|
374
|
+
const fallbackScript = path.join(rootDir, '.torusguard', 'scripts', 'harden_runner.py');
|
|
375
|
+
const actualScript = fs.existsSync(fallbackScript) ? fallbackScript : scriptPath;
|
|
353
376
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
377
|
+
const proc = spawnSync(pythonCmd, [actualScript, ...args.slice(1)], { stdio: 'inherit', cwd });
|
|
378
|
+
process.exit(proc.status !== null ? proc.status : 0);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Subcommand: apply
|
|
382
|
+
if (command === 'apply') {
|
|
383
|
+
const scriptPath = path.join(cwd, '.torusguard', 'scripts', 'apply_runner.py');
|
|
384
|
+
const fallbackScript = path.join(rootDir, '.torusguard', 'scripts', 'apply_runner.py');
|
|
385
|
+
const actualScript = fs.existsSync(fallbackScript) ? fallbackScript : scriptPath;
|
|
386
|
+
|
|
387
|
+
const proc = spawnSync(pythonCmd, [actualScript, ...args.slice(1)], { stdio: 'inherit', cwd });
|
|
388
|
+
process.exit(proc.status !== null ? proc.status : 0);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Subcommand: rollback
|
|
392
|
+
if (command === 'rollback') {
|
|
393
|
+
const scriptPath = path.join(cwd, '.torusguard', 'scripts', 'apply_runner.py');
|
|
394
|
+
const fallbackScript = path.join(rootDir, '.torusguard', 'scripts', 'apply_runner.py');
|
|
395
|
+
const actualScript = fs.existsSync(fallbackScript) ? fallbackScript : scriptPath;
|
|
396
|
+
|
|
397
|
+
const proc = spawnSync(pythonCmd, [actualScript, '--rollback', ...args.slice(1)], { stdio: 'inherit', cwd });
|
|
398
|
+
process.exit(proc.status !== null ? proc.status : 0);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Subcommand: recheck / verify
|
|
402
|
+
if (command === 'recheck' || command === 'verify') {
|
|
403
|
+
const scriptPath = path.join(cwd, '.torusguard', 'scripts', 'recheck_runner.py');
|
|
404
|
+
const fallbackScript = path.join(rootDir, '.torusguard', 'scripts', 'recheck_runner.py');
|
|
405
|
+
const actualScript = fs.existsSync(fallbackScript) ? fallbackScript : scriptPath;
|
|
406
|
+
|
|
407
|
+
const proc = spawnSync(pythonCmd, [actualScript, ...args.slice(1)], { stdio: 'inherit', cwd });
|
|
408
|
+
process.exit(proc.status !== null ? proc.status : 0);
|
|
361
409
|
}
|
|
362
410
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
411
|
+
// Subcommand: recipes
|
|
412
|
+
if (command === 'recipes') {
|
|
413
|
+
const scriptPath = path.join(cwd, '.torusguard', 'scripts', 'recipes_runner.py');
|
|
414
|
+
const fallbackScript = path.join(rootDir, '.torusguard', 'scripts', 'recipes_runner.py');
|
|
415
|
+
const actualScript = fs.existsSync(fallbackScript) ? fallbackScript : scriptPath;
|
|
416
|
+
|
|
417
|
+
const proc = spawnSync(pythonCmd, [actualScript, ...args.slice(1)], { stdio: 'inherit', cwd });
|
|
418
|
+
process.exit(proc.status !== null ? proc.status : 0);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Subcommand: init (scaffold workspace)
|
|
422
|
+
if (command === 'init') {
|
|
423
|
+
const localBootstrap = path.join(rootDir, 'skills', 'torusguard', 'bootstrap.py');
|
|
424
|
+
const localInstall = path.join(rootDir, 'install.py');
|
|
425
|
+
const scriptToRun = fs.existsSync(localBootstrap) ? localBootstrap : localInstall;
|
|
426
|
+
|
|
427
|
+
const scriptArgs = [scriptToRun, '--full-commands', ...args.slice(1)];
|
|
428
|
+
const proc = spawnSync(pythonCmd, scriptArgs, {
|
|
429
|
+
stdio: 'inherit',
|
|
430
|
+
cwd: cwd,
|
|
431
|
+
});
|
|
432
|
+
process.exit(proc.status !== null ? proc.status : 0);
|
|
433
|
+
}
|
|
367
434
|
|
|
368
|
-
|
|
435
|
+
// Unknown command fallback
|
|
436
|
+
console.error(`\n ${RED}✖ Unknown command:${RESET} ${WHITE}${command}${RESET}`);
|
|
437
|
+
console.error(` Run ${GREEN}npx torusguard help${RESET} for available commands.\n`);
|
|
438
|
+
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: torusguard
|
|
3
|
-
description: "
|
|
4
|
-
version: 1.
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# TorusGuard Master Security Router
|
|
8
|
-
|
|
9
|
-
**Principle:** If the browser receives it, users can inspect it. Keep secrets, database queries, and authorization strictly on trusted server-side code.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## ⚡ Workspace Bootstrap Check
|
|
14
|
-
1. **If `.torusguard/` exists on disk:** Full governance active. Load `.torusguard/memory/context.json` into prompt context for local-first intelligence. Route commands to specialist workflows below.
|
|
15
|
-
2. **If `.torusguard/` is absent (Autonomous AI Mode):** Operates standalone in any AI agent (Kimi, Antigravity, VS Code, Cursor). Apply
|
|
16
|
-
- Server-side auth & tenant scoping (`.filter(tenant=...)`).
|
|
17
|
-
- Zero client-side secrets (`SUPABASE_SERVICE_ROLE_KEY`, live API keys).
|
|
18
|
-
- Ponytail Protocol patch limits ($\le 35$ additions, $\le 25$ deletions).
|
|
19
|
-
- *Upgrade:* Run `npx torusguard init` to unlock local `.torusguard/`
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## Specialist Skill Routing (Lazy Loading)
|
|
24
|
-
Load **only** the designated sub-skill on demand to preserve the 1,000–1,500 token budget:
|
|
25
|
-
|
|
26
|
-
| Command | Specialist Skill | Agent |
|
|
27
|
-
| :--- | :--- | :--- |
|
|
28
|
-
| `/torusguard init` | `skills/torusguard-init/SKILL.md` | `profiler` |
|
|
29
|
-
| `/torusguard authorize` | `skills/torusguard-authorize/SKILL.md` | `reviewer` |
|
|
30
|
-
| `/torusguard audit` | `skills/torusguard-audit/SKILL.md` | `auditor` |
|
|
31
|
-
| `/torusguard verify` | `skills/torusguard-verify/SKILL.md` | `validator` |
|
|
32
|
-
| `/torusguard web-validate` | `skills/torusguard-web-validate/SKILL.md` | `validator` |
|
|
33
|
-
| `/torusguard exploit-check
|
|
34
|
-
| `/torusguard harden` | `skills/torusguard-harden/SKILL.md` | `remediator
|
|
35
|
-
| `/torusguard apply` | `skills/torusguard-apply/SKILL.md` | `remediator
|
|
36
|
-
| `/torusguard recheck` | `skills/torusguard-recheck/SKILL.md` | `reviewer` |
|
|
37
|
-
| `/torusguard report` | `skills/torusguard-report/SKILL.md` | `reviewer` |
|
|
38
|
-
| `/torusguard status` | `skills/torusguard-status/SKILL.md` | `reviewer` |
|
|
39
|
-
| `/torusguard memory` | `skills/torusguard/SKILL.md` | `reviewer` |
|
|
40
|
-
| `/torusguard full` | `skills/torusguard-full/SKILL.md` | *All* |
|
|
41
|
-
|
|
42
|
-
*Note: Never load all skills simultaneously. Lazy-load strictly on demand.*
|
|
1
|
+
---
|
|
2
|
+
name: torusguard
|
|
3
|
+
description: "Universal autonomous security engine: 71 rules across 11 families, polyglot stack detection across 16+ languages, governed remediation (Ponytail Protocol <=35 add, <=25 del), SARIF v2.1.0 exports, single-file HTML dashboards, and persistent security memory context for modern web applications."
|
|
4
|
+
version: 1.3.2
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# TorusGuard Master Security Router
|
|
8
|
+
|
|
9
|
+
**Principle:** If the browser or client receives it, users can inspect it. Keep secrets, database queries, and authorization strictly on trusted server-side code.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## ⚡ Workspace Bootstrap Check
|
|
14
|
+
1. **If `.torusguard/` exists on disk:** Full autonomous governance active. Load `.torusguard/memory/context.json` into prompt context for local-first intelligence. Route commands to specialist workflows below.
|
|
15
|
+
2. **If `.torusguard/` is absent (Autonomous AI Mode):** Operates standalone in any AI agent (Kimi, Antigravity, VS Code, Cursor, Claude Code, Windsurf). Apply universal security invariants:
|
|
16
|
+
- Server-side auth & tenant scoping (`.filter(tenant=...)`, `.Where("tenant_id = ?")`, `where: { tenantId: ... }`).
|
|
17
|
+
- Zero client-side secrets (`SUPABASE_SERVICE_ROLE_KEY`, live API keys, Stripe secret keys).
|
|
18
|
+
- Ponytail Protocol patch limits ($\le 35$ additions, $\le 25$ deletions, zero full-file rewrites).
|
|
19
|
+
- *Upgrade:* Run `npx torusguard init` to unlock local `.torusguard/` workspace tracking, persistent memory, and individual slash commands.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Specialist Skill Routing (Lazy Loading)
|
|
24
|
+
Load **only** the designated sub-skill on demand to preserve the 1,000–1,500 token budget:
|
|
25
|
+
|
|
26
|
+
| Command | Specialist Skill | Agent | Purpose |
|
|
27
|
+
| :--- | :--- | :--- | :--- |
|
|
28
|
+
| `/torusguard init` | `skills/torusguard-init/SKILL.md` | `profiler` | Workspace discovery, stack detection & scaffolding |
|
|
29
|
+
| `/torusguard authorize` | `skills/torusguard-authorize/SKILL.md` | `reviewer` | Legal scope definition & safety boundaries |
|
|
30
|
+
| `/torusguard audit` | `skills/torusguard-audit/SKILL.md` | `auditor` | Static AST security audit & root-cause clustering |
|
|
31
|
+
| `/torusguard verify` | `skills/torusguard-verify/SKILL.md` | `validator` | Evidence sufficiency & line match audit |
|
|
32
|
+
| `/torusguard web-validate` | `skills/torusguard-web-validate/SKILL.md` | `validator` | Authorized non-destructive HTTP probing |
|
|
33
|
+
| `/torusguard exploit-check`| `skills/torusguard-exploit-check/SKILL.md`| `validator` | Bounded single-step exploitability confirmation |
|
|
34
|
+
| `/torusguard harden` | `skills/torusguard-harden/SKILL.md` | `remediator`| Governed remediation under Ponytail Protocol |
|
|
35
|
+
| `/torusguard apply` | `skills/torusguard-apply/SKILL.md` | `remediator`| Governed patch application with rollback snapshots |
|
|
36
|
+
| `/torusguard recheck` | `skills/torusguard-recheck/SKILL.md` | `reviewer` | Differential AST re-scan & closure verification |
|
|
37
|
+
| `/torusguard report` | `skills/torusguard-report/SKILL.md` | `reviewer` | Executive posture reporting, SARIF & visual HTML export |
|
|
38
|
+
| `/torusguard status` | `skills/torusguard-status/SKILL.md` | `reviewer` | Diagnostic overview of posture, stack & rules |
|
|
39
|
+
| `/torusguard memory` | `skills/torusguard/SKILL.md` | `reviewer` | Persistent memory inspection, decay & context cards |
|
|
40
|
+
| `/torusguard full` | `skills/torusguard-full/SKILL.md` | *All* | End-to-end 7-stage closed-loop execution |
|
|
41
|
+
|
|
42
|
+
*Note: Never load all skills simultaneously. Lazy-load strictly on demand.*
|
|
@@ -57,12 +57,85 @@ def find_project_root(start_dir=None):
|
|
|
57
57
|
return current
|
|
58
58
|
|
|
59
59
|
|
|
60
|
+
import re
|
|
61
|
+
import unicodedata
|
|
62
|
+
|
|
63
|
+
ANSI_REGEX = re.compile(r'\033\[[0-9;]*m')
|
|
64
|
+
|
|
65
|
+
def get_visual_width(text: str) -> int:
|
|
66
|
+
"""Calculate the printable display width of a string (ANSI and emoji aware)."""
|
|
67
|
+
clean = ANSI_REGEX.sub('', text)
|
|
68
|
+
width = 0
|
|
69
|
+
for ch in clean:
|
|
70
|
+
ea = unicodedata.east_asian_width(ch)
|
|
71
|
+
if ea in ('W', 'F'):
|
|
72
|
+
width += 2
|
|
73
|
+
elif ord(ch) >= 0x1F300:
|
|
74
|
+
width += 2
|
|
75
|
+
else:
|
|
76
|
+
width += 1
|
|
77
|
+
return width
|
|
78
|
+
|
|
79
|
+
def truncate_visual(text: str, max_w: int = 67) -> str:
|
|
80
|
+
"""Truncate text visually without breaking ANSI escape codes."""
|
|
81
|
+
if get_visual_width(text) <= max_w:
|
|
82
|
+
return text
|
|
83
|
+
out, curr_w, in_ansi, ansi_buf = [], 0, False, ''
|
|
84
|
+
for ch in text:
|
|
85
|
+
if ch == '\033':
|
|
86
|
+
in_ansi = True
|
|
87
|
+
ansi_buf = ch
|
|
88
|
+
continue
|
|
89
|
+
if in_ansi:
|
|
90
|
+
ansi_buf += ch
|
|
91
|
+
if ch == 'm':
|
|
92
|
+
in_ansi = False
|
|
93
|
+
out.append(ansi_buf)
|
|
94
|
+
continue
|
|
95
|
+
ea = unicodedata.east_asian_width(ch)
|
|
96
|
+
cw = 2 if ea in ('W', 'F') or ord(ch) >= 0x1F300 else 1
|
|
97
|
+
if curr_w + cw > max_w - 3:
|
|
98
|
+
out.append('...')
|
|
99
|
+
break
|
|
100
|
+
out.append(ch)
|
|
101
|
+
curr_w += cw
|
|
102
|
+
return ''.join(out)
|
|
103
|
+
|
|
104
|
+
def card_line(content: str, max_w: int = 67, border: str = "│", border_color: str = CYAN) -> str:
|
|
105
|
+
"""Pad content so the card is exactly 75 visual columns total width."""
|
|
106
|
+
trunc = truncate_visual(content, max_w)
|
|
107
|
+
vis = get_visual_width(trunc)
|
|
108
|
+
pad = " " * max(0, max_w - vis)
|
|
109
|
+
return f" {border_color}{border}{RESET} {trunc}{pad} {border_color}{border}{RESET}"
|
|
110
|
+
|
|
111
|
+
def card_border_top(title: str = "", border_color: str = CYAN, double: bool = False) -> str:
|
|
112
|
+
left = "╔" if double else "┌"
|
|
113
|
+
right = "╗" if double else "┐"
|
|
114
|
+
h = "═" if double else "─"
|
|
115
|
+
if title:
|
|
116
|
+
vis = get_visual_width(title)
|
|
117
|
+
rem = max(0, 71 - 3 - vis - 1)
|
|
118
|
+
return f" {border_color}{left}{h} {BOLD}{WHITE}{title}{RESET}{border_color} {h * rem}{right}{RESET}"
|
|
119
|
+
return f" {border_color}{left}{h * 71}{right}{RESET}"
|
|
120
|
+
|
|
121
|
+
def card_border_bottom(border_color: str = CYAN, double: bool = False) -> str:
|
|
122
|
+
left = "╚" if double else "└"
|
|
123
|
+
right = "╝" if double else "┘"
|
|
124
|
+
h = "═" if double else "─"
|
|
125
|
+
return f" {border_color}{left}{h * 71}{right}{RESET}"
|
|
126
|
+
|
|
127
|
+
def card_divider(border_color: str = CYAN, double: bool = False) -> str:
|
|
128
|
+
left = "╠" if double else "├"
|
|
129
|
+
right = "╣" if double else "┤"
|
|
130
|
+
h = "═" if double else "─"
|
|
131
|
+
return f" {border_color}{left}{h * 71}{right}{RESET}"
|
|
132
|
+
|
|
60
133
|
def print_header():
|
|
61
134
|
"""Print the branded TorusGuard header card."""
|
|
62
135
|
print(f"""
|
|
63
136
|
{CYAN}╭─────────────────────────────────────────────────────────────────────────╮{RESET}
|
|
64
137
|
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
65
|
-
{CYAN}│{RESET} {BOLD}{WHITE}🛡️ T O R U S G U A R D{RESET} {GRAY}
|
|
138
|
+
{CYAN}│{RESET} {BOLD}{WHITE}🛡️ T O R U S G U A R D{RESET} {GRAY}v1.3.0{RESET} {CYAN}│{RESET}
|
|
66
139
|
{CYAN}│{RESET} {DIM}Autonomous Security Engine for AI-Built Applications{RESET} {CYAN}│{RESET}
|
|
67
140
|
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
68
141
|
{CYAN}╰─────────────────────────────────────────────────────────────────────────╯{RESET}
|
|
@@ -71,81 +144,71 @@ def print_header():
|
|
|
71
144
|
|
|
72
145
|
def print_step_1_assets(file_count):
|
|
73
146
|
"""Print the enhanced Step 1 asset unpacking card."""
|
|
74
|
-
print(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
""")
|
|
147
|
+
print(card_border_top("Step 1/3 ─── Unpacking Governance Assets"))
|
|
148
|
+
print(card_line(""))
|
|
149
|
+
print(card_line(f"{GREEN}✔{RESET} Canonical security rules {DIM}71 rules across 11 families{RESET}"))
|
|
150
|
+
print(card_line(f"{GREEN}✔{RESET} JSON validation schemas {DIM}8 formal schemas{RESET}"))
|
|
151
|
+
print(card_line(f"{GREEN}✔{RESET} Specialist agent specifications {DIM}5 isolated agents{RESET}"))
|
|
152
|
+
print(card_line(f"{GREEN}✔{RESET} Workflow templates {DIM}11 slash commands{RESET}"))
|
|
153
|
+
print(card_line(f"{GREEN}✔{RESET} Framework reference guides {DIM}10 security guides{RESET}"))
|
|
154
|
+
print(card_line(""))
|
|
155
|
+
print(card_line(f"{BOLD}{WHITE}{file_count} files unpacked{RESET}"))
|
|
156
|
+
print(card_border_bottom())
|
|
85
157
|
|
|
86
158
|
|
|
87
159
|
def print_step_2_profile(detected_stack=None):
|
|
88
160
|
"""Print the security profile & coverage card (in-process stack alignment)."""
|
|
161
|
+
print(card_border_top("Step 2/3 ─── Security Profile & Coverage"))
|
|
162
|
+
print(card_line(""))
|
|
163
|
+
print(card_line(f"{BOLD}Rule Families:{RESET}"))
|
|
164
|
+
print(card_line(f" {YELLOW}TG-SEC{RESET} Secrets & Credentials {YELLOW}TG-DB{RESET} Database Safety"))
|
|
165
|
+
print(card_line(f" {YELLOW}TG-INPUT{RESET} Input Validation {YELLOW}TG-AUTH{RESET} Authentication"))
|
|
166
|
+
print(card_line(f" {YELLOW}TG-CLIENT{RESET} Client Bundle Leaks {YELLOW}TG-DIFF{RESET} Diff Inspection"))
|
|
167
|
+
print(card_line(f" {YELLOW}TG-AGENT{RESET} AI Agent Security {YELLOW}TG-EDGE{RESET} Serverless"))
|
|
168
|
+
print(card_line(f" {YELLOW}TG-SUPPLY{RESET} Supply Chain & CI/CD {YELLOW}TG-SSRF{RESET} Outbound Net"))
|
|
169
|
+
print(card_line(f" {YELLOW}TG-BIZ{RESET} Business Logic"))
|
|
170
|
+
print(card_line(""))
|
|
171
|
+
print(card_line(f"{BOLD}Supported Stacks:{RESET}"))
|
|
172
|
+
print(card_line(f" {GREEN}Python{RESET} Django · FastAPI · Flask · DRF · SQLAlchemy"))
|
|
173
|
+
print(card_line(f" {GREEN}Node.js{RESET} Next.js · Express · React · Supabase · Firebase"))
|
|
174
|
+
print(card_line(""))
|
|
89
175
|
if detected_stack and detected_stack.get("framework") and detected_stack.get("framework") != "None":
|
|
90
176
|
fw = str(detected_stack.get("framework"))
|
|
91
177
|
lang = str(detected_stack.get("language", ""))
|
|
92
|
-
|
|
93
|
-
pad = " " * max(0, 66 - len(label))
|
|
94
|
-
status_line = f" {CYAN}│{RESET} {GREEN}✔{RESET} {BOLD}Auto-aligned stack:{RESET} {WHITE}{fw}{RESET} {DIM}({lang}){RESET}{pad}{CYAN}│{RESET}"
|
|
178
|
+
print(card_line(f"{GREEN}✔{RESET} {BOLD}Auto-aligned stack:{RESET} {WHITE}{fw}{RESET} {DIM}({lang}){RESET}"))
|
|
95
179
|
else:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
print(f""" {CYAN}┌─ {BOLD}Step 2/3{RESET} {CYAN}──────────────────── {WHITE}Security Profile & Coverage{RESET} {CYAN}────────┐{RESET}
|
|
99
|
-
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
100
|
-
{CYAN}│{RESET} {BOLD}Rule Families:{RESET} {CYAN}│{RESET}
|
|
101
|
-
{CYAN}│{RESET} {YELLOW}TG-SEC{RESET} Secrets & Credentials {YELLOW}TG-DB{RESET} Database Safety {CYAN}│{RESET}
|
|
102
|
-
{CYAN}│{RESET} {YELLOW}TG-INPUT{RESET} Input Validation {YELLOW}TG-AUTH{RESET} Authentication {CYAN}│{RESET}
|
|
103
|
-
{CYAN}│{RESET} {YELLOW}TG-CLIENT{RESET} Client Bundle Leaks {YELLOW}TG-DIFF{RESET} Diff Inspection {CYAN}│{RESET}
|
|
104
|
-
{CYAN}│{RESET} {YELLOW}TG-AGENT{RESET} AI Agent Security {YELLOW}TG-EDGE{RESET} Serverless {CYAN}│{RESET}
|
|
105
|
-
{CYAN}│{RESET} {YELLOW}TG-SUPPLY{RESET} Supply Chain & CI/CD {YELLOW}TG-SSRF{RESET} Outbound Net {CYAN}│{RESET}
|
|
106
|
-
{CYAN}│{RESET} {YELLOW}TG-BIZ{RESET} Business Logic {CYAN}│{RESET}
|
|
107
|
-
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
108
|
-
{CYAN}│{RESET} {BOLD}Supported Stacks:{RESET} {CYAN}│{RESET}
|
|
109
|
-
{CYAN}│{RESET} {GREEN}Python{RESET} Django {DIM}·{RESET} FastAPI {DIM}·{RESET} Flask {DIM}·{RESET} DRF {DIM}·{RESET} SQLAlchemy {CYAN}│{RESET}
|
|
110
|
-
{CYAN}│{RESET} {GREEN}Node.js{RESET} Next.js {DIM}·{RESET} Express {DIM}·{RESET} React {DIM}·{RESET} Supabase {DIM}·{RESET} Firebase {CYAN}│{RESET}
|
|
111
|
-
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
112
|
-
{status_line}
|
|
113
|
-
{CYAN}└───────────────────────────────────────────────────────────────────────┘{RESET}
|
|
114
|
-
""")
|
|
180
|
+
print(card_line(f"{DIM}ℹ Stack auto-detected on first /torusguard-audit run{RESET}"))
|
|
181
|
+
print(card_border_bottom())
|
|
115
182
|
|
|
116
183
|
|
|
117
184
|
def print_step_3_bridges(registered_ides):
|
|
118
185
|
"""Print the IDE command registration card."""
|
|
119
|
-
|
|
186
|
+
print(card_border_top("Step 3/3 ─── AI IDE Command Registration"))
|
|
187
|
+
print(card_line(""))
|
|
120
188
|
for r in registered_ides:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
print(
|
|
124
|
-
{CYAN}│{RESET} {CYAN}│{RESET}
|
|
125
|
-
{lines} {CYAN}│{RESET} {CYAN}│{RESET}
|
|
126
|
-
{CYAN}└───────────────────────────────────────────────────────────────────────┘{RESET}
|
|
127
|
-
""")
|
|
189
|
+
print(card_line(f"{GREEN}✔{RESET} {r}"))
|
|
190
|
+
print(card_line(""))
|
|
191
|
+
print(card_border_bottom())
|
|
128
192
|
|
|
129
193
|
|
|
130
194
|
def print_success_card():
|
|
131
195
|
"""Print the final success card with next steps."""
|
|
132
|
-
print(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
""")
|
|
196
|
+
print(card_border_top("", border_color=GREEN, double=True))
|
|
197
|
+
print(card_line("", border="║", border_color=GREEN))
|
|
198
|
+
print(card_line(f"{GREEN}{BOLD}✅ WORKSPACE INITIALIZED SUCCESSFULLY{RESET}", border="║", border_color=GREEN))
|
|
199
|
+
print(card_line("", border="║", border_color=GREEN))
|
|
200
|
+
print(card_divider(border_color=GREEN, double=True))
|
|
201
|
+
print(card_line("", border="║", border_color=GREEN))
|
|
202
|
+
print(card_line(f"{BOLD}Next Steps:{RESET}", border="║", border_color=GREEN))
|
|
203
|
+
print(card_line("", border="║", border_color=GREEN))
|
|
204
|
+
print(card_line(f" {CYAN}1.{RESET} In AI Chat {WHITE}/torusguard-audit{RESET} or {WHITE}/torusguard{RESET}", border="║", border_color=GREEN))
|
|
205
|
+
print(card_line(f" {CYAN}2.{RESET} In Terminal {WHITE}npx torusguard status{RESET}", border="║", border_color=GREEN))
|
|
206
|
+
print(card_line(f" {CYAN}3.{RESET} In CI/CD {WHITE}npx torusguard audit{RESET}", border="║", border_color=GREEN))
|
|
207
|
+
print(card_line("", border="║", border_color=GREEN))
|
|
208
|
+
print(card_line(f"{DIM}Docs{RESET} {CYAN}https://github.com/githubmofo/TorusGuard{RESET}", border="║", border_color=GREEN))
|
|
209
|
+
print(card_line(f"{DIM}NPM{RESET} {CYAN}https://npmjs.com/package/torusguard{RESET}", border="║", border_color=GREEN))
|
|
210
|
+
print(card_line("", border="║", border_color=GREEN))
|
|
211
|
+
print(card_border_bottom(border_color=GREEN, double=True))
|
|
149
212
|
|
|
150
213
|
|
|
151
214
|
def print_already_initialized(target_root, cfg):
|
|
@@ -157,7 +220,7 @@ def print_already_initialized(target_root, cfg):
|
|
|
157
220
|
|
|
158
221
|
{BOLD}▸ Project Root:{RESET} {GREEN}{target_root}{RESET}
|
|
159
222
|
{BOLD}▸ Workspace:{RESET} {GREEN}.torusguard/{RESET} {DIM}(Already Initialized){RESET}
|
|
160
|
-
{BOLD}▸ Version:{RESET} {CYAN}{cfg.get('version', '1.
|
|
223
|
+
{BOLD}▸ Version:{RESET} {CYAN}{cfg.get('version', '1.3.0')}{RESET}
|
|
161
224
|
{BOLD}▸ Severity Floor:{RESET} {YELLOW}{cfg.get('severity_threshold', 'medium')}{RESET}
|
|
162
225
|
|
|
163
226
|
{DIM}To refresh templates or re-scaffold, run:{RESET}
|
|
@@ -358,23 +421,39 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
|
|
|
358
421
|
3. Follow the phase execution steps defined in the workflow.
|
|
359
422
|
"""
|
|
360
423
|
|
|
361
|
-
# Ensure .agent/workflows and .
|
|
424
|
+
# Ensure .agents/workflows, .agents/skills, .agent/workflows, and .agent/skills are created
|
|
362
425
|
dest_workflow_dirs = []
|
|
363
|
-
if (target_root / ".agents").exists():
|
|
364
|
-
agents_wf = target_root / ".agents" / "workflows"
|
|
365
|
-
agents_wf.mkdir(parents=True, exist_ok=True)
|
|
366
|
-
(agents_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
367
|
-
dest_workflow_dirs.append(agents_wf)
|
|
368
|
-
registered_ides.append("Antigravity / Gemini .agents/workflows/torusguard.md")
|
|
369
426
|
|
|
427
|
+
# 1. Antigravity / Gemini (.agents/)
|
|
428
|
+
agents_wf = target_root / ".agents" / "workflows"
|
|
429
|
+
agents_wf.mkdir(parents=True, exist_ok=True)
|
|
430
|
+
(agents_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
431
|
+
dest_workflow_dirs.append(agents_wf)
|
|
432
|
+
registered_ides.append("Antigravity / Gemini .agents/workflows/torusguard.md")
|
|
433
|
+
|
|
434
|
+
# 2. Tribunal Agent Kit (.agent/)
|
|
370
435
|
agent_wf = target_root / ".agent" / "workflows"
|
|
371
436
|
agent_wf.mkdir(parents=True, exist_ok=True)
|
|
372
437
|
(agent_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
373
438
|
dest_workflow_dirs.append(agent_wf)
|
|
374
439
|
registered_ides.append("Tribunal Agent Kit .agent/workflows/torusguard.md")
|
|
375
440
|
|
|
441
|
+
# Unpack Skills into .agents/skills and .agent/skills for full IDE resolution
|
|
442
|
+
src_skills = torusguard_target / "skills"
|
|
443
|
+
if src_skills.is_dir():
|
|
444
|
+
for dest_base in [target_root / ".agents" / "skills", target_root / ".agent" / "skills"]:
|
|
445
|
+
dest_base.mkdir(parents=True, exist_ok=True)
|
|
446
|
+
for skill_dir in src_skills.iterdir():
|
|
447
|
+
if skill_dir.is_dir():
|
|
448
|
+
target_skill_dir = dest_base / skill_dir.name
|
|
449
|
+
if not target_skill_dir.exists():
|
|
450
|
+
try:
|
|
451
|
+
shutil.copytree(skill_dir, target_skill_dir)
|
|
452
|
+
except Exception:
|
|
453
|
+
pass
|
|
454
|
+
|
|
376
455
|
# When full_commands is requested (e.g. via NPM package npx torusguard init),
|
|
377
|
-
# unlock and register all
|
|
456
|
+
# unlock and register all individual slash commands
|
|
378
457
|
if full_commands:
|
|
379
458
|
src_wf = torusguard_target / "workflows"
|
|
380
459
|
if src_wf.is_dir():
|