# ACP Migration Gaps: Graph Definitions & Tool Portability

This document tracks differences between the v1 VS Code extension path and the ACP adapter
in `packages/kiro-agent`, covering graph definitions, context building, and tool availability.

## Status Legend

- 🔴 Not started
- 🟡 Partial / workaround in place
- 🟢 Done

---

## 1. Tools that need to move into `@kiro/agent`

These tools currently live in `src/extension/capabilities/tools/` and depend on VS Code APIs.
They are injected into the ACP agent as `clientTools` from the extension, which means standalone
ACP consumers (CLI, web, tests) don't have them at all.

The goal is to move the core logic into `packages/kiro-agent/src/tools/` with platform-abstracted
interfaces, then have the extension provide VS Code implementations via dependency injection.

### 1a. FileSearch 🟢

**Current location:** `packages/kiro-agent/src/tools/file-search.ts` (base class)
**Extension wrapper:** `src/extension/capabilities/tools/file-search.ts`

**Done:** Migrated `FileSearch` base class into agent package with `FileSearchProvider` DI
interface. Extension's `ToolFileSearch` is now a thin wrapper providing a VS Code implementation.
ACP standalone uses bash `find` via `createAcpFileSearchProvider`. Wired into all tool lists
(chat, spec agent, spec orchestrator) in `acp-workspace-connection.ts`.

### 1b. GrepSearch 🟢

**Current location:** `packages/kiro-agent/src/tools/grep-search.ts` (base class)
**Extension wrapper:** `src/extension/capabilities/tools/grep-search.ts`

**Done:** Migrated `GrepSearch` base class into agent package with `TextSearchProvider` DI
interface. Extension's `ToolGrepSearch` is now a thin wrapper providing a VS Code implementation.
ACP standalone uses ripgrep/grep via `createAcpTextSearchProvider`. Wired into all tool lists
(chat, spec agent, spec orchestrator) in `acp-workspace-connection.ts`.

### 1c. ReadCode 🔴

**Current location:** `src/extension/capabilities/tools/read-code.ts`
**VS Code dependency:** tree-sitter (`Parser` from `web-tree-sitter`)

**Plan:**

- Create `packages/kiro-agent/src/tools/read-code.ts` with a `ReadCode` base class
- Accept a `CodeParser` interface: `parse(code, language) => Signature[]`
- The tree-sitter logic (signature extraction, fuzzy matching) is pure computation and can
  move directly — it doesn't depend on VS Code, only on `web-tree-sitter`
- ACP factory creates an instance with a Node.js tree-sitter parser
- Extension can continue using its current tree-sitter setup
- Add `createAcpReadCodeTool()` to `acp-tool-factories.ts`

### 1d. EditCode 🔴

**Current location:** `src/extension/capabilities/tools/edit-code.ts`
**VS Code dependency:** tree-sitter (`Parser` from `web-tree-sitter`)

**Plan:**

- Create `packages/kiro-agent/src/tools/edit-code.ts` with an `EditCode` base class
- Same `CodeParser` interface as ReadCode — the AST operations (find node, replace, insert,
  delete) are pure computation over tree-sitter parse trees
- ACP factory creates an instance with a Node.js tree-sitter parser
- Add `createAcpEditCodeTool()` to `acp-tool-factories.ts`

### 1e. CreateHook 🔴

**Current location:** `src/extension/capabilities/tools/create-hook.ts`
**VS Code dependency:** `vscode.workspace.workspaceFolders`, `vscode.workspace.fs.writeFile()`

**Plan:**

- Create `packages/kiro-agent/src/tools/create-hook.ts` with a `CreateHook` base class
- The hook JSON construction logic (`createWhenClause`, `createThenClause`, `createHookFromInput`)
  is pure and can move directly
- Accept a `HookPersistence` interface: `saveHook(path, content) => void`
- ACP factory creates an instance backed by `workspace.fs.writeTextFile()`
- Add `createAcpCreateHookTool()` to `acp-tool-factories.ts`

### 1f. SemanticRename 🟡

**Current location:** `src/extension/capabilities/tools/semantic-rename.ts`
**VS Code dependency:** `vscode.commands.executeCommand('vscode.executeDocumentRenameProvider')`

**Plan:**

- This tool fundamentally depends on language server rename providers. It cannot work without
  an LSP-capable environment.
- Keep as `clientTools` injection only. No ACP standalone equivalent is feasible.
- Document that standalone ACP mode does not support semantic rename.

### 1g. SmartRelocate 🟡

**Current location:** `src/extension/capabilities/tools/smart-relocate.ts`
**VS Code dependency:** `vscode.workspace.applyEdit()` with `MoveFileOperation`, import update listeners

**Plan:**

- This tool depends on VS Code's file move + automatic import update pipeline.
- Keep as `clientTools` injection only. No ACP standalone equivalent is feasible.
- Document that standalone ACP mode does not support smart relocate.

### 1h. GetDiagnostics 🟡

**Current location:** `src/extension/capabilities/tools/get-diagnostics.ts`
**VS Code dependency:** `vscode.languages.getDiagnostics()`

**Plan:**

- This tool depends on language server diagnostics. It cannot work without an LSP environment.
- Keep as `clientTools` injection only.
- Document that standalone ACP mode does not support getDiagnostics.

### 1i. KiroPowers 🟡

**Current location:** `src/extension/capabilities/tools/kiro-powers.ts`
**VS Code dependency:** `MCPManagerSingleton`, VS Code commands, file system for power configs

**Plan:**

- Powers depend on MCP server management which is already partially abstracted via
  `SessionMCPManager` in the agent package.
- Evaluate whether the core list/activate/use flow can be extracted. The MCP tool execution
  path already works in ACP mode via `ACPMCPWrapper`.
- Lower priority — powers work through MCP which is already wired in ACP mode.

### 1j. DiscloseContext 🟡

**Current location:** `src/extension/capabilities/tools/disclose-context.ts`
**VS Code dependency:** `SteeringDocumentsController` which uses `vscode.workspace.workspaceFolders`

**Plan:**

- The steering document loading is already abstracted via `ISteeringProvider` /
  `ACPSteeringProvider` in the agent package.
- Create a portable `DiscloseContext` tool that uses `ISteeringProvider` instead of the
  VS Code `SteeringDocumentsController`.
- Medium priority — steering already works in ACP mode, but progressive disclosure
  (skills, auto-inclusion) doesn't.

---

## 2. Spec Orchestrator missing search tools in ACP mode

**Gap:** The v1 extension's `getSpecOrchestratorTools()` includes `FileSearch`, `GrepSearch`,
and `ReadCode` for non-empty workspaces. The ACP `acp-workspace-connection.ts` only provides
`ListDirectory`, `ReadFile`, `ReadMultipleFiles`, `GetUserInput`, `UpdateTaskStatus`, and
`InvokeSubAgent`.

**Impact:** The spec orchestrator in ACP mode cannot search the codebase before delegating
to subagents. It can only browse via `ListDirectory` and read known files.

**Fix:** FileSearch, GrepSearch are now ported and wired. ReadCode still needs porting (gap 1c).

Once ReadCode is ported, add it to `specOrchestratorTools` in `acp-workspace-connection.ts`.

**Status:** 🟡 (FileSearch and GrepSearch done, ReadCode pending)

---

## 3. `buildFromPrompt` missing `openFiles`/`activeFile`

**Gap:** In both `ChatAgentDefinition.buildFromPrompt()` and
`SpecGenerationDefinition.buildFromPrompt()`, the returned graph state does not include
`openFiles` or `activeFile`. The `buildFromMessages()` path does include them.

**Impact:** Intent detection cannot weight based on open spec files when using the prompt-based
invocation path. The `calculateWeightsFromFiles()` function in intent detection receives
`undefined` for both fields and returns no weight adjustments.

**Fix:** Add `openFiles` and `activeFile` to the return value of both `buildFromPrompt` methods:

In `ChatAgentDefinition.buildFromPrompt()`:

```typescript
return {
  agentIterationLimit: ITERATION_LIMIT,
  context: messages.reduce((ctx, message) => ctx.withNewMessage(message), ModelContext.empty()),
  chatSessionId,
  continuationId: this.preservedContinuationId ?? createContinuationId(),
  openFiles: loadOpenEditorFiles(), // MISSING
  activeFile: loadCurrentFile() || '', // MISSING
};
```

In `SpecGenerationDefinition.buildFromPrompt()`:

```typescript
return {
  inputParams: this.input,
  agentIterationLimit: ITERATION_LIMIT,
  context,
  chatSessionId,
  continuationId: this.preservedContinuationId ?? createContinuationId(),
  specTaskId: input.taskId,
  openFiles: specPlatform.loadOpenEditorFiles(), // MISSING
  activeFile: specPlatform.loadCurrentFile() || '', // MISSING
};
```

**Status:** 🔴

---

## 4. `FileContextProvider` / `SpecPlatformProvider` are no-ops in standalone ACP

**Gap:** Both providers default to stubs returning empty arrays / undefined. They are only
populated when the extension calls `initializeKiroAgent()`. In standalone ACP mode (no
extension), `loadCurrentFile()` and `loadOpenEditorFiles()` always return empty.

**Impact:**

- Intent detection file-weighting is always a no-op in standalone ACP
- Spec platform features (markdown parsing, task hooks, open files) don't work
- The `#[[openFiles]]` and `#[[currentFile]]` context providers return empty

**Fix options:**

1. Have the ACP client send open files / active file info via `_meta` on `PromptRequest`,
   then set the providers per-prompt in `KiroAgent.prompt()`.
2. Add `openFiles` and `activeFile` as optional fields on `acp.PromptRequest` (requires
   ACP protocol extension).
3. Accept this as a known limitation of standalone ACP mode and document it.

**Recommendation:** Option 1 — use `_meta.kiro.openFiles` and `_meta.kiro.activeFile` on
prompt requests. This keeps the ACP protocol clean while allowing IDE clients to pass
editor state.

**Status:** 🔴

---

## 5. Non-gaps (confirmed equivalent)

These areas were investigated and found to be identical between v1 and ACP:

- **FileTree context** — Both paths use the same `getFileTreeContext()` builder. Included in
  all build paths (messages and prompt) for both chat and spec definitions.
- **Open files context** — Both paths use `getOpenFilesContext()` in `buildFromPrompt`.
  `buildFromMessages` uses `loadOpenEditorFiles()` for the graph state but not as message context.
- **Graph structure** — `ChatAgentGraph`, `ToolAgentGraph` (`createSpecAgent`), and
  `SpecGenerationGraph` are defined once in `packages/kiro-agent/src/` and shared by both paths.
- **Graph nodes** — All nodes (intent detection, failure detection, user intervention, turn
  approval, summarization, user hooks, implicit rules) are identical.
- **System prompts** — Both paths use the same prompt templates (`getChatPrompt`,
  `getSystemPrompt`).
- **Tool execution flow** — `processChunkStream`, `populateMatchedSteering`, and the
  model invoke logic are shared.
- **Spec tools** — `getSpecTools(workspace)` is called identically in both paths.
- **SubAgent tools** — Both paths provide `ReportProgress` + `SubagentResponse`.
