@telelabsai/ship 1.1.2 → 1.1.4
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/.claude/agents/reviewer.md +47 -0
- package/.claude/hooks/git-safety.cjs +14 -22
- package/.claude/rules/code-quality.md +15 -0
- package/.claude/rules/security.md +10 -0
- package/.claude/shared/secret-patterns.json +62 -0
- package/.claude/skills/ship-review/SKILL.md +74 -0
- package/.claude/skills/ship-review/references/output-format.md +62 -0
- package/.claude/skills/ship-review/references/review-categories.md +169 -0
- package/.claude/skills/ship-review/references/severity-levels.md +49 -0
- package/.claude/skills/ship-secure/SKILL.md +60 -0
- package/.claude/skills/ship-secure/references/dependency-audit.md +71 -0
- package/.claude/skills/ship-secure/references/owasp-checks.md +197 -0
- package/.claude/skills/ship-secure/references/secret-patterns.md +50 -0
- package/.claude/skills/ship-test/SKILL.md +85 -0
- package/.claude/skills/ship-test/references/coverage-analysis.md +70 -0
- package/.claude/skills/ship-test/references/output-format.md +71 -0
- package/.claude/skills/ship-test/references/test-workflow.md +47 -0
- package/.claude/skills/ship-version/SKILL.md +4 -0
- package/.claude/skills/ship-version/references/safety-protocols.md +10 -16
- package/LICENSE +21 -0
- package/README.md +102 -11
- package/cli/bin.js +18 -1
- package/cli/commands/auth.js +141 -0
- package/cli/commands/init.js +37 -6
- package/cli/commands/sync.js +142 -0
- package/git-hooks/pre-commit.cjs +143 -0
- package/package.json +3 -2
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Dependency Audit
|
|
2
|
+
|
|
3
|
+
## Step 1: Run Package Manager Audit
|
|
4
|
+
|
|
5
|
+
| Ecosystem | Command |
|
|
6
|
+
|-----------|---------|
|
|
7
|
+
| npm | `npm audit --json 2>/dev/null` |
|
|
8
|
+
| yarn | `yarn audit --json 2>/dev/null` |
|
|
9
|
+
| pnpm | `pnpm audit --json 2>/dev/null` |
|
|
10
|
+
| pip | `pip audit --format json 2>/dev/null` or `safety check --json 2>/dev/null` |
|
|
11
|
+
| go | `govulncheck ./... 2>/dev/null` |
|
|
12
|
+
| cargo | `cargo audit --json 2>/dev/null` |
|
|
13
|
+
|
|
14
|
+
If command not available, fall back to reading lock files manually.
|
|
15
|
+
|
|
16
|
+
## Step 2: Analyze Results
|
|
17
|
+
|
|
18
|
+
For each vulnerability found:
|
|
19
|
+
- Package name and installed version
|
|
20
|
+
- CVE ID and severity (critical, high, medium, low)
|
|
21
|
+
- Description of the vulnerability
|
|
22
|
+
- Fixed version (if available)
|
|
23
|
+
- Whether it's a direct or transitive dependency
|
|
24
|
+
- Whether it's reachable in the codebase (import used or not)
|
|
25
|
+
|
|
26
|
+
## Step 3: Check for Outdated Packages
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm outdated --json 2>/dev/null
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Flag:
|
|
33
|
+
- Major version behind on security-critical packages (auth, crypto, http)
|
|
34
|
+
- Packages with no updates in 2+ years (potentially abandoned)
|
|
35
|
+
- Packages with known security track record issues
|
|
36
|
+
|
|
37
|
+
## Step 4: Check for Suspicious Packages
|
|
38
|
+
|
|
39
|
+
Flag:
|
|
40
|
+
- Packages with very low download counts
|
|
41
|
+
- Packages that were recently transferred to new owners
|
|
42
|
+
- Typosquatting (package names similar to popular ones)
|
|
43
|
+
- Packages requesting unnecessary permissions
|
|
44
|
+
|
|
45
|
+
## Severity Classification
|
|
46
|
+
|
|
47
|
+
Uses the same 3-level system as all Ship tools:
|
|
48
|
+
|
|
49
|
+
| Level | CVSS Mapping | When |
|
|
50
|
+
|-------|-------------|------|
|
|
51
|
+
| Critical | CVSS >= 7.0 | Known CVE with high/critical severity, exploit available |
|
|
52
|
+
| Warning | CVSS 4.0-6.9 | Known CVE with medium severity, outdated major version on critical package |
|
|
53
|
+
| Suggestion | CVSS < 4.0 | Low severity CVE, outdated package, informational |
|
|
54
|
+
|
|
55
|
+
## Output Format
|
|
56
|
+
|
|
57
|
+
```markdown
|
|
58
|
+
### Dependencies
|
|
59
|
+
|
|
60
|
+
#### Vulnerabilities
|
|
61
|
+
- [critical] package@version — CVE-XXXX-XXXXX: description
|
|
62
|
+
Fix: upgrade to package@fixed-version
|
|
63
|
+
|
|
64
|
+
#### Outdated (security-relevant)
|
|
65
|
+
- package@current → package@latest (N major versions behind)
|
|
66
|
+
|
|
67
|
+
#### Summary
|
|
68
|
+
Total packages: N
|
|
69
|
+
Vulnerable: N (critical: N, warning: N, suggestion: N)
|
|
70
|
+
Outdated: N
|
|
71
|
+
```
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# Vulnerability Checks
|
|
2
|
+
|
|
3
|
+
## A01: Broken Access Control
|
|
4
|
+
|
|
5
|
+
Check for:
|
|
6
|
+
- Endpoints without authentication middleware
|
|
7
|
+
- Missing authorization (user accessing other users' resources)
|
|
8
|
+
- CORS misconfiguration (wildcard *, credentials: true)
|
|
9
|
+
- Directory traversal (user input in file paths: `../../../etc/passwd`)
|
|
10
|
+
- Insecure direct object references (sequential IDs: `/api/users/1`, `/api/users/2`)
|
|
11
|
+
- Missing function-level access control (admin routes accessible to regular users)
|
|
12
|
+
- RBAC not enforced consistently
|
|
13
|
+
|
|
14
|
+
Patterns to search:
|
|
15
|
+
```
|
|
16
|
+
app.get('/admin (without auth middleware)
|
|
17
|
+
req.params.id (used directly to fetch without ownership check)
|
|
18
|
+
Access-Control-Allow-Origin: *
|
|
19
|
+
path.join(userInput)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## A02: Cryptographic Failures
|
|
23
|
+
|
|
24
|
+
Check for:
|
|
25
|
+
- Passwords stored in plain text or with weak hash (MD5, SHA1)
|
|
26
|
+
- Missing encryption on sensitive data at rest
|
|
27
|
+
- Hardcoded encryption keys or salts
|
|
28
|
+
- HTTP instead of HTTPS for sensitive data
|
|
29
|
+
- Weak random number generation (Math.random for tokens)
|
|
30
|
+
- Missing TLS version enforcement
|
|
31
|
+
- Sensitive data in URL parameters (tokens, passwords in query strings)
|
|
32
|
+
|
|
33
|
+
Patterns:
|
|
34
|
+
```
|
|
35
|
+
md5( sha1( Math.random()
|
|
36
|
+
password = secret = (in plain assignment without hashing)
|
|
37
|
+
http:// (for API calls with sensitive data)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## A03: Injection
|
|
41
|
+
|
|
42
|
+
Check for:
|
|
43
|
+
- SQL injection (string concatenation in queries)
|
|
44
|
+
- NoSQL injection (user input in MongoDB queries without sanitization)
|
|
45
|
+
- Command injection (user input in exec, spawn, system calls)
|
|
46
|
+
- LDAP injection
|
|
47
|
+
- XPath injection
|
|
48
|
+
- Template injection (user input in template engines)
|
|
49
|
+
- Header injection (user input in HTTP headers)
|
|
50
|
+
|
|
51
|
+
Patterns:
|
|
52
|
+
```
|
|
53
|
+
`SELECT * FROM users WHERE id = ${ (SQL injection)
|
|
54
|
+
exec(`${userInput} (command injection)
|
|
55
|
+
db.collection.find({ $where: (NoSQL injection)
|
|
56
|
+
res.setHeader(userInput (header injection)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## A04: Insecure Design
|
|
60
|
+
|
|
61
|
+
Check for:
|
|
62
|
+
- No rate limiting on authentication endpoints
|
|
63
|
+
- No account lockout after failed attempts
|
|
64
|
+
- Missing CAPTCHA on public forms
|
|
65
|
+
- No request throttling on expensive operations
|
|
66
|
+
- Trust boundary violations (trusting client-side validation)
|
|
67
|
+
- Business logic flaws (negative quantities, price manipulation)
|
|
68
|
+
|
|
69
|
+
## A05: Security Misconfiguration
|
|
70
|
+
|
|
71
|
+
Check for:
|
|
72
|
+
- Debug mode enabled in production config
|
|
73
|
+
- Default credentials in config files
|
|
74
|
+
- Unnecessary HTTP methods enabled (TRACE, OPTIONS on all routes)
|
|
75
|
+
- Missing security headers (X-Content-Type-Options, X-Frame-Options, CSP, HSTS)
|
|
76
|
+
- Verbose error messages exposing stack traces
|
|
77
|
+
- Directory listing enabled
|
|
78
|
+
- Unnecessary features/services running
|
|
79
|
+
- Default sample apps or docs deployed
|
|
80
|
+
|
|
81
|
+
Patterns:
|
|
82
|
+
```
|
|
83
|
+
DEBUG = True NODE_ENV !== 'production'
|
|
84
|
+
X-Powered-By (not disabled)
|
|
85
|
+
stack: (in error responses)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## A06: Vulnerable and Outdated Components
|
|
89
|
+
|
|
90
|
+
Check for:
|
|
91
|
+
- Known CVEs in dependencies (npm audit, pip audit)
|
|
92
|
+
- Outdated major versions of critical packages
|
|
93
|
+
- Abandoned packages (no updates in 2+ years)
|
|
94
|
+
- Packages with known security issues that haven't been patched
|
|
95
|
+
|
|
96
|
+
## A07: Identification and Authentication Failures
|
|
97
|
+
|
|
98
|
+
Check for:
|
|
99
|
+
- No password strength requirements
|
|
100
|
+
- Missing brute force protection
|
|
101
|
+
- Session tokens in URLs
|
|
102
|
+
- Sessions not invalidated on logout
|
|
103
|
+
- Missing session timeout
|
|
104
|
+
- Weak password recovery (security questions, predictable tokens)
|
|
105
|
+
- JWT without expiration or with excessive lifetime
|
|
106
|
+
- Missing token refresh mechanism
|
|
107
|
+
- No multi-factor authentication option on sensitive operations
|
|
108
|
+
|
|
109
|
+
Patterns:
|
|
110
|
+
```
|
|
111
|
+
jwt.sign(payload) (no expiresIn)
|
|
112
|
+
req.session.destroy() (missing or inconsistent)
|
|
113
|
+
token = req.query.token (token in URL)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## A08: Software and Data Integrity Failures
|
|
117
|
+
|
|
118
|
+
Check for:
|
|
119
|
+
- CI/CD pipeline without integrity verification
|
|
120
|
+
- Deserialization of untrusted data
|
|
121
|
+
- Auto-updates without signature verification
|
|
122
|
+
- npm/pip install from untrusted sources
|
|
123
|
+
|
|
124
|
+
## A09: Security Logging and Monitoring Failures
|
|
125
|
+
|
|
126
|
+
Check for:
|
|
127
|
+
- Failed login attempts not logged
|
|
128
|
+
- No audit trail for admin operations
|
|
129
|
+
- Sensitive data in logs (passwords, tokens, PII)
|
|
130
|
+
- No alerting on suspicious activity
|
|
131
|
+
- Logs without timestamps or user context
|
|
132
|
+
- Missing request ID for tracing
|
|
133
|
+
|
|
134
|
+
Patterns:
|
|
135
|
+
```
|
|
136
|
+
console.log(password console.log(token console.log(secret
|
|
137
|
+
catch (err) { } (swallowed with no logging)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## A10: Server-Side Request Forgery (SSRF)
|
|
141
|
+
|
|
142
|
+
Check for:
|
|
143
|
+
- User-supplied URLs used in server-side HTTP requests
|
|
144
|
+
- No URL validation or allowlist
|
|
145
|
+
- Internal service endpoints accessible via user input
|
|
146
|
+
- Redirect following without validation
|
|
147
|
+
|
|
148
|
+
Patterns:
|
|
149
|
+
```
|
|
150
|
+
fetch(userInput) axios.get(req.body.url)
|
|
151
|
+
http.get(url) (where url comes from user)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Exposed Endpoints and Infrastructure
|
|
155
|
+
|
|
156
|
+
Check for:
|
|
157
|
+
- Internal/admin endpoints accessible without auth or IP restriction
|
|
158
|
+
- Debug/test routes left in production (`/debug`, `/test`, `/__dev__`)
|
|
159
|
+
- Health check endpoints exposing sensitive info (DB strings, versions, env vars)
|
|
160
|
+
- GraphQL introspection enabled in production
|
|
161
|
+
- API documentation (Swagger/OpenAPI) accessible without authentication in production
|
|
162
|
+
- Unused or deprecated endpoints still active and reachable
|
|
163
|
+
- Default framework error pages revealing stack traces or framework version
|
|
164
|
+
- `.env`, `config.json`, or other config files accessible via HTTP
|
|
165
|
+
- Source maps served in production (exposes original source code)
|
|
166
|
+
- CORS wildcard (`*`) with `credentials: true`
|
|
167
|
+
|
|
168
|
+
Patterns:
|
|
169
|
+
```
|
|
170
|
+
/admin /debug /test (without auth middleware)
|
|
171
|
+
/graphql (with introspection enabled)
|
|
172
|
+
/api-docs /swagger (without auth in production)
|
|
173
|
+
/.env /config (accessible via HTTP)
|
|
174
|
+
*.map (source maps in production build)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Webhook and Payment Security (Full Codebase)
|
|
178
|
+
|
|
179
|
+
Check for:
|
|
180
|
+
- Webhook endpoints without signature verification
|
|
181
|
+
- Webhook secrets stored in source code instead of environment variables
|
|
182
|
+
- Payment endpoints without idempotency protection
|
|
183
|
+
- Financial operations without transaction wrapping
|
|
184
|
+
- Missing audit logging on payment events
|
|
185
|
+
- No rate limiting on payment or webhook endpoints
|
|
186
|
+
- Webhook handlers that return 200 before completing processing
|
|
187
|
+
- Missing dead letter queue for failed webhook events
|
|
188
|
+
- Payment amount validation missing (negative, zero, excessive amounts)
|
|
189
|
+
- No reconciliation mechanism between payment provider and local state
|
|
190
|
+
|
|
191
|
+
Patterns:
|
|
192
|
+
```
|
|
193
|
+
app.post('/webhook (without signature verification)
|
|
194
|
+
app.post('/payment (without idempotency middleware)
|
|
195
|
+
stripe.webhooks.construct (verify this is actually called, not skipped)
|
|
196
|
+
amount = req.body.amount (trusting client-sent amount)
|
|
197
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Secret Detection Patterns
|
|
2
|
+
|
|
3
|
+
All secret patterns are defined in a single source of truth:
|
|
4
|
+
|
|
5
|
+
**File:** `.claude/shared/secret-patterns.json`
|
|
6
|
+
|
|
7
|
+
This file is used by:
|
|
8
|
+
- `.claude/hooks/git-safety.cjs` (blocks staging sensitive files in Claude Code)
|
|
9
|
+
- `git-hooks/pre-commit.cjs` (blocks commits containing secrets)
|
|
10
|
+
- `ship-secure` skill (full codebase scan)
|
|
11
|
+
|
|
12
|
+
## How to Add New Patterns
|
|
13
|
+
|
|
14
|
+
Edit `.claude/shared/secret-patterns.json` once. All hooks and skills pick it up automatically.
|
|
15
|
+
|
|
16
|
+
## Categories in the Shared File
|
|
17
|
+
|
|
18
|
+
- **apiKeys** — AWS, OpenAI, Anthropic, GitHub, Stripe, Slack, SendGrid, etc.
|
|
19
|
+
- **credentials** — Hardcoded passwords, secrets, tokens, client secrets
|
|
20
|
+
- **databaseUrls** — MongoDB, PostgreSQL, MySQL, Redis, RabbitMQ connection strings
|
|
21
|
+
- **privateKeys** — RSA, EC, DSA, PGP private keys
|
|
22
|
+
- **dangerousFiles** — .env, .pem, .key, credentials.json, id_rsa, etc.
|
|
23
|
+
- **falsePositives** — process.env, os.environ, placeholders, .env.example
|
|
24
|
+
|
|
25
|
+
## Scan Targets
|
|
26
|
+
|
|
27
|
+
All source files excluding:
|
|
28
|
+
- `node_modules/`, `.git/`, `dist/`, `build/`, `.next/`
|
|
29
|
+
- Binary files
|
|
30
|
+
- Lock files (`package-lock.json`, `yarn.lock`)
|
|
31
|
+
|
|
32
|
+
## Severity Rules
|
|
33
|
+
|
|
34
|
+
Uses the same 3-level system as all Ship tools:
|
|
35
|
+
|
|
36
|
+
- Real API key or secret in source → Critical
|
|
37
|
+
- Private key in repository → Critical
|
|
38
|
+
- Database URL with credentials → Critical
|
|
39
|
+
- .env file tracked in git → Critical
|
|
40
|
+
- Hardcoded password in test file → Warning
|
|
41
|
+
- Pattern match that might be false positive → Suggestion
|
|
42
|
+
|
|
43
|
+
## False Positive Handling
|
|
44
|
+
|
|
45
|
+
Skip if value matches any entry in `falsePositives` array:
|
|
46
|
+
- Environment variable reference (`process.env.`, `os.environ`)
|
|
47
|
+
- Placeholder values (`<PLACEHOLDER>`, `YOUR_KEY_HERE`, `changeme`)
|
|
48
|
+
- Example files (`.env.example`, `.env.template`)
|
|
49
|
+
- Empty strings
|
|
50
|
+
- Commented out lines
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ship-test
|
|
3
|
+
description: "AI test analysis. Runs test suite, analyzes coverage, finds untested code paths, identifies weak assertions and flaky patterns."
|
|
4
|
+
argument-hint: "[--coverage] [--missing] [--ci]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ship-test — AI Test Analysis
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
ship test # run tests + analyze results
|
|
13
|
+
ship test --coverage # coverage report only
|
|
14
|
+
ship test --missing # find untested code paths
|
|
15
|
+
ship test --ci # CI mode (structured output, exit code)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Workflow
|
|
19
|
+
|
|
20
|
+
### Step 1: Detect Test Framework
|
|
21
|
+
|
|
22
|
+
Auto-detect from project files:
|
|
23
|
+
- `jest.config.*` or `jest` in package.json → Jest
|
|
24
|
+
- `vitest.config.*` or `vitest` in package.json → Vitest
|
|
25
|
+
- `mocha` in package.json → Mocha
|
|
26
|
+
- `.mocharc.*` → Mocha
|
|
27
|
+
- `pytest.ini` or `pyproject.toml` with pytest → Pytest
|
|
28
|
+
- `go test` → Go testing
|
|
29
|
+
- Fallback: read `scripts.test` from package.json
|
|
30
|
+
|
|
31
|
+
### Step 2: Run Tests
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Use the detected framework's command
|
|
35
|
+
npm test # or yarn test, pnpm test
|
|
36
|
+
# With coverage flag if supported
|
|
37
|
+
npm test -- --coverage
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Step 3: Analyze Results
|
|
41
|
+
|
|
42
|
+
Read test output and classify:
|
|
43
|
+
|
|
44
|
+
**Failures:** For each failed test:
|
|
45
|
+
- Which test failed (file, test name)
|
|
46
|
+
- What was expected vs received
|
|
47
|
+
- Root cause analysis (read the source code to understand why)
|
|
48
|
+
- Suggested fix
|
|
49
|
+
|
|
50
|
+
**Coverage:** Parse coverage output:
|
|
51
|
+
- Statements, branches, functions, lines percentages
|
|
52
|
+
- Files with lowest coverage
|
|
53
|
+
- Uncovered lines/branches
|
|
54
|
+
|
|
55
|
+
### Step 4: Find Untested Paths
|
|
56
|
+
|
|
57
|
+
Read source files and compare against test files:
|
|
58
|
+
- Functions with no corresponding test
|
|
59
|
+
- Error/catch blocks never tested
|
|
60
|
+
- Edge cases not covered (null, empty, boundary values)
|
|
61
|
+
- Conditional branches with no test for false path
|
|
62
|
+
- API endpoints without integration tests
|
|
63
|
+
|
|
64
|
+
### Step 5: Assess Test Quality
|
|
65
|
+
|
|
66
|
+
Check for:
|
|
67
|
+
- Weak assertions (only checking truthiness, not specific values)
|
|
68
|
+
- Tests that can never fail (no assertions)
|
|
69
|
+
- Flaky patterns (timing-dependent, order-dependent, global state)
|
|
70
|
+
- Mocking too much (mock hides real bugs)
|
|
71
|
+
- Not testing error scenarios
|
|
72
|
+
- Missing cleanup/teardown
|
|
73
|
+
- Duplicate test coverage (same thing tested multiple ways)
|
|
74
|
+
- Tests that test implementation, not behavior
|
|
75
|
+
|
|
76
|
+
### Step 6: Report
|
|
77
|
+
|
|
78
|
+
Output per `references/output-format.md`.
|
|
79
|
+
|
|
80
|
+
## Quick Reference
|
|
81
|
+
|
|
82
|
+
| Reference | Content |
|
|
83
|
+
|-----------|---------|
|
|
84
|
+
| `references/test-workflow.md` | Detailed test execution steps |
|
|
85
|
+
| `references/coverage-analysis.md` | Coverage analysis rules and thresholds |
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Coverage Analysis
|
|
2
|
+
|
|
3
|
+
## Thresholds
|
|
4
|
+
|
|
5
|
+
| Metric | Minimum | Good | Excellent |
|
|
6
|
+
|--------|---------|------|-----------|
|
|
7
|
+
| Statements | 70% | 80% | 90%+ |
|
|
8
|
+
| Branches | 60% | 75% | 85%+ |
|
|
9
|
+
| Functions | 70% | 85% | 95%+ |
|
|
10
|
+
| Lines | 70% | 80% | 90%+ |
|
|
11
|
+
|
|
12
|
+
## Verdict Rules
|
|
13
|
+
|
|
14
|
+
- FAIL if any test fails
|
|
15
|
+
- FAIL if statements coverage < 70% (configurable)
|
|
16
|
+
- PASS with warnings if coverage between 70-80%
|
|
17
|
+
- PASS if all tests pass and coverage >= 80%
|
|
18
|
+
|
|
19
|
+
## What to Flag
|
|
20
|
+
|
|
21
|
+
### Critical (blocks merge)
|
|
22
|
+
- Test failures
|
|
23
|
+
- Coverage dropped compared to main branch
|
|
24
|
+
- Critical path has zero test coverage (auth, payments, data mutations)
|
|
25
|
+
|
|
26
|
+
### Warning
|
|
27
|
+
- Coverage below threshold
|
|
28
|
+
- New code has lower coverage than existing code
|
|
29
|
+
- Error handling paths not tested
|
|
30
|
+
- Only happy path tested, no edge cases
|
|
31
|
+
|
|
32
|
+
### Suggestion
|
|
33
|
+
- Test could cover additional edge case
|
|
34
|
+
- Assertion could be more specific
|
|
35
|
+
- Test name doesn't describe what it tests
|
|
36
|
+
- Setup/teardown could be extracted to fixture
|
|
37
|
+
|
|
38
|
+
## Output Format
|
|
39
|
+
|
|
40
|
+
```markdown
|
|
41
|
+
## Ship Test
|
|
42
|
+
|
|
43
|
+
### Test Results
|
|
44
|
+
Passed: N | Failed: N | Skipped: N
|
|
45
|
+
Duration: Ns
|
|
46
|
+
|
|
47
|
+
### Failures
|
|
48
|
+
- file/test.ts — "test name"
|
|
49
|
+
Expected: X
|
|
50
|
+
Received: Y
|
|
51
|
+
Root cause: explanation
|
|
52
|
+
Fix: suggestion
|
|
53
|
+
|
|
54
|
+
### Coverage
|
|
55
|
+
Statements: N% | Branches: N% | Functions: N% | Lines: N%
|
|
56
|
+
|
|
57
|
+
### Untested Code Paths
|
|
58
|
+
- file/path.ts:LINE-LINE — description of what's not tested
|
|
59
|
+
- file/path.ts:LINE — edge case not covered
|
|
60
|
+
|
|
61
|
+
### Test Quality Issues
|
|
62
|
+
- [weak] file/test.ts:LINE — assertion only checks truthiness
|
|
63
|
+
- [flaky] file/test.ts:LINE — depends on timing
|
|
64
|
+
|
|
65
|
+
### Summary
|
|
66
|
+
Tests: N passed, N failed
|
|
67
|
+
Coverage: N% statements
|
|
68
|
+
Critical: N | Warning: N | Suggestion: N
|
|
69
|
+
Verdict: PASS or FAIL
|
|
70
|
+
```
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Test Output Format
|
|
2
|
+
|
|
3
|
+
## Standard Report
|
|
4
|
+
|
|
5
|
+
```markdown
|
|
6
|
+
## Ship Test
|
|
7
|
+
|
|
8
|
+
### Test Results
|
|
9
|
+
Passed: N | Failed: N | Skipped: N
|
|
10
|
+
Duration: Ns
|
|
11
|
+
|
|
12
|
+
### Failures
|
|
13
|
+
- file/test.ts:LINE — "test name"
|
|
14
|
+
Expected: value
|
|
15
|
+
Received: value
|
|
16
|
+
Root cause: explanation
|
|
17
|
+
Fix: suggestion
|
|
18
|
+
|
|
19
|
+
### Coverage
|
|
20
|
+
Statements: N% | Branches: N% | Functions: N% | Lines: N%
|
|
21
|
+
|
|
22
|
+
### Untested Code Paths
|
|
23
|
+
- file/path.ts:LINE-LINE — description of what's not tested
|
|
24
|
+
|
|
25
|
+
### Test Quality Issues
|
|
26
|
+
- [weak] file/test.ts:LINE — assertion only checks truthiness
|
|
27
|
+
- [flaky] file/test.ts:LINE — depends on timing
|
|
28
|
+
- [mock] file/test.ts:LINE — mocks hide real behavior
|
|
29
|
+
|
|
30
|
+
### Summary
|
|
31
|
+
Tests: N passed, N failed
|
|
32
|
+
Coverage: N% statements
|
|
33
|
+
Critical: N | Warning: N | Suggestion: N
|
|
34
|
+
Verdict: PASS or FAIL
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Rules
|
|
38
|
+
|
|
39
|
+
- Verdict is FAIL if any test fails
|
|
40
|
+
- Verdict is FAIL if coverage drops below threshold (default 70%)
|
|
41
|
+
- Group failures by file
|
|
42
|
+
- Include root cause analysis for each failure (read source code)
|
|
43
|
+
- Include fix suggestion for each failure
|
|
44
|
+
- Untested paths should reference specific file:line ranges
|
|
45
|
+
- Quality issues use tags: [weak], [flaky], [mock], [duplicate], [missing-cleanup]
|
|
46
|
+
|
|
47
|
+
## CI Mode
|
|
48
|
+
|
|
49
|
+
Same format but:
|
|
50
|
+
- No conversational text
|
|
51
|
+
- Just the markdown report
|
|
52
|
+
- Suitable for PR comments
|
|
53
|
+
|
|
54
|
+
## No Issues Found
|
|
55
|
+
|
|
56
|
+
```markdown
|
|
57
|
+
## Ship Test
|
|
58
|
+
|
|
59
|
+
### Test Results
|
|
60
|
+
Passed: N | Failed: 0 | Skipped: 0
|
|
61
|
+
Duration: Ns
|
|
62
|
+
|
|
63
|
+
### Coverage
|
|
64
|
+
Statements: N% | Branches: N% | Functions: N% | Lines: N%
|
|
65
|
+
|
|
66
|
+
### Summary
|
|
67
|
+
Tests: N passed, 0 failed
|
|
68
|
+
Coverage: N% statements
|
|
69
|
+
Critical: 0 | Warning: 0 | Suggestion: 0
|
|
70
|
+
Verdict: PASS
|
|
71
|
+
```
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Test Workflow
|
|
2
|
+
|
|
3
|
+
## Framework Detection
|
|
4
|
+
|
|
5
|
+
| File/Config | Framework | Run command |
|
|
6
|
+
|------------|-----------|-------------|
|
|
7
|
+
| `vitest.config.*` | Vitest | `npx vitest run` |
|
|
8
|
+
| `jest.config.*` | Jest | `npx jest` |
|
|
9
|
+
| `package.json` has `vitest` | Vitest | `npx vitest run` |
|
|
10
|
+
| `package.json` has `jest` | Jest | `npx jest` |
|
|
11
|
+
| `package.json` has `mocha` | Mocha | `npx mocha` |
|
|
12
|
+
| `pytest.ini` / `pyproject.toml` | Pytest | `pytest` |
|
|
13
|
+
| `go.mod` | Go | `go test ./...` |
|
|
14
|
+
| `Cargo.toml` | Rust | `cargo test` |
|
|
15
|
+
| Fallback | npm | `npm test` |
|
|
16
|
+
|
|
17
|
+
## Coverage Commands
|
|
18
|
+
|
|
19
|
+
| Framework | Coverage command |
|
|
20
|
+
|-----------|----------------|
|
|
21
|
+
| Vitest | `npx vitest run --coverage` |
|
|
22
|
+
| Jest | `npx jest --coverage` |
|
|
23
|
+
| Pytest | `pytest --cov` |
|
|
24
|
+
| Go | `go test -cover ./...` |
|
|
25
|
+
|
|
26
|
+
## Analyzing Failures
|
|
27
|
+
|
|
28
|
+
For each failed test:
|
|
29
|
+
|
|
30
|
+
1. Read the test file to understand what it tests
|
|
31
|
+
2. Read the source file to understand why it fails
|
|
32
|
+
3. Determine if:
|
|
33
|
+
- Test is wrong (outdated expectation)
|
|
34
|
+
- Source code has a bug
|
|
35
|
+
- Test is flaky (timing, order, environment)
|
|
36
|
+
4. Report with root cause and fix suggestion
|
|
37
|
+
|
|
38
|
+
## Untested Path Detection
|
|
39
|
+
|
|
40
|
+
1. List all source files (exclude tests, config, types)
|
|
41
|
+
2. For each source file, find corresponding test file
|
|
42
|
+
3. If no test file exists → report as "No tests"
|
|
43
|
+
4. If test file exists, compare:
|
|
44
|
+
- Exported functions vs tested functions
|
|
45
|
+
- Error handling paths vs error tests
|
|
46
|
+
- Conditional branches vs branch tests
|
|
47
|
+
5. Report uncovered paths with file:line references
|
|
@@ -71,6 +71,10 @@ type(scope): description
|
|
|
71
71
|
[optional: Refs: TICKET-ID]
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
+
## Agent
|
|
75
|
+
|
|
76
|
+
Use the `git-ops` agent for operations with verbose output (large diffs, long logs, merge conflicts) to keep main context clean.
|
|
77
|
+
|
|
74
78
|
## Core Workflow
|
|
75
79
|
|
|
76
80
|
### Step 1: Analyze
|
|
@@ -2,32 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
## Secret Detection
|
|
4
4
|
|
|
5
|
+
All secret patterns are defined in `.claude/shared/secret-patterns.json` (single source of truth).
|
|
6
|
+
|
|
5
7
|
### Scan Command
|
|
6
8
|
```bash
|
|
7
9
|
git diff --cached | grep -iE "(AKIA|api[_-]?key|token|password|secret|credential|private[_-]?key|mongodb://|postgres://|mysql://|redis://|-----BEGIN)"
|
|
8
10
|
```
|
|
9
11
|
|
|
10
|
-
###
|
|
11
|
-
|
|
12
|
-
| Category | Pattern |
|
|
13
|
-
|----------|---------|
|
|
14
|
-
| API Keys | `api[_-]?key`, `apiKey` |
|
|
15
|
-
| AWS | `AKIA[0-9A-Z]{16}` |
|
|
16
|
-
| Tokens | `token`, `auth_token`, `jwt` |
|
|
17
|
-
| Passwords | `password`, `passwd`, `pwd` |
|
|
18
|
-
| Private Keys | `-----BEGIN PRIVATE KEY-----` |
|
|
19
|
-
| DB URLs | `mongodb://`, `postgres://`, `mysql://` |
|
|
20
|
-
| OAuth | `client_secret`, `oauth_token` |
|
|
12
|
+
### Pattern Categories
|
|
21
13
|
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
14
|
+
Defined in `secret-patterns.json`:
|
|
15
|
+
- **apiKeys** — AWS, OpenAI, Anthropic, GitHub, Stripe, Slack, SendGrid, Google, etc.
|
|
16
|
+
- **credentials** — Hardcoded passwords, secrets, tokens, client secrets
|
|
17
|
+
- **databaseUrls** — MongoDB, PostgreSQL, MySQL, Redis, RabbitMQ connection strings
|
|
18
|
+
- **privateKeys** — RSA, EC, DSA, PGP private keys
|
|
19
|
+
- **dangerousFiles** — .env, .pem, .key, .p12, credentials.json, id_rsa, etc.
|
|
26
20
|
|
|
27
21
|
### On Detection
|
|
28
22
|
1. BLOCK commit
|
|
29
23
|
2. Show matching lines
|
|
30
|
-
3. Suggest `.gitignore` or
|
|
24
|
+
3. Suggest `.gitignore` or environment variables
|
|
31
25
|
4. Offer to unstage: `git reset HEAD <file>`
|
|
32
26
|
|
|
33
27
|
## Branch Protection
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 TeleLabs AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|