{"calls": [], "exit_before_cleanup": null, "initialize": {"capabilities": {"prompts": {}, "resources": {}, "tools": {}}, "protocolVersion": "2025-11-25", "serverInfo": {"name": "kawa-intents", "version": "0.3.0"}}, "list_change_notifications": 0, "monotonic_seconds": 0.3519053350028116, "outcome": "listed tools offline", "started_utc": "2026-10-17T15:08:48.697651Z", "status": "completed", "tools": [{"description": "Find past intents and decisions relevant to the current user request.\n\nWhen to use:\n- After you have done a quick initial exploration of the user's request and know which files are involved. Calling earlier with only a vague prompt gives weak results.\n- To pull task-specific context instead of dumping all recent activity — preferred for large projects.\n\nInputs of note:\n- `prompt`: the user request, in their words or your paraphrase.\n- `activeFiles` (recommended): files you have identified as relevant to the request. Significantly improves relevance.\n- `maxIntents`, `maxDecisions`, `minRelevance`: result-shaping caps and threshold.\n\nReturns:\n- `relevantIntents`: past work units (intents) related to the task, scored by relevance.\n- `relevantDecisions`: prior decisions related to the task — both intent-scoped and repo-scoped. Summary-only (no inline rationale, to keep context lean); call `get_decision_detail(decisionId)` for the full rationale/context/consequences of any decision you want to open.\n\nRecommended sequence:\n1. `check_active_intent` at session start to resume any existing work.\n2. Briefly explore the user's request to identify involved files.\n3. `get_relevant_context` with the prompt and `activeFiles` to inform the approach.", "inputSchema": {"properties": {"activeFiles": {"description": "Files currently being discussed or recently opened", "items": {"type": "string"}, "type": "array"}, "maxDecisions": {"description": "Maximum number of decisions to return", "type": "number"}, "maxIntents": {"description": "Maximum number of intents to return", "type": "number"}, "minRelevance": {"description": "Minimum relevance score (0-1)", "type": "number"}, "prompt": {"description": "The user request to find relevant context for", "type": "string"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}}, "required": ["repoPath", "prompt"], "type": "object"}, "name": "get_relevant_context"}, {"description": "REQUIRED before writing any code. Returns this session's current intent; if there is none, confirm the details with the user and call create_and_activate_intent.\n\nIntents are active PER SESSION — many can be active on one repo at once. hasActiveIntent reflects only YOUR session, while activeIntents lists every session's current intent (yours and teammates') and may be non-empty when you have none. A stale intent stays \"active\"; terminal states are committed / pushed / done / abandoned / superseded.", "inputSchema": {"properties": {"repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}}, "required": ["repoPath"], "type": "object"}, "name": "check_active_intent"}, {"description": "Create a new intent from the user's request and mark it as active for THIS session.\n\nCall this when check_active_intent returns no active intent for your session. Before calling:\n1. Summarize what the user is asking for\n2. Ask the user to confirm the intent details (title, description, type)\n3. Then call this tool with the confirmed details\n\nThis ensures all AI-generated code gets properly tracked and attributed.\n\nMulti-active model: many intents can be active on a repo at once (one per\nsession/teammate). Creating + activating one only sets YOUR session's current\nfocus — it never blocks or displaces another session's active intent, so there\nis no lock conflict to resolve.\n\nIf the tool returns conflicts (action=\"conflict\"), it found an existing\nteam-member intent that overlaps semantically or in files. Present the conflict\ndetails to the user and ask whether to proceed. If yes, retry with force=true to\nbypass conflict detection.", "inputSchema": {"properties": {"constraints": {"description": "Requirements or constraints for this work", "items": {"type": "string"}, "type": "array"}, "description": {"description": "What this intent accomplishes", "type": "string"}, "force": {"description": "Bypass conflict detection. Set to true after the user has reviewed detected conflicts and chosen to proceed anyway.", "type": "boolean"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}, "templateType": {"description": "Type of work", "enum": ["feature", "refactor", "exploration"], "type": "string"}, "title": {"description": "Short, descriptive title for the intent", "type": "string"}}, "required": ["repoPath", "title", "description"], "type": "object"}, "name": "create_and_activate_intent"}, {"description": "Activate an existing intent by ID — sets it as THIS session's current focus.\n\nUse this to:\n- Switch your current focus to a different intent found via list_team_intents or get_relevant_context\n- Re-activate an intent that was deactivated (e.g., to complete it)\n- Resume work on a previously created intent\n- Resume an \"abandoned\" intent (see below)\n\nAccepts both cloud IDs (from get_relevant_context / API) and local UUIDs (from list_team_intents).\n\nMulti-active model: activating an intent only moves YOUR session's current\npointer. Many intents can be active on a repo at once (one current per\nsession/teammate), so this never blocks on or displaces another session's\nactive intent — there is no lock to take over.\n\nResuming abandoned intents:\n- Abandoned intents have their decisions soft-deleted (invisible to recall and\n get_relevant_context). Activating one transparently restores them — single-intent\n decisions for this intent get their soft-delete cleared so the prior reasoning\n becomes visible again. Multi-intent decisions stay visible throughout (they were\n never soft-deleted).", "inputSchema": {"properties": {"intentId": {"description": "The cloud ID (preferred) or local UUID of the existing intent to activate.", "type": "string"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}}, "required": ["repoPath", "intentId"], "type": "object"}, "name": "activate_intent"}, {"description": "Resume an existing intent by ID in one call — activate it AND load its recorded decisions.\n\nUse this to pick up a handoff. When a prompt says \"follow up on intent \" (or you otherwise want to continue a specific existing intent), call resume_intent() instead of creating a new one. It:\n- activates the intent as THIS session's current focus (multi-active — never displaces a teammate's active intent), and\n- returns the intent's title/description/status plus its recorded decisions (summary-only; call get_decision_detail(id) for full rationale on any one).\n\nThis is the fast path for cross-developer handoff without a session or transcript export: the reasoning lives in Kawa Code, so a teammate resumes the thread from just the intent id. For the code itself, the intent's owner should have committed or pushed first (a prompt carries reasoning, not an uncommitted working tree).\n\nReturns { resumed, intentId, intent?, decisions[], count, message }. resumed=false with a message when the id can't be activated.", "inputSchema": {"properties": {"intentId": {"description": "The cloud ID (preferred) or local UUID of the intent to resume — e.g. the id from a \"follow up on intent \" handoff.", "type": "string"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}}, "required": ["repoPath", "intentId"], "type": "object"}, "name": "resume_intent"}, {"description": "Intents with code blocks in a file, so you can see in-progress work and team conflicts before editing.\n\nPass startLine + endLine to narrow to a range; the result then reports the exact overlap and warns when it hits a teammate's active intent.", "inputSchema": {"properties": {"endLine": {"description": "End line (1-based, inclusive). Provide with startLine to narrow to a range.", "type": "number"}, "filePath": {"description": "Path to the file (relative to repo root)", "type": "string"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}, "startLine": {"description": "Start line (1-based). Provide with endLine to narrow to a range.", "type": "number"}}, "required": ["repoPath", "filePath"], "type": "object"}, "name": "get_intents_for_file"}, {"description": "List intents from team members for this repository.\n\nUse this to:\n- See what your team is working on\n- Check for potential overlapping work before starting a new task\n- Review the status of various features/refactors in progress\n\nFiltering (status, author, date range) and pagination are applied server-side across the full result set (default: 50 per page; use limit/offset to page). `count` is the total number of matching intents, not just the returned page.", "inputSchema": {"properties": {"author": {"description": "Filter by author name or ID", "type": "string"}, "limit": {"description": "Maximum number of intents to return (default: 50)", "type": "number"}, "offset": {"description": "Number of intents to skip for pagination (default: 0)", "type": "number"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}, "since": {"description": "Filter intents updated after this ISO8601 date (e.g. \"2026-04-01\")", "type": "string"}, "status": {"description": "Filter by intent status.", "enum": ["active", "committed", "pushed", "done", "abandoned"], "type": "string"}, "until": {"description": "Filter intents updated before this ISO8601 date", "type": "string"}}, "required": ["repoPath"], "type": "object"}, "name": "list_team_intents"}, {"description": "Mark the active intent completed and clear it. Call after a successful git commit, passing commitSha so code blocks are captured.\n\nstatus: committed (default, local commit) | pushed | done | abandoned.\n\nYou MUST inspect the response:\n\n- success === true — done. If committedDecisionCount > 0, say N decisions were recorded; do NOT list them. If apiSyncDeferred, say the sync was deferred and will replay. If collisions is non-empty, relay it as an advisory coordination heads-up (collisions[].label + files) — the completion still succeeded. If deferredConflicts is non-empty, the completion ALSO succeeded; say \"N decision(s) need a disposition in the Kawa Code panel\" and do NOT re-run this tool.\n\n- success === false && reason === \"transient-failure\" — the intent stays active and nothing was lost. Report failedStage plus the error; retry once the cause clears, or abandon if it persists.\n\nAutonomous sessions: deferredConflicts is not a blocking state — log and continue.", "inputSchema": {"properties": {"commitSha": {"description": "The git commit SHA to associate with this intent (if already committed)", "type": "string"}, "humanApproved": {"description": "Set to true ONLY when the human has explicitly confirmed closing an intent created by ANOTHER team member. Required for that cross-author case; ignored for your own intents. NEVER set this on your own initiative — always ask the user first and only set it after they approve.", "type": "boolean"}, "intentId": {"description": "Target intent to complete/abandon. When omitted, completes THIS session's current intent. When provided, targets that specific intent directly — this is how you force-close an intent that is not your current one (e.g. another session's). Completing an intent created by ANOTHER team member additionally requires humanApproved=true (see below).", "type": "string"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}, "status": {"description": "The new status for the intent. Use \"committed\" after git commit, \"done\" when work is complete, \"abandoned\" to discard, \"superseded\" when another intent replaces this one.", "enum": ["committed", "pushed", "done", "abandoned", "superseded"], "type": "string"}, "supersededBy": {"description": "Intent ID that supersedes this one. Required when status is \"superseded\".", "type": "string"}}, "required": ["repoPath"], "type": "object"}, "name": "complete_intent"}, {"description": "Update an active intent's title, description, scope, or constraints.\n\nUse this to reformulate an intent as understanding evolves during work. Intents are\nliving documents — they should be updated to reflect what the work actually became,\nnot left as the initial guess. Common triggers for reformulation:\n- The real problem turned out to be different from the initial hypothesis\n- Scope expanded or narrowed during investigation\n- The approach changed after discovering constraints\n\nIf no intentId is provided, the currently active intent is updated.", "inputSchema": {"properties": {"constraints": {"description": "Updated constraints for this work", "items": {"type": "string"}, "type": "array"}, "description": {"description": "Updated description for the intent", "type": "string"}, "intentId": {"description": "ID of the intent to update. If omitted, updates the currently active intent.", "type": "string"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}, "scope": {"description": "Updated scope for the intent", "type": "object"}, "title": {"description": "Updated title for the intent", "type": "string"}}, "required": ["repoPath"], "type": "object"}, "name": "update_intent"}, {"description": "DEPRECATED — trivial changes (typos, one-line fixes, obvious bugs, doc updates, config changes) should skip the intent workflow entirely: just make the change and commit, no intent needed. Do not call this tool. Kept available for backwards compatibility only and will be removed in a future release.", "inputSchema": {"properties": {"files": {"description": "File paths modified (relative to repo root)", "items": {"type": "string"}, "type": "array"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to repository root", "type": "string"}, "title": {"description": "Short description of the work done", "type": "string"}}, "required": ["repoPath", "title"], "type": "object"}, "name": "log_work"}, {"description": "Silently record a decision point during development.\n\nCall this tool when you:\n- Choose between multiple alternatives (type: fork)\n- Try an approach that fails or is rejected (type: abandoned)\n- Find unexpected behavior or limitations (type: discovery)\n- Identify a hard constraint that must be respected (type: constraint)\n- Make an explicit trade-off between competing concerns (type: tradeoff)\n- Select an external library or dependency (type: dependency)\n\nDecisions can be **intent-scoped** (tied to a specific work unit) or **repo-scoped** (general knowledge like discoveries and constraints). Omit intentId for repo-scoped decisions.\n\nDecisions are accumulated silently during the session and presented for review before commit.\nThis creates a \"reasoning changelog\" that captures not just what was done, but why.\n\nIMPORTANT: Include constraintViolations when alternatives are rejected due to architectural constraints.", "inputSchema": {"properties": {"alternatives": {"description": "Other options that were considered", "items": {"type": "string"}, "type": "array"}, "appliesWhen": {"description": "Trigger condition / \"How to apply\" — populate ONLY when the decision is plainly conditional (e.g. \"language is Go\", \"when running in production\", \"when working in module X\", \"when the error is ECONNRESET\"). Skip when the rule has no clean activation condition or when the rationale already implies universality. Treat applies_when as load-bearing context the LLM uses at recall time to decide whether the decision is relevant — not a soft hint. Strong-signal-only.", "type": "string"}, "confidence": {"description": "Self-rated confidence in the decision. Meaningful only for extractor and infer_history sources — leave null for deliberate recordings.", "enum": ["high", "medium", "low"], "type": "string"}, "consequences": {"description": "Downstream implications of this decision", "type": "string"}, "constraintViolations": {"description": "Alternatives that were rejected due to constraint violations", "items": {"type": "object"}, "type": "array"}, "constraintsChecked": {"description": "Which architectural constraints were verified before this decision", "items": {"type": "string"}, "type": "array"}, "context": {"description": "What we were trying to accomplish when this decision was made", "type": "string"}, "intentId": {"description": "The intent ID this decision belongs to. Omit for repo-scoped decisions (discoveries, constraints) not tied to a specific work unit", "type": "string"}, "rationale": {"description": "Why this decision was made", "type": "string"}, "relatedFiles": {"description": "File paths affected by this decision", "items": {"type": "string"}, "type": "array"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root (enables offline sync)", "type": "string"}, "resolvedCollision": {"description": "Layer C audit — set ONLY when this decision records how you resolved a completion-time code collision (i.e. after complete_intent returned resolution_required). Links the decision to the live peer you yielded to or overrode.", "type": "object"}, "source": {"description": "Provenance: user (human-recorded), agent (AI deliberately recorded via this tool — the default), extractor (from thought-chain extraction), infer_history (from commit-history extraction). Most callers leave this as the default.", "enum": ["user", "agent", "extractor", "infer_history"], "type": "string"}, "sourceThoughtIds": {"description": "Thought-chain entry IDs this record was extracted from. Only set by the extractor path.", "items": {"type": "string"}, "type": "array"}, "summary": {"description": "Brief summary of the decision (< 100 chars recommended)", "type": "string"}, "supersedes": {"description": "Decision IDs that this one replaces. When a later decision supersedes an earlier one, pass the earlier decisionId(s) here so the evolve pipeline can track the lineage. Pass FULL decision IDs (36-char UUIDs) — a truncated 8-char prefix is rejected, because resolving it back would mean guessing which decision you meant. If you only have a prefix (e.g. read from a doc), look it up with get_decision_detail first and use the id it returns.", "items": {"type": "string"}, "type": "array"}, "surface": {"description": "Which ceremony(ies) this decision should be surfaced at, controlling when it interrupts future work. Values: \"pre-edit\" (per-edit block via pre_edit_decision_check — for correctness/security constraints), \"intent-create\" (injected at intent-framing time — for design/scalability constraints that must shape the approach, not a keystroke), \"stop\" (once-per-turn Stop/review gate — aggregate/after-the-fact checks), \"recall\" (passive; only via get_relevant_context). Omit for ordinary decisions — empty means default type-based routing. Strong-signal-only: set it only when the decision genuinely belongs at a non-default ceremony.", "items": {"enum": ["pre-edit", "intent-create", "stop", "recall"], "type": "string"}, "type": "array"}, "symptom": {"description": "Observable symptom that indicates this decision is relevant (e.g., error messages, runtime panics, unexpected behavior). Useful for discovery and constraint decisions.", "type": "string"}, "type": {"description": "Type of decision: fork (chose between alternatives), abandoned (tried and rejected), discovery (found unexpected behavior), constraint (identified hard requirement), tradeoff (made explicit trade-off), dependency (selected library/tool)", "enum": ["fork", "abandoned", "discovery", "constraint", "tradeoff", "dependency"], "type": "string"}}, "required": ["repoPath", "type", "summary", "rationale"], "type": "object"}, "name": "record_decision"}, {"description": "Get all decisions recorded in the current session for an intent.\n\nUse this before committing to review what decisions were captured during development.\nDecisions are presented for user review and can be edited or removed before being persisted.\n\nReturns:\n- intentId: The intent these decisions belong to\n- decisions: Array of decision points (summary-only — call get_decision_detail(decisionId) for full rationale/context/consequences/alternatives)\n- count: Number of decisions recorded", "inputSchema": {"properties": {"intentId": {"description": "The intent ID to get decisions for", "type": "string"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}}, "required": ["repoPath", "intentId"], "type": "object"}, "name": "get_session_decisions"}, {"description": "Get all decisions recorded for a project across all intents.\n\nUse this to review the project's decision history:\n- See what architectural decisions have been made\n- Understand past trade-offs and their rationale\n- Find decisions affecting specific files\n- Review constraint violations that were avoided\n\nReturns:\n- decisions: Array of decisions with their intent context\n- count: Total number of decisions\n\nEach decision includes (summary-only, to keep context lean — call get_decision_detail(decisionId) for full rationale/context/consequences/alternatives):\n- intentIds: The intents this decision belongs to (array — a decision can span multiple intents)\n- type: fork, abandoned, discovery, constraint, tradeoff, or dependency\n- summary: Brief description of the decision\n- relatedFiles: Files affected by this decision\n- constraintViolations: Options that were rejected due to constraints", "inputSchema": {"properties": {"repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}}, "required": ["repoPath"], "type": "object"}, "name": "get_project_decisions"}, {"description": "Expand one decision to its full detail.\n\nRecall surfaces (get_relevant_context, get_project_decisions, get_session_decisions) return decisions summary-only to keep context lean. Use this to pull the full reasoning for a single decision you want to open — pay for detail only where you ask for it.\n\nInputs:\n- `decisionId`: the decision to expand (the `id` / `decisionId` from a recall result).\n\nReturns the decision's `rationale`, `context`, `consequences`, `alternatives`, `symptom`, `appliesWhen`, `surface`, and related metadata. `found: false` when the id is unknown in this repo.\n\nReferences come pre-resolved, so describe them by name and never by ID alone:\n- `supersededDecisions` — the supersession chain, nearest first. Each carries `summary` and a `depth` (1 = directly superseded by this decision, 2 = what *that* one superseded). Use `depth` to render the chain correctly: with two entries at depth 1 this decision replaced both, whereas depth 1 then 2 is a lineage. `supersededOlderCount` > 0 means older ancestors exist beyond the cap — say \"+N older\".\n- `intents` — the intent(s) that produced this decision, with titles.", "inputSchema": {"properties": {"decisionId": {"description": "The decision ID to expand (from a recall result, e.g. get_relevant_context)", "type": "string"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}}, "required": ["repoPath", "decisionId"], "type": "object"}, "name": "get_decision_detail"}, {"description": "Edit or delete a decision in the current session.\n\nUse this when reviewing decisions before commit:\n- action: \"update\" - Modify the decision fields\n- action: \"delete\" - Remove the decision entirely\n\nOnly ephemeral (in-flight) session decisions are editable. Once a decision is\nsynced to Kawa Code, it is immutable — refine it instead by recording a new\ndecision with `supersedes: []`.\n\nThis allows users to curate their decision history before it's persisted.", "inputSchema": {"properties": {"action": {"description": "Action to perform: update modifies the decision, delete removes it", "enum": ["update", "delete"], "type": "string"}, "decisionId": {"description": "The decision ID to edit or delete", "type": "string"}, "intentId": {"description": "The intent ID the decision belongs to", "type": "string"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}, "updates": {"description": "Partial fields to update (only for action=update)", "type": "object"}}, "required": ["repoPath", "intentId", "decisionId", "action"], "type": "object"}, "name": "edit_session_decision"}, {"description": "Find intents from other team members that potentially conflict with the active intent.\n\nWhen to use:\n- Before committing, to surface overlapping team work so the user can coordinate before merging.\n\nInputs of note:\n- `intentId`: the active intent to check against.\n- `minScore` (optional): minimum match score to include in results.\n\nReturns scored conflict candidates with:\n- `score`: how strongly the candidate matches (higher = more likely conflict).\n- `overlappingFiles`: files affected by both intents.\n- `decisions`: decisions attached to the conflicting intent.\n- `authorId`: opaque owner id — use it only to tell whether the intent is someone else's. Who they are is shown in Kawa Code, not here.\n\nThe list is informational — review candidates and their decisions to decide whether coordination is needed.", "inputSchema": {"properties": {"intentId": {"description": "The active intent ID", "type": "string"}, "minScore": {"description": "Minimum similarity score threshold (default: 0.5)", "type": "number"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}}, "required": ["repoPath", "intentId"], "type": "object"}, "name": "detect_intent_conflicts"}, {"description": "One-time-ish bootstrap: mine a repo's git history into intents and decisions. Rare — use it to seed a repo that has no recorded history yet, or to extend coverage after many new commits. NOT part of the per-turn workflow.\n\nCosts real money and time, so it is a two-step call: run with estimateOnly (the default) to preview tokens/cost, show the user, then re-call with estimateOnly: false only if they agree. The run is asynchronous and reports progress in the Kawa Code app; it resumes automatically if interrupted.\n\nRe-run guard — do not defeat this casually. If the repo already has intents and the run cannot cleanly resume, or HEAD is not on the default branch, the call STOPS and returns needsDecision rather than running, because re-running blind risks duplicate intents. Show the user the reason and only re-call with force: true if they confirm. Prefer running on main/master.\n\nOmit commits to resume from the last run. See the README for the full parameter list.", "inputSchema": {"properties": {"allowCommitSplitting": {"description": "Allow splitting a single commit into multiple stories when it contains unrelated changes (recommended for repos with messy commit history)", "type": "boolean"}, "commitRange": {"description": "Optional git revspec to process a specific commit range instead of the N most recent (e.g. \"sha1..sha2\", \"branch1..branch2\", \"sha1^!\" for a single commit). Useful for recovering from dropped batches or targeted backfills. Mutually exclusive with `commits`.", "type": "string"}, "commits": {"description": "Number of recent commits to analyze. If omitted, the server resumes from the last commit infer_history processed for this repo (or falls back to 50 on first run). Mutually exclusive with `commitRange`.", "type": "number"}, "contextIssues": {"description": "Include context issues from commit date range (requires gh/glab CLI)", "type": "boolean"}, "estimateOnly": {"description": "If true (default), only estimate token cost without running the pipeline. Set to false to run the full pipeline.", "type": "boolean"}, "force": {"description": "Override the re-run guard. When the repo already has intents and infer_history cannot cleanly resume (missing/unreachable cursor), or when HEAD is not on the default branch, the run is stopped and a confirmation is requested. Set `force: true` to proceed anyway, accepting the duplicate-intent risk. Exact-commit duplicates are still skipped automatically; overlapping re-groupings are not. A forced run on a non-default branch additionally does NOT advance the resume cursor. Does not override a hard failure such as the desktop app being unreachable.", "type": "boolean"}, "maxStories": {"description": "Maximum number of stories to analyze in this run (0 = unlimited).", "type": "number"}, "model": {"description": "Model slug used for the token/cost estimate only. It does NOT select the model the run uses — that is configured in the Kawa Code app.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}}, "required": ["repoPath"], "type": "object"}, "name": "infer_history"}, {"description": "Resolve a live code collision with a peer BEFORE you write (Layer C resolution handoff).\n\nCall this when the Stop hook's collision report (or complete_intent's resolution_required gate) surfaced a live peer (a teammate or AI agent editing the same lines). Pass that collision's uid as peerUid and its overlapping ranges. You get back:\n- peerSnippet — the peer's actual (decrypted) code at the overlapping lines, so you can see what they wrote.\n- decisions — recorded reasoning attached to this file (region context).\n- guardrail — the policy you must follow when resolving:\n • Never overwrite a peer's COMMITTED work — yield or merge. Only override an uncommitted live diff, and only with a recorded rationale.\n • Your resolution is an ordinary git edit (revert/diff is the undo) — stay in your own working tree; build no bespoke undo.\n • Before completing, record_decision(type=fork|tradeoff, …) explaining how you resolved (and supersedes the peer's decision if you overrode it).\n • Choose or synthesize ONE coherent result — never blindly interleave both diffs.\n\nThis is advisory and proactive (no lock). Use it to adapt your edit and avoid the conflict.", "inputSchema": {"properties": {"filePath": {"description": "Path to the file being edited (relative to repoPath)", "type": "string"}, "intentId": {"description": "Active intent ID (advisory). Auto-detected by Kawa Code when omitted.", "type": "string"}, "peerUid": {"description": "The peer HAI whose live edits overlap — the `uid` of a collision from the Stop hook collision report.", "type": "string"}, "ranges": {"description": "Overlapping [start, end] line ranges (from the collision) to fetch the peer code for.", "items": {"items": {"type": "number"}, "type": "array"}, "type": "array"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}}, "required": ["repoPath", "peerUid", "filePath", "ranges"], "type": "object"}, "name": "get_resolution_context"}, {"description": "Get Kawa Code's AI verdict for live code overlaps with peers — SUGGEST-ONLY, never writes. For each overlap ({peerUid, filePath, ranges} from the Stop collision report), Kawa decrypts the peer's version locally (zero-knowledge) and judges it compatible / auto_resolvable / conflict, with confidence, a perf/security risk read, and a tier (0 no-op · 1 trivially auto-appliable · 2 draft-and-confirm · 3 conflict). Use it to understand a forming conflict before acting. For a surfaced tier-2/3 overlap, call get_resolution_context to read the peer's actual code. To actually apply the safe tier, use arbiter_apply.", "inputSchema": {"properties": {"intentId": {"description": "Active intent ID (advisory). Auto-detected by Kawa Code when omitted.", "type": "string"}, "overlaps": {"description": "The overlaps to judge — each { peerUid, filePath, ranges } from the Stop collision report.", "items": {"type": "object"}, "type": "array"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}}, "required": ["repoPath", "overlaps"], "type": "object"}, "name": "arbiter_resolve"}, {"description": "Resolve live code overlaps and AUTO-APPLY the safe tier. Kawa judges → adversarially verifies → and, for the trivial tier only (high-confidence single-range merge that passes verify), writes the merge to your worktree, records a decision, and republishes. Writes happen ONLY in an agent-owned worktree (a linked git worktree); on a human checkout — or when a peer holds the file-set lock — it behaves like arbiter_resolve (suggest-only, no writes). Returns per-overlap outcomes { tier, applied, announcement, verifyIssue?, verdict }. Call it when you are ready to incorporate the result, then RE-READ any file it applied to (it changed on disk). For surfaced (not-applied) overlaps, use get_resolution_context to see the peer code and resolve manually.", "inputSchema": {"properties": {"intentId": {"description": "Active intent ID (advisory; the auto-resolution decision is recorded under it).", "type": "string"}, "overlaps": {"description": "The overlaps to resolve — each { peerUid, filePath, ranges } from the Stop collision report.", "items": {"type": "object"}, "type": "array"}, "repoOrigin": {"description": "Git remote origin URL. Auto-detected from repoPath via git if not provided.", "type": "string"}, "repoPath": {"description": "Local path to the repository root", "type": "string"}}, "required": ["repoPath", "overlaps"], "type": "object"}, "name": "arbiter_apply"}], "tools_list_hashes": ["158b93260ff1dccabbd2cf7c4223f284699f13c3f6950aa33ea78b52191816d2"], "wall_limit_seconds": 45}