@collabchron/tharos 0.1.0 → 0.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Fennec Security
3
+ Copyright (c) 2026 Tharos Security
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -12,8 +12,11 @@ Tharos is a comprehensive security analysis tool that combines static code analy
12
12
 
13
13
  ### šŸ”’ Multi-Layer Security Analysis
14
14
  - **AST-Based Detection**: Fast, accurate pattern matching for common vulnerabilities
15
+ - **Scanner Mindset**: Context-aware analysis that ignores test files and mock data
16
+ - **Weighted Blocking**: Intelligent CI/CD gating based on finding severity
15
17
  - **AI Semantic Analysis**: Deep understanding of code context and intent
16
18
  - **Risk Scoring**: Automated 0-100 risk assessment for every finding
19
+ - **SARIF Export**: Standardized reporting for GitHub Advanced Security & other tools
17
20
  - **Suggested Fixes**: AI-generated code snippets to resolve issues
18
21
 
19
22
  ### šŸŒ Multi-Language Support
@@ -115,18 +118,39 @@ cp node_modules/tharos/policies/soc2.yaml tharos.yaml
115
118
  cp node_modules/tharos/policies/gdpr.yaml tharos.yaml
116
119
  ```
117
120
 
118
- ### 3. Set Up AI (Optional)
121
+ ### 3. Set Up AI Providers (Optional but Recommended)
122
+
123
+ Tharos works without AI but provides **deeper insights** with it enabled. Choose either provider (both have free tiers):
124
+
125
+ #### 🧠 Option 1: Google Gemini (Recommended)
126
+ **Best for:** Powerful analysis, generous free tier
127
+
119
128
  ```bash
120
- # Option 1: Use Groq (recommended)
121
- export GROQ_API_KEY="your-groq-key"
129
+ # Get your API key from https://makersuite.google.com/app/apikey
130
+ export GEMINI_API_KEY="your-gemini-key-here"
122
131
 
123
- # Option 2: Use Gemini
124
- export GEMINI_API_KEY="your-gemini-key"
132
+ # Or on Windows PowerShell:
133
+ $env:GEMINI_API_KEY="your-gemini-key-here"
134
+ ```
125
135
 
126
- # Option 3: Use local Ollama
127
- ollama serve
136
+ #### ⚔ Option 2: Groq (Fast & Free)
137
+ **Best for:** Speed, low latency
138
+
139
+ ```bash
140
+ # Get your free API key from https://console.groq.com
141
+ export GROQ_API_KEY="your-groq-key-here"
142
+
143
+ # Or on Windows PowerShell:
144
+ $env:GROQ_API_KEY="your-groq-key-here"
145
+ ```
146
+
147
+ **Check your setup:**
148
+ ```bash
149
+ tharos core setup
128
150
  ```
129
151
 
152
+
153
+
130
154
  ### 4. Run Analysis
131
155
  ```bash
132
156
  # Check all staged files
@@ -1,6 +1,8 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import { execa } from 'execa';
3
+ import { exec } from 'child_process';
4
+ import { promisify } from 'util';
5
+ const execAsync = promisify(exec);
4
6
  const HOOK_CONTENT = `#!/bin/sh
5
7
  # Tharos Git Hook
6
8
  // This hook is managed by Tharos. Do not modify manually.
@@ -52,7 +54,7 @@ export async function verifyHooks() {
52
54
  }
53
55
  async function findGitDir() {
54
56
  try {
55
- const { stdout } = await execa('git', ['rev-parse', '--git-dir']);
57
+ const { stdout } = await execAsync('git rev-parse --git-dir');
56
58
  return path.resolve(stdout.trim());
57
59
  }
58
60
  catch {
package/dist/index.js CHANGED
@@ -1,120 +1,21 @@
1
1
  #!/usr/bin/env node
2
- import { Command } from 'commander';
3
- import chalk from 'chalk';
2
+ import { spawn } from 'child_process';
4
3
  import path from 'path';
5
4
  import { fileURLToPath } from 'url';
6
- import { initHooks, verifyHooks } from './hooks/manager.js';
7
5
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
- const program = new Command();
9
- program
10
- .name('tharos')
11
- .description('Tharos: Intelligent, Unbreakable Code Policy Enforcement')
12
- .version('0.1.0');
13
- program
14
- .command('init')
15
- .description('Initialize Tharos hooks in the current repository')
16
- .action(async () => {
17
- console.log(chalk.cyan('šŸ›”ļø Initializing Tharos...'));
18
- try {
19
- await initHooks();
20
- console.log(chalk.green('āœ… Tharos hooks installed successfully!'));
21
- }
22
- catch (error) {
23
- console.error(chalk.red('āŒ Failed to initialize Tharos:'), error);
24
- process.exit(1);
25
- }
6
+ // Path to the Go binary
7
+ const binaryName = process.platform === 'win32' ? 'tharos.exe' : 'tharos';
8
+ const binaryPath = path.resolve(__dirname, binaryName);
9
+ // Pass all arguments to the Go binary
10
+ const args = process.argv.slice(2);
11
+ const child = spawn(binaryPath, args, {
12
+ stdio: 'inherit',
13
+ shell: false
26
14
  });
27
- program
28
- .command('sync')
29
- .description('Synchronize organizational policies with the cloud')
30
- .action(async () => {
31
- console.log(chalk.cyan('ā˜ļø Syncing Tharos policies with cloud...'));
32
- await new Promise(resolve => setTimeout(resolve, 1500)); // Simulate network latency
33
- console.log(chalk.green('āœ… Organizational policies synchronized!'));
34
- console.log(chalk.gray(' Applied Policy: SEC-RULE-2026 (Enforced)'));
15
+ child.on('exit', (code) => {
16
+ process.exit(code || 0);
35
17
  });
36
- program
37
- .command('check')
38
- .description('Run Tharos policy checks on staged files')
39
- .option('--self-heal', 'Perform self-healing if hooks are missing or tampered')
40
- .action(async (options) => {
41
- if (options.selfHeal) {
42
- await verifyHooks();
43
- }
44
- console.log(chalk.cyan('šŸ›”ļø Tharos is analyzing your intent...'));
45
- try {
46
- const { execa } = await import('execa');
47
- // Get staged files
48
- const { stdout: stagedFiles } = await execa('git', ['diff', '--cached', '--name-only']);
49
- const files = stagedFiles.split('\n').filter(f => f.match(/\.(js|ts|jsx|tsx)$/));
50
- if (files.length === 0) {
51
- console.log(chalk.gray('No relevant files staged for commit.'));
52
- return;
53
- }
54
- let globalBlock = false;
55
- for (const file of files) {
56
- console.log(chalk.white(`\nšŸ“„ Analyzing ${chalk.bold(file)}...`));
57
- try {
58
- const corePath = path.resolve(__dirname, 'tharos-core.exe');
59
- const { stdout } = await execa(corePath, ['analyze', file]);
60
- const result = JSON.parse(stdout);
61
- // Display Findings
62
- if (result.findings && result.findings.length > 0) {
63
- result.findings.forEach((finding) => {
64
- const color = finding.severity === 'block' ? chalk.red : chalk.yellow;
65
- const icon = finding.severity === 'block' ? 'šŸ›‘' : 'āš ļø';
66
- console.log(` ${icon} ${color(finding.type.toUpperCase())}: ${finding.message}`);
67
- if (finding.line) {
68
- console.log(chalk.gray(` Line ${finding.line}`));
69
- }
70
- if (finding.severity === 'block')
71
- globalBlock = true;
72
- });
73
- }
74
- else {
75
- console.log(chalk.green(' āœ… No issues found.'));
76
- }
77
- // Display AI Insights
78
- if (result.ai_insights && result.ai_insights.length > 0) {
79
- console.log(chalk.blue.italic('\n 🧠 Tharos AI Semantic Insights:'));
80
- result.ai_insights.forEach((insight) => {
81
- if (typeof insight === 'string') {
82
- console.log(` ✨ ${insight}`);
83
- return;
84
- }
85
- const score = insight.risk_score || 50;
86
- const recommendation = insight.recommendation || insight;
87
- const scoreColor = score > 70 ? chalk.red : score > 40 ? chalk.yellow : chalk.green;
88
- console.log(` ✨ ${recommendation}`);
89
- console.log(` šŸ“Š Risk Score: ${scoreColor(score + '/100')}`);
90
- if (insight.suggested_fix) {
91
- console.log(chalk.cyan('\n šŸ’” Suggested Fix:'));
92
- console.log(chalk.gray(' ---------------------------------------'));
93
- console.log(insight.suggested_fix.split('\n').map((line) => ` ${line}`).join('\n'));
94
- console.log(chalk.gray(' ---------------------------------------'));
95
- }
96
- });
97
- }
98
- else if (result.findings && result.findings.length > 0) {
99
- console.log(chalk.gray('\n šŸ’” Tip: No AI insights available.'));
100
- console.log(chalk.gray(' Run "ollama serve" or use Tharos Cloud for smart analysis.'));
101
- }
102
- }
103
- catch (e) {
104
- console.error(chalk.red(` āŒ Failed to analyze ${file}:`), e);
105
- }
106
- }
107
- if (globalBlock) {
108
- console.log(chalk.red('\nšŸ›‘ Commit blocked by Tharos policy. Please fix the issues above.'));
109
- process.exit(1);
110
- }
111
- else {
112
- console.log(chalk.green('\n✨ Tharos logic check passed! Proceeding...'));
113
- }
114
- }
115
- catch (error) {
116
- console.error(chalk.red('āŒ Tharos check execution failed:'), error);
117
- process.exit(1);
118
- }
18
+ child.on('error', (err) => {
19
+ console.error(`Failed to start Tharos binary: ${err.message}`);
20
+ process.exit(1);
119
21
  });
120
- program.parse();
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@collabchron/tharos",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "description": "Tharos: Intelligent, Unbreakable Code Policy Enforcement",
5
5
  "keywords": [
6
6
  "security",
@@ -26,18 +26,13 @@
26
26
  "tharos": "dist/index.js"
27
27
  },
28
28
  "scripts": {
29
- "build": "tsc",
29
+ "build": "tsc && copy go-core\\tharos.exe dist\\tharos.exe",
30
30
  "start": "node --loader ts-node/esm src/index.ts",
31
31
  "dev": "node --loader ts-node/esm src/index.ts",
32
32
  "test": "echo \"Error: no test specified\" && exit 1"
33
33
  },
34
- "dependencies": {
35
- "chalk": "^5.3.0",
36
- "commander": "^12.0.0",
37
- "execa": "^8.0.1"
38
- },
34
+ "dependencies": {},
39
35
  "devDependencies": {
40
- "@napi-rs/cli": "^3.5.1",
41
36
  "@types/node": "^20.11.0",
42
37
  "ts-node": "^10.9.2",
43
38
  "typescript": "^5.3.3"