context-mode 1.0.53 → 1.0.56
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-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.openclaw-plugin/openclaw.plugin.json +1 -1
- package/.openclaw-plugin/package.json +1 -1
- package/README.md +103 -32
- package/build/adapters/antigravity/index.d.ts +1 -3
- package/build/adapters/antigravity/index.js +0 -30
- package/build/adapters/claude-code/hooks.d.ts +18 -0
- package/build/adapters/claude-code/hooks.js +23 -0
- package/build/adapters/claude-code/index.d.ts +1 -3
- package/build/adapters/claude-code/index.js +48 -35
- package/build/adapters/client-map.js +1 -0
- package/build/adapters/codex/index.d.ts +1 -3
- package/build/adapters/codex/index.js +1 -31
- package/build/adapters/cursor/index.d.ts +1 -3
- package/build/adapters/cursor/index.js +0 -11
- package/build/adapters/detect.d.ts +1 -0
- package/build/adapters/detect.js +18 -2
- package/build/adapters/gemini-cli/index.d.ts +1 -3
- package/build/adapters/gemini-cli/index.js +0 -30
- package/build/adapters/kiro/index.d.ts +1 -3
- package/build/adapters/kiro/index.js +0 -30
- package/build/adapters/openclaw/index.d.ts +1 -3
- package/build/adapters/openclaw/index.js +0 -38
- package/build/adapters/opencode/index.d.ts +5 -4
- package/build/adapters/opencode/index.js +37 -41
- package/build/adapters/types.d.ts +1 -14
- package/build/adapters/vscode-copilot/index.d.ts +1 -3
- package/build/adapters/vscode-copilot/index.js +0 -32
- package/build/adapters/zed/index.d.ts +1 -3
- package/build/adapters/zed/index.js +0 -30
- package/build/cli.js +12 -28
- package/build/executor.d.ts +0 -1
- package/build/executor.js +28 -16
- package/build/openclaw-plugin.js +12 -34
- package/build/opencode-plugin.d.ts +1 -0
- package/build/opencode-plugin.js +5 -9
- package/build/runtime.js +29 -11
- package/build/server.d.ts +2 -0
- package/build/server.js +69 -61
- package/build/store.d.ts +4 -3
- package/build/store.js +101 -34
- package/build/truncate.d.ts +4 -17
- package/build/truncate.js +4 -52
- package/cli.bundle.mjs +184 -157
- package/configs/codex/AGENTS.md +19 -0
- package/configs/kilo/AGENTS.md +58 -0
- package/configs/kilo/kilo.json +10 -0
- package/hooks/core/tool-naming.mjs +1 -0
- package/hooks/ensure-deps.mjs +80 -2
- package/hooks/pretooluse.mjs +25 -20
- package/hooks/routing-block.mjs +10 -1
- package/hooks/session-snapshot.bundle.mjs +13 -13
- package/hooks/sessionstart.mjs +25 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/server.bundle.mjs +159 -129
- package/skills/context-mode-ops/SKILL.md +111 -0
- package/skills/context-mode-ops/agent-teams.md +198 -0
- package/skills/context-mode-ops/communication.md +224 -0
- package/skills/context-mode-ops/release.md +199 -0
- package/skills/context-mode-ops/review-pr.md +269 -0
- package/skills/context-mode-ops/tdd.md +329 -0
- package/skills/context-mode-ops/triage-issue.md +218 -0
- package/skills/context-mode-ops/validation.md +238 -0
- package/start.mjs +5 -52
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# Validation Patterns
|
|
2
|
+
|
|
3
|
+
Cross-cutting validation rules used by ALL workflows (triage, review, release).
|
|
4
|
+
|
|
5
|
+
## ENV Variable Verification
|
|
6
|
+
|
|
7
|
+
LLMs frequently hallucinate environment variables. Every ENV var in an issue or PR must be verified.
|
|
8
|
+
|
|
9
|
+
### Verification Protocol
|
|
10
|
+
|
|
11
|
+
For EACH environment variable mentioned:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
Step 1: GREP — Does it exist in context-mode source?
|
|
15
|
+
→ rg "{ENV_VAR}" src/
|
|
16
|
+
→ If found: VERIFIED (we already use it)
|
|
17
|
+
→ If not found: continue to Step 2
|
|
18
|
+
|
|
19
|
+
Step 2: GREP ADAPTERS — Is it in the adapter detect logic?
|
|
20
|
+
→ Read src/adapters/detect.ts
|
|
21
|
+
→ Check the verified env vars comment block at the top
|
|
22
|
+
→ If listed: VERIFIED (we know about it)
|
|
23
|
+
|
|
24
|
+
Step 3: WEBSEARCH — Does the platform document it?
|
|
25
|
+
→ WebSearch: "{PLATFORM} {ENV_VAR} environment variable"
|
|
26
|
+
→ Check official docs, GitHub repos, release notes
|
|
27
|
+
→ If found in official source: REAL but we don't use it yet
|
|
28
|
+
|
|
29
|
+
Step 4: CONTEXT7 — Library documentation check
|
|
30
|
+
→ resolve-library-id for the platform
|
|
31
|
+
→ query-docs for the ENV var
|
|
32
|
+
→ Cross-reference with Step 3
|
|
33
|
+
|
|
34
|
+
Step 5: VERDICT
|
|
35
|
+
→ VERIFIED: We use it and it's real
|
|
36
|
+
→ REAL_NEW: Platform has it but we don't use it yet
|
|
37
|
+
→ HALLUCINATED: No evidence it exists — flag it
|
|
38
|
+
→ DEPRECATED: Used to exist but was removed
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Known Verified ENV Vars (Reference)
|
|
42
|
+
|
|
43
|
+
| Platform | Verified ENV Vars | Source |
|
|
44
|
+
|----------|------------------|--------|
|
|
45
|
+
| Claude Code | `CLAUDE_PROJECT_DIR`, `CLAUDE_SESSION_ID` | src/adapters/detect.ts |
|
|
46
|
+
| Gemini CLI | `GEMINI_PROJECT_DIR`, `GEMINI_CLI` | src/adapters/detect.ts |
|
|
47
|
+
| OpenCode | `OPENCODE`, `OPENCODE_PID` | src/adapters/detect.ts |
|
|
48
|
+
| OpenClaw | `OPENCLAW_HOME`, `OPENCLAW_CLI` | src/adapters/detect.ts |
|
|
49
|
+
| Kilo | `KILO`, `KILO_PID` | src/adapters/detect.ts |
|
|
50
|
+
| Codex | `CODEX_CI`, `CODEX_THREAD_ID` | src/adapters/detect.ts |
|
|
51
|
+
| VS Code Copilot | `VSCODE_PID`, `VSCODE_CWD` | src/adapters/detect.ts |
|
|
52
|
+
| Cursor | `CURSOR_TRACE_ID`, `CURSOR_CLI` | src/adapters/detect.ts |
|
|
53
|
+
| Override | `CONTEXT_MODE_PLATFORM` | src/adapters/detect.ts |
|
|
54
|
+
|
|
55
|
+
Any ENV var NOT in this table must go through the full verification protocol.
|
|
56
|
+
|
|
57
|
+
## Adapter Test Matrix
|
|
58
|
+
|
|
59
|
+
### Full Matrix Run
|
|
60
|
+
|
|
61
|
+
```shell
|
|
62
|
+
# Run ALL adapter tests
|
|
63
|
+
npx vitest run tests/adapters/
|
|
64
|
+
|
|
65
|
+
# Individual adapter (for targeted testing)
|
|
66
|
+
npx vitest run tests/adapters/claude-code.test.ts
|
|
67
|
+
npx vitest run tests/adapters/gemini-cli.test.ts
|
|
68
|
+
npx vitest run tests/adapters/opencode.test.ts
|
|
69
|
+
npx vitest run tests/adapters/openclaw.test.ts
|
|
70
|
+
npx vitest run tests/adapters/kilo.test.ts
|
|
71
|
+
npx vitest run tests/adapters/codex.test.ts
|
|
72
|
+
npx vitest run tests/adapters/vscode-copilot.test.ts
|
|
73
|
+
npx vitest run tests/adapters/cursor.test.ts
|
|
74
|
+
npx vitest run tests/adapters/antigravity.test.ts
|
|
75
|
+
npx vitest run tests/adapters/kiro.test.ts
|
|
76
|
+
npx vitest run tests/adapters/zed.test.ts
|
|
77
|
+
|
|
78
|
+
# Detection logic
|
|
79
|
+
npx vitest run tests/adapters/detect.test.ts
|
|
80
|
+
npx vitest run tests/adapters/client-map.test.ts
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Report Format
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
ADAPTER TEST MATRIX
|
|
87
|
+
═══════════════════
|
|
88
|
+
claude-code ✓ 5/5 gemini-cli ✓ 4/4
|
|
89
|
+
opencode ✓ 6/6 openclaw ✓ 3/3
|
|
90
|
+
kilo ✓ 4/4 codex ✓ 3/3
|
|
91
|
+
vscode-copilot ✓ 4/4 cursor ✓ 3/3
|
|
92
|
+
antigravity ✓ 2/2 kiro ✓ 3/3
|
|
93
|
+
pi ✓ 2/2 zed ✓ 2/2
|
|
94
|
+
detect ✓ 8/8 client-map ✓ 6/6
|
|
95
|
+
───────────────────────────────────────────
|
|
96
|
+
TOTAL: {N}/{N} passed | 0 failed
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Core Module Tests
|
|
100
|
+
|
|
101
|
+
```shell
|
|
102
|
+
# Core tests
|
|
103
|
+
npx vitest run tests/core/routing.test.ts
|
|
104
|
+
npx vitest run tests/core/search.test.ts
|
|
105
|
+
npx vitest run tests/core/server.test.ts
|
|
106
|
+
npx vitest run tests/core/cli.test.ts
|
|
107
|
+
|
|
108
|
+
# Module tests
|
|
109
|
+
npx vitest run tests/store.test.ts
|
|
110
|
+
npx vitest run tests/executor.test.ts
|
|
111
|
+
npx vitest run tests/security.test.ts
|
|
112
|
+
npx vitest run tests/formatters.test.ts
|
|
113
|
+
|
|
114
|
+
# Hook tests
|
|
115
|
+
npx vitest run tests/hooks/
|
|
116
|
+
|
|
117
|
+
# Full suite
|
|
118
|
+
npm test
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## OS Compatibility Checks
|
|
122
|
+
|
|
123
|
+
### Path Handling
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
// WRONG — breaks on Windows
|
|
127
|
+
const configPath = homedir + "/.config/opencode/config.json";
|
|
128
|
+
|
|
129
|
+
// CORRECT — works everywhere
|
|
130
|
+
const configPath = path.join(homedir(), ".config", "opencode", "config.json");
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Grep for potential issues:
|
|
134
|
+
```shell
|
|
135
|
+
# String concatenation with path separators
|
|
136
|
+
rg "homedir\(\)\s*\+" src/
|
|
137
|
+
rg '"/\.' src/
|
|
138
|
+
rg "'\\./" src/
|
|
139
|
+
|
|
140
|
+
# Direct slash usage in paths (should use path.join)
|
|
141
|
+
rg 'path\s*=.*"/' src/ --type ts
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Temp Directory
|
|
145
|
+
|
|
146
|
+
```javascript
|
|
147
|
+
// WRONG — hardcoded /tmp
|
|
148
|
+
const tmpFile = "/tmp/context-mode-output.txt";
|
|
149
|
+
|
|
150
|
+
// CORRECT — uses OS temp dir
|
|
151
|
+
const tmpFile = path.join(os.tmpdir(), "context-mode-output.txt");
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Grep for hardcoded temp:
|
|
155
|
+
```shell
|
|
156
|
+
rg '"/tmp/' src/
|
|
157
|
+
rg "'/tmp/" src/
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Native Bindings (better-sqlite3)
|
|
161
|
+
|
|
162
|
+
Check that `better-sqlite3` is in `optionalDependencies` (not `dependencies`) and the code handles the case where it's not available:
|
|
163
|
+
|
|
164
|
+
```shell
|
|
165
|
+
rg "better-sqlite3" src/ --type ts
|
|
166
|
+
rg "optionalDependencies" package.json
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Process Spawn
|
|
170
|
+
|
|
171
|
+
```javascript
|
|
172
|
+
// WRONG — shell: true behaves differently on Windows
|
|
173
|
+
spawn("command", { shell: true });
|
|
174
|
+
|
|
175
|
+
// CORRECT — explicit shell selection
|
|
176
|
+
spawn("command", { shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh" });
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Hook Format Validation
|
|
180
|
+
|
|
181
|
+
Each platform has different hook formats. Verify changes match:
|
|
182
|
+
|
|
183
|
+
| Platform | Hook Format | Key Differences |
|
|
184
|
+
|----------|------------|-----------------|
|
|
185
|
+
| Claude Code | `hooks.json` in plugin dir | `PreToolUse`, `PostToolUse`, `PreCompact`, `SessionStart` |
|
|
186
|
+
| Gemini CLI | `~/.gemini/settings.json` | `BeforeTool`, `AfterTool`, `PreCompress`, `SessionStart` + `matcher` |
|
|
187
|
+
| VS Code Copilot | `.github/hooks/*.json` | Same as Claude Code but separate file |
|
|
188
|
+
| Cursor | `.cursor/hooks.json` | No `SessionStart` (injects via file instead) |
|
|
189
|
+
| OpenCode | `opencode.json` | Uses `agents` section, not traditional hooks |
|
|
190
|
+
| OpenClaw | `openclaw.plugin.json` | Extension model, not hook-based |
|
|
191
|
+
|
|
192
|
+
## Security Checks
|
|
193
|
+
|
|
194
|
+
### Sandbox Escape
|
|
195
|
+
|
|
196
|
+
```shell
|
|
197
|
+
# File writing attempts through ctx_execute
|
|
198
|
+
rg "writeFile\|appendFile\|createWriteStream" src/executor.ts
|
|
199
|
+
|
|
200
|
+
# Path traversal
|
|
201
|
+
rg "\.\.\/" src/ --type ts
|
|
202
|
+
|
|
203
|
+
# Command injection vectors
|
|
204
|
+
rg "exec\(.*\$\{" src/ --type ts
|
|
205
|
+
rg "spawn\(.*\$\{" src/ --type ts
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Information Disclosure
|
|
209
|
+
|
|
210
|
+
```shell
|
|
211
|
+
# Sensitive paths
|
|
212
|
+
rg "process\.env\b" src/ --type ts | grep -v "test"
|
|
213
|
+
|
|
214
|
+
# Home directory exposure
|
|
215
|
+
rg "homedir\(\)" src/ --type ts
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## TypeScript Validation
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# Full type check
|
|
222
|
+
npm run typecheck
|
|
223
|
+
|
|
224
|
+
# Should report 0 errors
|
|
225
|
+
# If errors exist, they MUST be fixed before shipping
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Pre-Ship Checklist
|
|
229
|
+
|
|
230
|
+
Every change, regardless of workflow, must pass:
|
|
231
|
+
|
|
232
|
+
- [ ] `npm run typecheck` — 0 errors
|
|
233
|
+
- [ ] `npm test` — all pass
|
|
234
|
+
- [ ] Adapter tests — all 12 pass (or N/A if untouched)
|
|
235
|
+
- [ ] ENV vars — all verified against real platform source
|
|
236
|
+
- [ ] Path handling — no hardcoded separators
|
|
237
|
+
- [ ] Hook format — matches target platform's schema
|
|
238
|
+
- [ ] No security regressions
|
package/start.mjs
CHANGED
|
@@ -1,52 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { execSync } from "node:child_process";
|
|
3
|
-
import { existsSync,
|
|
3
|
+
import { existsSync, chmodSync, readFileSync, writeFileSync, readdirSync } from "node:fs";
|
|
4
4
|
import { dirname, resolve } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { homedir } from "node:os";
|
|
7
|
-
import { createRequire } from "node:module";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* ABI-aware native binary caching for better-sqlite3 (#148).
|
|
11
|
-
* Users with mise/asdf may run concurrent sessions with different Node versions.
|
|
12
|
-
* Each ABI needs its own compiled binary — cache them side-by-side.
|
|
13
|
-
*/
|
|
14
|
-
function ensureNativeCompat(pluginRoot) {
|
|
15
|
-
try {
|
|
16
|
-
const abi = process.versions.modules;
|
|
17
|
-
const nativeDir = resolve(pluginRoot, "node_modules", "better-sqlite3", "build", "Release");
|
|
18
|
-
const binaryPath = resolve(nativeDir, "better_sqlite3.node");
|
|
19
|
-
const abiCachePath = resolve(nativeDir, `better_sqlite3.abi${abi}.node`);
|
|
20
|
-
|
|
21
|
-
if (!existsSync(nativeDir)) return;
|
|
22
|
-
|
|
23
|
-
if (existsSync(abiCachePath)) {
|
|
24
|
-
copyFileSync(abiCachePath, binaryPath);
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (!existsSync(binaryPath)) return;
|
|
29
|
-
|
|
30
|
-
try {
|
|
31
|
-
const req = createRequire(resolve(pluginRoot, "package.json"));
|
|
32
|
-
req("better-sqlite3");
|
|
33
|
-
copyFileSync(binaryPath, abiCachePath);
|
|
34
|
-
} catch (probeErr) {
|
|
35
|
-
if (probeErr?.message?.includes("NODE_MODULE_VERSION")) {
|
|
36
|
-
execSync("npm rebuild better-sqlite3", {
|
|
37
|
-
cwd: pluginRoot,
|
|
38
|
-
stdio: "pipe",
|
|
39
|
-
timeout: 60000,
|
|
40
|
-
});
|
|
41
|
-
if (existsSync(binaryPath)) {
|
|
42
|
-
copyFileSync(binaryPath, abiCachePath);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
} catch {
|
|
47
|
-
/* best effort — server will report the error on first DB access */
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
7
|
|
|
51
8
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
52
9
|
const originalCwd = process.cwd();
|
|
@@ -115,9 +72,10 @@ if (cacheMatch) {
|
|
|
115
72
|
}
|
|
116
73
|
}
|
|
117
74
|
|
|
118
|
-
// Ensure native dependencies
|
|
119
|
-
|
|
120
|
-
|
|
75
|
+
// Ensure native dependencies + ABI compatibility (shared with hooks via ensure-deps.mjs)
|
|
76
|
+
// ensure-deps handles better-sqlite3 install + ABI cache/rebuild automatically (#148, #203)
|
|
77
|
+
import "./hooks/ensure-deps.mjs";
|
|
78
|
+
// Also install pure-JS deps used by server
|
|
121
79
|
for (const pkg of ["turndown", "turndown-plugin-gfm", "@mixmark-io/domino"]) {
|
|
122
80
|
if (!existsSync(resolve(__dirname, "node_modules", pkg))) {
|
|
123
81
|
try {
|
|
@@ -130,11 +88,6 @@ for (const pkg of ["turndown", "turndown-plugin-gfm", "@mixmark-io/domino"]) {
|
|
|
130
88
|
}
|
|
131
89
|
}
|
|
132
90
|
|
|
133
|
-
// Ensure better-sqlite3 native binary matches current Node.js ABI (#148)
|
|
134
|
-
// Users with mise/asdf may run concurrent sessions with different Node versions.
|
|
135
|
-
// Each ABI needs its own compiled binary — cache them side-by-side.
|
|
136
|
-
ensureNativeCompat(__dirname);
|
|
137
|
-
|
|
138
91
|
// Self-heal: create CLI shim if cli.bundle.mjs is missing (marketplace installs)
|
|
139
92
|
if (!existsSync(resolve(__dirname, "cli.bundle.mjs")) && existsSync(resolve(__dirname, "build", "cli.js"))) {
|
|
140
93
|
const shimPath = resolve(__dirname, "cli.bundle.mjs");
|