kiwimatecoder 0.1.0__py3-none-any.whl
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.
- kiwimatecoder/__init__.py +8 -0
- kiwimatecoder/__main__.py +12 -0
- kiwimatecoder/acp/__init__.py +13 -0
- kiwimatecoder/acp/protocol.py +115 -0
- kiwimatecoder/acp/server.py +823 -0
- kiwimatecoder/acp/stdio.py +32 -0
- kiwimatecoder/agent.py +1162 -0
- kiwimatecoder/ai.py +68 -0
- kiwimatecoder/audit.py +65 -0
- kiwimatecoder/browser.py +261 -0
- kiwimatecoder/catalog.py +445 -0
- kiwimatecoder/checkpoints.py +103 -0
- kiwimatecoder/client.py +820 -0
- kiwimatecoder/clipboard.py +99 -0
- kiwimatecoder/commands.py +6757 -0
- kiwimatecoder/config.py +5335 -0
- kiwimatecoder/diagnostics.py +295 -0
- kiwimatecoder/documents.py +299 -0
- kiwimatecoder/evals/__init__.py +39 -0
- kiwimatecoder/evals/cases.py +230 -0
- kiwimatecoder/evals/render.py +46 -0
- kiwimatecoder/evals/runner.py +319 -0
- kiwimatecoder/events.py +95 -0
- kiwimatecoder/forge.py +172 -0
- kiwimatecoder/git.py +164 -0
- kiwimatecoder/headless.py +255 -0
- kiwimatecoder/hooks.py +170 -0
- kiwimatecoder/hunks.py +260 -0
- kiwimatecoder/i18n.py +368 -0
- kiwimatecoder/images.py +195 -0
- kiwimatecoder/index/__init__.py +14 -0
- kiwimatecoder/index/builder.py +376 -0
- kiwimatecoder/index/embeddings.py +151 -0
- kiwimatecoder/index/search.py +247 -0
- kiwimatecoder/index/store.py +251 -0
- kiwimatecoder/instructions.py +83 -0
- kiwimatecoder/jobs.py +594 -0
- kiwimatecoder/lsp/__init__.py +56 -0
- kiwimatecoder/lsp/client.py +548 -0
- kiwimatecoder/lsp/manager.py +353 -0
- kiwimatecoder/lsp/protocol.py +79 -0
- kiwimatecoder/main.py +4258 -0
- kiwimatecoder/mcp/__init__.py +45 -0
- kiwimatecoder/mcp/client.py +385 -0
- kiwimatecoder/mcp/errors.py +7 -0
- kiwimatecoder/mcp/manager.py +253 -0
- kiwimatecoder/mcp/protocol.py +132 -0
- kiwimatecoder/media.py +904 -0
- kiwimatecoder/memory.py +141 -0
- kiwimatecoder/network.py +112 -0
- kiwimatecoder/notify.py +139 -0
- kiwimatecoder/permissions.py +171 -0
- kiwimatecoder/pickers.py +417 -0
- kiwimatecoder/plugins.py +245 -0
- kiwimatecoder/pricing.py +167 -0
- kiwimatecoder/prompts.py +213 -0
- kiwimatecoder/providers.py +342 -0
- kiwimatecoder/redaction.py +66 -0
- kiwimatecoder/remote.py +294 -0
- kiwimatecoder/repl.py +1388 -0
- kiwimatecoder/routing.py +65 -0
- kiwimatecoder/sandbox.py +169 -0
- kiwimatecoder/sdk.py +146 -0
- kiwimatecoder/session.py +574 -0
- kiwimatecoder/share.py +386 -0
- kiwimatecoder/shell.py +660 -0
- kiwimatecoder/skills.py +138 -0
- kiwimatecoder/sync.py +513 -0
- kiwimatecoder/team.py +249 -0
- kiwimatecoder/telemetry.py +392 -0
- kiwimatecoder/templates.py +108 -0
- kiwimatecoder/tools/__init__.py +190 -0
- kiwimatecoder/tools/ask.py +62 -0
- kiwimatecoder/tools/base.py +69 -0
- kiwimatecoder/tools/browser.py +261 -0
- kiwimatecoder/tools/edit_file.py +143 -0
- kiwimatecoder/tools/forge.py +207 -0
- kiwimatecoder/tools/git.py +158 -0
- kiwimatecoder/tools/image.py +300 -0
- kiwimatecoder/tools/io.py +346 -0
- kiwimatecoder/tools/list_dir.py +67 -0
- kiwimatecoder/tools/lsp.py +254 -0
- kiwimatecoder/tools/memory.py +115 -0
- kiwimatecoder/tools/paths.py +234 -0
- kiwimatecoder/tools/read_file.py +113 -0
- kiwimatecoder/tools/registry.py +91 -0
- kiwimatecoder/tools/run_bash.py +189 -0
- kiwimatecoder/tools/search.py +224 -0
- kiwimatecoder/tools/selection.py +108 -0
- kiwimatecoder/tools/shell.py +158 -0
- kiwimatecoder/tools/skill.py +46 -0
- kiwimatecoder/tools/task.py +61 -0
- kiwimatecoder/tools/todo.py +77 -0
- kiwimatecoder/tools/web.py +146 -0
- kiwimatecoder/tools/write_file.py +83 -0
- kiwimatecoder/ui.py +189 -0
- kiwimatecoder/updater.py +502 -0
- kiwimatecoder/web.py +499 -0
- kiwimatecoder-0.1.0.dist-info/METADATA +2016 -0
- kiwimatecoder-0.1.0.dist-info/RECORD +104 -0
- kiwimatecoder-0.1.0.dist-info/WHEEL +5 -0
- kiwimatecoder-0.1.0.dist-info/entry_points.txt +2 -0
- kiwimatecoder-0.1.0.dist-info/licenses/LICENSE +21 -0
- kiwimatecoder-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Run the CLI with ``python -m kiwimatecoder``.
|
|
2
|
+
|
|
3
|
+
Background jobs spawn headless agent runs this way so they do not depend on the
|
|
4
|
+
``kiwimatecoder`` console script being on PATH.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from kiwimatecoder.main import app
|
|
10
|
+
|
|
11
|
+
if __name__ == "__main__":
|
|
12
|
+
app()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Agent Client Protocol (ACP) server for editor integration.
|
|
2
|
+
|
|
3
|
+
The public surface is small: :class:`~kiwimatecoder.acp.server.AcpServer`
|
|
4
|
+
speaks JSON-RPC 2.0 over newline-delimited JSON, :mod:`kiwimatecoder.acp.stdio`
|
|
5
|
+
wires that to real stdin/stdout, and :mod:`kiwimatecoder.acp.protocol` holds
|
|
6
|
+
the transport-agnostic codec. See the README's "Editor integration (ACP)"
|
|
7
|
+
section for the implemented subset.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from kiwimatecoder.acp.protocol import decode_lines, encode
|
|
11
|
+
from kiwimatecoder.acp.server import AcpServer
|
|
12
|
+
|
|
13
|
+
__all__ = ["AcpServer", "decode_lines", "encode"]
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"""Newline-delimited JSON-RPC 2.0 framing for the ACP server.
|
|
2
|
+
|
|
3
|
+
ACP messages are JSON-RPC 2.0 objects sent one per line over stdio, so this
|
|
4
|
+
module is a tiny, transport-agnostic codec: :func:`encode` renders a message
|
|
5
|
+
as a terminated line and :func:`decode_lines` incrementally consumes a buffer,
|
|
6
|
+
returning the messages found so far plus whatever partial line is left over.
|
|
7
|
+
Malformed lines are dropped rather than raising, so a broken client can never
|
|
8
|
+
take the server down; the server reports a parse error before falling back to
|
|
9
|
+
this codec (see :meth:`kiwimatecoder.acp.server.AcpServer._handle_line`).
|
|
10
|
+
|
|
11
|
+
Everything here is pure and synchronous; no I/O or asyncio.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import json
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
19
|
+
# Standard JSON-RPC 2.0 error codes plus the server-defined range.
|
|
20
|
+
ERROR_PARSE = -32700
|
|
21
|
+
ERROR_INVALID_REQUEST = -32600
|
|
22
|
+
ERROR_METHOD_NOT_FOUND = -32601
|
|
23
|
+
ERROR_INVALID_PARAMS = -32602
|
|
24
|
+
ERROR_INTERNAL = -32603
|
|
25
|
+
ERROR_SERVER = -32000
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class AcpError(Exception):
|
|
29
|
+
"""A JSON-RPC error that should be returned to the caller."""
|
|
30
|
+
|
|
31
|
+
def __init__(self, code: int, message: str, data: Any = None) -> None:
|
|
32
|
+
super().__init__(message)
|
|
33
|
+
self.code = code
|
|
34
|
+
self.message = message
|
|
35
|
+
self.data = data
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class AcpTimeoutError(TimeoutError):
|
|
39
|
+
"""Raised when a request to the client is not answered in time."""
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class IdAllocator:
|
|
43
|
+
"""Monotonic request-id source for agent -> client requests."""
|
|
44
|
+
|
|
45
|
+
def __init__(self, start: int = 0) -> None:
|
|
46
|
+
self._value = start
|
|
47
|
+
|
|
48
|
+
def next(self) -> int:
|
|
49
|
+
self._value += 1
|
|
50
|
+
return self._value
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def encode(message: Any) -> str:
|
|
54
|
+
"""Render ``message`` as one newline-terminated JSON line."""
|
|
55
|
+
return json.dumps(message, separators=(",", ":"), ensure_ascii=False) + "\n"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def decode_lines(buffer: str) -> tuple[list[dict[str, Any]], str]:
|
|
59
|
+
"""Split complete JSON lines out of ``buffer``.
|
|
60
|
+
|
|
61
|
+
Returns ``(messages, remainder)`` where ``remainder`` is the unterminated
|
|
62
|
+
tail (empty when the buffer ended on a newline). Non-object and malformed
|
|
63
|
+
lines are skipped so one bad message cannot poison the stream.
|
|
64
|
+
"""
|
|
65
|
+
messages: list[dict[str, Any]] = []
|
|
66
|
+
remainder = buffer
|
|
67
|
+
while "\n" in remainder:
|
|
68
|
+
line, remainder = remainder.split("\n", 1)
|
|
69
|
+
text = line.strip()
|
|
70
|
+
if not text:
|
|
71
|
+
continue
|
|
72
|
+
try:
|
|
73
|
+
payload = json.loads(text)
|
|
74
|
+
except json.JSONDecodeError:
|
|
75
|
+
continue
|
|
76
|
+
if isinstance(payload, dict):
|
|
77
|
+
messages.append(payload)
|
|
78
|
+
return messages, remainder
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def request_message(
|
|
82
|
+
request_id: int, method: str, params: dict[str, Any] | None = None
|
|
83
|
+
) -> dict[str, Any]:
|
|
84
|
+
"""Build a JSON-RPC request object."""
|
|
85
|
+
return {
|
|
86
|
+
"jsonrpc": "2.0",
|
|
87
|
+
"id": request_id,
|
|
88
|
+
"method": method,
|
|
89
|
+
"params": params if params is not None else {},
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def notification_message(
|
|
94
|
+
method: str, params: dict[str, Any] | None = None
|
|
95
|
+
) -> dict[str, Any]:
|
|
96
|
+
"""Build a JSON-RPC notification (no ``id``, no response expected)."""
|
|
97
|
+
message: dict[str, Any] = {"jsonrpc": "2.0", "method": method}
|
|
98
|
+
if params is not None:
|
|
99
|
+
message["params"] = params
|
|
100
|
+
return message
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def success_response(request_id: Any, result: Any) -> dict[str, Any]:
|
|
104
|
+
"""Build a JSON-RPC success response."""
|
|
105
|
+
return {"jsonrpc": "2.0", "id": request_id, "result": result if result is not None else {}}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def error_response(
|
|
109
|
+
request_id: Any, code: int, message: str, data: Any = None
|
|
110
|
+
) -> dict[str, Any]:
|
|
111
|
+
"""Build a JSON-RPC error response."""
|
|
112
|
+
error: dict[str, Any] = {"code": code, "message": message}
|
|
113
|
+
if data is not None:
|
|
114
|
+
error["data"] = data
|
|
115
|
+
return {"jsonrpc": "2.0", "id": request_id, "error": error}
|