clikit-plugin 0.2.6 → 0.2.7
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.
|
@@ -9,6 +9,6 @@ export interface GitGuardResult {
|
|
|
9
9
|
command: string;
|
|
10
10
|
reason?: string;
|
|
11
11
|
}
|
|
12
|
-
export declare function checkDangerousCommand(command:
|
|
12
|
+
export declare function checkDangerousCommand(command: unknown, allowForceWithLease?: boolean): GitGuardResult;
|
|
13
13
|
export declare function formatBlockedWarning(result: GitGuardResult): string;
|
|
14
14
|
//# sourceMappingURL=git-guard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-guard.d.ts","sourceRoot":"","sources":["../../src/hooks/git-guard.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"git-guard.d.ts","sourceRoot":"","sources":["../../src/hooks/git-guard.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,mBAAmB,UAAO,GAAG,cAAc,CAalG;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAEnE"}
|
|
@@ -24,8 +24,8 @@ export interface EnforcementResult {
|
|
|
24
24
|
reason?: string;
|
|
25
25
|
suggestion?: string;
|
|
26
26
|
}
|
|
27
|
-
export declare function isFileInScope(filePath:
|
|
28
|
-
export declare function checkEditPermission(filePath:
|
|
27
|
+
export declare function isFileInScope(filePath: unknown, scope: TaskScope): boolean;
|
|
28
|
+
export declare function checkEditPermission(filePath: unknown, scope: TaskScope | undefined, config?: SwarmEnforcerConfig): EnforcementResult;
|
|
29
29
|
export declare function extractFileFromToolInput(toolName: unknown, input: Record<string, unknown>): string | undefined;
|
|
30
30
|
export declare function formatEnforcementWarning(result: EnforcementResult): string;
|
|
31
31
|
//# sourceMappingURL=swarm-enforcer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swarm-enforcer.d.ts","sourceRoot":"","sources":["../../src/hooks/swarm-enforcer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"swarm-enforcer.d.ts","sourceRoot":"","sources":["../../src/hooks/swarm-enforcer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,SAAS,GACf,OAAO,CAsBT;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,MAAM,CAAC,EAAE,mBAAmB,GAC3B,iBAAiB,CAyBnB;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,GAAG,SAAS,CA6BpB;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAM1E"}
|
package/dist/index.js
CHANGED
|
@@ -3884,6 +3884,9 @@ var DANGEROUS_PATTERNS = [
|
|
|
3884
3884
|
{ pattern: /git\s+branch\s+-D/, reason: "Force-deleting branch may lose unmerged work" }
|
|
3885
3885
|
];
|
|
3886
3886
|
function checkDangerousCommand(command, allowForceWithLease = true) {
|
|
3887
|
+
if (typeof command !== "string") {
|
|
3888
|
+
return { blocked: false, command: "" };
|
|
3889
|
+
}
|
|
3887
3890
|
for (const { pattern, reason } of DANGEROUS_PATTERNS) {
|
|
3888
3891
|
if (pattern.test(command)) {
|
|
3889
3892
|
if (allowForceWithLease && /--force-with-lease/.test(command)) {
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
date: 2026-02-15
|
|
3
|
+
phase: implementing
|
|
4
|
+
branch: main
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Handoff: CliKit Complete Type Guard Audit
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Status Summary
|
|
12
|
+
|
|
13
|
+
CliKit plugin v0.2.6 published with many type guards. Typecheck passes. However, there are still potential runtime issues where OpenCode passes non-string values that could cause `.toLowerCase()`, `.test()`, `.split()` etc. to fail.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Version History
|
|
18
|
+
|
|
19
|
+
| Version | Fix |
|
|
20
|
+
|---------|-----|
|
|
21
|
+
| 0.2.1 | Type guards in hooks (truncator, security-check, compaction) |
|
|
22
|
+
| 0.2.2 | Abort on JSON parse error |
|
|
23
|
+
| 0.2.3 | Fix JSONC comment stripping breaking URLs |
|
|
24
|
+
| 0.2.4 | Remove backup logic, fix `todos.filter` error |
|
|
25
|
+
| 0.2.5 | Fix `path.join` error - guards for projectDir/cwd params |
|
|
26
|
+
| 0.2.6 | Fix `text.toLowerCase` error in subagent-question-blocker |
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Remaining Issues (Need Type Guards)
|
|
31
|
+
|
|
32
|
+
### 1. git-guard.ts: `checkDangerousCommand`
|
|
33
|
+
**Line 25:** `command: string` - no type guard
|
|
34
|
+
**Used:** `index.ts:221` - `toolInput.command as string | undefined`
|
|
35
|
+
**Risk:** `pattern.test(command)` fails if command is object
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// Fix needed:
|
|
39
|
+
export function checkDangerousCommand(command: unknown, allowForceWithLease = true): GitGuardResult {
|
|
40
|
+
if (typeof command !== "string") {
|
|
41
|
+
return { blocked: false, command: "" };
|
|
42
|
+
}
|
|
43
|
+
// ... rest
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. swarm-enforcer.ts: `isFileInScope`
|
|
48
|
+
**Line 33-36:** `filePath: string` - no type guard
|
|
49
|
+
**Risk:** `path.resolve(filePath)` fails if filePath is not string
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// Fix needed:
|
|
53
|
+
export function isFileInScope(filePath: unknown, scope: TaskScope): boolean {
|
|
54
|
+
if (typeof filePath !== "string") return false;
|
|
55
|
+
// ...
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 3. swarm-enforcer.ts: `checkEditPermission`
|
|
60
|
+
**Line 59-62:** `filePath: string` - no type guard
|
|
61
|
+
|
|
62
|
+
### 4. index.ts: Tool input casting
|
|
63
|
+
Multiple places where `toolInput.X as string | undefined` is used but the value could be an object:
|
|
64
|
+
- Line 218: `toolInput.command`
|
|
65
|
+
- Line 269: `toolInput.prompt`
|
|
66
|
+
- Line 335: `toolInput.filePath`
|
|
67
|
+
- Line 351: `toolInput.filePath`
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Files Modified (Uncommitted)
|
|
72
|
+
|
|
73
|
+
| File | Status |
|
|
74
|
+
|------|--------|
|
|
75
|
+
| `.opencode/package.json` | v0.2.6 |
|
|
76
|
+
| `.opencode/src/cli.ts` | Removed backup, fixed JSONC |
|
|
77
|
+
| `.opencode/src/config.ts` | Type guard for loadCliKitConfig |
|
|
78
|
+
| `.opencode/src/index.ts` | Array.isArray for todos |
|
|
79
|
+
| `.opencode/src/hooks/auto-format.ts` | Type guards |
|
|
80
|
+
| `.opencode/src/hooks/comment-checker.ts` | Type guards |
|
|
81
|
+
| `.opencode/src/hooks/compaction.ts` | Type guards |
|
|
82
|
+
| `.opencode/src/hooks/env-context.ts` | Type guards |
|
|
83
|
+
| `.opencode/src/hooks/security-check.ts` | Type guards |
|
|
84
|
+
| `.opencode/src/hooks/session-notification.ts` | Type guards |
|
|
85
|
+
| `.opencode/src/hooks/subagent-question-blocker.ts` | Type guards |
|
|
86
|
+
| `.opencode/src/hooks/swarm-enforcer.ts` | Partial (extractFileFromToolInput only) |
|
|
87
|
+
| `.opencode/src/hooks/todo-enforcer.ts` | Type guards |
|
|
88
|
+
| `.opencode/src/hooks/truncator.ts` | Type guards |
|
|
89
|
+
| `.opencode/src/hooks/typecheck-gate.ts` | Type guards |
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Git State
|
|
94
|
+
|
|
95
|
+
- **Branch:** `main`
|
|
96
|
+
- **Last commit:** `31b200c` - Update README with simplified installation
|
|
97
|
+
- **Uncommitted changes:** 15 files
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Next Steps
|
|
102
|
+
|
|
103
|
+
1. [ ] Add type guard to `git-guard.ts:checkDangerousCommand(command: unknown)`
|
|
104
|
+
2. [ ] Add type guard to `swarm-enforcer.ts:isFileInScope(filePath: unknown)`
|
|
105
|
+
3. [ ] Add type guard to `swarm-enforcer.ts:checkEditPermission(filePath: unknown)`
|
|
106
|
+
4. [ ] Run typecheck
|
|
107
|
+
5. [ ] Publish v0.2.7
|
|
108
|
+
6. [ ] Test: `opencode` starts without errors
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Pattern for Type Guards
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
// Before (breaks on non-string):
|
|
116
|
+
export function myFunc(content: string): Result {
|
|
117
|
+
return content.split("\n"); // CRASH if content is object
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// After (safe):
|
|
121
|
+
export function myFunc(content: unknown): Result {
|
|
122
|
+
if (typeof content !== "string") {
|
|
123
|
+
return defaultResult; // Safe fallback
|
|
124
|
+
}
|
|
125
|
+
return content.split("\n");
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Resume Command
|
|
132
|
+
|
|
133
|
+
To resume, use `/resume` and it will:
|
|
134
|
+
1. Load this handoff
|
|
135
|
+
2. Propose fixing remaining type guards in git-guard.ts and swarm-enforcer.ts
|
|
136
|
+
3. Publish v0.2.7
|