claude-spotter 1.5.5 → 1.5.6

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.5.6 — 2026-08-05
4
+
5
+ - **Codexの動的nested MCP利用を採用として記録する。** `functions.exec`内で
6
+ `ALL_TOOLS.find(...name === "mcp__...")`から取得したtoolを`tools[tool.name](...)`で実行する
7
+ 現行Codexの呼び方を認識する。単なるlookupや文字列・コメント内の記述は利用として数えない。
8
+ - **実際の誤判定を回帰化。** `mcp__aiterm__pty_open`を実行済みなのに`usedToolIds=[]`となった形を
9
+ focused testとStop hookの評価DB統合テストへ固定し、`adopted`になることを確認する。
10
+
3
11
  ## 1.5.5 — 2026-08-05
4
12
 
5
13
  - **提案時文脈をexact sessionへ戻した。** 評価記録がproject全体の最新threadを読む
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-spotter",
3
- "version": "1.5.5",
3
+ "version": "1.5.6",
4
4
  "description": "Audit agent running alongside Claude Code that catches missed tool calls — 気づく役と実行する役の分離",
5
5
  "type": "module",
6
6
  "bin": {
@@ -167,8 +167,26 @@ function codexShellInputs(toolInput) {
167
167
  function nestedMcpToolIds(toolInput) {
168
168
  if (typeof toolInput !== 'string') return [];
169
169
  const executable = maskJavaScriptLiteralsAndComments(toolInput);
170
- const matches = executable.matchAll(/\btools\.(mcp__[A-Za-z0-9_-]+__[A-Za-z0-9_.:/-]+)\s*\(/gu);
171
- return [...new Set([...matches].map((match) => match[1]).filter(validCatalogId))];
170
+ const adopted = new Set(
171
+ [...executable.matchAll(/\btools\.(mcp__[A-Za-z0-9_-]+__[A-Za-z0-9_.:/-]+)\s*\(/gu)]
172
+ .map((match) => match[1])
173
+ .filter(validCatalogId),
174
+ );
175
+
176
+ // Codex may resolve a lazily exposed MCP tool by its exact name, then invoke it through the
177
+ // returned metadata object: `const tool = ALL_TOOLS.find(x => x.name === "mcp__...");
178
+ // await tools[tool.name](...)`. Count only bindings that are followed by that executable call.
179
+ const bindingPattern = /\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*ALL_TOOLS\.find\s*\(\s*([A-Za-z_$][\w$]*)\s*=>\s*\2\.name\s*={2,3}/gu;
180
+ for (const binding of executable.matchAll(bindingPattern)) {
181
+ let valueStart = binding.index + binding[0].length;
182
+ while (/\s/u.test(toolInput[valueStart] ?? '')) valueStart += 1;
183
+ const parsedName = parseJavaScriptStringAt(toolInput, valueStart);
184
+ if (!parsedName || !MCP_ID_PATTERN.test(parsedName.value)) continue;
185
+ const variable = escapedRegExp(binding[1]);
186
+ const callPattern = new RegExp(String.raw`\btools\s*\[\s*${variable}\.name\s*\]\s*\(`, 'u');
187
+ if (callPattern.test(executable.slice(parsedName.end))) adopted.add(parsedName.value);
188
+ }
189
+ return [...adopted];
172
190
  }
173
191
 
174
192
  function escapedRegExp(value) {