context-mode 1.0.54 → 1.0.57

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.
Files changed (52) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.openclaw-plugin/openclaw.plugin.json +1 -1
  4. package/.openclaw-plugin/package.json +1 -1
  5. package/README.md +20 -6
  6. package/build/adapters/antigravity/index.d.ts +1 -3
  7. package/build/adapters/antigravity/index.js +0 -30
  8. package/build/adapters/claude-code/index.d.ts +1 -3
  9. package/build/adapters/claude-code/index.js +15 -34
  10. package/build/adapters/codex/index.d.ts +1 -3
  11. package/build/adapters/codex/index.js +1 -31
  12. package/build/adapters/cursor/index.d.ts +1 -3
  13. package/build/adapters/cursor/index.js +0 -11
  14. package/build/adapters/gemini-cli/index.d.ts +1 -3
  15. package/build/adapters/gemini-cli/index.js +0 -30
  16. package/build/adapters/kiro/index.d.ts +1 -3
  17. package/build/adapters/kiro/index.js +0 -30
  18. package/build/adapters/openclaw/index.d.ts +1 -3
  19. package/build/adapters/openclaw/index.js +0 -38
  20. package/build/adapters/opencode/index.d.ts +1 -3
  21. package/build/adapters/opencode/index.js +15 -34
  22. package/build/adapters/types.d.ts +0 -13
  23. package/build/adapters/vscode-copilot/index.d.ts +1 -3
  24. package/build/adapters/vscode-copilot/index.js +0 -32
  25. package/build/adapters/zed/index.d.ts +1 -3
  26. package/build/adapters/zed/index.js +0 -30
  27. package/build/executor.d.ts +0 -1
  28. package/build/executor.js +26 -14
  29. package/build/openclaw-plugin.js +0 -30
  30. package/build/opencode-plugin.d.ts +1 -0
  31. package/build/opencode-plugin.js +1 -8
  32. package/build/server.js +82 -19
  33. package/build/truncate.d.ts +4 -17
  34. package/build/truncate.js +4 -52
  35. package/cli.bundle.mjs +110 -137
  36. package/hooks/ensure-deps.mjs +80 -2
  37. package/hooks/routing-block.mjs +12 -1
  38. package/hooks/session-helpers.mjs +13 -0
  39. package/hooks/session-snapshot.bundle.mjs +13 -13
  40. package/hooks/sessionstart.mjs +5 -2
  41. package/openclaw.plugin.json +1 -1
  42. package/package.json +1 -1
  43. package/server.bundle.mjs +83 -107
  44. package/skills/context-mode-ops/SKILL.md +111 -0
  45. package/skills/context-mode-ops/agent-teams.md +198 -0
  46. package/skills/context-mode-ops/communication.md +224 -0
  47. package/skills/context-mode-ops/release.md +199 -0
  48. package/skills/context-mode-ops/review-pr.md +269 -0
  49. package/skills/context-mode-ops/tdd.md +329 -0
  50. package/skills/context-mode-ops/triage-issue.md +218 -0
  51. package/skills/context-mode-ops/validation.md +238 -0
  52. 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, copyFileSync, chmodSync, readFileSync, writeFileSync, readdirSync } from "node:fs";
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 are available (shared with hooks via ensure-deps.mjs)
119
- import { ensureDeps } from "./hooks/ensure-deps.mjs";
120
- // ensure-deps handles better-sqlite3; also install pure-JS deps used by server
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");