@kawacode/mcp 6.9.5 → 7.0.1
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 +23 -0
- package/README.md +88 -1
- package/build/index.js +20 -15
- package/build/index.js.map +1 -1
- package/build/prompts/intent-first-workflow.js +1 -2
- package/build/prompts/intent-first-workflow.js.map +1 -1
- package/build/tools/_mangled-args.d.ts +63 -0
- package/build/tools/_mangled-args.js +116 -0
- package/build/tools/_mangled-args.js.map +1 -0
- package/build/tools/_mangled-args.test.js +110 -0
- package/build/tools/_mangled-args.test.js.map +1 -0
- package/build/tools/activate-intent.d.ts +5 -52
- package/build/tools/activate-intent.js +14 -7
- package/build/tools/activate-intent.js.map +1 -1
- package/build/tools/arbiter-apply.d.ts +0 -52
- package/build/tools/arbiter-apply.js +0 -3
- package/build/tools/arbiter-apply.js.map +1 -1
- package/build/tools/arbiter-resolve.d.ts +0 -52
- package/build/tools/arbiter-resolve.js +0 -3
- package/build/tools/arbiter-resolve.js.map +1 -1
- package/build/tools/check-active-intent.d.ts +0 -52
- package/build/tools/check-active-intent.js +2 -24
- package/build/tools/check-active-intent.js.map +1 -1
- package/build/tools/complete-intent.d.ts +4 -56
- package/build/tools/complete-intent.js +15 -44
- package/build/tools/complete-intent.js.map +1 -1
- package/build/tools/create-intent.d.ts +0 -52
- package/build/tools/create-intent.js +0 -4
- package/build/tools/create-intent.js.map +1 -1
- package/build/tools/detect-intent-conflicts.d.ts +0 -52
- package/build/tools/detect-intent-conflicts.js +0 -3
- package/build/tools/detect-intent-conflicts.js.map +1 -1
- package/build/tools/edit-session-decision.d.ts +0 -52
- package/build/tools/edit-session-decision.js +0 -3
- package/build/tools/edit-session-decision.js.map +1 -1
- package/build/tools/get-decision-detail.d.ts +19 -55
- package/build/tools/get-decision-detail.js +12 -7
- package/build/tools/get-decision-detail.js.map +1 -1
- package/build/tools/get-intents-for-file.d.ts +35 -53
- package/build/tools/get-intents-for-file.js +61 -26
- package/build/tools/get-intents-for-file.js.map +1 -1
- package/build/tools/get-project-decisions.d.ts +0 -52
- package/build/tools/get-project-decisions.js +0 -3
- package/build/tools/get-project-decisions.js.map +1 -1
- package/build/tools/get-relevant-context.d.ts +0 -52
- package/build/tools/get-relevant-context.js +0 -3
- package/build/tools/get-relevant-context.js.map +1 -1
- package/build/tools/get-resolution-context.d.ts +0 -52
- package/build/tools/get-resolution-context.js +0 -4
- package/build/tools/get-resolution-context.js.map +1 -1
- package/build/tools/get-session-decisions.d.ts +10 -53
- package/build/tools/get-session-decisions.js +2 -4
- package/build/tools/get-session-decisions.js.map +1 -1
- package/build/tools/index.d.ts +11 -631
- package/build/tools/index.js +2 -9
- package/build/tools/index.js.map +1 -1
- package/build/tools/infer-history.js +4 -19
- package/build/tools/infer-history.js.map +1 -1
- package/build/tools/list-team-intents.d.ts +4 -56
- package/build/tools/list-team-intents.js +0 -3
- package/build/tools/list-team-intents.js.map +1 -1
- package/build/tools/log-work.d.ts +0 -52
- package/build/tools/log-work.js +0 -3
- package/build/tools/log-work.js.map +1 -1
- package/build/tools/pre-edit-acknowledge.d.ts +0 -52
- package/build/tools/pre-edit-acknowledge.js +0 -2
- package/build/tools/pre-edit-acknowledge.js.map +1 -1
- package/build/tools/pre-edit-decision-check.d.ts +0 -52
- package/build/tools/pre-edit-decision-check.js +0 -4
- package/build/tools/pre-edit-decision-check.js.map +1 -1
- package/build/tools/record-decision.d.ts +2 -52
- package/build/tools/record-decision.js +6 -5
- package/build/tools/record-decision.js.map +1 -1
- package/build/tools/resume-intent.d.ts +0 -52
- package/build/tools/resume-intent.js +6 -4
- package/build/tools/resume-intent.js.map +1 -1
- package/build/tools/update-intent.d.ts +0 -52
- package/build/tools/update-intent.js +1 -5
- package/build/tools/update-intent.js.map +1 -1
- package/build/types/refs.d.ts +73 -0
- package/build/types/refs.js +73 -0
- package/build/types/refs.js.map +1 -0
- package/package.json +1 -1
- package/build/tools/_fork-fields.d.ts +0 -84
- package/build/tools/_fork-fields.js +0 -65
- package/build/tools/_fork-fields.js.map +0 -1
- package/build/tools/_salvage-mangled-args.d.ts +0 -38
- package/build/tools/_salvage-mangled-args.js +0 -87
- package/build/tools/_salvage-mangled-args.js.map +0 -1
- package/build/tools/_salvage-mangled-args.test.js +0 -73
- package/build/tools/_salvage-mangled-args.test.js.map +0 -1
- package/build/tools/evolve-decisions.d.ts +0 -90
- package/build/tools/evolve-decisions.js +0 -40
- package/build/tools/evolve-decisions.js.map +0 -1
- package/build/tools/get-intents-for-lines.d.ts +0 -123
- package/build/tools/get-intents-for-lines.js +0 -67
- package/build/tools/get-intents-for-lines.js.map +0 -1
- package/build/tools/update-features.d.ts +0 -31
- package/build/tools/update-features.js +0 -51
- package/build/tools/update-features.js.map +0 -1
- /package/build/tools/{_salvage-mangled-args.test.d.ts → _mangled-args.test.d.ts} +0 -0
package/CLAUDE.md.example
CHANGED
|
@@ -105,6 +105,29 @@ A decision is worth recording **only if** a future developer (or Claude in a fut
|
|
|
105
105
|
|
|
106
106
|
---
|
|
107
107
|
|
|
108
|
+
## Referring to intents and decisions in prose
|
|
109
|
+
|
|
110
|
+
**Never refer to an intent or decision by ID alone in user-facing prose.** Lead with the title or summary, and **always** carry the ID in parentheses after it. The parenthesised ID is load-bearing, not decoration: it is what Kawa Code matches to resolve the reference.
|
|
111
|
+
|
|
112
|
+
- **Decisions** — an 8-char prefix is fine: `"Summary text" (7a7d1a36)`.
|
|
113
|
+
- **Intents** — use the **full 24-character ID**, never a prefix: `"Intent title" (6a34c9658212aa730480e0e6)`.
|
|
114
|
+
|
|
115
|
+
The asymmetry is unavoidable. Decision IDs are UUIDs, so their leading bits are uniformly random and 8 chars identify exactly one decision. Intent IDs are MongoDB ObjectIds, whose first 4 bytes are a **creation timestamp** — two intents created in the same second by the same process share their first 18 hex characters, so a truncated intent ID does not identify a single intent at all.
|
|
116
|
+
|
|
117
|
+
Instead of:
|
|
118
|
+
|
|
119
|
+
> ❌ `7a7d1a36 supersedes 2cc444ec, which superseded 97c701e7`
|
|
120
|
+
|
|
121
|
+
write:
|
|
122
|
+
|
|
123
|
+
> ✅ `"Bare-id lineage is unreadable" (7a7d1a36) supersedes "Force-bypass on retarget" (2cc444ec)`
|
|
124
|
+
|
|
125
|
+
No extra lookup is needed — `get_decision_detail` returns `supersededDecisions[]` (each with a `summary` and a `depth`) and `intents[]` with titles, already resolved.
|
|
126
|
+
|
|
127
|
+
Passing IDs back in follows the same rule: `record_decision(supersedes: […])` requires **full** decision IDs, and a truncated prefix is rejected rather than guessed at.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
108
131
|
## Committing pre-existing changes
|
|
109
132
|
|
|
110
133
|
When uncommitted changes exist that weren't made under an active intent:
|
package/README.md
CHANGED
|
@@ -104,7 +104,7 @@ Disable telemetry with `KAWA_PRE_EDIT_TELEMETRY=off`.
|
|
|
104
104
|
|
|
105
105
|
## Key Features
|
|
106
106
|
|
|
107
|
-
- **Real-time team conflict detection** — see when a teammate is editing the same files or lines in their working copy, *before either of you commits*. Most version-control tooling shows you this after the merge conflict; Kawa shows you before.
|
|
107
|
+
- **Real-time team conflict detection** — see when a teammate is editing the same files or lines in their working copy, *before either of you commits*. Most version-control tooling shows you this after the merge conflict; Kawa shows you before. Kawa can also *judge* an overlap and apply the safe tier of merge for you — though that write only happens [in an agent-owned worktree](#auto-resolution-requires-a-worktree).
|
|
108
108
|
- **Cross-session AI memory** — your AI assistant picks up where it left off across days, branches, and machines. No re-explaining the architecture every morning.
|
|
109
109
|
- **Decision history with reasoning** — record forks, trade-offs, and abandoned approaches with their *why*. Future sessions and teammates inherit the context instead of re-deriving it.
|
|
110
110
|
- **Commit ↔ intent linkage** — every commit is automatically associated with the intent that drove it. `git log` shows what changed; Kawa shows why.
|
|
@@ -112,6 +112,49 @@ Disable telemetry with `KAWA_PRE_EDIT_TELEMETRY=off`.
|
|
|
112
112
|
- **Zero-knowledge encryption** — code blocks encrypted client-side before sync. The Kawa cloud cannot decrypt your team's code.
|
|
113
113
|
- **Cross-platform** — works with Claude Code, Cursor, and any MCP-compatible AI assistant.
|
|
114
114
|
|
|
115
|
+
## Running several agents in parallel
|
|
116
|
+
|
|
117
|
+
Kawa Code is built for more than one worker on a repository at a time — that's what the conflict detection is *for*. If those workers are AI agents you're running yourself, give each one its own [git worktree](https://git-scm.com/docs/git-worktree). Agents sharing a single checkout overwrite each other's edits with no conflict marker and no git history: nothing is committed between the two writes, so nothing notices.
|
|
118
|
+
|
|
119
|
+
### Set up worktrees
|
|
120
|
+
|
|
121
|
+
In Claude Code, background sessions already require a worktree — `worktree.bgIsolation` defaults to `"worktree"`, which blocks edits to the main checkout until the session enters one. You only need to touch it if a project has explicitly opted out with `"none"`. Subagents take `isolation: "worktree"` per spawn.
|
|
122
|
+
|
|
123
|
+
Two settings are worth tuning, because the defaults surprise people:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"worktree": {
|
|
128
|
+
"baseRef": "head",
|
|
129
|
+
"symlinkDirectories": ["node_modules", "target"]
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
- **`baseRef`** — defaults to `"fresh"`, which branches from `origin/<default-branch>`. If you work on unpushed commits, set `"head"` to branch from your local HEAD instead. Either way this is a *commit* boundary: uncommitted working-tree changes don't travel into a new worktree, so land your work before spawning agents that need it.
|
|
135
|
+
- **`symlinkDirectories`** — nothing is symlinked unless you say so, so every worktree gets its own copy of whatever you leave out. Symlink *dependency* directories freely: `node_modules` is the same content for every worktree, and sharing it costs nothing. **Do not symlink compiled-language build output** — `target/`, `build/`, `obj/`. Those tools name artifacts deterministically from the crate/module and its inputs, *without* encoding which checkout they came from, so two worktrees building into one directory write the same filenames and silently overwrite each other. The symptom is the dangerous part: your suite goes **green while running another checkout's binaries**. Only a test that resolves a path baked in at compile time (Rust's `env!("CARGO_MANIFEST_DIR")`, `include_str!`, or an equivalent) will notice; everything else passes. If a suite ever looks suspiciously green after another checkout built in the same place, clean the build directory and re-run before believing it.
|
|
136
|
+
|
|
137
|
+
Because compiled build directories can't be shared, they multiply — one per worktree, each growing independently, and they get large enough to matter (a mature Rust `target/` reaches hundreds of gigabytes). Two things keep that affordable, and they solve different halves:
|
|
138
|
+
|
|
139
|
+
- **Speed** — a compiler cache such as [`sccache`](https://github.com/mozilla/sccache) is safe across worktrees precisely because it caches *results* keyed by input hash rather than sharing an output directory.
|
|
140
|
+
- **Disk** — prune periodically. For Rust, [`cargo-sweep`](https://github.com/holmgr/cargo-sweep) removes stale artifacts by age or to a size cap; wire it into whatever cadence fits your setup — after merging a worktree back is a natural trigger. One caveat worth knowing before you rely on it: sweeping only reclaims artifacts the build tool still tracks. If that index has been lost, the leftovers are orphaned and a sweep reports nothing to do no matter the flags — a full clean is the only thing that reclaims them.
|
|
141
|
+
|
|
142
|
+
### Keeping agents from colliding
|
|
143
|
+
|
|
144
|
+
Isolation alone would just give you several agents doing overlapping work in private. Kawa's job is the coordination on top.
|
|
145
|
+
|
|
146
|
+
Each agent session gets its own identity, and intents are tracked **per session** — so several intents can be active on one repository at once, each with its own current focus, without a lock and without agents clobbering each other's context. From there the normal machinery applies across agents exactly as it does across teammates: `get_relevant_context` surfaces what the *other* agents have already decided, `create_and_activate_intent` reports a conflict when new work overlaps something already in flight, and the pre-edit check fires on reasoning any of them recorded.
|
|
147
|
+
|
|
148
|
+
The practical result: your agents inherit each other's decisions instead of re-deriving them, and you find out about overlapping work while it's still cheap to redirect — not at merge time.
|
|
149
|
+
|
|
150
|
+
### Auto-resolution requires a worktree
|
|
151
|
+
|
|
152
|
+
Kawa can do more than *report* an overlap — `arbiter_resolve` judges each one, and `arbiter_apply` will write the safe tier of merge for you. That write is deliberately gated:
|
|
153
|
+
|
|
154
|
+
> `arbiter_apply` writes **only in an agent-owned worktree**. On a human checkout — or when a peer holds the file-set lock — it stays suggest-only.
|
|
155
|
+
|
|
156
|
+
This is the sharpest practical reason to put agents in worktrees. Run them on a shared checkout and auto-resolution silently never engages; you get the conflict surfaced and nothing else, with no error to tell you a capability was switched off. The guardrail is intentional — Kawa won't rewrite a human's working tree underneath them — but it does mean the setup decides whether half the feature is available.
|
|
157
|
+
|
|
115
158
|
## Handing off work to a teammate (no session export)
|
|
116
159
|
|
|
117
160
|
Because the reasoning behind your work — your intents and recorded decisions — lives in Kawa Code rather than in the chat log, a teammate can pick up where you left off from a single prompt. No transcript sharing, no session restore.
|
|
@@ -143,6 +186,50 @@ The payoff compounds: the port doesn't re-litigate settled arguments or faithful
|
|
|
143
186
|
|
|
144
187
|
The [CLAUDE.md template](./CLAUDE.md.example) ships a compact version of this workflow, so agents set up through the Kawa Code welcome flow follow it automatically.
|
|
145
188
|
|
|
189
|
+
## Occasional operations
|
|
190
|
+
|
|
191
|
+
Most Kawa tools run every turn — check the active intent, recall context, record a decision. The operations below are different: you run them **rarely**, sometimes once per repository. They cost real time and money, and they are not part of the per-turn loop.
|
|
192
|
+
|
|
193
|
+
### Seeding a repo from its git history — `infer_history`
|
|
194
|
+
|
|
195
|
+
A brand-new Kawa repo knows nothing about work that predates it. `infer_history` mines the existing commit history into intents and decisions, so recall has something to draw on from day one. Run it **once** when you connect a repo with meaningful history; after that it extends incrementally.
|
|
196
|
+
|
|
197
|
+
It is agent-invoked — ask your assistant, e.g. *"Run infer_history with max 3000 commits"*. There is no button for it in the Kawa Code app.
|
|
198
|
+
|
|
199
|
+
**Always estimate first.** The tool defaults to `estimateOnly: true`, which returns a token/cost preview without running anything. Look at the number, then re-run with `estimateOnly: false` to actually start. A run is asynchronous — it returns immediately and reports progress in the Kawa Code app — and resumes from where it stopped if interrupted.
|
|
200
|
+
|
|
201
|
+
| Parameter | Default | Purpose |
|
|
202
|
+
|---|---|---|
|
|
203
|
+
| `estimateOnly` | `true` | Preview cost without running. Set `false` to execute. |
|
|
204
|
+
| `commits` | resume | How many recent commits to analyze. Omit to continue from the last run. |
|
|
205
|
+
| `commitRange` | — | Git revspec (`sha1..sha2`, `branch1..branch2`, `sha1^!`) for a specific window. Mutually exclusive with `commits`. Good for backfilling a PR or recovering a dropped batch. |
|
|
206
|
+
| `contextIssues` | `false` | Pull in PR/MR descriptions and issue discussions. Needs an authenticated `gh` or `glab`; silently skipped otherwise. |
|
|
207
|
+
| `allowCommitSplitting` | `false` | Enable when one commit often mixes unrelated changes. |
|
|
208
|
+
| `maxStories` | — | Per-run cap on stories analyzed. |
|
|
209
|
+
| `model` | — | Affects the **estimate only**. The run's model is configured in the Kawa Code app. |
|
|
210
|
+
| `force` | `false` | Override the re-run guard — see below. |
|
|
211
|
+
|
|
212
|
+
**The re-run guard.** If the repo already has intents and the run can't cleanly resume (missing or unreachable cursor), or `HEAD` isn't on the default branch, the call stops and returns `needsDecision` instead of running. That's deliberate: re-running blind duplicates intents. Read the reason, and only pass `force: true` if it genuinely applies. Prefer running on `main`/`master`; `force` exists for the deliberate feature-branch case.
|
|
213
|
+
|
|
214
|
+
GitHub and GitLab are both supported; the forge is detected from the remote origin.
|
|
215
|
+
|
|
216
|
+
### Decision evolution — automatic, no call needed
|
|
217
|
+
|
|
218
|
+
Curating decisions into an evolution graph is **phase 5 of `infer_history`**, run automatically once the analysis completes. There is no separate step and nothing to invoke.
|
|
219
|
+
|
|
220
|
+
> Earlier versions exposed an `evolve_decisions` tool. It has been removed: it required a `stories` array that only ever existed inside the pipeline's own memory, so no assistant could construct a valid call. Nothing is lost — the curation still runs, as part of `infer_history`.
|
|
221
|
+
|
|
222
|
+
### Updating the feature catalog — use the Features panel
|
|
223
|
+
|
|
224
|
+
Features group a repo's intents into a browsable catalog. Rebuild it from the **Features** panel in the Kawa Code app:
|
|
225
|
+
|
|
226
|
+
- **Update features** — additive. Folds intents that aren't in the catalog yet into the existing features. This is the everyday action.
|
|
227
|
+
- **Rebuild** — cold rebuild from scratch, keeping locked features. Use when the catalog has drifted badly.
|
|
228
|
+
|
|
229
|
+
Progress shows in the app, and the catalog also extends automatically after an `infer_history` run.
|
|
230
|
+
|
|
231
|
+
> Earlier versions exposed an `update_features` MCP tool that sent the same request as the **Update features** button. It has been removed — one button and one tool doing the identical thing meant every session paid for a tool schema it never needed. Press the button instead.
|
|
232
|
+
|
|
146
233
|
## Development
|
|
147
234
|
|
|
148
235
|
```bash
|
package/build/index.js
CHANGED
|
@@ -3,8 +3,8 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
|
3
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
4
|
import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
5
5
|
import { connectToMuninn, ensureRepo } from './services/muninn-ipc.js';
|
|
6
|
-
import {
|
|
7
|
-
import { allTools, getRelevantContext, checkActiveIntent, createAndActivateIntent, activateIntent, resumeIntent, getIntentsForFile,
|
|
6
|
+
import { resolveMangledArgs, describeChainedArgs } from './tools/_mangled-args.js';
|
|
7
|
+
import { allTools, getRelevantContext, checkActiveIntent, createAndActivateIntent, activateIntent, resumeIntent, getIntentsForFile, listTeamIntents, completeIntent, updateIntent, logWork, recordDecision, getSessionDecisions, getProjectDecisions, getDecisionDetail, editSessionDecision, detectIntentConflicts, inferHistory, preEditDecisionCheck, preEditAcknowledge, getResolutionContext, arbiterResolve, arbiterApply } from './tools/index.js';
|
|
8
8
|
import { prompts } from './prompts/intent-first-workflow.js';
|
|
9
9
|
import { resources, readActiveIntentResource } from './resources/active-intent.js';
|
|
10
10
|
// Create MCP server
|
|
@@ -46,15 +46,29 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
46
46
|
// A malformed tool-call block (a parameter closed with `</fieldName>` instead
|
|
47
47
|
// of the required closing tag, followed by one opened without the required
|
|
48
48
|
// prefix) makes the harness fold the next field's name AND value into the
|
|
49
|
-
// preceding string.
|
|
50
|
-
//
|
|
49
|
+
// preceding string. One seam covers every tool. A single absorbed field is
|
|
50
|
+
// put back mechanically; a chain is refused rather than reconstructed, so the
|
|
51
|
+
// model re-emits. Both outcomes are logged. See _mangled-args.ts.
|
|
51
52
|
let args = rawArgs;
|
|
52
53
|
const schema = allTools.find(t => t.name === name)?.inputSchema;
|
|
53
54
|
if (args && typeof args === 'object' && schema) {
|
|
54
|
-
const { args: repaired, salvaged } =
|
|
55
|
+
const { args: repaired, salvaged, chained } = resolveMangledArgs(args, Object.keys(schema.shape));
|
|
56
|
+
if (chained.length > 0) {
|
|
57
|
+
const message = describeChainedArgs(name, chained);
|
|
58
|
+
// stderr only — stdout is the MCP transport.
|
|
59
|
+
console.error(`[MuninnIPC] ${message}`);
|
|
60
|
+
return {
|
|
61
|
+
content: [
|
|
62
|
+
{
|
|
63
|
+
type: 'text',
|
|
64
|
+
text: JSON.stringify({ success: false, error: message, tool: name }, null, 2),
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
isError: true,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
55
70
|
if (salvaged.length > 0) {
|
|
56
71
|
args = repaired;
|
|
57
|
-
// stderr only — stdout is the MCP transport.
|
|
58
72
|
console.error(`[MuninnIPC] Recovered ${salvaged.length} malformed argument(s) for ${name}: ` +
|
|
59
73
|
salvaged.map(s => `${s.field} (absorbed by ${s.fromField})`).join(', '));
|
|
60
74
|
}
|
|
@@ -84,9 +98,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
84
98
|
case 'get_intents_for_file':
|
|
85
99
|
result = await getIntentsForFile(args);
|
|
86
100
|
break;
|
|
87
|
-
case 'get_intents_for_lines':
|
|
88
|
-
result = await getIntentsForLines(args);
|
|
89
|
-
break;
|
|
90
101
|
case 'list_team_intents':
|
|
91
102
|
result = await listTeamIntents(args);
|
|
92
103
|
break;
|
|
@@ -120,12 +131,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
120
131
|
case 'infer_history':
|
|
121
132
|
result = await inferHistory(args);
|
|
122
133
|
break;
|
|
123
|
-
case 'evolve_decisions':
|
|
124
|
-
result = await evolveDecisions(args);
|
|
125
|
-
break;
|
|
126
|
-
case 'update_features':
|
|
127
|
-
result = await updateFeatures(args);
|
|
128
|
-
break;
|
|
129
134
|
case 'pre_edit_decision_check':
|
|
130
135
|
result = await preEditDecisionCheck(args);
|
|
131
136
|
break;
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,EACzB,SAAS,EACT,QAAQ,EACT,MAAM,oCAAoC,CAAA;AAE3C,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,EACzB,SAAS,EACT,QAAQ,EACT,MAAM,oCAAoC,CAAA;AAE3C,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACtE,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAElF,OAAO,EACL,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACvB,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,YAAY,EACZ,OAAO,EACP,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,YAAY,EACb,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,OAAO,EAA6B,MAAM,oCAAoC,CAAA;AACvF,OAAO,EAAE,SAAS,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAA;AAElF,oBAAoB;AACpB,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;IACE,IAAI,EAAE,cAAc;IACpB,OAAO,EAAE,OAAO;CACjB,EACD;IACE,YAAY,EAAE;QACZ,KAAK,EAAE,EAAE;QACT,OAAO,EAAE,EAAE;QACX,SAAS,EAAE,EAAE;KACd;CACF,CACF,CAAA;AAED,sBAAsB;AACtB,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;IAC1D,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,WAAW,EAAE;gBACX,IAAI,EAAE,QAAiB;gBACvB,UAAU,EAAE,MAAM,CAAC,WAAW,CAC5B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;oBAC3D,GAAG;oBACH;wBACE,GAAG,YAAY,CAAC,KAAK,CAAC;wBACtB,WAAW,EAAG,KAAa,CAAC,IAAI,EAAE,WAAW,IAAI,EAAE;qBACpD;iBACF,CAAC,CACH;gBACD,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;qBAC7C,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;qBACzC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC;aACvB;SACF,CAAC,CAAC;KACJ,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,oBAAoB;AACpB,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,CAAA;IAEnD,8EAA8E;IAC9E,2EAA2E;IAC3E,0EAA0E;IAC1E,2EAA2E;IAC3E,8EAA8E;IAC9E,kEAAkE;IAClE,IAAI,IAAI,GAAG,OAAO,CAAA;IAClB,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,WAAW,CAAA;IAC/D,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,EAAE,CAAC;QAC/C,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,kBAAkB,CAC9D,IAA+B,EAC/B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAC1B,CAAA;QACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;YAClD,6CAA6C;YAC7C,OAAO,CAAC,KAAK,CAAC,eAAe,OAAO,EAAE,CAAC,CAAA;YACvC,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;qBAC9E;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAA;QACH,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,IAAI,GAAG,QAAQ,CAAA;YACf,OAAO,CAAC,KAAK,CACX,yBAAyB,QAAQ,CAAC,MAAM,8BAA8B,IAAI,IAAI;gBAC5E,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,iBAAiB,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAC1E,CAAA;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAI,IAAY,EAAE,QAAQ,CAAA;QACxC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAA;QAC5B,CAAC;QAED,IAAI,MAAW,CAAA;QAEf,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,sBAAsB;gBACzB,MAAM,GAAG,MAAM,kBAAkB,CAAC,IAAW,CAAC,CAAA;gBAC9C,MAAK;YACP,KAAK,qBAAqB;gBACxB,MAAM,GAAG,MAAM,iBAAiB,CAAC,IAAW,CAAC,CAAA;gBAC7C,MAAK;YACP,KAAK,4BAA4B;gBAC/B,MAAM,GAAG,MAAM,uBAAuB,CAAC,IAAW,CAAC,CAAA;gBACnD,MAAK;YACP,KAAK,iBAAiB;gBACpB,MAAM,GAAG,MAAM,cAAc,CAAC,IAAW,CAAC,CAAA;gBAC1C,MAAK;YACP,KAAK,eAAe;gBAClB,MAAM,GAAG,MAAM,YAAY,CAAC,IAAW,CAAC,CAAA;gBACxC,MAAK;YACP,KAAK,sBAAsB;gBACzB,MAAM,GAAG,MAAM,iBAAiB,CAAC,IAAW,CAAC,CAAA;gBAC7C,MAAK;YACP,KAAK,mBAAmB;gBACtB,MAAM,GAAG,MAAM,eAAe,CAAC,IAAW,CAAC,CAAA;gBAC3C,MAAK;YACP,KAAK,iBAAiB;gBACpB,MAAM,GAAG,MAAM,cAAc,CAAC,IAAW,CAAC,CAAA;gBAC1C,MAAK;YACP,KAAK,eAAe;gBAClB,MAAM,GAAG,MAAM,YAAY,CAAC,IAAW,CAAC,CAAA;gBACxC,MAAK;YACP,KAAK,UAAU;gBACb,MAAM,GAAG,MAAM,OAAO,CAAC,IAAW,CAAC,CAAA;gBACnC,MAAK;YACP,KAAK,iBAAiB;gBACpB,MAAM,GAAG,MAAM,cAAc,CAAC,IAAW,CAAC,CAAA;gBAC1C,MAAK;YACP,KAAK,uBAAuB;gBAC1B,MAAM,GAAG,MAAM,mBAAmB,CAAC,IAAW,CAAC,CAAA;gBAC/C,MAAK;YACP,KAAK,uBAAuB;gBAC1B,MAAM,GAAG,MAAM,mBAAmB,CAAC,IAAW,CAAC,CAAA;gBAC/C,MAAK;YACP,KAAK,qBAAqB;gBACxB,MAAM,GAAG,MAAM,iBAAiB,CAAC,IAAW,CAAC,CAAA;gBAC7C,MAAK;YACP,KAAK,uBAAuB;gBAC1B,MAAM,GAAG,MAAM,mBAAmB,CAAC,IAAW,CAAC,CAAA;gBAC/C,MAAK;YACP,KAAK,yBAAyB;gBAC5B,MAAM,GAAG,MAAM,qBAAqB,CAAC,IAAW,CAAC,CAAA;gBACjD,MAAK;YACP,KAAK,eAAe;gBAClB,MAAM,GAAG,MAAM,YAAY,CAAC,IAAW,CAAC,CAAA;gBACxC,MAAK;YACP,KAAK,yBAAyB;gBAC5B,MAAM,GAAG,MAAM,oBAAoB,CAAC,IAAW,CAAC,CAAA;gBAChD,MAAK;YACP,KAAK,sBAAsB;gBACzB,MAAM,GAAG,MAAM,kBAAkB,CAAC,IAAW,CAAC,CAAA;gBAC9C,MAAK;YACP,KAAK,wBAAwB;gBAC3B,MAAM,GAAG,MAAM,oBAAoB,CAAC,IAAW,CAAC,CAAA;gBAChD,MAAK;YACP,KAAK,iBAAiB;gBACpB,MAAM,GAAG,MAAM,cAAc,CAAC,IAAW,CAAC,CAAA;gBAC1C,MAAK;YACP,KAAK,eAAe;gBAClB,MAAM,GAAG,MAAM,YAAY,CAAC,IAAW,CAAC,CAAA;gBACxC,MAAK;YACP;gBACE,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,iBAAiB,IAAI,EAAE,CAAC,CAAA;QACzE,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;iBACtC;aACF;SACF,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,yEAAyE;QACzE,uEAAuE;QACvE,4DAA4D;QAC5D,qEAAqE;QACrE,4BAA4B;QAC5B,IAAI,KAAK,YAAY,QAAQ;YAAE,MAAM,KAAK,CAAA;QAC1C,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAA;QAChF,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,OAAO;wBACd,IAAI,EAAE,IAAI;qBACX,EAAE,IAAI,EAAE,CAAC,CAAC;iBACZ;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAA;IACH,CAAC;AACH,CAAC,CAAC,CAAA;AAEF,wBAAwB;AACxB,MAAM,CAAC,iBAAiB,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;IAC5D,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACzB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,SAAS,EAAE,CAAC,CAAC,SAAS;SACvB,CAAC,CAAC;KACJ,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,0BAA0B;AAC1B,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IACjE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAA;IAEhD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;IACjD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,mBAAmB,IAAI,EAAE,CAAC,CAAA;IACzE,CAAC;IAED,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,IAAW,CAAC;iBACpC;aACF;SACF;KACF,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,0BAA0B;AAC1B,MAAM,CAAC,iBAAiB,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;IAC9D,OAAO;QACL,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC7B,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,QAAQ,EAAE,CAAC,CAAC,QAAQ;SACrB,CAAC,CAAC;KACJ,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,0BAA0B;AAC1B,MAAM,CAAC,iBAAiB,CAAC,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IACpE,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,MAAM,CAAA;IAE9B,IAAI,GAAG,KAAK,sBAAsB,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,wBAAwB,EAAE,CAAA;QAChD,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG;oBACH,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,OAAO;iBACd;aACF;SACF,CAAA;IACH,CAAC;IAED,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,qBAAqB,GAAG,EAAE,CAAC,CAAA;AAC1E,CAAC,CAAC,CAAA;AAEF,8DAA8D;AAC9D,SAAS,YAAY,CAAC,OAAY;IAChC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvC,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;QAC3B,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;QAC3B,KAAK,YAAY;YACf,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;QAC5B,KAAK,UAAU;YACb,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;QAClE,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;QAC3B,KAAK,SAAS;YACZ,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAA;QACtD,KAAK,aAAa,CAAC;QACnB,KAAK,YAAY;YACf,OAAO,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC7C,KAAK,QAAQ,CAAC;QACd,KAAK,YAAY,CAAC;QAClB,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;QAC3B;YACE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;IAC7B,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,OAAY;IAC9B,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvC,OAAO,QAAQ,KAAK,aAAa,IAAI,QAAQ,KAAK,YAAY,CAAA;AAChE,CAAC;AAED,mBAAmB;AACnB,KAAK,UAAU,IAAI;IACjB,sDAAsD;IACtD,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAA;IAEtE,kDAAkD;IAClD,IAAI,CAAC;QACH,MAAM,eAAe,EAAE,CAAA;QACvB,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAA;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,YAAa,GAAa,CAAC,OAAO,EAAE,CAAC,CAAA;QACnD,OAAO,CAAC,KAAK,CAAC,oEAAoE,CAAC,CAAA;IACrF,CAAC;IAED,4BAA4B;IAC5B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAA;IAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAE/B,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAA;AAClD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;IACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
|
|
@@ -182,8 +182,7 @@ For each group:
|
|
|
182
182
|
|------|-------------|
|
|
183
183
|
| \`check_active_intent\` | Before starting any code task |
|
|
184
184
|
| \`create_and_activate_intent\` | When no active intent and user requests code changes |
|
|
185
|
-
| \`get_intents_for_file\` | Before modifying files (check for team conflicts) |
|
|
186
|
-
| \`get_intents_for_lines\` | Before modifying specific line ranges |
|
|
185
|
+
| \`get_intents_for_file\` | Before modifying files (check for team conflicts); add \`startLine\`/\`endLine\` for a specific range |
|
|
187
186
|
| \`complete_intent\` | After successful git commit, or to abandon |
|
|
188
187
|
| \`list_team_intents\` | To see what teammates are working on |
|
|
189
188
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intent-first-workflow.js","sourceRoot":"","sources":["../../src/prompts/intent-first-workflow.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,IAAI,EAAE,yBAAyB;IAC/B,WAAW,EAAE,4HAA4H;IACzI,SAAS,EAAE;QACT;YACE,IAAI,EAAE,kBAAkB;YACxB,WAAW,EAAE,uDAAuD;YACpE,QAAQ,EAAE,KAAK;SAChB;KACF;IACD,SAAS,EAAE,CAAC,IAAoC,EAAE,EAAE;QAClD,MAAM,WAAW,GAAG,IAAI,EAAE,gBAAgB;YACxC,CAAC,CAAC,yBAAyB,IAAI,CAAC,gBAAgB,EAAE;YAClD,CAAC,CAAC,EAAE,CAAA;QAEN,OAAO,qCAAqC,WAAW
|
|
1
|
+
{"version":3,"file":"intent-first-workflow.js","sourceRoot":"","sources":["../../src/prompts/intent-first-workflow.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,IAAI,EAAE,yBAAyB;IAC/B,WAAW,EAAE,4HAA4H;IACzI,SAAS,EAAE;QACT;YACE,IAAI,EAAE,kBAAkB;YACxB,WAAW,EAAE,uDAAuD;YACpE,QAAQ,EAAE,KAAK;SAChB;KACF;IACD,SAAS,EAAE,CAAC,IAAoC,EAAE,EAAE;QAClD,MAAM,WAAW,GAAG,IAAI,EAAE,gBAAgB;YACxC,CAAC,CAAC,yBAAyB,IAAI,CAAC,gBAAgB,EAAE;YAClD,CAAC,CAAC,EAAE,CAAA;QAEN,OAAO,qCAAqC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4FAsLiC,CAAA;IAC1F,CAAC;CACF,CAAA;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,yBAAyB,CAAC,CAAA"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handling for tool-call args mangled by a mis-closed parameter tag.
|
|
3
|
+
*
|
|
4
|
+
* When an LLM emits a parameter block that is opened correctly but closed with
|
|
5
|
+
* `</fieldName>` instead of the required closing tag — and the NEXT parameter is
|
|
6
|
+
* opened without the required prefix — the harness's tool-call parser never sees
|
|
7
|
+
* a parameter boundary. Everything up to the next well-formed close is folded
|
|
8
|
+
* into the preceding field's string value. What reaches this process is
|
|
9
|
+
* perfectly valid JSON in which one field carries a self-describing tail:
|
|
10
|
+
*
|
|
11
|
+
* { consequences: 'real text</consequences>\n<parameter name="symptom">real symptom' }
|
|
12
|
+
*
|
|
13
|
+
* Still live: reproduced end-to-end on 2026-08-04, and it fired twice in the
|
|
14
|
+
* session that reworked this module. It is model-side and provider-universal, so
|
|
15
|
+
* no amount of prompt discipline retires it.
|
|
16
|
+
*
|
|
17
|
+
* TWO OUTCOMES, deliberately split:
|
|
18
|
+
*
|
|
19
|
+
* - ONE absorbed field. Losslessly recoverable — the tail names its field and
|
|
20
|
+
* carries that field's value verbatim, with nothing left over. Repaired here.
|
|
21
|
+
* This is a compensating path, which the project otherwise forbids; it is
|
|
22
|
+
* accepted because the alternative is silent corruption of records that
|
|
23
|
+
* become immutable on sync, and because the recovery is mechanical rather
|
|
24
|
+
* than inferred.
|
|
25
|
+
*
|
|
26
|
+
* - A CHAIN (the absorbed value itself carries further markup). Recovering it
|
|
27
|
+
* means deciding where one value ends and the next begins across forms that
|
|
28
|
+
* vary — inner parameters closed correctly, emissions cut off mid-tag,
|
|
29
|
+
* trailing block closers. That is reconstruction, not recovery, so it is
|
|
30
|
+
* refused instead: the caller rejects the tool call and the model re-emits.
|
|
31
|
+
*
|
|
32
|
+
* Every outcome is logged by the caller. Nothing here is silent.
|
|
33
|
+
*/
|
|
34
|
+
export interface SalvageEntry {
|
|
35
|
+
/** The field whose value was recovered. */
|
|
36
|
+
field: string;
|
|
37
|
+
/** The field that had absorbed it. */
|
|
38
|
+
fromField: string;
|
|
39
|
+
}
|
|
40
|
+
export interface ChainedEntry {
|
|
41
|
+
/** The field whose string absorbed the rest of the emission. */
|
|
42
|
+
field: string;
|
|
43
|
+
/** The first field named in the tail. */
|
|
44
|
+
absorbed: string;
|
|
45
|
+
}
|
|
46
|
+
export interface MangledArgsResult {
|
|
47
|
+
/** `args` with every single-field absorption undone. Never partially chained. */
|
|
48
|
+
args: Record<string, unknown>;
|
|
49
|
+
/** Recoveries applied. */
|
|
50
|
+
salvaged: SalvageEntry[];
|
|
51
|
+
/** Chains found. Non-empty means the caller must refuse the tool call. */
|
|
52
|
+
chained: ChainedEntry[];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Undo single-field absorptions in `args` and report chains. Returns a new
|
|
56
|
+
* object; `args` is untouched.
|
|
57
|
+
*
|
|
58
|
+
* `knownFields` are the schema field names of the tool being called — neither
|
|
59
|
+
* recovery nor refusal is triggered by a tail naming anything outside that set.
|
|
60
|
+
*/
|
|
61
|
+
export declare function resolveMangledArgs(args: Record<string, unknown>, knownFields: readonly string[]): MangledArgsResult;
|
|
62
|
+
/** Operator-readable refusal naming what to re-send. */
|
|
63
|
+
export declare function describeChainedArgs(name: string, chained: readonly ChainedEntry[]): string;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handling for tool-call args mangled by a mis-closed parameter tag.
|
|
3
|
+
*
|
|
4
|
+
* When an LLM emits a parameter block that is opened correctly but closed with
|
|
5
|
+
* `</fieldName>` instead of the required closing tag — and the NEXT parameter is
|
|
6
|
+
* opened without the required prefix — the harness's tool-call parser never sees
|
|
7
|
+
* a parameter boundary. Everything up to the next well-formed close is folded
|
|
8
|
+
* into the preceding field's string value. What reaches this process is
|
|
9
|
+
* perfectly valid JSON in which one field carries a self-describing tail:
|
|
10
|
+
*
|
|
11
|
+
* { consequences: 'real text</consequences>\n<parameter name="symptom">real symptom' }
|
|
12
|
+
*
|
|
13
|
+
* Still live: reproduced end-to-end on 2026-08-04, and it fired twice in the
|
|
14
|
+
* session that reworked this module. It is model-side and provider-universal, so
|
|
15
|
+
* no amount of prompt discipline retires it.
|
|
16
|
+
*
|
|
17
|
+
* TWO OUTCOMES, deliberately split:
|
|
18
|
+
*
|
|
19
|
+
* - ONE absorbed field. Losslessly recoverable — the tail names its field and
|
|
20
|
+
* carries that field's value verbatim, with nothing left over. Repaired here.
|
|
21
|
+
* This is a compensating path, which the project otherwise forbids; it is
|
|
22
|
+
* accepted because the alternative is silent corruption of records that
|
|
23
|
+
* become immutable on sync, and because the recovery is mechanical rather
|
|
24
|
+
* than inferred.
|
|
25
|
+
*
|
|
26
|
+
* - A CHAIN (the absorbed value itself carries further markup). Recovering it
|
|
27
|
+
* means deciding where one value ends and the next begins across forms that
|
|
28
|
+
* vary — inner parameters closed correctly, emissions cut off mid-tag,
|
|
29
|
+
* trailing block closers. That is reconstruction, not recovery, so it is
|
|
30
|
+
* refused instead: the caller rejects the tool call and the model re-emits.
|
|
31
|
+
*
|
|
32
|
+
* Every outcome is logged by the caller. Nothing here is silent.
|
|
33
|
+
*/
|
|
34
|
+
/** `</host>` + optional whitespace + a parameter opening + everything after it. */
|
|
35
|
+
const MANGLED_TAIL = /<\/([A-Za-z_][\w-]*)>\s*<parameter name="([A-Za-z_]\w*)">([\s\S]*)$/;
|
|
36
|
+
/**
|
|
37
|
+
* Any residue in a recovered value means the emission carried more than one
|
|
38
|
+
* absorbed field — a further parameter, its own closing tag, or an opening cut
|
|
39
|
+
* off mid-tag.
|
|
40
|
+
*/
|
|
41
|
+
const RESIDUAL_MARKUP = /<parameter name="|<\/[A-Za-z_][\w-]*>|<[A-Za-z]*$/;
|
|
42
|
+
/**
|
|
43
|
+
* Arrays and objects arrive as JSON text; anything else is a plain string.
|
|
44
|
+
* Only attempt a parse when the value actually looks structured, so a string
|
|
45
|
+
* like "123" or "true" is never silently coerced to another type.
|
|
46
|
+
*/
|
|
47
|
+
function parseSalvagedValue(raw) {
|
|
48
|
+
const trimmed = raw.trim();
|
|
49
|
+
if (trimmed.startsWith('[') || trimmed.startsWith('{')) {
|
|
50
|
+
try {
|
|
51
|
+
return JSON.parse(trimmed);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Not valid JSON after all — keep the text rather than dropping it.
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return trimmed;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Undo single-field absorptions in `args` and report chains. Returns a new
|
|
61
|
+
* object; `args` is untouched.
|
|
62
|
+
*
|
|
63
|
+
* `knownFields` are the schema field names of the tool being called — neither
|
|
64
|
+
* recovery nor refusal is triggered by a tail naming anything outside that set.
|
|
65
|
+
*/
|
|
66
|
+
export function resolveMangledArgs(args, knownFields) {
|
|
67
|
+
const known = new Set(knownFields);
|
|
68
|
+
const out = { ...args };
|
|
69
|
+
const salvaged = [];
|
|
70
|
+
const chained = [];
|
|
71
|
+
for (const [hostField, hostValue] of Object.entries(args)) {
|
|
72
|
+
if (typeof hostValue !== 'string')
|
|
73
|
+
continue;
|
|
74
|
+
const match = hostValue.match(MANGLED_TAIL);
|
|
75
|
+
if (!match || match.index === undefined)
|
|
76
|
+
continue;
|
|
77
|
+
const [, closingTag, targetField, rawValue] = match;
|
|
78
|
+
// Three guards, all required. Any miss means this is probably genuine prose
|
|
79
|
+
// (a decision *documenting* this very bug legitimately contains these
|
|
80
|
+
// markers — two such records exist in prod), so leave it alone and let
|
|
81
|
+
// normal validation decide.
|
|
82
|
+
//
|
|
83
|
+
// 1. the bogus closing tag names the host field — evidence of a mis-closed
|
|
84
|
+
// host parameter rather than an incidental mention
|
|
85
|
+
if (closingTag !== hostField)
|
|
86
|
+
continue;
|
|
87
|
+
// 2. the absorbed field is real for this tool
|
|
88
|
+
if (!known.has(targetField))
|
|
89
|
+
continue;
|
|
90
|
+
// 3. it was not otherwise supplied — never overwrite genuine input
|
|
91
|
+
const existing = out[targetField];
|
|
92
|
+
if (existing !== undefined && existing !== null && existing !== '')
|
|
93
|
+
continue;
|
|
94
|
+
// Past the guards the field IS mangled. The only question left is whether
|
|
95
|
+
// the recovery is mechanical or a guess.
|
|
96
|
+
if (RESIDUAL_MARKUP.test(rawValue)) {
|
|
97
|
+
chained.push({ field: hostField, absorbed: targetField });
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
out[hostField] = hostValue.slice(0, match.index).trimEnd();
|
|
101
|
+
out[targetField] = parseSalvagedValue(rawValue);
|
|
102
|
+
salvaged.push({ field: targetField, fromField: hostField });
|
|
103
|
+
}
|
|
104
|
+
return { args: out, salvaged, chained };
|
|
105
|
+
}
|
|
106
|
+
/** Operator-readable refusal naming what to re-send. */
|
|
107
|
+
export function describeChainedArgs(name, chained) {
|
|
108
|
+
const detail = chained
|
|
109
|
+
.map(c => `"${c.field}" absorbed "${c.absorbed}" and at least one more field`)
|
|
110
|
+
.join('; ');
|
|
111
|
+
return (`Malformed tool call for ${name}: ${detail}. A parameter was closed with ` +
|
|
112
|
+
`</fieldName> instead of the required closing tag, so the parameters that ` +
|
|
113
|
+
`followed were folded into it. Too much was run together to separate safely, ` +
|
|
114
|
+
`so nothing was recorded. Re-send the call with every parameter closed correctly.`);
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=_mangled-args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_mangled-args.js","sourceRoot":"","sources":["../../src/tools/_mangled-args.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { resolveMangledArgs, describeChainedArgs } from './_mangled-args.js';
|
|
4
|
+
const FIELDS = [
|
|
5
|
+
'summary',
|
|
6
|
+
'rationale',
|
|
7
|
+
'consequences',
|
|
8
|
+
'symptom',
|
|
9
|
+
'appliesWhen',
|
|
10
|
+
'alternatives',
|
|
11
|
+
'relatedFiles',
|
|
12
|
+
'supersedes',
|
|
13
|
+
];
|
|
14
|
+
test('recovers a single string field absorbed by a mis-closed host parameter', () => {
|
|
15
|
+
const { args, salvaged, chained } = resolveMangledArgs({
|
|
16
|
+
consequences: 'Real consequences text.</consequences>\n<parameter name="symptom">Real symptom text.',
|
|
17
|
+
}, FIELDS);
|
|
18
|
+
assert.equal(args.consequences, 'Real consequences text.');
|
|
19
|
+
assert.equal(args.symptom, 'Real symptom text.');
|
|
20
|
+
assert.deepEqual(salvaged, [{ field: 'symptom', fromField: 'consequences' }]);
|
|
21
|
+
assert.deepEqual(chained, []);
|
|
22
|
+
});
|
|
23
|
+
test('JSON-parses an absorbed array value', () => {
|
|
24
|
+
const { args } = resolveMangledArgs({
|
|
25
|
+
consequences: 'Text.</consequences>\n<parameter name="alternatives">["option A", "option B"]',
|
|
26
|
+
}, FIELDS);
|
|
27
|
+
assert.equal(args.consequences, 'Text.');
|
|
28
|
+
assert.deepEqual(args.alternatives, ['option A', 'option B']);
|
|
29
|
+
});
|
|
30
|
+
test('refuses a chain instead of unwinding it', () => {
|
|
31
|
+
// Prod shape (decision 048c8de5): the inner parameter closed correctly, so the
|
|
32
|
+
// array and the next field ran together. Separating them is reconstruction.
|
|
33
|
+
const original = 'R text.</rationale>\n<parameter name="supersedes">["146172a8"]</parameter>\n<parameter name="alternatives">["keep DELETE on abandon"]';
|
|
34
|
+
const { args, salvaged, chained } = resolveMangledArgs({ rationale: original }, FIELDS);
|
|
35
|
+
assert.equal(args.rationale, original, 'left untouched — the caller refuses the call');
|
|
36
|
+
assert.equal(args.supersedes, undefined);
|
|
37
|
+
assert.deepEqual(salvaged, []);
|
|
38
|
+
assert.deepEqual(chained, [{ field: 'rationale', absorbed: 'supersedes' }]);
|
|
39
|
+
});
|
|
40
|
+
test('refuses when the recovered value keeps a trailing close tag', () => {
|
|
41
|
+
// Prod shape (decision e484aadb): the last field kept its own close plus the
|
|
42
|
+
// emission's block closers.
|
|
43
|
+
const { salvaged, chained } = resolveMangledArgs({
|
|
44
|
+
consequences: 'C text.</consequences>\n<parameter name="relatedFiles">["deploy.sh"]</parameter>\n</invoke>',
|
|
45
|
+
}, FIELDS);
|
|
46
|
+
assert.deepEqual(salvaged, []);
|
|
47
|
+
assert.equal(chained.length, 1);
|
|
48
|
+
});
|
|
49
|
+
test('refuses when the emission was cut off mid-tag', () => {
|
|
50
|
+
// Prod shape (decision 077c1809).
|
|
51
|
+
const { salvaged, chained } = resolveMangledArgs({ rationale: 'R text.</rationale>\n<parameter name="symptom">S text.</symptom>\n<paramet' }, FIELDS);
|
|
52
|
+
assert.deepEqual(salvaged, []);
|
|
53
|
+
assert.equal(chained.length, 1);
|
|
54
|
+
});
|
|
55
|
+
test('does NOT touch prose that merely mentions the markers', () => {
|
|
56
|
+
// A decision (or intent description) recorded *about* this bug. Two such
|
|
57
|
+
// records exist in prod and must keep passing through untouched.
|
|
58
|
+
const original = 'Docs: a value may end with </consequences>\n<parameter name="symptom">like so.';
|
|
59
|
+
const { args, salvaged, chained } = resolveMangledArgs({ rationale: original }, FIELDS);
|
|
60
|
+
assert.equal(args.rationale, original);
|
|
61
|
+
assert.equal(args.symptom, undefined);
|
|
62
|
+
assert.deepEqual(salvaged, []);
|
|
63
|
+
assert.deepEqual(chained, []);
|
|
64
|
+
});
|
|
65
|
+
test('does NOT act on an unknown target field', () => {
|
|
66
|
+
const original = 'Text.</consequences>\n<parameter name="notARealField">value';
|
|
67
|
+
const { args, salvaged, chained } = resolveMangledArgs({ consequences: original }, FIELDS);
|
|
68
|
+
assert.equal(args.consequences, original);
|
|
69
|
+
assert.deepEqual(salvaged, []);
|
|
70
|
+
assert.deepEqual(chained, []);
|
|
71
|
+
});
|
|
72
|
+
test('never overwrites a target the caller actually supplied', () => {
|
|
73
|
+
const original = 'Text.</consequences>\n<parameter name="symptom">absorbed symptom';
|
|
74
|
+
const { args, salvaged } = resolveMangledArgs({ consequences: original, symptom: 'genuine symptom' }, FIELDS);
|
|
75
|
+
assert.equal(args.symptom, 'genuine symptom');
|
|
76
|
+
assert.equal(args.consequences, original);
|
|
77
|
+
assert.deepEqual(salvaged, []);
|
|
78
|
+
});
|
|
79
|
+
test('leaves clean args untouched and reports nothing', () => {
|
|
80
|
+
const input = { summary: 'A summary', alternatives: ['x'], relatedFiles: ['a.ts'] };
|
|
81
|
+
const { args, salvaged, chained } = resolveMangledArgs(input, FIELDS);
|
|
82
|
+
assert.deepEqual(args, input);
|
|
83
|
+
assert.deepEqual(salvaged, []);
|
|
84
|
+
assert.deepEqual(chained, []);
|
|
85
|
+
});
|
|
86
|
+
test('does not mutate the caller-supplied args object', () => {
|
|
87
|
+
const input = {
|
|
88
|
+
consequences: 'Text.</consequences>\n<parameter name="symptom">S.',
|
|
89
|
+
};
|
|
90
|
+
resolveMangledArgs(input, FIELDS);
|
|
91
|
+
assert.equal(input.consequences, 'Text.</consequences>\n<parameter name="symptom">S.');
|
|
92
|
+
});
|
|
93
|
+
test('keeps the raw text when an absorbed structured value is not valid JSON', () => {
|
|
94
|
+
const { args } = resolveMangledArgs({ consequences: 'Text.</consequences>\n<parameter name="alternatives">[not, valid, json' }, FIELDS);
|
|
95
|
+
assert.equal(args.alternatives, '[not, valid, json');
|
|
96
|
+
});
|
|
97
|
+
test('ignores non-string fields', () => {
|
|
98
|
+
const { args, salvaged } = resolveMangledArgs({ relatedFiles: ['a.ts', 'b.ts'], summary: 'clean' }, FIELDS);
|
|
99
|
+
assert.deepEqual(args.relatedFiles, ['a.ts', 'b.ts']);
|
|
100
|
+
assert.deepEqual(salvaged, []);
|
|
101
|
+
});
|
|
102
|
+
test('the chained refusal names the host and the first absorbed field', () => {
|
|
103
|
+
const message = describeChainedArgs('record_decision', [
|
|
104
|
+
{ field: 'rationale', absorbed: 'supersedes' },
|
|
105
|
+
]);
|
|
106
|
+
assert.match(message, /record_decision/);
|
|
107
|
+
assert.match(message, /"rationale" absorbed "supersedes"/);
|
|
108
|
+
assert.match(message, /nothing was recorded/);
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=_mangled-args.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_mangled-args.test.js","sourceRoot":"","sources":["../../src/tools/_mangled-args.test.ts"],"names":[],"mappings":"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"}
|