torusguard 2.1.2 → 2.1.3
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 +3 -3
- package/.torusguard/config/torusguard.json +1 -1
- package/.torusguard/scripts/__pycache__/term_ui.cpython-314.pyc +0 -0
- package/.torusguard/scripts/status_runner.py +3 -3
- package/.torusguard/scripts/term_ui.py +1 -1
- package/README.md +64 -8
- package/bin/torusguard.js +26 -26
- package/package.json +2 -1
- package/skills/torusguard/__pycache__/bootstrap.cpython-314.pyc +0 -0
- package/skills/torusguard/bootstrap.py +32 -65
- package/skills/torusguard/payload/.manifest.json +7 -7
- package/skills/torusguard/payload/config/torusguard.json +1 -1
- package/skills/torusguard/payload/scripts/status_runner.py +3 -3
- package/skills/torusguard/payload/scripts/stride_generator.py +1 -1
- package/skills/torusguard/payload/scripts/term_ui.py +1 -1
- package/skills/torusguard/payload/skills/torusguard/bootstrap.py +32 -65
- package/skills/torusguard/payload/skills/torusguard-review/SKILL.md +2 -2
- package/skills/torusguard/payload/skills/torusguard-threatmodel/SKILL.md +2 -2
- package/skills/torusguard-review/SKILL.md +2 -2
- package/skills/torusguard-threatmodel/SKILL.md +2 -2
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"agents/validator.md": "79fc4431de5c5507f8730aee6c5c3e61fd238cbf8cf8c7c6aac462eee9761ed6",
|
|
10
10
|
"config/scope.json": "b198a86186b4c6d5e1af516bf4e3a6afa8878e622ca1d57a5bf72d294f8c6f25",
|
|
11
11
|
"config/slash-commands.json": "305c1dc5b556e8d64ad9dd585dafac1a9955cf1bd5321429955b19b7a62736b6",
|
|
12
|
-
"config/torusguard.json": "
|
|
12
|
+
"config/torusguard.json": "e8e41f3be04a06deb32ce5faaa93ddd608abfb2694b30325cac5085f3bfec9d8",
|
|
13
13
|
"core/__init__.py": "2120562452ae03c84468d67246dc93376f7ebcde8e4ca767c6253bc92c35dbbf",
|
|
14
14
|
"core/agent_roles.py": "d7189dbf1d3ae4e330eb316bed5d399a18992295addf466f4c6552bc14ae6a34",
|
|
15
15
|
"core/ast_walker.py": "309564d168e6eb9e3e93aceb29a95a61872b35a4da7235ee49e79e9d3a5e7cc6",
|
|
@@ -216,9 +216,9 @@
|
|
|
216
216
|
"scripts/sarif_exporter.py": "86700765212adb3ab590ca72614bf3ad4ce7ce60e3193f7f3bd1a04d34d10f6e",
|
|
217
217
|
"scripts/skill_profiler.py": "ada83e022795febb2365a73753656ff881993d77cf73517e818d668e961adb45",
|
|
218
218
|
"scripts/stack_detect.py": "c05a1ade4c8692025476bf7ea080a8f07c92e5d8e9a04f94c1654386352ffbdc",
|
|
219
|
-
"scripts/status_runner.py": "
|
|
219
|
+
"scripts/status_runner.py": "a7421e25e2e34c1b83960ad117f5ea23d6f08b8af8b664be3fe03f70a3962db3",
|
|
220
220
|
"scripts/stride_generator.py": "c7a4ea2a19a7386dfc6c0fb301e933a32de2c8963ffa605e5aaa651cf880507f",
|
|
221
|
-
"scripts/term_ui.py": "
|
|
221
|
+
"scripts/term_ui.py": "a23435c703c4e8b68c5b80a539d59de2eda1cb01b0d9c47909ba72efde3be29b",
|
|
222
222
|
"skills/torusguard/SKILL.md": "15c69cb10eca1a10344b494888dce57e2baf227c3282bd54424a36ce35fb2460",
|
|
223
223
|
"skills/torusguard/bootstrap.py": "f7ce48cc310dcdbf86c028f05a8f5ad22677f4cebb1bec5c90d173a9044342c5",
|
|
224
224
|
"skills/torusguard/references/auth-and-sessions.md": "c3e4b9600cb53fc28c993922dc880accbec5783ac90d5ee98d63b52762d19525",
|
|
Binary file
|
|
@@ -58,7 +58,7 @@ def collect_status(target_dir: Path) -> WorkspaceStatus:
|
|
|
58
58
|
is_init = tg_dir.is_dir()
|
|
59
59
|
|
|
60
60
|
# 1. Read config
|
|
61
|
-
version = "1.
|
|
61
|
+
version = "2.1.3"
|
|
62
62
|
stack_name = "Undetected"
|
|
63
63
|
cfg_file = tg_dir / "config" / "torusguard.json"
|
|
64
64
|
if cfg_file.is_file():
|
|
@@ -94,7 +94,7 @@ def collect_status(target_dir: Path) -> WorkspaceStatus:
|
|
|
94
94
|
if rules_root.is_dir():
|
|
95
95
|
active_rules_count = sum(1 for f in rules_root.rglob("TG-*.md"))
|
|
96
96
|
if active_rules_count == 0:
|
|
97
|
-
active_rules_count =
|
|
97
|
+
active_rules_count = 88 # Canonical rule catalog default
|
|
98
98
|
|
|
99
99
|
# 3. Read run history
|
|
100
100
|
total_runs = 0
|
|
@@ -210,7 +210,7 @@ def print_status_card(status: WorkspaceStatus) -> None:
|
|
|
210
210
|
print(format_box_line(f"Workspace: {WHITE}{status.target_path}{RESET}", 67))
|
|
211
211
|
print(format_box_line(f"Status: {init_str}", 67))
|
|
212
212
|
print(format_box_line(f"Stack: {BOLD}{WHITE}{status.stack_detected}{RESET}", 67))
|
|
213
|
-
print(format_box_line(f"Active Rules: {GREEN}{status.active_rules_count}{RESET} canonical rules enabled across
|
|
213
|
+
print(format_box_line(f"Active Rules: {GREEN}{status.active_rules_count}{RESET} canonical rules enabled across 22 families", 67))
|
|
214
214
|
print(card_border_bottom(CYAN))
|
|
215
215
|
print()
|
|
216
216
|
|
|
@@ -143,7 +143,7 @@ def card_divider(title: str = "", border_color: str = CYAN, double: bool = False
|
|
|
143
143
|
return f" {border_color}{left}{h} {BOLD}{WHITE}{title}{RESET}{border_color} {h * rem}{right}{RESET}"
|
|
144
144
|
return f" {border_color}{left}{h * 71}{right}{RESET}"
|
|
145
145
|
|
|
146
|
-
def card_header(title: str, subtitle: str = "", version: str = "
|
|
146
|
+
def card_header(title: str, subtitle: str = "", version: str = "v2.1.3", border_color: str = CYAN) -> str:
|
|
147
147
|
"""Generate standardized 75-column curved header box."""
|
|
148
148
|
top = f" {border_color}╭{'─' * 71}╮{RESET}"
|
|
149
149
|
bottom = f" {border_color}╰{'─' * 71}╯{RESET}"
|
package/README.md
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
13
13
|
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
|
|
14
|
-
<a href="https://github.com/githubmofo/TorusGuard/releases"><img src="https://img.shields.io/badge/version-v2.1.
|
|
15
|
-
<a href="https://www.npmjs.com/package/torusguard"><img src="https://img.shields.io/badge/npm-v2.1.
|
|
14
|
+
<a href="https://github.com/githubmofo/TorusGuard/releases"><img src="https://img.shields.io/badge/version-v2.1.3-orange.svg" alt="Version"></a>
|
|
15
|
+
<a href="https://www.npmjs.com/package/torusguard"><img src="https://img.shields.io/badge/npm-v2.1.3-CB3837?logo=npm&logoColor=white" alt="npm: v2.1.3"></a>
|
|
16
16
|
<img src="https://img.shields.io/badge/Privacy-Local_First-success" alt="Privacy: Local First">
|
|
17
17
|
<img src="https://img.shields.io/badge/Dependencies-Zero-brightgreen" alt="Dependencies: Zero">
|
|
18
18
|
<img src="https://img.shields.io/badge/SARIF-v2.1.0-6C3483" alt="SARIF">
|
|
@@ -276,24 +276,55 @@ flowchart TD
|
|
|
276
276
|
|
|
277
277
|
---
|
|
278
278
|
|
|
279
|
-
## 🚀 Installation
|
|
279
|
+
## 🚀 Installation & How to Use (3 Options)
|
|
280
|
+
|
|
281
|
+
TorusGuard can be run without installation via `npx`, installed globally or locally via `npm`, compiled from source with `go build`, or installed via `go install`.
|
|
282
|
+
|
|
283
|
+
| Option | Method | Best For | Dedicated Guide |
|
|
284
|
+
| :--- | :--- | :--- | :--- |
|
|
285
|
+
| **Option 1** | **npm & npx** | Node.js developers, zero-install CLI, CI/CD | 📖 [Option 1 Guide](docs/usage/option-1-npm.md) |
|
|
286
|
+
| **Option 2** | **Build from Source** | Contributors, custom rules, Go development | 📖 [Option 2 Guide](docs/usage/option-2-source.md) |
|
|
287
|
+
| **Option 3** | **Go Install** | Go projects, single-binary, zero Node.js/npm | 📖 [Option 3 Guide](docs/usage/option-3-go-install.md) |
|
|
288
|
+
|
|
289
|
+
---
|
|
280
290
|
|
|
281
291
|
### Option 1: npm (Primary)
|
|
282
292
|
|
|
293
|
+
#### Method A: Direct NPX Zero-Install (Recommended)
|
|
294
|
+
Run directly without installing any packages globally or locally:
|
|
295
|
+
|
|
283
296
|
```bash
|
|
284
|
-
|
|
297
|
+
npx torusguard init
|
|
285
298
|
```
|
|
286
299
|
|
|
287
|
-
|
|
300
|
+
*Tip: Use `npx torusguard@latest init` to guarantee the freshest release.*
|
|
288
301
|
|
|
302
|
+
#### Method B: Global Installation
|
|
289
303
|
```bash
|
|
290
|
-
|
|
304
|
+
npm install -g torusguard
|
|
305
|
+
torusguard init
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
#### Method C: Local Project Installation
|
|
309
|
+
```bash
|
|
310
|
+
npm install -D torusguard
|
|
291
311
|
```
|
|
292
312
|
|
|
313
|
+
> 💡 **Using TorusGuard after `npm install torusguard`:**
|
|
314
|
+
> TorusGuard is a CLI security engine, not an importable JavaScript library. When installed locally, the binary resides in `node_modules/.bin/torusguard`.
|
|
315
|
+
> You can run it via:
|
|
316
|
+
> - `npx torusguard init` *(npx automatically uses your local `node_modules` binary)*
|
|
317
|
+
> - Adding `"security:audit": "torusguard audit"` to your `package.json` scripts (`npm run security:audit`)
|
|
318
|
+
> - Direct path: `./node_modules/.bin/torusguard audit`
|
|
319
|
+
|
|
293
320
|
<a href="https://www.npmjs.com/package/torusguard">
|
|
294
|
-
<img src="https://img.shields.io/badge/npm-v2.1.
|
|
321
|
+
<img src="https://img.shields.io/badge/npm-v2.1.3-CB3837?logo=npm&logoColor=white" alt="npm package">
|
|
295
322
|
</a>
|
|
296
323
|
|
|
324
|
+
👉 **[Read the Full Option 1 (npm & npx) Dedicated Guide →](docs/usage/option-1-npm.md)**
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
297
328
|
### Option 2: Build from Source (Recommended for Contributors)
|
|
298
329
|
|
|
299
330
|
```bash
|
|
@@ -302,12 +333,37 @@ cd TorusGuard
|
|
|
302
333
|
go build -o torusguard ./cmd/torusguard
|
|
303
334
|
```
|
|
304
335
|
|
|
336
|
+
On Windows:
|
|
337
|
+
```powershell
|
|
338
|
+
go build -o torusguard.exe ./cmd/torusguard
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Run directly:
|
|
342
|
+
```bash
|
|
343
|
+
./torusguard init
|
|
344
|
+
./torusguard audit
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
👉 **[Read the Full Option 2 (Build from Source) Dedicated Guide →](docs/usage/option-2-source.md)**
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
305
351
|
### Option 3: Go Install
|
|
306
352
|
|
|
353
|
+
Install directly into `$GOPATH/bin`:
|
|
354
|
+
|
|
307
355
|
```bash
|
|
308
|
-
go install github.com/
|
|
356
|
+
go install github.com/githubmofo/TorusGuard/cmd/torusguard@latest
|
|
309
357
|
```
|
|
310
358
|
|
|
359
|
+
Verify and run:
|
|
360
|
+
```bash
|
|
361
|
+
torusguard --version
|
|
362
|
+
torusguard init
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
👉 **[Read the Full Option 3 (Go Install) Dedicated Guide →](docs/usage/option-3-go-install.md)**
|
|
366
|
+
|
|
311
367
|
---
|
|
312
368
|
|
|
313
369
|
## 💻 Usage
|
package/bin/torusguard.js
CHANGED
|
@@ -15,14 +15,15 @@ const command = args[0] || 'init';
|
|
|
15
15
|
const rootDir = path.resolve(__dirname, '..');
|
|
16
16
|
const cwd = process.cwd();
|
|
17
17
|
|
|
18
|
+
let PKG_VERSION = '2.1.3';
|
|
19
|
+
try {
|
|
20
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(rootDir, 'package.json'), 'utf-8'));
|
|
21
|
+
PKG_VERSION = pkg.version || PKG_VERSION;
|
|
22
|
+
} catch (e) {}
|
|
23
|
+
|
|
18
24
|
// Parse version flag immediately
|
|
19
25
|
if (command === '--version' || command === '-v' || command === 'version') {
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
const pkg = JSON.parse(fs.readFileSync(path.join(rootDir, 'package.json'), 'utf-8'));
|
|
23
|
-
ver = pkg.version || ver;
|
|
24
|
-
} catch (e) {}
|
|
25
|
-
console.log(`torusguard v${ver}`);
|
|
26
|
+
console.log(`torusguard v${PKG_VERSION}`);
|
|
26
27
|
process.exit(0);
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -196,7 +197,7 @@ function cardDivider(title = '', borderColor = CYAN, double = false) {
|
|
|
196
197
|
return ` ${borderColor}${left}${h.repeat(71)}${right}${RESET}`;
|
|
197
198
|
}
|
|
198
199
|
|
|
199
|
-
function cardHeader(title, subtitle = '', version =
|
|
200
|
+
function cardHeader(title, subtitle = '', version = `v${PKG_VERSION}`, borderColor = CYAN) {
|
|
200
201
|
const top = ` ${borderColor}╭${'─'.repeat(71)}╮${RESET}`;
|
|
201
202
|
const bottom = ` ${borderColor}╰${'─'.repeat(71)}╯${RESET}`;
|
|
202
203
|
const empty = ` ${borderColor}│${' '.repeat(71)}│${RESET}`;
|
|
@@ -214,7 +215,7 @@ function cardHeader(title, subtitle = '', version = 'v1.3.6', borderColor = CYAN
|
|
|
214
215
|
|
|
215
216
|
function printHelp() {
|
|
216
217
|
console.log();
|
|
217
|
-
console.log(cardHeader('🛡️ T O R U S G U A R D C L I', 'Autonomous Security Engine for AI-Built Applications',
|
|
218
|
+
console.log(cardHeader('🛡️ T O R U S G U A R D C L I', 'Autonomous Security Engine for AI-Built Applications', `v${PKG_VERSION}`));
|
|
218
219
|
console.log(`\n ${BOLD}Usage:${RESET} ${GREEN}npx torusguard${RESET} ${WHITE}[command]${RESET} ${GRAY}[options]${RESET}\n`);
|
|
219
220
|
|
|
220
221
|
console.log(cardBorderTop('Commands'));
|
|
@@ -309,7 +310,7 @@ if (command === 'status') {
|
|
|
309
310
|
}
|
|
310
311
|
|
|
311
312
|
console.log();
|
|
312
|
-
console.log(cardHeader('🛡️ TORUSGUARD SECURITY POSTURE', '',
|
|
313
|
+
console.log(cardHeader('🛡️ TORUSGUARD SECURITY POSTURE', '', `v${PKG_VERSION}`));
|
|
313
314
|
console.log(`\n ${BOLD}▸ Workspace:${RESET} ${GREEN}${cwd}${RESET}`);
|
|
314
315
|
console.log(` ${BOLD}▸ Governance:${RESET} ${GREEN}Full Local Governance (.torusguard/)${RESET}`);
|
|
315
316
|
console.log(` ${BOLD}▸ Living Report:${RESET} ${CYAN}security_report.md${RESET}\n`);
|
|
@@ -331,7 +332,7 @@ if (command === 'status') {
|
|
|
331
332
|
console.log();
|
|
332
333
|
|
|
333
334
|
console.log(cardBorderTop('Governance Telemetry'));
|
|
334
|
-
console.log(formatBoxLine(`Rules Catalog: ${GREEN}
|
|
335
|
+
console.log(formatBoxLine(`Rules Catalog: ${GREEN}88 Canonical Security Rules${RESET} (22 families)`));
|
|
335
336
|
console.log(formatBoxLine(`Severity Floor: ${YELLOW}${cfg.severity_threshold || 'medium'}${RESET}`));
|
|
336
337
|
console.log(formatBoxLine(`Runs Directory: ${DIM}${cfg.runs_dir || '.torusguard/runs'}${RESET}`));
|
|
337
338
|
console.log(formatBoxLine(`Ponytail Bounds: ${GREEN}<= 35 additions, <= 25 deletions${RESET}`));
|
|
@@ -339,16 +340,18 @@ if (command === 'status') {
|
|
|
339
340
|
console.log(cardBorderBottom());
|
|
340
341
|
console.log();
|
|
341
342
|
|
|
342
|
-
console.log(cardBorderTop('Rule Families (
|
|
343
|
-
console.log(formatBoxLine(`${YELLOW}TG-SEC${RESET} Secrets (7)
|
|
344
|
-
console.log(formatBoxLine(`${YELLOW}TG-
|
|
343
|
+
console.log(cardBorderTop('Rule Families (22 Families / 88 Rules)'));
|
|
344
|
+
console.log(formatBoxLine(`${YELLOW}TG-SEC${RESET} Secrets & Tokens (7) ${YELLOW}TG-AUTH${RESET} Authentication (8)`));
|
|
345
|
+
console.log(formatBoxLine(`${YELLOW}TG-DB${RESET} Database Isolation (4) ${YELLOW}TG-INPUT${RESET} Input & Traversal (8)`));
|
|
345
346
|
console.log(formatBoxLine(`${YELLOW}TG-RATE${RESET} Rate Limiting (3) ${YELLOW}TG-AGENT${RESET} AI Agent Security (4)`));
|
|
346
|
-
console.log(formatBoxLine(`${YELLOW}TG-SSRF${RESET} Server Request (4)
|
|
347
|
-
console.log(formatBoxLine(`${YELLOW}TG-WS${RESET} WebSocket (4)
|
|
348
|
-
console.log(formatBoxLine(`${YELLOW}TG-GQL${RESET} GraphQL
|
|
349
|
-
console.log(formatBoxLine(`${YELLOW}TG-BIZ${RESET} Business Logic (4) ${YELLOW}TG-CACHE${RESET} Cache
|
|
350
|
-
console.log(formatBoxLine(`${YELLOW}TG-CLIENT${RESET} Client
|
|
351
|
-
console.log(formatBoxLine(`${YELLOW}TG-DIFF${RESET}
|
|
347
|
+
console.log(formatBoxLine(`${YELLOW}TG-SSRF${RESET} Server-Side Request (4) ${YELLOW}TG-WEBHOOK${RESET} Webhook Signature (4)`));
|
|
348
|
+
console.log(formatBoxLine(`${YELLOW}TG-WS${RESET} WebSocket Safety (4) ${YELLOW}TG-CSRF${RESET} Cross-Site Request (2)`));
|
|
349
|
+
console.log(formatBoxLine(`${YELLOW}TG-GQL${RESET} GraphQL Introspection (4)${YELLOW}TG-SUPPLY${RESET} Supply Chain Health (6)`));
|
|
350
|
+
console.log(formatBoxLine(`${YELLOW}TG-BIZ${RESET} Business Logic (4) ${YELLOW}TG-CACHE${RESET} Cache Poisoning (3)`));
|
|
351
|
+
console.log(formatBoxLine(`${YELLOW}TG-CLIENT${RESET} Client Bundle Secrets (2)${YELLOW}TG-PLATFORM${RESET}Platform Hardening (4)`));
|
|
352
|
+
console.log(formatBoxLine(`${YELLOW}TG-DIFF${RESET} Polyglot Bypass Guard (3)${YELLOW}TG-EDGE${RESET} Edge & Serverless (2)`));
|
|
353
|
+
console.log(formatBoxLine(`${YELLOW}TG-CONT${RESET} Container Hardening (4) ${YELLOW}TG-GIT${RESET} Git Secret Mining (3)`));
|
|
354
|
+
console.log(formatBoxLine(`${YELLOW}TG-REDOS${RESET} ReDoS Complexity Guard (2)${YELLOW}TG-RAG${RESET} RAG & Vector Scoping (3)`));
|
|
352
355
|
console.log(cardBorderBottom());
|
|
353
356
|
|
|
354
357
|
console.log(`\n ${DIM}Quick Action:${RESET} In your AI chat, run ${CYAN}/torusguard-audit${RESET} to scan.\n`);
|
|
@@ -640,6 +643,9 @@ if (command === 'recipes') {
|
|
|
640
643
|
if (command === 'init') {
|
|
641
644
|
const { target, remaining } = parseTargetAndArgs(args);
|
|
642
645
|
const targetDir = path.resolve(cwd, target);
|
|
646
|
+
if (!fs.existsSync(targetDir)) {
|
|
647
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
648
|
+
}
|
|
643
649
|
const localBootstrap = path.join(rootDir, 'skills', 'torusguard', 'bootstrap.py');
|
|
644
650
|
const localInstall = path.join(rootDir, 'install.py');
|
|
645
651
|
const scriptToRun = fs.existsSync(localBootstrap) ? localBootstrap : localInstall;
|
|
@@ -655,13 +661,7 @@ if (command === 'init') {
|
|
|
655
661
|
// Subcommand: update
|
|
656
662
|
if (command === 'update') {
|
|
657
663
|
const https = require('https');
|
|
658
|
-
const
|
|
659
|
-
let currentVersion = '1.4.0';
|
|
660
|
-
try {
|
|
661
|
-
if (fs.existsSync(pkgJsonPath)) {
|
|
662
|
-
currentVersion = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')).version || currentVersion;
|
|
663
|
-
}
|
|
664
|
-
} catch (e) {}
|
|
664
|
+
const currentVersion = PKG_VERSION;
|
|
665
665
|
|
|
666
666
|
console.log();
|
|
667
667
|
console.log(cardHeader('🛡️ TORUSGUARD UPDATE CHECK', 'Package Distribution & Registry Verifier', `v${currentVersion}`));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "torusguard",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.3",
|
|
4
4
|
"description": "Security guardrails, governed remediation, and authorized runtime validation for AI-built web applications.",
|
|
5
5
|
"main": "bin/torusguard.js",
|
|
6
6
|
"bin": {
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"LICENSE"
|
|
16
16
|
],
|
|
17
17
|
"scripts": {
|
|
18
|
+
"postinstall": "node -e \"console.log('\\n🛡️ TorusGuard v2.1.3 installed! Run: npx torusguard init\\n')\"",
|
|
18
19
|
"test": "python harness/runner.py",
|
|
19
20
|
"init": "node bin/torusguard.js init",
|
|
20
21
|
"status": "node bin/torusguard.js status",
|
|
Binary file
|
|
@@ -144,7 +144,7 @@ def card_divider(title: str = "", border_color: str = CYAN, double: bool = False
|
|
|
144
144
|
return f" {border_color}{left}{h} {BOLD}{WHITE}{title}{RESET}{border_color} {h * rem}{right}{RESET}"
|
|
145
145
|
return f" {border_color}{left}{h * 71}{right}{RESET}"
|
|
146
146
|
|
|
147
|
-
def card_header(title: str, subtitle: str = "", version: str = "v2.1.
|
|
147
|
+
def card_header(title: str, subtitle: str = "", version: str = "v2.1.3", border_color: str = CYAN) -> str:
|
|
148
148
|
"""Generate standardized 75-column curved header box."""
|
|
149
149
|
top = f" {border_color}╭{'─' * 71}╮{RESET}"
|
|
150
150
|
bottom = f" {border_color}╰{'─' * 71}╯{RESET}"
|
|
@@ -164,7 +164,7 @@ def card_header(title: str, subtitle: str = "", version: str = "v2.1.2", border_
|
|
|
164
164
|
def print_header():
|
|
165
165
|
"""Print the branded TorusGuard header card."""
|
|
166
166
|
print()
|
|
167
|
-
print(card_header("🛡️ T O R U S G U A R D", "Autonomous Security Engine for AI-Built Applications", version="v2.1.
|
|
167
|
+
print(card_header("🛡️ T O R U S G U A R D", "Autonomous Security Engine for AI-Built Applications", version="v2.1.3"))
|
|
168
168
|
print()
|
|
169
169
|
|
|
170
170
|
|
|
@@ -172,13 +172,13 @@ def print_step_1_assets(file_count):
|
|
|
172
172
|
"""Print the enhanced Step 1 asset unpacking card."""
|
|
173
173
|
print(card_border_top("Step 1/3 ─── Unpacking Governance Assets"))
|
|
174
174
|
print(card_line(""))
|
|
175
|
-
print(card_line(f"{GREEN}✔{RESET} Canonical security rules {DIM}
|
|
175
|
+
print(card_line(f"{GREEN}✔{RESET} Canonical security rules {DIM}88 rules across 22 families{RESET}"))
|
|
176
176
|
print(card_line(f"{GREEN}✔{RESET} JSON validation schemas {DIM}8 formal schemas{RESET}"))
|
|
177
177
|
print(card_line(f"{GREEN}✔{RESET} Specialist agent specifications {DIM}5 isolated agents{RESET}"))
|
|
178
|
-
print(card_line(f"{GREEN}✔{RESET}
|
|
179
|
-
print(card_line(f"{GREEN}✔{RESET} Framework reference guides {DIM}
|
|
178
|
+
print(card_line(f"{GREEN}✔{RESET} Governed workflow templates {DIM}25 commands & 13 MCP tools{RESET}"))
|
|
179
|
+
print(card_line(f"{GREEN}✔{RESET} Framework reference guides {DIM}22 architectural guides{RESET}"))
|
|
180
180
|
print(card_line(""))
|
|
181
|
-
print(card_line(f"{BOLD}{WHITE}{file_count} files unpacked{RESET}"))
|
|
181
|
+
print(card_line(f"{BOLD}{WHITE}{file_count} files unpacked into .torusguard/{RESET}"))
|
|
182
182
|
print(card_border_bottom())
|
|
183
183
|
|
|
184
184
|
|
|
@@ -186,13 +186,18 @@ def print_step_2_profile(detected_stack=None):
|
|
|
186
186
|
"""Print the security profile & coverage card (in-process stack alignment)."""
|
|
187
187
|
print(card_border_top("Step 2/3 ─── Security Profile & Coverage"))
|
|
188
188
|
print(card_line(""))
|
|
189
|
-
print(card_line(f"{BOLD}Rule Families:{RESET}"))
|
|
190
|
-
print(card_line(f" {YELLOW}TG-SEC{RESET} Secrets &
|
|
191
|
-
print(card_line(f" {YELLOW}TG-
|
|
192
|
-
print(card_line(f" {YELLOW}TG-
|
|
193
|
-
print(card_line(f" {YELLOW}TG-
|
|
194
|
-
print(card_line(f" {YELLOW}TG-
|
|
195
|
-
print(card_line(f" {YELLOW}TG-
|
|
189
|
+
print(card_line(f"{BOLD}Rule Families (88 Rules Across 22 Families):{RESET}"))
|
|
190
|
+
print(card_line(f" {YELLOW}TG-SEC{RESET} Secrets & Tokens {YELLOW}TG-AUTH{RESET} Authentication"))
|
|
191
|
+
print(card_line(f" {YELLOW}TG-DB{RESET} Database Isolation {YELLOW}TG-INPUT{RESET} Input Sanitization"))
|
|
192
|
+
print(card_line(f" {YELLOW}TG-RATE{RESET} Rate Limiting {YELLOW}TG-AGENT{RESET} AI Prompt Injection"))
|
|
193
|
+
print(card_line(f" {YELLOW}TG-SSRF{RESET} Server-Side Request {YELLOW}TG-WEBHOOK{RESET} Webhook Signature"))
|
|
194
|
+
print(card_line(f" {YELLOW}TG-WS{RESET} WebSocket Safety {YELLOW}TG-CSRF{RESET} Cross-Site Request"))
|
|
195
|
+
print(card_line(f" {YELLOW}TG-GQL{RESET} GraphQL Introspection {YELLOW}TG-SUPPLY{RESET} Supply Chain Health"))
|
|
196
|
+
print(card_line(f" {YELLOW}TG-BIZ{RESET} Business Logic Limits {YELLOW}TG-CACHE{RESET} Cache Poisoning"))
|
|
197
|
+
print(card_line(f" {YELLOW}TG-CLIENT{RESET} Client Bundle Secrets {YELLOW}TG-PLATFORM{RESET}Platform Hardening"))
|
|
198
|
+
print(card_line(f" {YELLOW}TG-DIFF{RESET} Polyglot Bypass Guard {YELLOW}TG-EDGE{RESET} Edge & Serverless"))
|
|
199
|
+
print(card_line(f" {YELLOW}TG-CONT{RESET} Container Hardening {YELLOW}TG-GIT{RESET} Git Secret Mining"))
|
|
200
|
+
print(card_line(f" {YELLOW}TG-REDOS{RESET} ReDoS Complexity Guard {YELLOW}TG-RAG{RESET} RAG & Vector Scoping"))
|
|
196
201
|
print(card_line(""))
|
|
197
202
|
print(card_line(f"{BOLD}Supported Stacks:{RESET}"))
|
|
198
203
|
print(card_line(f" {GREEN}Python{RESET} Django · FastAPI · Flask · DRF · SQLAlchemy"))
|
|
@@ -227,7 +232,7 @@ def print_success_card():
|
|
|
227
232
|
print(card_line("", border="║", border_color=GREEN))
|
|
228
233
|
print(card_line(f"{BOLD}Next Steps:{RESET}", border="║", border_color=GREEN))
|
|
229
234
|
print(card_line("", border="║", border_color=GREEN))
|
|
230
|
-
print(card_line(f" {CYAN}1.{RESET} In AI Chat {WHITE}/torusguard
|
|
235
|
+
print(card_line(f" {CYAN}1.{RESET} In AI Chat {WHITE}/torusguard audit{RESET} or {WHITE}/torusguard status{RESET}", border="║", border_color=GREEN))
|
|
231
236
|
print(card_line(f" {CYAN}2.{RESET} In Terminal {WHITE}npx torusguard status{RESET}", border="║", border_color=GREEN))
|
|
232
237
|
print(card_line(f" {CYAN}3.{RESET} In CI/CD {WHITE}npx torusguard audit{RESET}", border="║", border_color=GREEN))
|
|
233
238
|
print(card_line("", border="║", border_color=GREEN))
|
|
@@ -238,16 +243,21 @@ def print_success_card():
|
|
|
238
243
|
|
|
239
244
|
|
|
240
245
|
def print_already_initialized(target_root, cfg):
|
|
241
|
-
"""Print the already-initialized status card."""
|
|
246
|
+
"""Print the already-initialized status card with dynamic width alignment."""
|
|
242
247
|
print()
|
|
243
248
|
top = f" {CYAN}╭{'─' * 71}╮{RESET}"
|
|
244
249
|
bottom = f" {CYAN}╰{'─' * 71}╯{RESET}"
|
|
245
|
-
|
|
250
|
+
title_text = f"{BOLD}{WHITE}🛡️ TORUSGUARD WORKSPACE{RESET}"
|
|
251
|
+
status_text = f"{GREEN}[Active]{RESET}"
|
|
252
|
+
title_vis = get_visual_width("🛡️ TORUSGUARD WORKSPACE")
|
|
253
|
+
status_vis = get_visual_width("[Active]")
|
|
254
|
+
pad_count = max(1, 67 - title_vis - status_vis)
|
|
255
|
+
title_line = card_line(f"{title_text}{' ' * pad_count}{status_text}")
|
|
246
256
|
print(f"{top}\n{title_line}\n{bottom}")
|
|
247
257
|
print(f"""
|
|
248
258
|
{BOLD}▸ Project Root:{RESET} {GREEN}{target_root}{RESET}
|
|
249
259
|
{BOLD}▸ Workspace:{RESET} {GREEN}.torusguard/{RESET} {DIM}(Already Initialized){RESET}
|
|
250
|
-
{BOLD}▸ Version:{RESET} {CYAN}{cfg.get('version', '2.1.
|
|
260
|
+
{BOLD}▸ Version:{RESET} {CYAN}{cfg.get('version', '2.1.3')}{RESET}
|
|
251
261
|
{BOLD}▸ Severity Floor:{RESET} {YELLOW}{cfg.get('severity_threshold', 'medium')}{RESET}
|
|
252
262
|
|
|
253
263
|
{DIM}To refresh templates or re-scaffold, run:{RESET}
|
|
@@ -454,53 +464,10 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
|
|
|
454
464
|
3. Follow the phase execution steps defined in the workflow.
|
|
455
465
|
"""
|
|
456
466
|
|
|
457
|
-
#
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
#
|
|
461
|
-
agents_wf = target_root / ".agents" / "workflows"
|
|
462
|
-
agents_wf.mkdir(parents=True, exist_ok=True)
|
|
463
|
-
(agents_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
464
|
-
dest_workflow_dirs.append(agents_wf)
|
|
465
|
-
registered_ides.append("Antigravity / Gemini .agents/workflows/torusguard.md")
|
|
466
|
-
|
|
467
|
-
# 2. Tribunal Agent Kit (.agent/)
|
|
468
|
-
agent_wf = target_root / ".agent" / "workflows"
|
|
469
|
-
agent_wf.mkdir(parents=True, exist_ok=True)
|
|
470
|
-
(agent_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
471
|
-
dest_workflow_dirs.append(agent_wf)
|
|
472
|
-
registered_ides.append("Tribunal Agent Kit .agent/workflows/torusguard.md")
|
|
473
|
-
|
|
474
|
-
# Unpack Skills into .agents/skills and .agent/skills for full IDE resolution
|
|
475
|
-
src_skills = torusguard_target / "skills"
|
|
476
|
-
if src_skills.is_dir():
|
|
477
|
-
for dest_base in [target_root / ".agents" / "skills", target_root / ".agent" / "skills"]:
|
|
478
|
-
dest_base.mkdir(parents=True, exist_ok=True)
|
|
479
|
-
for skill_dir in src_skills.iterdir():
|
|
480
|
-
if skill_dir.is_dir():
|
|
481
|
-
target_skill_dir = dest_base / skill_dir.name
|
|
482
|
-
if not target_skill_dir.exists():
|
|
483
|
-
try:
|
|
484
|
-
shutil.copytree(skill_dir, target_skill_dir)
|
|
485
|
-
except Exception:
|
|
486
|
-
pass
|
|
487
|
-
|
|
488
|
-
# When full_commands is requested (e.g. via NPM package npx torusguard init),
|
|
489
|
-
# unlock and register all individual slash commands
|
|
490
|
-
if full_commands:
|
|
491
|
-
src_wf = torusguard_target / "workflows"
|
|
492
|
-
if src_wf.is_dir():
|
|
493
|
-
count = 0
|
|
494
|
-
for wf_file in src_wf.glob("*.md"):
|
|
495
|
-
if wf_file.name == "torusguard.md":
|
|
496
|
-
continue
|
|
497
|
-
cmd_filename = f"torusguard-{wf_file.name}"
|
|
498
|
-
for d in dest_workflow_dirs:
|
|
499
|
-
shutil.copy2(wf_file, d / cmd_filename)
|
|
500
|
-
count += 1
|
|
501
|
-
registered_ides.append(f"{count} Slash Commands /torusguard-audit, -harden, -apply, ...")
|
|
502
|
-
|
|
503
|
-
# Claude Code (.claude/commands)
|
|
467
|
+
# Core workspace governance is self-contained in .torusguard/
|
|
468
|
+
registered_ides.append("Workspace Core .torusguard/ (Workflows & Skills)")
|
|
469
|
+
|
|
470
|
+
# Claude Code (.claude/commands) - only if .claude exists
|
|
504
471
|
claude_dir = target_root / ".claude"
|
|
505
472
|
if claude_dir.exists():
|
|
506
473
|
claude_commands = claude_dir / "commands"
|
|
@@ -508,7 +475,7 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
|
|
|
508
475
|
(claude_commands / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
509
476
|
registered_ides.append("Claude Code .claude/commands/torusguard.md")
|
|
510
477
|
|
|
511
|
-
# Cursor (.cursor/rules)
|
|
478
|
+
# Cursor (.cursor/rules) - only if .cursor exists
|
|
512
479
|
cursor_dir = target_root / ".cursor"
|
|
513
480
|
if cursor_dir.exists():
|
|
514
481
|
cursor_rules = cursor_dir / "rules"
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"agents/validator.md": "79fc4431de5c5507f8730aee6c5c3e61fd238cbf8cf8c7c6aac462eee9761ed6",
|
|
10
10
|
"config/scope.json": "b198a86186b4c6d5e1af516bf4e3a6afa8878e622ca1d57a5bf72d294f8c6f25",
|
|
11
11
|
"config/slash-commands.json": "305c1dc5b556e8d64ad9dd585dafac1a9955cf1bd5321429955b19b7a62736b6",
|
|
12
|
-
"config/torusguard.json": "
|
|
12
|
+
"config/torusguard.json": "e8e41f3be04a06deb32ce5faaa93ddd608abfb2694b30325cac5085f3bfec9d8",
|
|
13
13
|
"core/__init__.py": "2120562452ae03c84468d67246dc93376f7ebcde8e4ca767c6253bc92c35dbbf",
|
|
14
14
|
"core/agent_roles.py": "d7189dbf1d3ae4e330eb316bed5d399a18992295addf466f4c6552bc14ae6a34",
|
|
15
15
|
"core/ast_walker.py": "309564d168e6eb9e3e93aceb29a95a61872b35a4da7235ee49e79e9d3a5e7cc6",
|
|
@@ -215,11 +215,11 @@
|
|
|
215
215
|
"scripts/safety_gate.py": "3379b7534b2590cf563717a448983ad8ed7e8f174f0ad65683d33e8a10f51558",
|
|
216
216
|
"scripts/sarif_exporter.py": "86700765212adb3ab590ca72614bf3ad4ce7ce60e3193f7f3bd1a04d34d10f6e",
|
|
217
217
|
"scripts/stack_detect.py": "c05a1ade4c8692025476bf7ea080a8f07c92e5d8e9a04f94c1654386352ffbdc",
|
|
218
|
-
"scripts/status_runner.py": "
|
|
219
|
-
"scripts/stride_generator.py": "
|
|
220
|
-
"scripts/term_ui.py": "
|
|
218
|
+
"scripts/status_runner.py": "a7421e25e2e34c1b83960ad117f5ea23d6f08b8af8b664be3fe03f70a3962db3",
|
|
219
|
+
"scripts/stride_generator.py": "6db98e8d9272c3c69f7c9be71cc4d9db6fe48553a3d7850ca62399ce4471ece8",
|
|
220
|
+
"scripts/term_ui.py": "a23435c703c4e8b68c5b80a539d59de2eda1cb01b0d9c47909ba72efde3be29b",
|
|
221
221
|
"skills/torusguard/SKILL.md": "15c69cb10eca1a10344b494888dce57e2baf227c3282bd54424a36ce35fb2460",
|
|
222
|
-
"skills/torusguard/bootstrap.py": "
|
|
222
|
+
"skills/torusguard/bootstrap.py": "178145eb36d15974ec9833d5c434dd31bba955d40a04cc9c12aed04058d1936a",
|
|
223
223
|
"skills/torusguard/references/auth-and-sessions.md": "c3e4b9600cb53fc28c993922dc880accbec5783ac90d5ee98d63b52762d19525",
|
|
224
224
|
"skills/torusguard/references/business-logic-and-abuse.md": "58e87df2864d468af70c1ff39f5d540c687fa846b671457f85046ab2065fe99c",
|
|
225
225
|
"skills/torusguard/references/cache-and-sensitive-responses.md": "81b4a7a08e11dafa4ec58d868c4a35f1f891d0dcdcfbcefaef81e1b9ba94f5a1",
|
|
@@ -262,9 +262,9 @@
|
|
|
262
262
|
"skills/torusguard-recheck/SKILL.md": "a5c4539ec6d091179c8ba53792fba46f26795976f392d2305e357f25a2966c55",
|
|
263
263
|
"skills/torusguard-redos/SKILL.md": "b09b39bd98589613b2107c177e247f6224fb54ab2f028b4339ae01aac9d28c67",
|
|
264
264
|
"skills/torusguard-report/SKILL.md": "509185ea6730601cf9a44e136219cace61cd0523f8e112de03e4ef1c35e60585",
|
|
265
|
-
"skills/torusguard-review/SKILL.md": "
|
|
265
|
+
"skills/torusguard-review/SKILL.md": "0c540a587befee455f027d752e261ed5885ec21def2c52471bd29bec69178307",
|
|
266
266
|
"skills/torusguard-status/SKILL.md": "e9741a20313a8304bc7565b194949a59ec7cfd4945b197517680164b3197efc0",
|
|
267
|
-
"skills/torusguard-threatmodel/SKILL.md": "
|
|
267
|
+
"skills/torusguard-threatmodel/SKILL.md": "3f589ea931998475536e25c77f85ddc17447012f860b4cee8d75e7b0f219ce82",
|
|
268
268
|
"skills/torusguard-verify/SKILL.md": "aeb4d3c7924253607d130e48491d83bf7b7a21707cd1dac2ba97d64f5e259fd6",
|
|
269
269
|
"skills/torusguard-web-validate/SKILL.md": "f1df00e10abd823d9a8c4daa1a3af7f26c5263c6c8e58e05b61b647d01a25489",
|
|
270
270
|
"templates/audit-report.template.md": "71149dd05b01a74287a47781fdc71fd2d1b4b70337da303bf78767d0410a6c90",
|
|
@@ -58,7 +58,7 @@ def collect_status(target_dir: Path) -> WorkspaceStatus:
|
|
|
58
58
|
is_init = tg_dir.is_dir()
|
|
59
59
|
|
|
60
60
|
# 1. Read config
|
|
61
|
-
version = "1.
|
|
61
|
+
version = "2.1.3"
|
|
62
62
|
stack_name = "Undetected"
|
|
63
63
|
cfg_file = tg_dir / "config" / "torusguard.json"
|
|
64
64
|
if cfg_file.is_file():
|
|
@@ -94,7 +94,7 @@ def collect_status(target_dir: Path) -> WorkspaceStatus:
|
|
|
94
94
|
if rules_root.is_dir():
|
|
95
95
|
active_rules_count = sum(1 for f in rules_root.rglob("TG-*.md"))
|
|
96
96
|
if active_rules_count == 0:
|
|
97
|
-
active_rules_count =
|
|
97
|
+
active_rules_count = 88 # Canonical rule catalog default
|
|
98
98
|
|
|
99
99
|
# 3. Read run history
|
|
100
100
|
total_runs = 0
|
|
@@ -210,7 +210,7 @@ def print_status_card(status: WorkspaceStatus) -> None:
|
|
|
210
210
|
print(format_box_line(f"Workspace: {WHITE}{status.target_path}{RESET}", 67))
|
|
211
211
|
print(format_box_line(f"Status: {init_str}", 67))
|
|
212
212
|
print(format_box_line(f"Stack: {BOLD}{WHITE}{status.stack_detected}{RESET}", 67))
|
|
213
|
-
print(format_box_line(f"Active Rules: {GREEN}{status.active_rules_count}{RESET} canonical rules enabled across
|
|
213
|
+
print(format_box_line(f"Active Rules: {GREEN}{status.active_rules_count}{RESET} canonical rules enabled across 22 families", 67))
|
|
214
214
|
print(card_border_bottom(CYAN))
|
|
215
215
|
print()
|
|
216
216
|
|
|
@@ -142,7 +142,7 @@ def generate_stride_report(root_dir: Path) -> str:
|
|
|
142
142
|
|
|
143
143
|
report = f"""# TorusGuard Architectural Threat Model & STRIDE Register
|
|
144
144
|
|
|
145
|
-
**Generated by:** TorusGuard Threat Modeling Engine (v2.1.
|
|
145
|
+
**Generated by:** TorusGuard Threat Modeling Engine (v2.1.3)
|
|
146
146
|
**Workspace:** `{root_dir.resolve().as_posix()}`
|
|
147
147
|
**Analyzed Routes:** {comp['total_routes_detected']}
|
|
148
148
|
**Identified Data Stores:** {', '.join(comp['datastores'])}
|
|
@@ -143,7 +143,7 @@ def card_divider(title: str = "", border_color: str = CYAN, double: bool = False
|
|
|
143
143
|
return f" {border_color}{left}{h} {BOLD}{WHITE}{title}{RESET}{border_color} {h * rem}{right}{RESET}"
|
|
144
144
|
return f" {border_color}{left}{h * 71}{right}{RESET}"
|
|
145
145
|
|
|
146
|
-
def card_header(title: str, subtitle: str = "", version: str = "
|
|
146
|
+
def card_header(title: str, subtitle: str = "", version: str = "v2.1.3", border_color: str = CYAN) -> str:
|
|
147
147
|
"""Generate standardized 75-column curved header box."""
|
|
148
148
|
top = f" {border_color}╭{'─' * 71}╮{RESET}"
|
|
149
149
|
bottom = f" {border_color}╰{'─' * 71}╯{RESET}"
|
|
@@ -144,7 +144,7 @@ def card_divider(title: str = "", border_color: str = CYAN, double: bool = False
|
|
|
144
144
|
return f" {border_color}{left}{h} {BOLD}{WHITE}{title}{RESET}{border_color} {h * rem}{right}{RESET}"
|
|
145
145
|
return f" {border_color}{left}{h * 71}{right}{RESET}"
|
|
146
146
|
|
|
147
|
-
def card_header(title: str, subtitle: str = "", version: str = "v2.1.
|
|
147
|
+
def card_header(title: str, subtitle: str = "", version: str = "v2.1.3", border_color: str = CYAN) -> str:
|
|
148
148
|
"""Generate standardized 75-column curved header box."""
|
|
149
149
|
top = f" {border_color}╭{'─' * 71}╮{RESET}"
|
|
150
150
|
bottom = f" {border_color}╰{'─' * 71}╯{RESET}"
|
|
@@ -164,7 +164,7 @@ def card_header(title: str, subtitle: str = "", version: str = "v2.1.2", border_
|
|
|
164
164
|
def print_header():
|
|
165
165
|
"""Print the branded TorusGuard header card."""
|
|
166
166
|
print()
|
|
167
|
-
print(card_header("🛡️ T O R U S G U A R D", "Autonomous Security Engine for AI-Built Applications", version="v2.1.
|
|
167
|
+
print(card_header("🛡️ T O R U S G U A R D", "Autonomous Security Engine for AI-Built Applications", version="v2.1.3"))
|
|
168
168
|
print()
|
|
169
169
|
|
|
170
170
|
|
|
@@ -172,13 +172,13 @@ def print_step_1_assets(file_count):
|
|
|
172
172
|
"""Print the enhanced Step 1 asset unpacking card."""
|
|
173
173
|
print(card_border_top("Step 1/3 ─── Unpacking Governance Assets"))
|
|
174
174
|
print(card_line(""))
|
|
175
|
-
print(card_line(f"{GREEN}✔{RESET} Canonical security rules {DIM}
|
|
175
|
+
print(card_line(f"{GREEN}✔{RESET} Canonical security rules {DIM}88 rules across 22 families{RESET}"))
|
|
176
176
|
print(card_line(f"{GREEN}✔{RESET} JSON validation schemas {DIM}8 formal schemas{RESET}"))
|
|
177
177
|
print(card_line(f"{GREEN}✔{RESET} Specialist agent specifications {DIM}5 isolated agents{RESET}"))
|
|
178
|
-
print(card_line(f"{GREEN}✔{RESET}
|
|
179
|
-
print(card_line(f"{GREEN}✔{RESET} Framework reference guides {DIM}
|
|
178
|
+
print(card_line(f"{GREEN}✔{RESET} Governed workflow templates {DIM}25 commands & 13 MCP tools{RESET}"))
|
|
179
|
+
print(card_line(f"{GREEN}✔{RESET} Framework reference guides {DIM}22 architectural guides{RESET}"))
|
|
180
180
|
print(card_line(""))
|
|
181
|
-
print(card_line(f"{BOLD}{WHITE}{file_count} files unpacked{RESET}"))
|
|
181
|
+
print(card_line(f"{BOLD}{WHITE}{file_count} files unpacked into .torusguard/{RESET}"))
|
|
182
182
|
print(card_border_bottom())
|
|
183
183
|
|
|
184
184
|
|
|
@@ -186,13 +186,18 @@ def print_step_2_profile(detected_stack=None):
|
|
|
186
186
|
"""Print the security profile & coverage card (in-process stack alignment)."""
|
|
187
187
|
print(card_border_top("Step 2/3 ─── Security Profile & Coverage"))
|
|
188
188
|
print(card_line(""))
|
|
189
|
-
print(card_line(f"{BOLD}Rule Families:{RESET}"))
|
|
190
|
-
print(card_line(f" {YELLOW}TG-SEC{RESET} Secrets &
|
|
191
|
-
print(card_line(f" {YELLOW}TG-
|
|
192
|
-
print(card_line(f" {YELLOW}TG-
|
|
193
|
-
print(card_line(f" {YELLOW}TG-
|
|
194
|
-
print(card_line(f" {YELLOW}TG-
|
|
195
|
-
print(card_line(f" {YELLOW}TG-
|
|
189
|
+
print(card_line(f"{BOLD}Rule Families (88 Rules Across 22 Families):{RESET}"))
|
|
190
|
+
print(card_line(f" {YELLOW}TG-SEC{RESET} Secrets & Tokens {YELLOW}TG-AUTH{RESET} Authentication"))
|
|
191
|
+
print(card_line(f" {YELLOW}TG-DB{RESET} Database Isolation {YELLOW}TG-INPUT{RESET} Input Sanitization"))
|
|
192
|
+
print(card_line(f" {YELLOW}TG-RATE{RESET} Rate Limiting {YELLOW}TG-AGENT{RESET} AI Prompt Injection"))
|
|
193
|
+
print(card_line(f" {YELLOW}TG-SSRF{RESET} Server-Side Request {YELLOW}TG-WEBHOOK{RESET} Webhook Signature"))
|
|
194
|
+
print(card_line(f" {YELLOW}TG-WS{RESET} WebSocket Safety {YELLOW}TG-CSRF{RESET} Cross-Site Request"))
|
|
195
|
+
print(card_line(f" {YELLOW}TG-GQL{RESET} GraphQL Introspection {YELLOW}TG-SUPPLY{RESET} Supply Chain Health"))
|
|
196
|
+
print(card_line(f" {YELLOW}TG-BIZ{RESET} Business Logic Limits {YELLOW}TG-CACHE{RESET} Cache Poisoning"))
|
|
197
|
+
print(card_line(f" {YELLOW}TG-CLIENT{RESET} Client Bundle Secrets {YELLOW}TG-PLATFORM{RESET}Platform Hardening"))
|
|
198
|
+
print(card_line(f" {YELLOW}TG-DIFF{RESET} Polyglot Bypass Guard {YELLOW}TG-EDGE{RESET} Edge & Serverless"))
|
|
199
|
+
print(card_line(f" {YELLOW}TG-CONT{RESET} Container Hardening {YELLOW}TG-GIT{RESET} Git Secret Mining"))
|
|
200
|
+
print(card_line(f" {YELLOW}TG-REDOS{RESET} ReDoS Complexity Guard {YELLOW}TG-RAG{RESET} RAG & Vector Scoping"))
|
|
196
201
|
print(card_line(""))
|
|
197
202
|
print(card_line(f"{BOLD}Supported Stacks:{RESET}"))
|
|
198
203
|
print(card_line(f" {GREEN}Python{RESET} Django · FastAPI · Flask · DRF · SQLAlchemy"))
|
|
@@ -227,7 +232,7 @@ def print_success_card():
|
|
|
227
232
|
print(card_line("", border="║", border_color=GREEN))
|
|
228
233
|
print(card_line(f"{BOLD}Next Steps:{RESET}", border="║", border_color=GREEN))
|
|
229
234
|
print(card_line("", border="║", border_color=GREEN))
|
|
230
|
-
print(card_line(f" {CYAN}1.{RESET} In AI Chat {WHITE}/torusguard
|
|
235
|
+
print(card_line(f" {CYAN}1.{RESET} In AI Chat {WHITE}/torusguard audit{RESET} or {WHITE}/torusguard status{RESET}", border="║", border_color=GREEN))
|
|
231
236
|
print(card_line(f" {CYAN}2.{RESET} In Terminal {WHITE}npx torusguard status{RESET}", border="║", border_color=GREEN))
|
|
232
237
|
print(card_line(f" {CYAN}3.{RESET} In CI/CD {WHITE}npx torusguard audit{RESET}", border="║", border_color=GREEN))
|
|
233
238
|
print(card_line("", border="║", border_color=GREEN))
|
|
@@ -238,16 +243,21 @@ def print_success_card():
|
|
|
238
243
|
|
|
239
244
|
|
|
240
245
|
def print_already_initialized(target_root, cfg):
|
|
241
|
-
"""Print the already-initialized status card."""
|
|
246
|
+
"""Print the already-initialized status card with dynamic width alignment."""
|
|
242
247
|
print()
|
|
243
248
|
top = f" {CYAN}╭{'─' * 71}╮{RESET}"
|
|
244
249
|
bottom = f" {CYAN}╰{'─' * 71}╯{RESET}"
|
|
245
|
-
|
|
250
|
+
title_text = f"{BOLD}{WHITE}🛡️ TORUSGUARD WORKSPACE{RESET}"
|
|
251
|
+
status_text = f"{GREEN}[Active]{RESET}"
|
|
252
|
+
title_vis = get_visual_width("🛡️ TORUSGUARD WORKSPACE")
|
|
253
|
+
status_vis = get_visual_width("[Active]")
|
|
254
|
+
pad_count = max(1, 67 - title_vis - status_vis)
|
|
255
|
+
title_line = card_line(f"{title_text}{' ' * pad_count}{status_text}")
|
|
246
256
|
print(f"{top}\n{title_line}\n{bottom}")
|
|
247
257
|
print(f"""
|
|
248
258
|
{BOLD}▸ Project Root:{RESET} {GREEN}{target_root}{RESET}
|
|
249
259
|
{BOLD}▸ Workspace:{RESET} {GREEN}.torusguard/{RESET} {DIM}(Already Initialized){RESET}
|
|
250
|
-
{BOLD}▸ Version:{RESET} {CYAN}{cfg.get('version', '2.1.
|
|
260
|
+
{BOLD}▸ Version:{RESET} {CYAN}{cfg.get('version', '2.1.3')}{RESET}
|
|
251
261
|
{BOLD}▸ Severity Floor:{RESET} {YELLOW}{cfg.get('severity_threshold', 'medium')}{RESET}
|
|
252
262
|
|
|
253
263
|
{DIM}To refresh templates or re-scaffold, run:{RESET}
|
|
@@ -454,53 +464,10 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
|
|
|
454
464
|
3. Follow the phase execution steps defined in the workflow.
|
|
455
465
|
"""
|
|
456
466
|
|
|
457
|
-
#
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
#
|
|
461
|
-
agents_wf = target_root / ".agents" / "workflows"
|
|
462
|
-
agents_wf.mkdir(parents=True, exist_ok=True)
|
|
463
|
-
(agents_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
464
|
-
dest_workflow_dirs.append(agents_wf)
|
|
465
|
-
registered_ides.append("Antigravity / Gemini .agents/workflows/torusguard.md")
|
|
466
|
-
|
|
467
|
-
# 2. Tribunal Agent Kit (.agent/)
|
|
468
|
-
agent_wf = target_root / ".agent" / "workflows"
|
|
469
|
-
agent_wf.mkdir(parents=True, exist_ok=True)
|
|
470
|
-
(agent_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
471
|
-
dest_workflow_dirs.append(agent_wf)
|
|
472
|
-
registered_ides.append("Tribunal Agent Kit .agent/workflows/torusguard.md")
|
|
473
|
-
|
|
474
|
-
# Unpack Skills into .agents/skills and .agent/skills for full IDE resolution
|
|
475
|
-
src_skills = torusguard_target / "skills"
|
|
476
|
-
if src_skills.is_dir():
|
|
477
|
-
for dest_base in [target_root / ".agents" / "skills", target_root / ".agent" / "skills"]:
|
|
478
|
-
dest_base.mkdir(parents=True, exist_ok=True)
|
|
479
|
-
for skill_dir in src_skills.iterdir():
|
|
480
|
-
if skill_dir.is_dir():
|
|
481
|
-
target_skill_dir = dest_base / skill_dir.name
|
|
482
|
-
if not target_skill_dir.exists():
|
|
483
|
-
try:
|
|
484
|
-
shutil.copytree(skill_dir, target_skill_dir)
|
|
485
|
-
except Exception:
|
|
486
|
-
pass
|
|
487
|
-
|
|
488
|
-
# When full_commands is requested (e.g. via NPM package npx torusguard init),
|
|
489
|
-
# unlock and register all individual slash commands
|
|
490
|
-
if full_commands:
|
|
491
|
-
src_wf = torusguard_target / "workflows"
|
|
492
|
-
if src_wf.is_dir():
|
|
493
|
-
count = 0
|
|
494
|
-
for wf_file in src_wf.glob("*.md"):
|
|
495
|
-
if wf_file.name == "torusguard.md":
|
|
496
|
-
continue
|
|
497
|
-
cmd_filename = f"torusguard-{wf_file.name}"
|
|
498
|
-
for d in dest_workflow_dirs:
|
|
499
|
-
shutil.copy2(wf_file, d / cmd_filename)
|
|
500
|
-
count += 1
|
|
501
|
-
registered_ides.append(f"{count} Slash Commands /torusguard-audit, -harden, -apply, ...")
|
|
502
|
-
|
|
503
|
-
# Claude Code (.claude/commands)
|
|
467
|
+
# Core workspace governance is self-contained in .torusguard/
|
|
468
|
+
registered_ides.append("Workspace Core .torusguard/ (Workflows & Skills)")
|
|
469
|
+
|
|
470
|
+
# Claude Code (.claude/commands) - only if .claude exists
|
|
504
471
|
claude_dir = target_root / ".claude"
|
|
505
472
|
if claude_dir.exists():
|
|
506
473
|
claude_commands = claude_dir / "commands"
|
|
@@ -508,7 +475,7 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
|
|
|
508
475
|
(claude_commands / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
|
|
509
476
|
registered_ides.append("Claude Code .claude/commands/torusguard.md")
|
|
510
477
|
|
|
511
|
-
# Cursor (.cursor/rules)
|
|
478
|
+
# Cursor (.cursor/rules) - only if .cursor exists
|
|
512
479
|
cursor_dir = target_root / ".cursor"
|
|
513
480
|
if cursor_dir.exists():
|
|
514
481
|
cursor_rules = cursor_dir / "rules"
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
name: torusguard-review
|
|
3
3
|
description: Differential PR and Git diff incremental security review — detects newly introduced vulnerabilities between Git branches or commits with net security score deltas.
|
|
4
4
|
tools: Read, Grep, Glob, Bash, Edit, Write
|
|
5
|
-
version: 2.1.
|
|
6
|
-
last-updated: 2026-
|
|
5
|
+
version: 2.1.3
|
|
6
|
+
last-updated: 2026-10-01
|
|
7
7
|
skills:
|
|
8
8
|
- torusguard
|
|
9
9
|
- torusguard-audit
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
name: torusguard-threatmodel
|
|
3
3
|
description: Synthesizes an architectural STRIDE threat model, interactive Mermaid Data Flow Diagram (DFD), and trust boundary register into SECURITY_THREAT_MODEL.md.
|
|
4
4
|
tools: Read, Grep, Glob, Bash, Edit, Write
|
|
5
|
-
version: 2.1.
|
|
6
|
-
last-updated: 2026-
|
|
5
|
+
version: 2.1.3
|
|
6
|
+
last-updated: 2026-10-01
|
|
7
7
|
skills:
|
|
8
8
|
- torusguard
|
|
9
9
|
- torusguard-audit
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
name: torusguard-review
|
|
3
3
|
description: Differential PR and Git diff incremental security review — detects newly introduced vulnerabilities between Git branches or commits with net security score deltas.
|
|
4
4
|
tools: Read, Grep, Glob, Bash, Edit, Write
|
|
5
|
-
version: 2.1.
|
|
6
|
-
last-updated: 2026-
|
|
5
|
+
version: 2.1.3
|
|
6
|
+
last-updated: 2026-10-01
|
|
7
7
|
skills:
|
|
8
8
|
- torusguard
|
|
9
9
|
- torusguard-audit
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
name: torusguard-threatmodel
|
|
3
3
|
description: Synthesizes an architectural STRIDE threat model, interactive Mermaid Data Flow Diagram (DFD), and trust boundary register into SECURITY_THREAT_MODEL.md.
|
|
4
4
|
tools: Read, Grep, Glob, Bash, Edit, Write
|
|
5
|
-
version: 2.1.
|
|
6
|
-
last-updated: 2026-
|
|
5
|
+
version: 2.1.3
|
|
6
|
+
last-updated: 2026-10-01
|
|
7
7
|
skills:
|
|
8
8
|
- torusguard
|
|
9
9
|
- torusguard-audit
|