@kawacode/mcp 6.1.5 → 6.8.0
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.md.example +13 -0
- package/build/index.js +13 -1
- package/build/index.js.map +1 -1
- package/build/kawacode-on-pre-edit.d.ts +5 -0
- package/build/kawacode-on-pre-edit.js +73 -9
- package/build/kawacode-on-pre-edit.js.map +1 -1
- package/build/kawacode-on-stop.d.ts +49 -23
- package/build/kawacode-on-stop.js +288 -38
- package/build/kawacode-on-stop.js.map +1 -1
- package/build/services/muninn-ipc.d.ts +19 -1
- package/build/services/muninn-ipc.js +20 -2
- package/build/services/muninn-ipc.js.map +1 -1
- package/build/stop/uncompleted-commit.d.ts +63 -0
- package/build/stop/uncompleted-commit.js +188 -0
- package/build/stop/uncompleted-commit.js.map +1 -0
- package/build/stop/uncompleted-commit.test.d.ts +1 -0
- package/build/stop/uncompleted-commit.test.js +135 -0
- package/build/stop/uncompleted-commit.test.js.map +1 -0
- package/build/telemetry.d.ts +54 -0
- package/build/telemetry.js +84 -0
- package/build/telemetry.js.map +1 -0
- package/build/tools/activate-intent.d.ts +1 -14
- package/build/tools/activate-intent.js +17 -56
- package/build/tools/activate-intent.js.map +1 -1
- package/build/tools/arbiter-apply.d.ts +132 -0
- package/build/tools/arbiter-apply.js +59 -0
- package/build/tools/arbiter-apply.js.map +1 -0
- package/build/tools/arbiter-resolve.d.ts +132 -0
- package/build/tools/arbiter-resolve.js +58 -0
- package/build/tools/arbiter-resolve.js.map +1 -0
- package/build/tools/check-active-intent.d.ts +21 -12
- package/build/tools/check-active-intent.js +54 -27
- package/build/tools/check-active-intent.js.map +1 -1
- package/build/tools/complete-intent.d.ts +43 -10
- package/build/tools/complete-intent.js +51 -84
- package/build/tools/complete-intent.js.map +1 -1
- package/build/tools/create-intent.d.ts +1 -21
- package/build/tools/create-intent.js +18 -106
- package/build/tools/create-intent.js.map +1 -1
- package/build/tools/get-decision-detail.d.ts +109 -0
- package/build/tools/get-decision-detail.js +57 -0
- package/build/tools/get-decision-detail.js.map +1 -0
- package/build/tools/get-project-decisions.d.ts +0 -4
- package/build/tools/get-project-decisions.js +4 -6
- package/build/tools/get-project-decisions.js.map +1 -1
- package/build/tools/get-relevant-context.d.ts +0 -1
- package/build/tools/get-relevant-context.js +18 -3
- package/build/tools/get-relevant-context.js.map +1 -1
- package/build/tools/get-resolution-context.d.ts +154 -0
- package/build/tools/get-resolution-context.js +78 -0
- package/build/tools/get-resolution-context.js.map +1 -0
- package/build/tools/get-session-decisions.d.ts +0 -5
- package/build/tools/get-session-decisions.js +5 -5
- package/build/tools/get-session-decisions.js.map +1 -1
- package/build/tools/index.d.ts +216 -7
- package/build/tools/index.js +13 -3
- package/build/tools/index.js.map +1 -1
- package/build/tools/list-team-intents.d.ts +6 -6
- package/build/tools/list-team-intents.js +2 -2
- package/build/tools/list-team-intents.js.map +1 -1
- package/build/tools/pre-edit-acknowledge.d.ts +12 -0
- package/build/tools/pre-edit-acknowledge.js +21 -0
- package/build/tools/pre-edit-acknowledge.js.map +1 -1
- package/build/tools/pre-edit-decision-check.js +2 -0
- package/build/tools/pre-edit-decision-check.js.map +1 -1
- package/build/tools/record-decision.d.ts +76 -0
- package/build/tools/record-decision.js +10 -0
- package/build/tools/record-decision.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure transcript detection for the complete_intent hard gate (kawacode-on-stop
|
|
3
|
+
* job 3). Kept separate from the bin entry so it's unit-testable without
|
|
4
|
+
* triggering the hook's main().
|
|
5
|
+
*
|
|
6
|
+
* The signal we want: the agent ran `git commit` but never finalized the work
|
|
7
|
+
* with complete_intent. We read Claude Code's own transcript (harness
|
|
8
|
+
* introspection — not Muninn's concern) and compare the position of the last
|
|
9
|
+
* SUCCESSFUL commit against the last complete_intent call.
|
|
10
|
+
*/
|
|
11
|
+
/** Flatten a tool_result `content` (string | array of {type,text}) to plain text. */
|
|
12
|
+
export function toolResultText(content) {
|
|
13
|
+
if (typeof content === 'string')
|
|
14
|
+
return content;
|
|
15
|
+
if (Array.isArray(content)) {
|
|
16
|
+
return content
|
|
17
|
+
.map(c => (typeof c === 'string' ? c : typeof c?.text === 'string' ? c.text : ''))
|
|
18
|
+
.join(' ');
|
|
19
|
+
}
|
|
20
|
+
return '';
|
|
21
|
+
}
|
|
22
|
+
/** A Bash command that *invokes* `git commit` (incl. `git -C <path> commit`),
|
|
23
|
+
* excluding dry runs. NOTE: a true match here is necessary but NOT sufficient —
|
|
24
|
+
* a command can merely MENTION "git commit" as data (printf/echo/heredoc/docs,
|
|
25
|
+
* `git log --grep`). Confirm an actual commit with {@link looksLikeCommitOutput}
|
|
26
|
+
* on the tool_result before treating it as a commit. */
|
|
27
|
+
export function isGitCommitCommand(name, cmd) {
|
|
28
|
+
if (name !== 'Bash' || !cmd)
|
|
29
|
+
return false;
|
|
30
|
+
if (/--dry-run/.test(cmd))
|
|
31
|
+
return false;
|
|
32
|
+
return /\bgit\s+(?:-C\s+\S+\s+)?commit\b/.test(cmd);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* True when text contains git's commit-success line: `[<ref> <shorthash>] …`
|
|
36
|
+
* (covers commit / amend / merge / cherry-pick / root-commit). This is the
|
|
37
|
+
* authoritative "a commit actually happened" signal — `git log`/`git show` and
|
|
38
|
+
* non-git output don't produce a bracketed short-hash line, and a command that
|
|
39
|
+
* only mentions "git commit" as data produces no such output at all.
|
|
40
|
+
*
|
|
41
|
+
* Tradeoff: `git commit --quiet` suppresses this line, so a quiet commit is a
|
|
42
|
+
* false NEGATIVE (no gate). That's the safe bias for a hard gate — a missed nag
|
|
43
|
+
* is far less disruptive than a false block (the printf-in-transcript bug).
|
|
44
|
+
*/
|
|
45
|
+
export function looksLikeCommitOutput(text) {
|
|
46
|
+
return /\[[^\]\n]*\b[0-9a-f]{7,40}\b[^\]\n]*\]/.test(text);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* True when the transcript shows a SUCCESSFUL `git commit` tool_use that lands
|
|
50
|
+
* after the most recent complete_intent tool_use (or with no complete_intent
|
|
51
|
+
* after it) — i.e. the agent committed without finalizing.
|
|
52
|
+
*
|
|
53
|
+
* A commit counts only when BOTH hold: the command invokes git commit AND its
|
|
54
|
+
* tool_result carries the commit-success signature (not is_error). Requiring
|
|
55
|
+
* the result signature is what stops a command that merely *mentions* "git
|
|
56
|
+
* commit" (e.g. a printf crafting a fixture) from being read as a real commit.
|
|
57
|
+
* A complete_intent call counts even if it later failed (conflicts): the agent
|
|
58
|
+
* tried, so we don't nag.
|
|
59
|
+
*
|
|
60
|
+
* @param transcriptText raw JSONL contents of the Claude Code transcript
|
|
61
|
+
*/
|
|
62
|
+
export function detectUncompletedCommit(transcriptText) {
|
|
63
|
+
const lines = transcriptText.split('\n');
|
|
64
|
+
const commits = [];
|
|
65
|
+
const results = new Map();
|
|
66
|
+
let lastCompleteIdx = -1;
|
|
67
|
+
for (let i = 0; i < lines.length; i++) {
|
|
68
|
+
const ln = lines[i].trim();
|
|
69
|
+
if (!ln)
|
|
70
|
+
continue;
|
|
71
|
+
let obj;
|
|
72
|
+
try {
|
|
73
|
+
obj = JSON.parse(ln);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const content = obj?.message?.content;
|
|
79
|
+
if (!Array.isArray(content))
|
|
80
|
+
continue;
|
|
81
|
+
for (const item of content) {
|
|
82
|
+
if (item?.type === 'tool_use') {
|
|
83
|
+
const name = item.name || '';
|
|
84
|
+
if (/complete_intent/.test(name)) {
|
|
85
|
+
lastCompleteIdx = i;
|
|
86
|
+
}
|
|
87
|
+
else if (isGitCommitCommand(name, item?.input?.command || '')) {
|
|
88
|
+
commits.push({ idx: i, id: item.id });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else if (item?.type === 'tool_result' && item.tool_use_id) {
|
|
92
|
+
results.set(item.tool_use_id, {
|
|
93
|
+
isError: item.is_error === true,
|
|
94
|
+
text: toolResultText(item.content),
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Most recent commit CONFIRMED by its result signature. A candidate with no
|
|
100
|
+
// result, an errored result, or output lacking the signature does not count.
|
|
101
|
+
let lastCommitIdx = -1;
|
|
102
|
+
for (const c of commits) {
|
|
103
|
+
if (!c.id)
|
|
104
|
+
continue;
|
|
105
|
+
const r = results.get(c.id);
|
|
106
|
+
if (!r || r.isError)
|
|
107
|
+
continue;
|
|
108
|
+
if (!looksLikeCommitOutput(r.text))
|
|
109
|
+
continue;
|
|
110
|
+
if (c.idx > lastCommitIdx)
|
|
111
|
+
lastCommitIdx = c.idx;
|
|
112
|
+
}
|
|
113
|
+
if (lastCommitIdx === -1)
|
|
114
|
+
return false;
|
|
115
|
+
return lastCommitIdx > lastCompleteIdx;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Gate-SAVE detection (VALUE_METRICS.md V8): the inverse of an uncompleted
|
|
119
|
+
* commit — a CONFIRMED `git commit` exists AND a complete_intent call lands at
|
|
120
|
+
* or after it (the commit was finalized). Used at the Stop hook to emit the
|
|
121
|
+
* acted-on signal only when a prior gate block held the turn open
|
|
122
|
+
* (`stop_hook_active`) and the agent then completed the intent — i.e. the gate
|
|
123
|
+
* preceded a completion that would otherwise have skipped distillation +
|
|
124
|
+
* block auto-capture.
|
|
125
|
+
*
|
|
126
|
+
* Mirrors detectUncompletedCommit's parsing exactly (a commit counts only when
|
|
127
|
+
* its tool_result carries the commit-success signature, per decision 64b340d8 —
|
|
128
|
+
* a command merely MENTIONING "git commit" does not count) and flips the final
|
|
129
|
+
* position comparison.
|
|
130
|
+
*
|
|
131
|
+
* Correlation, not causation: this says "a completion followed a confirmed
|
|
132
|
+
* commit while the turn was held open", not "the gate caused the completion".
|
|
133
|
+
*/
|
|
134
|
+
export function detectGateSave(transcriptText) {
|
|
135
|
+
const lines = transcriptText.split('\n');
|
|
136
|
+
const commits = [];
|
|
137
|
+
const results = new Map();
|
|
138
|
+
let lastCompleteIdx = -1;
|
|
139
|
+
for (let i = 0; i < lines.length; i++) {
|
|
140
|
+
const ln = lines[i].trim();
|
|
141
|
+
if (!ln)
|
|
142
|
+
continue;
|
|
143
|
+
let obj;
|
|
144
|
+
try {
|
|
145
|
+
obj = JSON.parse(ln);
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
const content = obj?.message?.content;
|
|
151
|
+
if (!Array.isArray(content))
|
|
152
|
+
continue;
|
|
153
|
+
for (const item of content) {
|
|
154
|
+
if (item?.type === 'tool_use') {
|
|
155
|
+
const name = item.name || '';
|
|
156
|
+
if (/complete_intent/.test(name)) {
|
|
157
|
+
lastCompleteIdx = i;
|
|
158
|
+
}
|
|
159
|
+
else if (isGitCommitCommand(name, item?.input?.command || '')) {
|
|
160
|
+
commits.push({ idx: i, id: item.id });
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else if (item?.type === 'tool_result' && item.tool_use_id) {
|
|
164
|
+
results.set(item.tool_use_id, {
|
|
165
|
+
isError: item.is_error === true,
|
|
166
|
+
text: toolResultText(item.content),
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
let lastCommitIdx = -1;
|
|
172
|
+
for (const c of commits) {
|
|
173
|
+
if (!c.id)
|
|
174
|
+
continue;
|
|
175
|
+
const r = results.get(c.id);
|
|
176
|
+
if (!r || r.isError)
|
|
177
|
+
continue;
|
|
178
|
+
if (!looksLikeCommitOutput(r.text))
|
|
179
|
+
continue;
|
|
180
|
+
if (c.idx > lastCommitIdx)
|
|
181
|
+
lastCommitIdx = c.idx;
|
|
182
|
+
}
|
|
183
|
+
if (lastCommitIdx === -1)
|
|
184
|
+
return false;
|
|
185
|
+
// A complete_intent at or after the last confirmed commit = the commit is finalized.
|
|
186
|
+
return lastCompleteIdx >= lastCommitIdx;
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=uncompleted-commit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uncompleted-commit.js","sourceRoot":"","sources":["../../src/stop/uncompleted-commit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { detectGateSave, detectUncompletedCommit, isGitCommitCommand, looksLikeCommitOutput, toolResultText, } from './uncompleted-commit.js';
|
|
4
|
+
/** A realistic `git commit` success result (the bracketed short-hash line). */
|
|
5
|
+
const COMMIT_OK = '[main 1a2b3c4] Add the thing\n 1 file changed, 2 insertions(+)';
|
|
6
|
+
// ---- transcript line builders (Claude Code JSONL shape) ----
|
|
7
|
+
function bash(command, id) {
|
|
8
|
+
return JSON.stringify({
|
|
9
|
+
type: 'assistant',
|
|
10
|
+
message: { role: 'assistant', content: [{ type: 'tool_use', name: 'Bash', id, input: { command } }] },
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function toolUse(name, id) {
|
|
14
|
+
return JSON.stringify({
|
|
15
|
+
type: 'assistant',
|
|
16
|
+
message: { role: 'assistant', content: [{ type: 'tool_use', name, id, input: {} }] },
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function result(toolUseId, opts = {}) {
|
|
20
|
+
return JSON.stringify({
|
|
21
|
+
type: 'user',
|
|
22
|
+
message: {
|
|
23
|
+
role: 'user',
|
|
24
|
+
content: [{ type: 'tool_result', tool_use_id: toolUseId, is_error: opts.isError ?? false, content: opts.text ?? 'ok' }],
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
const COMPLETE = 'mcp__kawa-intents__complete_intent';
|
|
29
|
+
test('isGitCommitCommand', async (t) => {
|
|
30
|
+
await t.test('plain commit', () => assert.equal(isGitCommitCommand('Bash', 'git commit -m "x"'), true));
|
|
31
|
+
await t.test('git -C path commit', () => assert.equal(isGitCommitCommand('Bash', 'git -C /repo commit -am "x"'), true));
|
|
32
|
+
await t.test('chained with &&', () => assert.equal(isGitCommitCommand('Bash', 'git add -A && git commit -m "x"'), true));
|
|
33
|
+
await t.test('dry-run excluded', () => assert.equal(isGitCommitCommand('Bash', 'git commit --dry-run'), false));
|
|
34
|
+
await t.test('non-Bash tool excluded', () => assert.equal(isGitCommitCommand('Edit', 'git commit -m "x"'), false));
|
|
35
|
+
await t.test('git log mentioning commit not matched', () => assert.equal(isGitCommitCommand('Bash', 'git log --pretty=%H'), false));
|
|
36
|
+
});
|
|
37
|
+
test('toolResultText flattens shapes', async (t) => {
|
|
38
|
+
await t.test('string', () => assert.equal(toolResultText('hello'), 'hello'));
|
|
39
|
+
await t.test('array of text parts', () => assert.equal(toolResultText([{ type: 'text', text: 'a' }, { type: 'text', text: 'b' }]), 'a b'));
|
|
40
|
+
await t.test('other → empty', () => assert.equal(toolResultText({ foo: 1 }), ''));
|
|
41
|
+
});
|
|
42
|
+
test('looksLikeCommitOutput', async (t) => {
|
|
43
|
+
await t.test('standard commit line', () => assert.equal(looksLikeCommitOutput('[main 1a2b3c4] msg'), true));
|
|
44
|
+
await t.test('root commit', () => assert.equal(looksLikeCommitOutput('[main (root-commit) 0e1f2a3] init'), true));
|
|
45
|
+
await t.test('detached HEAD', () => assert.equal(looksLikeCommitOutput('[detached HEAD abc1234] msg'), true));
|
|
46
|
+
await t.test('nothing-to-commit output → false', () => assert.equal(looksLikeCommitOutput('nothing to commit, working tree clean'), false));
|
|
47
|
+
await t.test('empty (printf wrote a file) → false', () => assert.equal(looksLikeCommitOutput(''), false));
|
|
48
|
+
await t.test('git log oneline → false', () => assert.equal(looksLikeCommitOutput('1a2b3c4 some subject\nded5678 another'), false));
|
|
49
|
+
});
|
|
50
|
+
test('detectUncompletedCommit', async (t) => {
|
|
51
|
+
await t.test('no commit at all → false', () => {
|
|
52
|
+
const t1 = [toolUse('Read', 'r1'), result('r1')].join('\n');
|
|
53
|
+
assert.equal(detectUncompletedCommit(t1), false);
|
|
54
|
+
});
|
|
55
|
+
await t.test('confirmed commit with no completion → true', () => {
|
|
56
|
+
const t1 = [bash('git commit -m "x"', 'c1'), result('c1', { text: COMMIT_OK })].join('\n');
|
|
57
|
+
assert.equal(detectUncompletedCommit(t1), true);
|
|
58
|
+
});
|
|
59
|
+
await t.test('REGRESSION: command merely MENTIONS "git commit" (printf, no commit output) → false', () => {
|
|
60
|
+
// The printf-in-transcript false positive: a Bash command that contains the
|
|
61
|
+
// string "git commit" as data, writing a fixture; its result has no commit
|
|
62
|
+
// signature, so it must NOT be read as a real commit.
|
|
63
|
+
const printf = bash(`printf '%s' '{"command":"git commit -m \\"x\\""}' > /tmp/fixture.jsonl`, 'p1');
|
|
64
|
+
const t1 = [printf, result('p1', { text: '' })].join('\n');
|
|
65
|
+
assert.equal(detectUncompletedCommit(t1), false);
|
|
66
|
+
});
|
|
67
|
+
await t.test('command looks like commit but result has no signature → false', () => {
|
|
68
|
+
const t1 = [bash('git commit -m "x"', 'c1'), result('c1', { text: 'ok' })].join('\n');
|
|
69
|
+
assert.equal(detectUncompletedCommit(t1), false);
|
|
70
|
+
});
|
|
71
|
+
await t.test('commit then complete_intent → false', () => {
|
|
72
|
+
const t1 = [bash('git commit -m "x"', 'c1'), result('c1', { text: COMMIT_OK }), toolUse(COMPLETE, 'k1'), result('k1')].join('\n');
|
|
73
|
+
assert.equal(detectUncompletedCommit(t1), false);
|
|
74
|
+
});
|
|
75
|
+
await t.test('complete then a NEW confirmed commit after it → true', () => {
|
|
76
|
+
const t1 = [
|
|
77
|
+
bash('git commit -m "a"', 'c1'), result('c1', { text: COMMIT_OK }),
|
|
78
|
+
toolUse(COMPLETE, 'k1'), result('k1'),
|
|
79
|
+
bash('git commit -m "b"', 'c2'), result('c2', { text: '[main 9f8e7d6] b\n 1 file changed' }),
|
|
80
|
+
].join('\n');
|
|
81
|
+
assert.equal(detectUncompletedCommit(t1), true);
|
|
82
|
+
});
|
|
83
|
+
await t.test('failed commit (is_error) → false', () => {
|
|
84
|
+
const t1 = [bash('git commit -m "x"', 'c1'), result('c1', { isError: true, text: 'fatal' })].join('\n');
|
|
85
|
+
assert.equal(detectUncompletedCommit(t1), false);
|
|
86
|
+
});
|
|
87
|
+
await t.test('"nothing to commit" → false', () => {
|
|
88
|
+
const t1 = [bash('git commit -m "x"', 'c1'), result('c1', { text: 'On branch main\nnothing to commit, working tree clean' })].join('\n');
|
|
89
|
+
assert.equal(detectUncompletedCommit(t1), false);
|
|
90
|
+
});
|
|
91
|
+
await t.test('attempted complete_intent (failed, conflicts) still suppresses the gate', () => {
|
|
92
|
+
// complete_intent was called after the commit even though it may have failed
|
|
93
|
+
// (conflicts) — the agent tried, so no nag.
|
|
94
|
+
const t1 = [
|
|
95
|
+
bash('git commit -m "x"', 'c1'), result('c1', { text: COMMIT_OK }),
|
|
96
|
+
toolUse(COMPLETE, 'k1'), result('k1', { text: '{ "success": false, "reason": "conflicts" }' }),
|
|
97
|
+
].join('\n');
|
|
98
|
+
assert.equal(detectUncompletedCommit(t1), false);
|
|
99
|
+
});
|
|
100
|
+
await t.test('garbage / non-JSON lines are skipped', () => {
|
|
101
|
+
const t1 = ['', 'not json', bash('git commit -m "x"', 'c1'), result('c1', { text: COMMIT_OK })].join('\n');
|
|
102
|
+
assert.equal(detectUncompletedCommit(t1), true);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
test('detectGateSave (VALUE_METRICS V8 acted-on)', async (t) => {
|
|
106
|
+
await t.test('confirmed commit then complete_intent → true (the inverse of uncompleted)', () => {
|
|
107
|
+
const t1 = [bash('git commit -m "x"', 'c1'), result('c1', { text: COMMIT_OK }), toolUse(COMPLETE, 'k1'), result('k1')].join('\n');
|
|
108
|
+
assert.equal(detectGateSave(t1), true);
|
|
109
|
+
});
|
|
110
|
+
await t.test('confirmed commit with NO completion → false (gate would still fire, not a save)', () => {
|
|
111
|
+
const t1 = [bash('git commit -m "x"', 'c1'), result('c1', { text: COMMIT_OK })].join('\n');
|
|
112
|
+
assert.equal(detectGateSave(t1), false);
|
|
113
|
+
});
|
|
114
|
+
await t.test('no commit at all → false', () => {
|
|
115
|
+
const t1 = [toolUse(COMPLETE, 'k1'), result('k1')].join('\n');
|
|
116
|
+
assert.equal(detectGateSave(t1), false);
|
|
117
|
+
});
|
|
118
|
+
await t.test('command merely MENTIONS "git commit" then complete → false (no confirmed commit)', () => {
|
|
119
|
+
const printf = bash(`printf '%s' 'git commit -m x' > /tmp/f`, 'p1');
|
|
120
|
+
const t1 = [printf, result('p1', { text: '' }), toolUse(COMPLETE, 'k1'), result('k1')].join('\n');
|
|
121
|
+
assert.equal(detectGateSave(t1), false);
|
|
122
|
+
});
|
|
123
|
+
await t.test('complete BEFORE the last confirmed commit → false (commit not finalized)', () => {
|
|
124
|
+
const t1 = [
|
|
125
|
+
toolUse(COMPLETE, 'k1'), result('k1'),
|
|
126
|
+
bash('git commit -m "later"', 'c1'), result('c1', { text: COMMIT_OK }),
|
|
127
|
+
].join('\n');
|
|
128
|
+
assert.equal(detectGateSave(t1), false);
|
|
129
|
+
});
|
|
130
|
+
await t.test('failed commit (is_error) then complete → false', () => {
|
|
131
|
+
const t1 = [bash('git commit -m "x"', 'c1'), result('c1', { isError: true, text: 'fatal' }), toolUse(COMPLETE, 'k1'), result('k1')].join('\n');
|
|
132
|
+
assert.equal(detectGateSave(t1), false);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
//# sourceMappingURL=uncompleted-commit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uncompleted-commit.test.js","sourceRoot":"","sources":["../../src/stop/uncompleted-commit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context-injection telemetry (VALUE_METRICS.md Phase 2, Track B).
|
|
3
|
+
*
|
|
4
|
+
* At each of the 5 injection points where Kawa adds context to an agent's turn,
|
|
5
|
+
* we SIZE the payload we're about to inject (≈ chars/4 tokens) and emit a
|
|
6
|
+
* fire-and-forget IPC to Muninn, which forwards it to kawa.api. This is the COST
|
|
7
|
+
* side of the headline ratio ("Kawa adds ≈N tokens/turn"), paired with an
|
|
8
|
+
* "acted on" signal for the benefit side.
|
|
9
|
+
*
|
|
10
|
+
* Keep-mcp-thin: this module ONLY sizes + hashes + forwards. No storage, no API
|
|
11
|
+
* client, no business logic — Muninn owns the forward and the API owns the
|
|
12
|
+
* store. Every emit is fire-and-forget and swallows its own errors, so telemetry
|
|
13
|
+
* can never block or fail a tool call or a hook.
|
|
14
|
+
*
|
|
15
|
+
* Zero-knowledge: we emit token COUNTS, item COUNTS, and opaque decision ids
|
|
16
|
+
* only — never the strings measured. The repo origin is HASHED here before it
|
|
17
|
+
* leaves the process (`hashOrigin`, byte-identical to
|
|
18
|
+
* kawa.api/scripts/value-report.ts so `--repo` filtering matches).
|
|
19
|
+
*/
|
|
20
|
+
export type InjectionType = 'recall' | 'pre_edit' | 'stop_gate' | 'stop_collision' | 'check_active';
|
|
21
|
+
/** ≈ tokens for a string payload (chars/4, rounded up). Labelled "≈" wherever published. */
|
|
22
|
+
export declare function estimateTokens(s: string | undefined | null): number;
|
|
23
|
+
/**
|
|
24
|
+
* Hash a repo origin for the zero-knowledge aggregate. MUST stay byte-identical
|
|
25
|
+
* to `hashOrigin` in kawa.api/scripts/value-report.ts (which hashes the
|
|
26
|
+
* lowercased origin) so a `--repo <origin>` filter matches these rows. Callers
|
|
27
|
+
* pass the lowercased origin.
|
|
28
|
+
*/
|
|
29
|
+
export declare function hashOrigin(origin: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Emit one context-injection sizing. Fire-and-forget: returns a resolved
|
|
32
|
+
* promise even on failure. Callers in the long-lived server may ignore the
|
|
33
|
+
* result; hook callers should include it in their pre-disconnect await set so
|
|
34
|
+
* the socket write flushes before the process exits.
|
|
35
|
+
*/
|
|
36
|
+
export declare function emitInjection(args: {
|
|
37
|
+
type: InjectionType;
|
|
38
|
+
tokensEst: number;
|
|
39
|
+
itemCount: number;
|
|
40
|
+
/** raw repo origin — hashed here before it leaves the process */
|
|
41
|
+
repoOrigin: string;
|
|
42
|
+
/** recall only — surfaced decision ids, for the read-side recall→supersedes join */
|
|
43
|
+
decisionIds?: string[];
|
|
44
|
+
}): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Emit one "acted on" signal (R2 acted-on rate; V8 gate-saves when
|
|
47
|
+
* type='stop_gate'). Fire-and-forget.
|
|
48
|
+
*/
|
|
49
|
+
export declare function emitActedOn(args: {
|
|
50
|
+
type: InjectionType;
|
|
51
|
+
/** the surfaced id that was used (e.g. a decisionId) */
|
|
52
|
+
refId?: string;
|
|
53
|
+
repoOrigin: string;
|
|
54
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context-injection telemetry (VALUE_METRICS.md Phase 2, Track B).
|
|
3
|
+
*
|
|
4
|
+
* At each of the 5 injection points where Kawa adds context to an agent's turn,
|
|
5
|
+
* we SIZE the payload we're about to inject (≈ chars/4 tokens) and emit a
|
|
6
|
+
* fire-and-forget IPC to Muninn, which forwards it to kawa.api. This is the COST
|
|
7
|
+
* side of the headline ratio ("Kawa adds ≈N tokens/turn"), paired with an
|
|
8
|
+
* "acted on" signal for the benefit side.
|
|
9
|
+
*
|
|
10
|
+
* Keep-mcp-thin: this module ONLY sizes + hashes + forwards. No storage, no API
|
|
11
|
+
* client, no business logic — Muninn owns the forward and the API owns the
|
|
12
|
+
* store. Every emit is fire-and-forget and swallows its own errors, so telemetry
|
|
13
|
+
* can never block or fail a tool call or a hook.
|
|
14
|
+
*
|
|
15
|
+
* Zero-knowledge: we emit token COUNTS, item COUNTS, and opaque decision ids
|
|
16
|
+
* only — never the strings measured. The repo origin is HASHED here before it
|
|
17
|
+
* leaves the process (`hashOrigin`, byte-identical to
|
|
18
|
+
* kawa.api/scripts/value-report.ts so `--repo` filtering matches).
|
|
19
|
+
*/
|
|
20
|
+
import * as crypto from 'node:crypto';
|
|
21
|
+
import { request, SESSION_ID } from './services/muninn-ipc.js';
|
|
22
|
+
/** Coarse char→token approximation; deterministic, no tokenizer dep. Matches
|
|
23
|
+
* CHARS_PER_TOKEN in kawacode-on-pre-edit.ts and the "≈ chars/4" method the
|
|
24
|
+
* value-report publishes. */
|
|
25
|
+
const CHARS_PER_TOKEN = 4;
|
|
26
|
+
/** ≈ tokens for a string payload (chars/4, rounded up). Labelled "≈" wherever published. */
|
|
27
|
+
export function estimateTokens(s) {
|
|
28
|
+
return Math.ceil((s ? s.length : 0) / CHARS_PER_TOKEN);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Hash a repo origin for the zero-knowledge aggregate. MUST stay byte-identical
|
|
32
|
+
* to `hashOrigin` in kawa.api/scripts/value-report.ts (which hashes the
|
|
33
|
+
* lowercased origin) so a `--repo <origin>` filter matches these rows. Callers
|
|
34
|
+
* pass the lowercased origin.
|
|
35
|
+
*/
|
|
36
|
+
export function hashOrigin(origin) {
|
|
37
|
+
return 'sha256:' + crypto.createHash('sha256').update(origin || '').digest('hex').slice(0, 16);
|
|
38
|
+
}
|
|
39
|
+
function enabled() {
|
|
40
|
+
return process.env.KAWA_VALUE_TELEMETRY !== 'off';
|
|
41
|
+
}
|
|
42
|
+
/** ISO timestamp (informational; the API windows on its own _c). */
|
|
43
|
+
function nowIso() {
|
|
44
|
+
return new Date().toISOString();
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Emit one context-injection sizing. Fire-and-forget: returns a resolved
|
|
48
|
+
* promise even on failure. Callers in the long-lived server may ignore the
|
|
49
|
+
* result; hook callers should include it in their pre-disconnect await set so
|
|
50
|
+
* the socket write flushes before the process exits.
|
|
51
|
+
*/
|
|
52
|
+
export function emitInjection(args) {
|
|
53
|
+
if (!enabled())
|
|
54
|
+
return Promise.resolve();
|
|
55
|
+
const data = {
|
|
56
|
+
type: args.type,
|
|
57
|
+
tokensEst: args.tokensEst,
|
|
58
|
+
itemCount: args.itemCount,
|
|
59
|
+
sessionId: SESSION_ID,
|
|
60
|
+
repoOriginHash: hashOrigin((args.repoOrigin || '').toLowerCase()),
|
|
61
|
+
ts: nowIso(),
|
|
62
|
+
};
|
|
63
|
+
if (args.decisionIds && args.decisionIds.length)
|
|
64
|
+
data.decisionIds = args.decisionIds;
|
|
65
|
+
return request('telemetry', 'record', data).then(() => { }).catch(() => { });
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Emit one "acted on" signal (R2 acted-on rate; V8 gate-saves when
|
|
69
|
+
* type='stop_gate'). Fire-and-forget.
|
|
70
|
+
*/
|
|
71
|
+
export function emitActedOn(args) {
|
|
72
|
+
if (!enabled())
|
|
73
|
+
return Promise.resolve();
|
|
74
|
+
const data = {
|
|
75
|
+
type: args.type,
|
|
76
|
+
sessionId: SESSION_ID,
|
|
77
|
+
repoOriginHash: hashOrigin((args.repoOrigin || '').toLowerCase()),
|
|
78
|
+
ts: nowIso(),
|
|
79
|
+
};
|
|
80
|
+
if (args.refId)
|
|
81
|
+
data.refId = args.refId;
|
|
82
|
+
return request('telemetry', 'acted_on', data).then(() => { }).catch(() => { });
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAE9D;;8BAE8B;AAC9B,MAAM,eAAe,GAAG,CAAC,CAAA;AAIzB,4FAA4F;AAC5F,MAAM,UAAU,cAAc,CAAC,CAA4B;IACzD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAA;AACxD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAChG,CAAC;AAED,SAAS,OAAO;IACd,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,KAAK,CAAA;AACnD,CAAC;AAED,oEAAoE;AACpE,SAAS,MAAM;IACb,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;AACjC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAQ7B;IACC,IAAI,CAAC,OAAO,EAAE;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;IACxC,MAAM,IAAI,GAAwB;QAChC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,SAAS,EAAE,UAAU;QACrB,cAAc,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACjE,EAAE,EAAE,MAAM,EAAE;KACb,CAAA;IACD,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM;QAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;IACpF,OAAO,OAAO,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;AAC5E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAK3B;IACC,IAAI,CAAC,OAAO,EAAE;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;IACxC,MAAM,IAAI,GAAwB;QAChC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,SAAS,EAAE,UAAU;QACrB,cAAc,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACjE,EAAE,EAAE,MAAM,EAAE;KACb,CAAA;IACD,IAAI,IAAI,CAAC,KAAK;QAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;IACvC,OAAO,OAAO,CAAC,WAAW,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;AAC9E,CAAC"}
|
|
@@ -17,10 +17,8 @@ export declare const activateIntentSchema: z.ZodObject<{
|
|
|
17
17
|
repoOrigin: z.ZodOptional<z.ZodString>;
|
|
18
18
|
repoPath: z.ZodString;
|
|
19
19
|
intentId: z.ZodString;
|
|
20
|
-
force: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
21
20
|
}, "strip", z.ZodTypeAny, {
|
|
22
21
|
repoPath: string;
|
|
23
|
-
force: boolean;
|
|
24
22
|
intentId: string;
|
|
25
23
|
repoOrigin?: string | undefined;
|
|
26
24
|
forkAuthor?: {
|
|
@@ -39,22 +37,14 @@ export declare const activateIntentSchema: z.ZodObject<{
|
|
|
39
37
|
forkOrigin: string;
|
|
40
38
|
} | undefined;
|
|
41
39
|
workspaceId?: string | undefined;
|
|
42
|
-
force?: boolean | undefined;
|
|
43
40
|
}>;
|
|
44
41
|
export type ActivateIntentInput = z.infer<typeof activateIntentSchema>;
|
|
45
|
-
export interface ActiveIntentLockConflict {
|
|
46
|
-
existingIntentId: string;
|
|
47
|
-
title?: string;
|
|
48
|
-
createdBy?: string;
|
|
49
|
-
author?: string;
|
|
50
|
-
}
|
|
51
42
|
export interface ActivateIntentResponse {
|
|
52
43
|
success: boolean;
|
|
53
44
|
intentId: string;
|
|
54
|
-
action?: 'activated' | 'already_active'
|
|
45
|
+
action?: 'activated' | 'already_active';
|
|
55
46
|
previousActiveId?: string;
|
|
56
47
|
message: string;
|
|
57
|
-
lockConflict?: ActiveIntentLockConflict;
|
|
58
48
|
}
|
|
59
49
|
export declare function activateIntent(input: ActivateIntentInput): Promise<ActivateIntentResponse>;
|
|
60
50
|
export declare const activateIntentTool: {
|
|
@@ -78,10 +68,8 @@ export declare const activateIntentTool: {
|
|
|
78
68
|
repoOrigin: z.ZodOptional<z.ZodString>;
|
|
79
69
|
repoPath: z.ZodString;
|
|
80
70
|
intentId: z.ZodString;
|
|
81
|
-
force: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
82
71
|
}, "strip", z.ZodTypeAny, {
|
|
83
72
|
repoPath: string;
|
|
84
|
-
force: boolean;
|
|
85
73
|
intentId: string;
|
|
86
74
|
repoOrigin?: string | undefined;
|
|
87
75
|
forkAuthor?: {
|
|
@@ -100,7 +88,6 @@ export declare const activateIntentTool: {
|
|
|
100
88
|
forkOrigin: string;
|
|
101
89
|
} | undefined;
|
|
102
90
|
workspaceId?: string | undefined;
|
|
103
|
-
force?: boolean | undefined;
|
|
104
91
|
}>;
|
|
105
92
|
handler: typeof activateIntent;
|
|
106
93
|
};
|