acp-port 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/CONTRIBUTING.md +167 -0
  3. package/LICENSE +21 -0
  4. package/README.md +212 -2
  5. package/dist/acp/stdio.d.ts +3 -0
  6. package/dist/acp/stdio.js +23 -0
  7. package/dist/acp/stdio.js.map +1 -0
  8. package/dist/agent/agent.d.ts +5 -0
  9. package/dist/agent/agent.js +110 -0
  10. package/dist/agent/agent.js.map +1 -0
  11. package/dist/agent/prompt-content.d.ts +2 -0
  12. package/dist/agent/prompt-content.js +21 -0
  13. package/dist/agent/prompt-content.js.map +1 -0
  14. package/dist/agent/session.d.ts +19 -0
  15. package/dist/agent/session.js +64 -0
  16. package/dist/agent/session.js.map +1 -0
  17. package/dist/agent/turn.d.ts +16 -0
  18. package/dist/agent/turn.js +151 -0
  19. package/dist/agent/turn.js.map +1 -0
  20. package/dist/cli/arguments.d.ts +16 -0
  21. package/dist/cli/arguments.js +105 -0
  22. package/dist/cli/arguments.js.map +1 -0
  23. package/dist/cli/commands.d.ts +1 -0
  24. package/dist/cli/commands.js +34 -0
  25. package/dist/cli/commands.js.map +1 -0
  26. package/dist/cli/index.d.ts +2 -0
  27. package/dist/cli/index.js +9 -0
  28. package/dist/cli/index.js.map +1 -0
  29. package/dist/config/schema.d.ts +99 -0
  30. package/dist/config/schema.js +72 -0
  31. package/dist/config/schema.js.map +1 -0
  32. package/dist/providers/adapters/anthropic-provider.d.ts +10 -0
  33. package/dist/providers/adapters/anthropic-provider.js +174 -0
  34. package/dist/providers/adapters/anthropic-provider.js.map +1 -0
  35. package/dist/providers/adapters/openai-provider.d.ts +14 -0
  36. package/dist/providers/adapters/openai-provider.js +170 -0
  37. package/dist/providers/adapters/openai-provider.js.map +1 -0
  38. package/dist/providers/create-provider.d.ts +2 -0
  39. package/dist/providers/create-provider.js +13 -0
  40. package/dist/providers/create-provider.js.map +1 -0
  41. package/dist/providers/provider-contract.d.ts +65 -0
  42. package/dist/providers/provider-contract.js +2 -0
  43. package/dist/providers/provider-contract.js.map +1 -0
  44. package/dist/providers/provider-registry.d.ts +15 -0
  45. package/dist/providers/provider-registry.js +59 -0
  46. package/dist/providers/provider-registry.js.map +1 -0
  47. package/dist/providers/support/request-handling.d.ts +10 -0
  48. package/dist/providers/support/request-handling.js +62 -0
  49. package/dist/providers/support/request-handling.js.map +1 -0
  50. package/dist/providers/support/sdk-clients.d.ts +10 -0
  51. package/dist/providers/support/sdk-clients.js +59 -0
  52. package/dist/providers/support/sdk-clients.js.map +1 -0
  53. package/dist/tools/catalog.d.ts +39 -0
  54. package/dist/tools/catalog.js +54 -0
  55. package/dist/tools/catalog.js.map +1 -0
  56. package/dist/tools/runner.d.ts +29 -0
  57. package/dist/tools/runner.js +219 -0
  58. package/dist/tools/runner.js.map +1 -0
  59. package/dist/tools/workspace-path.d.ts +1 -0
  60. package/dist/tools/workspace-path.js +50 -0
  61. package/dist/tools/workspace-path.js.map +1 -0
  62. package/docs/architecture.md +163 -0
  63. package/docs/capabilities.md +117 -0
  64. package/docs/configuration.md +167 -0
  65. package/docs/editor-integration.md +205 -0
  66. package/docs/providers.md +178 -0
  67. package/docs/releases.md +123 -0
  68. package/docs/troubleshooting.md +122 -0
  69. package/package.json +63 -4
package/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # Changelog
2
+
3
+ Releases and their changes are recorded here automatically by semantic-release.
@@ -0,0 +1,167 @@
1
+ # Contributing to ACP Port
2
+
3
+ ACP Port is a TypeScript ACP agent that connects an editor to an LLM API. Contributions can improve provider compatibility, editor behavior, tool execution, documentation, or the development workflow. The [architecture guide](docs/architecture.md) explains the runtime and extension points; the [README](README.md) covers installation and everyday use.
4
+
5
+ ## Set up a checkout
6
+
7
+ Use Node.js **24.21.0** and **pnpm 12.8.1**, as pinned in `mise.toml`; run `mise install` if you use mise. Source development requires Node.js **22.14.0 or newer** because of the release tooling. The published CLI itself supports Node.js 22.12.0 or newer. CI checks Node.js 22 and 24. Clone your fork or the repository, enter its directory, and install the versions recorded in the lockfile:
8
+
9
+ ```sh
10
+ pnpm install --frozen-lockfile
11
+ pnpm run check
12
+ pnpm run build
13
+ ```
14
+
15
+ `pnpm install --frozen-lockfile` requires the committed `pnpm-lock.yaml`. Use `pnpm add <package>` or `pnpm add -D <package>` when intentionally adding dependencies, and commit the manifest and lockfile changes together. Keep pnpm as the package manager and do not create an npm lockfile.
16
+
17
+ The automated tests use fake providers, temporary workspaces, and local HTTP servers. They do not need API credentials or a running local model server. Tests that open loopback listeners need an environment that permits local networking.
18
+
19
+ ## Run and develop the CLI
20
+
21
+ Run directly from TypeScript during development:
22
+
23
+ ```sh
24
+ pnpm run dev --help
25
+ pnpm run dev models --base-url http://127.0.0.1:1234/v1
26
+ pnpm run dev models --base-url http://127.0.0.1:11434/v1 --json
27
+ ```
28
+
29
+ The `models` examples require the corresponding endpoint to be running. Model discovery lists available models; it does not download them.
30
+
31
+ Build and check the executable users will actually run:
32
+
33
+ ```sh
34
+ pnpm run build
35
+ node dist/cli/index.js --help
36
+ node dist/cli/index.js --version
37
+ ```
38
+
39
+ To test your changes in an ACP editor, use an absolute Node executable path and the absolute path to the built `dist/cli/index.js` in the editor's agent configuration. Rebuild after source changes and restart the editor's agent process. Starting a new conversation within the same existing process does not reload JavaScript.
40
+
41
+ The user-facing examples launch the npm release through `npx -y acp-port`. To test this checkout instead, replace that entry's `command` with your absolute Node executable path and replace its first two arguments, `"-y", "acp-port"`, with the absolute path to `dist/cli/index.js`. Keep the remaining endpoint options and environment unchanged.
42
+
43
+ For a development entry that skips compilation, launch `tsx` through Node directly:
44
+
45
+ ```json
46
+ {
47
+ "command": "/absolute/path/to/node",
48
+ "args": [
49
+ "--import",
50
+ "/absolute/path/to/acp-port/node_modules/tsx/dist/loader.mjs",
51
+ "/absolute/path/to/acp-port/src/cli/index.ts",
52
+ "--base-url",
53
+ "http://127.0.0.1:1234/v1"
54
+ ],
55
+ "env": {
56
+ "API_KEY": ""
57
+ }
58
+ }
59
+ ```
60
+
61
+ This is the launch object; place it in the structure your editor expects, as shown in the [editor integration guide](docs/editor-integration.md), replacing its npx launch settings. The loader path is specific to the installed `tsx` package layout; use the npm release for regular use and the built entry point to check compiled local changes. Restart the agent after edits when using this source entry as well. The empty `API_KEY` is appropriate for an unauthenticated local endpoint.
62
+
63
+ Launch the Node entry point directly in editor configurations: package-manager script wrappers can write banners to stdout. During ACP operation, stdout must contain only protocol messages. Send diagnostics to stderr.
64
+
65
+ ## Commands and checks
66
+
67
+ | Command | Purpose |
68
+ | --- | --- |
69
+ | `pnpm run dev <args>` | Run the source CLI using `tsx`. |
70
+ | `pnpm run typecheck` | Check production and test TypeScript without emitting files. |
71
+ | `pnpm test` | Run `src/**/*.test.ts` with the Node.js test runner and `tsx`; each test has a 15-second timeout. |
72
+ | `pnpm run check` | Run type checking followed by the test suite. |
73
+ | `pnpm run build` | Emit ESM JavaScript, source maps, and declarations to `dist/`; exclude tests. |
74
+ | `pnpm run format:check` | Check formatting with Biome without writing fixes. |
75
+ | `pnpm run lint` | Run Biome checks **and write fixes**, including formatting and import organization. |
76
+ | `pnpm run lint:check` | Run Biome checks without writing fixes. |
77
+ | `pnpm pack --dry-run` | Rebuild and inspect the package file list without publishing. |
78
+
79
+ Before opening a pull request, run the same checks as CI:
80
+
81
+ ```sh
82
+ pnpm run check
83
+ pnpm run build
84
+ pnpm run format:check
85
+ pnpm run lint:check
86
+ ```
87
+
88
+ CI runs these after `pnpm install --frozen-lockfile` on both supported Node.js matrix versions and verifies the npm package contents. `pnpm run check` runs type checking and tests; build, formatting, and lint checks are separate. After both matrix jobs pass, qualifying commits on the canonical repository's default branch trigger the automated release. Pull requests and fork pushes only run checks. See the [release guide](docs/releases.md) for maintainer setup.
89
+
90
+ For a focused test run:
91
+
92
+ ```sh
93
+ node --import tsx --test --test-timeout=15000 src/providers/adapters/openai-provider.test.ts
94
+ node --import tsx --test --test-timeout=15000 --test-name-pattern="cancellation" "src/**/*.test.ts"
95
+ ```
96
+
97
+ `tsx` executes TypeScript but does not replace type checking. Run `pnpm run typecheck` after changing types or adding tests.
98
+
99
+ ## Find the code to change
100
+
101
+ | Change | Starting point | Relevant tests |
102
+ | --- | --- | --- |
103
+ | CLI options, defaults, or validation | `src/cli/arguments.ts`, `src/config/schema.ts` | `src/cli/arguments.test.ts`, `src/config/schema.test.ts`, `src/cli/index.test.ts` |
104
+ | Model discovery or endpoint selection | `src/providers/provider-registry.ts`, `src/agent/session.ts` | `src/providers/provider-registry.test.ts`, `src/agent/agent.test.ts` |
105
+ | OpenAI-compatible streaming or Gemini metadata | `src/providers/adapters/openai-provider.ts` | `src/providers/adapters/openai-provider.test.ts` |
106
+ | Anthropic Messages API | `src/providers/adapters/anthropic-provider.ts` | `src/providers/adapters/anthropic-provider.test.ts` |
107
+ | Credentials, SDK setup, request deadlines | `src/providers/support/` | Tests beside those modules |
108
+ | Session state, prompt processing, model/tool loop | `src/agent/` | `src/agent/agent.test.ts` |
109
+ | Tool schemas, permissions, paths, terminals | `src/tools/` | `src/tools/runner.test.ts` |
110
+ | Process lifecycle or ACP stdio transport | `src/acp/stdio.ts`, `src/cli/index.ts` | `src/acp/stdio.test.ts`, `src/cli/index.test.ts` |
111
+
112
+ See [extending the implementation](docs/architecture.md#extending-the-implementation) for the files and behavior required when adding a provider, tool, or ACP capability.
113
+
114
+ ## Testing expectations
115
+
116
+ Add regression coverage for behavior changes at the layer responsible for them. Existing tests demonstrate the conventions:
117
+
118
+ - **Provider tests** run local HTTP servers that return model lists, streamed text, tool fragments, API failures, or stalled responses. Test outgoing request payloads and observable events, including incomplete streams and cancellation.
119
+ - **Agent tests** connect an ACP client to the agent and inject a fake provider factory. Test protocol state, session isolation, model switching, history, tool loops, and stop reasons without invoking a real LLM.
120
+ - **Tool tests** supply a fake ACP client and temporary workspace. Cover permission denial, invalid input, path traversal and symlinks, timeout handling, and terminal cleanup where relevant.
121
+ - **CLI and stdio tests** spawn `src/cli/index.ts` using `node --import tsx`. The stdio tests exercise an HTTP-backed tool round trip through a simulated editor; they do not require a previous build.
122
+
123
+ Keep fixtures and test credentials synthetic. Assert that credentials, endpoint configuration, and provider metadata stay within the intended endpoint. When changing tool handling, verify that interrupted or denied operations cannot later execute after a delayed editor response.
124
+
125
+ Real editor and provider smoke tests are useful when changing compatibility. Record the editor, provider/server version, model, and what you exercised in the pull request. Automated mocks do not establish that every advertised model works in a real editor. Use your own disposable workspace for manual file and command tests.
126
+
127
+ ## Code conventions
128
+
129
+ - Use TypeScript with the repository's strict settings and NodeNext ESM imports. Local imports in source files use the emitted `.js` extension.
130
+ - Follow `.editorconfig` and Biome: two spaces, LF newlines, a final newline, and organized imports.
131
+ - Keep vendor SDK types and wire formats inside provider adapters and support modules. The agent and tools exchange the types in `provider-contract.ts`.
132
+ - Keep schemas strict. Validate configuration and tool input before use, and preserve cancellation and output limits.
133
+ - Keep endpoint selection explicit. Do not add automatic fallback to another provider or ambient SDK credential discovery.
134
+ - Preserve ACP stdout. Log human-readable diagnostics to stderr and avoid exposing SDK response bodies or request credentials.
135
+
136
+ ## Package verification
137
+
138
+ The package delivers the `acp-port` executable at `dist/cli/index.js`; it has no public JavaScript import API. Its internal modules use ESM. TypeScript also emits `.d.ts` and `.js.map` files. Production builds exclude `*.test.ts`.
139
+
140
+ Run `pnpm pack --dry-run` to inspect what a package consumer receives. The `prepack` hook cleans and rebuilds the output. The manifest includes `dist/`, `docs/`, `CHANGELOG.md`, `CONTRIBUTING.md`, `README.md`, and `LICENSE`, so the user guides, including their inline editor configurations, ship with the executable. The source tree is not packaged; use a repository checkout for development. Review the actual file list after any packaging change. Build output is ignored by Git and should not be hand-edited.
141
+
142
+ When running `pnpm run build` directly after deleting or renaming source modules, run `pnpm run clean` first: TypeScript does not remove output left by previous builds. Packaging already performs this cleanup through `prepack`.
143
+
144
+ To exercise a real local tarball without publishing:
145
+
146
+ ```sh
147
+ pnpm pack
148
+ ```
149
+
150
+ Install the resulting `.tgz` into a temporary consumer project and run its `acp-port --help` and `acp-port --version` commands. This validates package layout and executable resolution without relying on an npm release. The release workflow publishes to npm after CI passes; a successful local build does not establish that a version is available on npm.
151
+
152
+ ## Pull requests and bug reports
153
+
154
+ Use a [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/) title for your pull request, for example `fix(cli): preserve an explicitly empty API key` or `feat(providers): support another model API`. The PR title check validates this format. Prefer squash merging and keep the PR title as the squash commit subject so semantic-release can determine the version from the default branch's history.
155
+
156
+ - `fix:` and `perf:` produce patch releases.
157
+ - `feat:` produces a minor release.
158
+ - A `!` after the type/scope or a `BREAKING CHANGE:` footer produces a major release.
159
+ - `docs:`, `test:`, `refactor:`, `build:`, `ci:`, `style:`, and `chore:` do not produce releases by themselves; a breaking change still does.
160
+
161
+ Use the squash commit body for any `BREAKING CHANGE:` explanation. If a maintainer chooses another merge method, the commits that land on the default branch must carry the intended release information. Do not manually bump `package.json`, create release tags, or edit generated changelog entries. The [release guide](docs/releases.md) describes how those artifacts are created.
162
+
163
+ Keep a pull request focused on a concrete behavior. Explain the problem, the resulting behavior, relevant tests, and any manual compatibility checks. Update the README and reference pages, including their editor configuration examples, when user-visible behavior changes. Do not include real API keys, private endpoint headers, generated build files, or unrelated formatting changes.
164
+
165
+ For a bug report, include the ACP Port and Node.js versions, operating system, editor version, provider type, sanitized launch arguments, model ID, and a minimal reproduction. Distinguish a failed model-list request from a failed prompt or tool call. Redact secrets and private prompt/file content from logs.
166
+
167
+ The project is licensed under the [MIT License](LICENSE).
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 acp-port contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,213 @@
1
- # Temporary Holding Version
1
+ # acp-port
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **Connect a model API to your editor through the Agent Client Protocol.**
4
+
5
+ acp-port is a TypeScript CLI that runs as an ACP coding agent. It connects an ACP-capable editor to local model servers, LLM gateways, and cloud APIs. The editor provides the conversation UI, workspace context, permissions, and file/terminal access; acp-port handles model discovery, streaming responses, conversation history, and the model's tool loop.
6
+
7
+ Use it with LM Studio, Ollama, LiteLLM, OpenRouter, OpenAI, Anthropic, or Google's OpenAI-compatible Gemini endpoint. Choose the endpoint and model you want to use, then register acp-port as a custom agent in your editor.
8
+
9
+ ## Documentation
10
+
11
+ | I want to… | Start here |
12
+ | --- | --- |
13
+ | Run it for the first time | [Quick start](#quick-start) |
14
+ | Connect Zed, JetBrains Air, JetBrains AI Assistant, or another ACP client | [Editor integration](docs/editor-integration.md) |
15
+ | Configure a particular model server or cloud service | [Provider guide](docs/providers.md) |
16
+ | Understand every CLI flag, environment variable, and default | [Configuration reference](docs/configuration.md) |
17
+ | Understand tools, permissions, data flow, and limits | [Capabilities and limits](docs/capabilities.md) |
18
+ | Diagnose startup, model, authentication, or tool errors | [Troubleshooting](docs/troubleshooting.md) |
19
+ | Develop, test, or contribute to the project | [Contributing](CONTRIBUTING.md) |
20
+ | Configure automatic versions, changelogs, tags, and npm publishing | [Release guide](docs/releases.md) |
21
+ | Understand the implementation or add a provider/tool | [Architecture and extension guide](docs/architecture.md) |
22
+
23
+ ## How it works
24
+
25
+ [ACP](https://agentclientprotocol.com/get-started/introduction) standardizes communication between editors and coding agents. acp-port implements the agent side and translates model API responses into ACP messages.
26
+
27
+ ```mermaid
28
+ flowchart LR
29
+ Editor["ACP editor / IDE"] <-->|"ACP over stdin/stdout"| Agent["acp-port"]
30
+ Agent <-->|"HTTP: model discovery + streaming inference"| API["Local server or cloud API"]
31
+ Agent -->|"File, terminal, and permission requests"| Editor
32
+ ```
33
+
34
+ A typical turn works like this:
35
+
36
+ 1. The editor launches acp-port and opens a session with a workspace directory.
37
+ 2. acp-port discovers the endpoint's models and returns a model selector to the editor.
38
+ 3. Your prompt and conversation history go to the selected model API.
39
+ 4. Text streams back to the editor. If the model requests a tool, acp-port validates the request and uses the editor's ACP file or terminal capability.
40
+ 5. Tool results go back to the model, which can continue working or finish the turn.
41
+
42
+ The CLI starts a process that speaks ACP over stdio. It has no interactive terminal chat UI or HTTP listening port. Model servers still run separately. Model discovery lists available IDs; it does not download weights. acp-port does not launch other coding agents or run MCP servers.
43
+
44
+ ## Quick start
45
+
46
+ ### 1. Run with npx
47
+
48
+ Requires **Node.js 22.12 or later**, with npm and npx available. Run the published CLI directly:
49
+
50
+ ```sh
51
+ npx -y acp-port --version
52
+ npx -y acp-port --help
53
+ ```
54
+
55
+ No repository checkout, build step, or global installation is needed for the npm release. `npx` downloads the package when needed, and `-y` skips npm's installation confirmation so editor launches can proceed without an interactive prompt. See the [npm npx reference](https://docs.npmjs.com/cli/v11/commands/npx).
56
+
57
+ **Release status:** `acp-port` is not yet available on the public npm registry. The `npx` examples describe usage after the first npm release. To try the unpublished source or contribute changes, follow [CONTRIBUTING.md](CONTRIBUTING.md).
58
+
59
+ ### 2. Start your endpoint and check its models
60
+
61
+ For LM Studio, download a suitable chat model in LM Studio and start its local API server. For the usual local port:
62
+
63
+ ```sh
64
+ API_KEY='' npx -y acp-port models --base-url http://127.0.0.1:1234/v1
65
+ ```
66
+
67
+ For a running Ollama server with a model already downloaded:
68
+
69
+ ```sh
70
+ API_KEY='' npx -y acp-port models --base-url http://127.0.0.1:11434/v1
71
+ ```
72
+
73
+ For an authenticated gateway, set `API_KEY` in the process environment:
74
+
75
+ ```sh
76
+ API_KEY=YOUR_GATEWAY_KEY npx -y acp-port models \
77
+ --base-url https://gateway.example.com/v1 --json
78
+ ```
79
+
80
+ The local examples clear any inherited key for an unauthenticated server; substitute its token if you enabled authentication. The inline environment syntax above is for POSIX shells. In PowerShell, use `$env:API_KEY = "YOUR_GATEWAY_KEY"` (or `""` for no key) before running the command. Editor examples use an `env` object instead.
81
+
82
+ `models` prints a catalog and exits. A catalog entry such as `endpoint/vendor/model` contains an internal endpoint prefix; pass only the upstream ID, `vendor/model`, to `--default-model`.
83
+
84
+ If your server cannot list models, provide a known model ID:
85
+
86
+ ```sh
87
+ npx -y acp-port models \
88
+ --base-url http://127.0.0.1:1234/v1 \
89
+ --default-model YOUR_MODEL_ID --no-discovery
90
+ ```
91
+
92
+ With discovery disabled, this command checks the configured catalog without contacting the endpoint. Your first editor prompt tests inference. See the [provider guide](docs/providers.md) for server preparation, authentication, and compatibility requirements.
93
+
94
+ ### 3. Add it to your editor
95
+
96
+ For Zed, add a custom agent under `agent_servers` in your settings:
97
+
98
+ ```json
99
+ {
100
+ "agent_servers": {
101
+ "LM Studio via acp-port": {
102
+ "type": "custom",
103
+ "command": "npx",
104
+ "args": [
105
+ "-y", "acp-port",
106
+ "--base-url", "http://127.0.0.1:1234/v1",
107
+ "--default-model", "YOUR_MODEL_ID"
108
+ ],
109
+ "env": { "API_KEY": "" }
110
+ }
111
+ }
112
+ }
113
+ ```
114
+
115
+ Replace `YOUR_MODEL_ID` with an upstream ID from discovery. Setting `API_KEY` to an empty string deliberately disables authentication for this local endpoint, even if the editor inherits a key from your shell. Set the endpoint's actual key when authentication is enabled. If the editor cannot find `npx`, see the [launch settings and PATH guidance](docs/editor-integration.md#understand-the-launch-settings).
116
+
117
+ Open a project, select this agent, and start a conversation. An explicit `--default-model` chooses the initial model; other discovered models remain selectable. Without it, acp-port selects the first discovered model, which may not be the model you want for coding.
118
+
119
+ The [editor integration guide](docs/editor-integration.md) includes copyable configurations for Zed and JetBrains, multiple endpoints, Windows paths, remote workspaces, and a first-session smoke test.
120
+
121
+ ## Choosing a provider
122
+
123
+ `--provider` selects an API adapter. `--base-url` selects the actual server. For example, `--provider openai --base-url http://127.0.0.1:11434/v1` sends requests to Ollama using the OpenAI API format.
124
+
125
+ | Service | Adapter | Base URL | Authentication |
126
+ | --- | --- | --- | --- |
127
+ | LM Studio | `openai` (default) | `http://127.0.0.1:1234/v1` | Optional, depending on server settings |
128
+ | Ollama | `openai` | `http://127.0.0.1:11434/v1` | Usually omitted for a local server |
129
+ | LiteLLM | `openai` | Your gateway's API base URL | Gateway key, when required |
130
+ | OpenRouter | `openai` | `https://openrouter.ai/api/v1` | OpenRouter API key |
131
+ | OpenAI | `openai` | `https://api.openai.com/v1` (default) | OpenAI API key |
132
+ | Anthropic | `anthropic` | `https://api.anthropic.com` (default for this adapter) | Anthropic API key |
133
+ | Gemini | `gemini` | `https://generativelanguage.googleapis.com/v1beta/openai` (default for this adapter) | Gemini API key |
134
+
135
+ All CLI providers read **`API_KEY`**. Variables such as `OPENAI_API_KEY` do not configure this CLI. Anthropic and Gemini require a nonblank key; the OpenAI adapter allows unauthenticated local servers, but the hosted OpenAI service requires authentication. See [provider setup and official API references](docs/providers.md).
136
+
137
+ OpenAI, Gemini, and compatible gateways use streaming **Chat Completions**. Anthropic uses the native **Messages API**. The endpoint must support the selected protocol; a model appearing in `/models` does not establish chat support, tool support, or account access to inference. The OpenAI Responses API is not implemented.
138
+
139
+ Each CLI process connects to one endpoint. Create separate editor entries to use multiple servers or credentials. Requests do not automatically fall back to another provider.
140
+
141
+ ## Commands and settings
142
+
143
+ ```sh
144
+ # Inspect the available options.
145
+ npx -y acp-port --help
146
+
147
+ # Discover models without starting an ACP session.
148
+ npx -y acp-port models --base-url http://127.0.0.1:1234/v1 --json
149
+
150
+ # Start the ACP agent; omitting "serve" has the same effect.
151
+ npx -y acp-port serve --base-url http://127.0.0.1:1234/v1
152
+
153
+ # Use a known model without a model-list request.
154
+ npx -y acp-port --base-url http://127.0.0.1:1234/v1 \
155
+ --default-model YOUR_MODEL_ID --no-discovery
156
+ ```
157
+
158
+ | Option | Purpose |
159
+ | --- | --- |
160
+ | `--provider openai\|anthropic\|gemini` | Choose the API format and default URL. Defaults to `openai`. |
161
+ | `--base-url URL` | Override the API base URL. |
162
+ | `--default-model MODEL_ID` | Select one initial upstream model ID and keep it available if discovery fails. |
163
+ | `--name NAME` | Set the endpoint label used in model names. |
164
+ | `--no-discovery` | Skip model discovery. Requires `--default-model`. |
165
+ | `--no-tools` | Omit all tools for models that only support text chat. |
166
+ | `--json` | Print structured catalog data with the `models` command. |
167
+ | `--help`, `-h`, `--version` | Print usage or version and exit. |
168
+
169
+ Connection options and `API_KEY` are supplied per launch. There is no acp-port configuration file, automatic `.env` loading, or interactive sign-in flow. Your editor's settings file configures how the editor launches the process.
170
+
171
+ The [configuration reference](docs/configuration.md) documents validation, model IDs, environment handling, and fixed CLI limits. Settings without CLI flags, such as custom headers, timeouts, and the system prompt, require source changes.
172
+
173
+ ## Capabilities and limits
174
+
175
+ - Streams text and accepts embedded text resources. Resource links supply metadata; their contents are not automatically fetched.
176
+ - Exposes `read_file`, `write_file`, and `run_command` when the editor advertises the matching ACP capabilities and tools are enabled.
177
+ - Requests editor permission before each write or command. File reads do not request a separate approval from acp-port.
178
+ - Validates file paths and command working directories against the session workspace. Commands run with the editor's permissions; acp-port provides no operating-system sandbox.
179
+ - Keeps sessions in memory. Restarting the agent loses their history; session reload and automatic history summarization are unavailable.
180
+ - Defaults to 12 model requests per turn, 200,000 history characters, and 120-second provider/tool timeouts. A character budget is not a model token budget.
181
+ - Supports text-based coding workflows. Images, audio, binary attachments, and MCP servers are unsupported; sessions that forward MCP servers are rejected.
182
+
183
+ Prompts, attached text, conversation history, and tool results are sent to the selected model endpoint. Choose that endpoint with your workspace's data requirements in mind. See [capabilities and limits](docs/capabilities.md) for the exact tool behavior and data flow.
184
+
185
+ Automated tests cover mocked provider APIs, ACP sessions, permission handling, and a stdio tool round trip. They do not establish compatibility with every model or replace a live test in your editor. For common failures, see [troubleshooting](docs/troubleshooting.md).
186
+
187
+ ## Development
188
+
189
+ ```sh
190
+ pnpm install --frozen-lockfile
191
+ pnpm run dev --help
192
+ pnpm run dev models --base-url http://127.0.0.1:1234/v1
193
+ pnpm run check
194
+ pnpm run build
195
+ pnpm run format:check
196
+ pnpm run lint:check
197
+ ```
198
+
199
+ Use **Node.js 24.21.0 and pnpm 12.8.1** for development; `mise install` installs these versions from `mise.toml`. Source development requires Node.js 22.14.0 or newer because of the release tooling, while the published CLI supports Node.js 22.12.0 or newer. The committed `pnpm-lock.yaml` makes local and CI installs repeatable.
200
+
201
+ The project uses TypeScript, native ESM, the ACP SDK, Zod, and the OpenAI/Anthropic SDKs. Tests run directly from TypeScript with Node's test runner and `tsx`; a build is not required to run them. Editors using `dist/cli/index.js` require a new build and process restart to pick up source changes.
202
+
203
+ Read [CONTRIBUTING.md](CONTRIBUTING.md) for the local workflow, focused tests, package checks, and contribution guidance. GitHub Actions checks Node.js 22 and 24, then semantic-release publishes qualifying commits from the default branch with a changelog, Git tag, and GitHub Release. See the [release guide](docs/releases.md) for the one-time npm and GitHub setup. The [architecture guide](docs/architecture.md) maps the internal modules, explains the session/tool loop, and walks through adding providers and tools.
204
+
205
+ ## Migrating from older configuration
206
+
207
+ File-based configuration and external-agent management are no longer supported. `acp-port.json` and `ACP_PORT_CONFIG` are ignored, and old configuration files are left on disk. Move connection settings into each editor entry's arguments and `env.API_KEY`. Replace old options with those in the [configuration reference](docs/configuration.md).
208
+
209
+ The ACP agent registry distributes ready-made agents. It is separate from a model server's catalog. acp-port connects model APIs to ACP; it does not install or launch agents from that registry.
210
+
211
+ ## License
212
+
213
+ [MIT](LICENSE).
@@ -0,0 +1,3 @@
1
+ import { type AgentOptions } from "../agent/agent.js";
2
+ import type { Config } from "../config/schema.js";
3
+ export declare function serve(config: Config, options: AgentOptions): Promise<void>;
@@ -0,0 +1,23 @@
1
+ import stream from "node:stream";
2
+ import { ndJsonStream } from "@agentclientprotocol/sdk";
3
+ import { createAgent } from "../agent/agent.js";
4
+ import { createProvider } from "../providers/create-provider.js";
5
+ import { ProviderRegistry } from "../providers/provider-registry.js";
6
+ export async function serve(config, options) {
7
+ const registry = new ProviderRegistry(config.providers, createProvider, (message) => process.stderr.write(`acp-port: ${message}\n`));
8
+ const transport = ndJsonStream(stream.Writable.toWeb(process.stdout), stream.Readable.toWeb(process.stdin));
9
+ const connection = createAgent(config, registry, options).connect(transport);
10
+ const close = () => {
11
+ void connection.close();
12
+ };
13
+ process.on("SIGINT", close);
14
+ process.on("SIGTERM", close);
15
+ try {
16
+ await connection.closed;
17
+ }
18
+ finally {
19
+ process.off("SIGINT", close);
20
+ process.off("SIGTERM", close);
21
+ }
22
+ }
23
+ //# sourceMappingURL=stdio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../src/acp/stdio.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAqB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAErE,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,MAAc,EACd,OAAqB;IAErB,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CACnC,MAAM,CAAC,SAAS,EAChB,cAAc,EACd,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,OAAO,IAAI,CAAC,CAC5D,CAAC;IACF,MAAM,SAAS,GAAG,YAAY,CAC5B,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EACrC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CACrC,CAAC;IACF,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,KAAK,UAAU,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC5B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,MAAM,CAAC;IAC1B,CAAC;YAAS,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAChC,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Config } from "../config/schema.js";
2
+ import type { ProviderRegistry } from "../providers/provider-registry.js";
3
+ import { type AgentOptions } from "./session.js";
4
+ export type { AgentOptions } from "./session.js";
5
+ export declare function createAgent(config: Config, registry: ProviderRegistry, options?: AgentOptions): import("@agentclientprotocol/sdk").AgentApp;
@@ -0,0 +1,110 @@
1
+ import { agent, PROTOCOL_VERSION, RequestError, } from "@agentclientprotocol/sdk";
2
+ import { z } from "zod";
3
+ import pkg from "../../package.json" with { type: "json" };
4
+ import { createSession, getSessionConfigOptions, selectSessionModel, } from "./session.js";
5
+ import { runSessionPrompt } from "./turn.js";
6
+ export function createAgent(config, registry, options = {}) {
7
+ let initialized = false;
8
+ let capabilities = {};
9
+ const sessions = new Map();
10
+ const getSession = (id) => {
11
+ if (!initialized) {
12
+ throw RequestError.invalidRequest(undefined, "Initialize the connection first.");
13
+ }
14
+ const session = sessions.get(id);
15
+ if (!session) {
16
+ throw RequestError.invalidParams(undefined, "Unknown session.");
17
+ }
18
+ return session;
19
+ };
20
+ const updateSelectedModel = async (session, modelId, client) => {
21
+ selectSessionModel(session, modelId);
22
+ const configOptions = getSessionConfigOptions(session);
23
+ await client.notify("session/update", {
24
+ sessionId: session.id,
25
+ update: { sessionUpdate: "config_option_update", configOptions },
26
+ });
27
+ return configOptions;
28
+ };
29
+ return (agent({ name: "acp-port" })
30
+ .onConnect(({ signal }) => {
31
+ signal.addEventListener("abort", () => {
32
+ for (const session of sessions.values()) {
33
+ session.activeTurn?.abort();
34
+ }
35
+ sessions.clear();
36
+ }, { once: true });
37
+ })
38
+ .onRequest("initialize", ({ params }) => {
39
+ if (initialized) {
40
+ throw RequestError.invalidRequest(undefined, "This connection is already initialized.");
41
+ }
42
+ capabilities = params.clientCapabilities ?? {};
43
+ initialized = true;
44
+ return {
45
+ protocolVersion: PROTOCOL_VERSION,
46
+ agentInfo: {
47
+ name: "acp-port",
48
+ title: "ACP Port",
49
+ version: pkg.version,
50
+ },
51
+ agentCapabilities: {
52
+ loadSession: false,
53
+ promptCapabilities: {
54
+ embeddedContext: true,
55
+ image: false,
56
+ audio: false,
57
+ },
58
+ mcpCapabilities: { http: false, sse: false },
59
+ },
60
+ authMethods: [],
61
+ };
62
+ })
63
+ .onRequest("authenticate", () => {
64
+ throw RequestError.invalidParams(undefined, "API credentials come from the configured environment variable. Interactive authentication is not supported.");
65
+ })
66
+ .onRequest("session/new", async ({ params, signal }) => {
67
+ if (!initialized) {
68
+ throw RequestError.invalidRequest(undefined, "Initialize the connection first.");
69
+ }
70
+ if (params.mcpServers.length) {
71
+ throw RequestError.invalidParams(undefined, "MCP servers are not supported by acp-port. Disable MCP forwarding for this agent in the editor.");
72
+ }
73
+ const session = await createSession(params.cwd, config, registry, options, signal);
74
+ sessions.set(session.id, session);
75
+ return {
76
+ sessionId: session.id,
77
+ configOptions: getSessionConfigOptions(session),
78
+ };
79
+ })
80
+ .onRequest("session/set_config_option", async ({ params, client }) => {
81
+ const session = getSession(params.sessionId);
82
+ if (params.configId !== "model" || typeof params.value !== "string") {
83
+ throw RequestError.invalidParams(undefined, "Only the model select option is supported.");
84
+ }
85
+ const configOptions = await updateSelectedModel(session, params.value, client);
86
+ return { configOptions };
87
+ })
88
+ // A small bridge for older editors; the current API is session/set_config_option.
89
+ .onRequest("session/set_model", z.object({ sessionId: z.string(), modelId: z.string() }), async ({ params, client }) => {
90
+ const session = getSession(params.sessionId);
91
+ await updateSelectedModel(session, params.modelId, client);
92
+ return {};
93
+ })
94
+ .onNotification("session/cancel", ({ params }) => {
95
+ sessions.get(params.sessionId)?.activeTurn?.abort();
96
+ })
97
+ .onRequest("session/prompt", async ({ params, client, signal }) => {
98
+ const session = getSession(params.sessionId);
99
+ return runSessionPrompt({
100
+ config,
101
+ registry,
102
+ session,
103
+ capabilities,
104
+ client,
105
+ signal,
106
+ prompt: params.prompt,
107
+ });
108
+ }));
109
+ }
110
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/agent/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { type ContentBlock } from "@agentclientprotocol/sdk";
2
+ export declare function extractPromptText(blocks: ContentBlock[]): string;
@@ -0,0 +1,21 @@
1
+ import { RequestError } from "@agentclientprotocol/sdk";
2
+ export function extractPromptText(blocks) {
3
+ return blocks
4
+ .map((block) => {
5
+ switch (block.type) {
6
+ case "text":
7
+ return block.text;
8
+ case "resource":
9
+ if ("text" in block.resource) {
10
+ return `Resource: ${block.resource.uri}\n${block.resource.text}`;
11
+ }
12
+ throw RequestError.invalidParams(undefined, "Binary resources are not supported. Attach text instead.");
13
+ case "resource_link":
14
+ return `Referenced resource: ${block.name}\nURI: ${block.uri}`;
15
+ default:
16
+ throw RequestError.invalidParams(undefined, `Unsupported prompt content: ${block.type}`);
17
+ }
18
+ })
19
+ .join("\n\n");
20
+ }
21
+ //# sourceMappingURL=prompt-content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-content.js","sourceRoot":"","sources":["../../src/agent/prompt-content.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE3E,MAAM,UAAU,iBAAiB,CAAC,MAAsB;IACtD,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,MAAM;gBACT,OAAO,KAAK,CAAC,IAAI,CAAC;YACpB,KAAK,UAAU;gBACb,IAAI,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;oBAC7B,OAAO,aAAa,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACnE,CAAC;gBACD,MAAM,YAAY,CAAC,aAAa,CAC9B,SAAS,EACT,0DAA0D,CAC3D,CAAC;YACJ,KAAK,eAAe;gBAClB,OAAO,wBAAwB,KAAK,CAAC,IAAI,UAAU,KAAK,CAAC,GAAG,EAAE,CAAC;YACjE;gBACE,MAAM,YAAY,CAAC,aAAa,CAC9B,SAAS,EACT,+BAA+B,KAAK,CAAC,IAAI,EAAE,CAC5C,CAAC;QACN,CAAC;IACH,CAAC,CAAC;SACD,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { type SessionConfigOption } from "@agentclientprotocol/sdk";
2
+ import type { Config } from "../config/schema.js";
3
+ import type { Message } from "../providers/provider-contract.js";
4
+ import type { ProviderRegistry, RegisteredModel } from "../providers/provider-registry.js";
5
+ export interface AgentOptions {
6
+ provider?: string;
7
+ model?: string;
8
+ }
9
+ export interface AgentSession {
10
+ id: string;
11
+ workspaceDirectory: string;
12
+ modelCatalog: RegisteredModel[];
13
+ selectedModel: RegisteredModel;
14
+ history: Message[];
15
+ activeTurn?: AbortController;
16
+ }
17
+ export declare function createSession(workspaceDirectory: string, config: Config, registry: ProviderRegistry, options: AgentOptions, signal: AbortSignal): Promise<AgentSession>;
18
+ export declare function getSessionConfigOptions(session: AgentSession): SessionConfigOption[];
19
+ export declare function selectSessionModel(session: AgentSession, modelId: string): void;