claw-code 0.2.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.
- claw_code-0.2.0.dist-info/METADATA +560 -0
- claw_code-0.2.0.dist-info/RECORD +110 -0
- claw_code-0.2.0.dist-info/WHEEL +5 -0
- claw_code-0.2.0.dist-info/entry_points.txt +2 -0
- claw_code-0.2.0.dist-info/licenses/LICENSE +68 -0
- claw_code-0.2.0.dist-info/top_level.txt +1 -0
- src/QueryEngine.py +19 -0
- src/Tool.py +15 -0
- src/__init__.py +29 -0
- src/assistant/__init__.py +16 -0
- src/bootstrap/__init__.py +16 -0
- src/bootstrap_graph.py +27 -0
- src/bridge/__init__.py +16 -0
- src/buddy/__init__.py +16 -0
- src/cli/__init__.py +16 -0
- src/command_graph.py +34 -0
- src/commands.py +90 -0
- src/components/__init__.py +16 -0
- src/config.py +58 -0
- src/constants/__init__.py +16 -0
- src/context.py +47 -0
- src/coordinator/__init__.py +16 -0
- src/costHook.py +8 -0
- src/cost_tracker.py +13 -0
- src/deferred_init.py +31 -0
- src/dialogLaunchers.py +15 -0
- src/direct_modes.py +21 -0
- src/entrypoints/__init__.py +16 -0
- src/execution_registry.py +51 -0
- src/history.py +22 -0
- src/hooks/__init__.py +16 -0
- src/init_wizard.py +238 -0
- src/ink.py +6 -0
- src/interactiveHelpers.py +5 -0
- src/keybindings/__init__.py +16 -0
- src/main.py +274 -0
- src/memdir/__init__.py +16 -0
- src/migrations/__init__.py +16 -0
- src/model_detection.py +96 -0
- src/models.py +49 -0
- src/moreright/__init__.py +16 -0
- src/native_ts/__init__.py +16 -0
- src/outputStyles/__init__.py +16 -0
- src/parity_audit.py +138 -0
- src/permissions.py +20 -0
- src/plugins/__init__.py +16 -0
- src/port_manifest.py +52 -0
- src/prefetch.py +23 -0
- src/projectOnboardingState.py +10 -0
- src/query.py +13 -0
- src/query_engine.py +289 -0
- src/reference_data/__init__.py +1 -0
- src/reference_data/archive_surface_snapshot.json +63 -0
- src/reference_data/commands_snapshot.json +1037 -0
- src/reference_data/subsystems/assistant.json +8 -0
- src/reference_data/subsystems/bootstrap.json +8 -0
- src/reference_data/subsystems/bridge.json +32 -0
- src/reference_data/subsystems/buddy.json +13 -0
- src/reference_data/subsystems/cli.json +26 -0
- src/reference_data/subsystems/components.json +32 -0
- src/reference_data/subsystems/constants.json +28 -0
- src/reference_data/subsystems/coordinator.json +8 -0
- src/reference_data/subsystems/entrypoints.json +15 -0
- src/reference_data/subsystems/hooks.json +32 -0
- src/reference_data/subsystems/keybindings.json +21 -0
- src/reference_data/subsystems/memdir.json +15 -0
- src/reference_data/subsystems/migrations.json +18 -0
- src/reference_data/subsystems/moreright.json +8 -0
- src/reference_data/subsystems/native_ts.json +11 -0
- src/reference_data/subsystems/outputStyles.json +8 -0
- src/reference_data/subsystems/plugins.json +9 -0
- src/reference_data/subsystems/remote.json +11 -0
- src/reference_data/subsystems/schemas.json +8 -0
- src/reference_data/subsystems/screens.json +10 -0
- src/reference_data/subsystems/server.json +10 -0
- src/reference_data/subsystems/services.json +32 -0
- src/reference_data/subsystems/skills.json +27 -0
- src/reference_data/subsystems/state.json +13 -0
- src/reference_data/subsystems/types.json +18 -0
- src/reference_data/subsystems/upstreamproxy.json +9 -0
- src/reference_data/subsystems/utils.json +32 -0
- src/reference_data/subsystems/vim.json +12 -0
- src/reference_data/subsystems/voice.json +8 -0
- src/reference_data/tools_snapshot.json +922 -0
- src/remote/__init__.py +16 -0
- src/remote_runtime.py +25 -0
- src/repl.py +577 -0
- src/replLauncher.py +5 -0
- src/runtime.py +205 -0
- src/schemas/__init__.py +16 -0
- src/screens/__init__.py +16 -0
- src/server/__init__.py +16 -0
- src/services/__init__.py +16 -0
- src/services/ollama_adapter.py +251 -0
- src/services/ollama_setup.py +192 -0
- src/session_store.py +79 -0
- src/setup.py +77 -0
- src/skills/__init__.py +16 -0
- src/state/__init__.py +16 -0
- src/system_init.py +23 -0
- src/task.py +5 -0
- src/tasks.py +11 -0
- src/tool_pool.py +37 -0
- src/tools.py +96 -0
- src/transcript.py +23 -0
- src/types/__init__.py +16 -0
- src/upstreamproxy/__init__.py +16 -0
- src/utils/__init__.py +16 -0
- src/vim/__init__.py +16 -0
- src/voice/__init__.py +16 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Apache License
|
|
2
|
+
## Version 2.0, January 2004
|
|
3
|
+
|
|
4
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
5
|
+
|
|
6
|
+
### 1. Definitions
|
|
7
|
+
|
|
8
|
+
"License" means the terms and conditions for use, reproduction, and distribution as defined in Sections 1 through 9 of this document.
|
|
9
|
+
|
|
10
|
+
"Licensor" means the copyright owner or entity authorized by the copyright owner that is granting the License. For legal entities, the entity making a contribution and all other entities that control, are controlled by, or are under common control with that entity.
|
|
11
|
+
|
|
12
|
+
"Legal Entity" means the union of the acting entity and all other entities that control, are controlled by, or are under common control with it.
|
|
13
|
+
|
|
14
|
+
"You" (or "Your") means an individual or Legal Entity exercising permissions granted by this License.
|
|
15
|
+
|
|
16
|
+
"Source" form means the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
|
17
|
+
|
|
18
|
+
"Object" form means any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
|
19
|
+
|
|
20
|
+
"Work" means the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
|
21
|
+
|
|
22
|
+
"Derivative Works" means any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship.
|
|
23
|
+
|
|
24
|
+
"Contribution" means any work of authorship, including the original Work and any Derivative Works thereof, that is intentionally submitted to, or received by, Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner.
|
|
25
|
+
|
|
26
|
+
"Contributor" means Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
|
27
|
+
|
|
28
|
+
### 2. Grant of Copyright License
|
|
29
|
+
|
|
30
|
+
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
|
31
|
+
|
|
32
|
+
### 3. Grant of Patent License
|
|
33
|
+
|
|
34
|
+
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
|
35
|
+
|
|
36
|
+
### 4. Redistribution
|
|
37
|
+
|
|
38
|
+
You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
|
39
|
+
|
|
40
|
+
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
|
41
|
+
|
|
42
|
+
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
|
|
43
|
+
|
|
44
|
+
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
|
45
|
+
|
|
46
|
+
(d) If the Work includes a "NOTICE" text file, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear.
|
|
47
|
+
|
|
48
|
+
### 5. Submission of Contributions
|
|
49
|
+
|
|
50
|
+
Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contribution.
|
|
51
|
+
|
|
52
|
+
### 6. Trademarks
|
|
53
|
+
|
|
54
|
+
This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
|
55
|
+
|
|
56
|
+
### 7. Disclaimer of Warranty
|
|
57
|
+
|
|
58
|
+
Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
|
|
59
|
+
|
|
60
|
+
### 8. Limitation of Liability
|
|
61
|
+
|
|
62
|
+
In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work.
|
|
63
|
+
|
|
64
|
+
### 9. Accepting Warranty or Additional Liability
|
|
65
|
+
|
|
66
|
+
While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
|
67
|
+
|
|
68
|
+
END OF TERMS AND CONDITIONS
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
src
|
src/QueryEngine.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from .query_engine import QueryEnginePort
|
|
4
|
+
from .runtime import PortRuntime
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class QueryEngineRuntime(QueryEnginePort):
|
|
8
|
+
def route(self, prompt: str, limit: int = 5) -> str:
|
|
9
|
+
matches = PortRuntime().route_prompt(prompt, limit=limit)
|
|
10
|
+
lines = ['# Query Engine Route', '', f'Prompt: {prompt}', '']
|
|
11
|
+
if not matches:
|
|
12
|
+
lines.append('No mirrored command/tool matches found.')
|
|
13
|
+
return '\n'.join(lines)
|
|
14
|
+
lines.append('Matches:')
|
|
15
|
+
lines.extend(f'- [{match.kind}] {match.name} ({match.score}) — {match.source_hint}' for match in matches)
|
|
16
|
+
return '\n'.join(lines)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
__all__ = ['QueryEnginePort', 'QueryEngineRuntime']
|
src/Tool.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass(frozen=True)
|
|
7
|
+
class ToolDefinition:
|
|
8
|
+
name: str
|
|
9
|
+
purpose: str
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
DEFAULT_TOOLS = (
|
|
13
|
+
ToolDefinition('port_manifest', 'Summarize the active Python workspace'),
|
|
14
|
+
ToolDefinition('query_engine', 'Render a Python-first porting summary'),
|
|
15
|
+
)
|
src/__init__.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Python porting workspace for the Claude Code rewrite effort."""
|
|
2
|
+
|
|
3
|
+
from .commands import PORTED_COMMANDS, build_command_backlog
|
|
4
|
+
from .parity_audit import ParityAuditResult, run_parity_audit
|
|
5
|
+
from .port_manifest import PortManifest, build_port_manifest
|
|
6
|
+
from .query_engine import QueryEnginePort, TurnResult
|
|
7
|
+
from .runtime import PortRuntime, RuntimeSession
|
|
8
|
+
from .session_store import StoredSession, load_session, save_session
|
|
9
|
+
from .system_init import build_system_init_message
|
|
10
|
+
from .tools import PORTED_TOOLS, build_tool_backlog
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
'ParityAuditResult',
|
|
14
|
+
'PortManifest',
|
|
15
|
+
'PortRuntime',
|
|
16
|
+
'QueryEnginePort',
|
|
17
|
+
'RuntimeSession',
|
|
18
|
+
'StoredSession',
|
|
19
|
+
'TurnResult',
|
|
20
|
+
'PORTED_COMMANDS',
|
|
21
|
+
'PORTED_TOOLS',
|
|
22
|
+
'build_command_backlog',
|
|
23
|
+
'build_port_manifest',
|
|
24
|
+
'build_system_init_message',
|
|
25
|
+
'build_tool_backlog',
|
|
26
|
+
'load_session',
|
|
27
|
+
'run_parity_audit',
|
|
28
|
+
'save_session',
|
|
29
|
+
]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Python package placeholder for the archived `assistant` subsystem."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'assistant.json'
|
|
9
|
+
_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text())
|
|
10
|
+
|
|
11
|
+
ARCHIVE_NAME = _SNAPSHOT['archive_name']
|
|
12
|
+
MODULE_COUNT = _SNAPSHOT['module_count']
|
|
13
|
+
SAMPLE_FILES = tuple(_SNAPSHOT['sample_files'])
|
|
14
|
+
PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references."
|
|
15
|
+
|
|
16
|
+
__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES']
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Python package placeholder for the archived `bootstrap` subsystem."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'bootstrap.json'
|
|
9
|
+
_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text())
|
|
10
|
+
|
|
11
|
+
ARCHIVE_NAME = _SNAPSHOT['archive_name']
|
|
12
|
+
MODULE_COUNT = _SNAPSHOT['module_count']
|
|
13
|
+
SAMPLE_FILES = tuple(_SNAPSHOT['sample_files'])
|
|
14
|
+
PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references."
|
|
15
|
+
|
|
16
|
+
__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES']
|
src/bootstrap_graph.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass(frozen=True)
|
|
7
|
+
class BootstrapGraph:
|
|
8
|
+
stages: tuple[str, ...]
|
|
9
|
+
|
|
10
|
+
def as_markdown(self) -> str:
|
|
11
|
+
lines = ['# Bootstrap Graph', '']
|
|
12
|
+
lines.extend(f'- {stage}' for stage in self.stages)
|
|
13
|
+
return '\n'.join(lines)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def build_bootstrap_graph() -> BootstrapGraph:
|
|
17
|
+
return BootstrapGraph(
|
|
18
|
+
stages=(
|
|
19
|
+
'top-level prefetch side effects',
|
|
20
|
+
'warning handler and environment guards',
|
|
21
|
+
'CLI parser and pre-action trust gate',
|
|
22
|
+
'setup() + commands/agents parallel load',
|
|
23
|
+
'deferred init after trust',
|
|
24
|
+
'mode routing: local / remote / ssh / teleport / direct-connect / deep-link',
|
|
25
|
+
'query engine submit loop',
|
|
26
|
+
)
|
|
27
|
+
)
|
src/bridge/__init__.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Python package placeholder for the archived `bridge` subsystem."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'bridge.json'
|
|
9
|
+
_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text())
|
|
10
|
+
|
|
11
|
+
ARCHIVE_NAME = _SNAPSHOT['archive_name']
|
|
12
|
+
MODULE_COUNT = _SNAPSHOT['module_count']
|
|
13
|
+
SAMPLE_FILES = tuple(_SNAPSHOT['sample_files'])
|
|
14
|
+
PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references."
|
|
15
|
+
|
|
16
|
+
__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES']
|
src/buddy/__init__.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Python package placeholder for the archived `buddy` subsystem."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'buddy.json'
|
|
9
|
+
_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text())
|
|
10
|
+
|
|
11
|
+
ARCHIVE_NAME = _SNAPSHOT['archive_name']
|
|
12
|
+
MODULE_COUNT = _SNAPSHOT['module_count']
|
|
13
|
+
SAMPLE_FILES = tuple(_SNAPSHOT['sample_files'])
|
|
14
|
+
PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references."
|
|
15
|
+
|
|
16
|
+
__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES']
|
src/cli/__init__.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Python package placeholder for the archived `cli` subsystem."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'cli.json'
|
|
9
|
+
_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text())
|
|
10
|
+
|
|
11
|
+
ARCHIVE_NAME = _SNAPSHOT['archive_name']
|
|
12
|
+
MODULE_COUNT = _SNAPSHOT['module_count']
|
|
13
|
+
SAMPLE_FILES = tuple(_SNAPSHOT['sample_files'])
|
|
14
|
+
PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references."
|
|
15
|
+
|
|
16
|
+
__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES']
|
src/command_graph.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
from .commands import get_commands
|
|
6
|
+
from .models import PortingModule
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass(frozen=True)
|
|
10
|
+
class CommandGraph:
|
|
11
|
+
builtins: tuple[PortingModule, ...]
|
|
12
|
+
plugin_like: tuple[PortingModule, ...]
|
|
13
|
+
skill_like: tuple[PortingModule, ...]
|
|
14
|
+
|
|
15
|
+
def flattened(self) -> tuple[PortingModule, ...]:
|
|
16
|
+
return self.builtins + self.plugin_like + self.skill_like
|
|
17
|
+
|
|
18
|
+
def as_markdown(self) -> str:
|
|
19
|
+
lines = [
|
|
20
|
+
'# Command Graph',
|
|
21
|
+
'',
|
|
22
|
+
f'Builtins: {len(self.builtins)}',
|
|
23
|
+
f'Plugin-like commands: {len(self.plugin_like)}',
|
|
24
|
+
f'Skill-like commands: {len(self.skill_like)}',
|
|
25
|
+
]
|
|
26
|
+
return '\n'.join(lines)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def build_command_graph() -> CommandGraph:
|
|
30
|
+
commands = get_commands()
|
|
31
|
+
builtins = tuple(module for module in commands if 'plugin' not in module.source_hint.lower() and 'skills' not in module.source_hint.lower())
|
|
32
|
+
plugin_like = tuple(module for module in commands if 'plugin' in module.source_hint.lower())
|
|
33
|
+
skill_like = tuple(module for module in commands if 'skills' in module.source_hint.lower())
|
|
34
|
+
return CommandGraph(builtins=builtins, plugin_like=plugin_like, skill_like=skill_like)
|
src/commands.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from functools import lru_cache
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from .models import PortingBacklog, PortingModule
|
|
9
|
+
|
|
10
|
+
SNAPSHOT_PATH = Path(__file__).resolve().parent / 'reference_data' / 'commands_snapshot.json'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class CommandExecution:
|
|
15
|
+
name: str
|
|
16
|
+
source_hint: str
|
|
17
|
+
prompt: str
|
|
18
|
+
handled: bool
|
|
19
|
+
message: str
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@lru_cache(maxsize=1)
|
|
23
|
+
def load_command_snapshot() -> tuple[PortingModule, ...]:
|
|
24
|
+
raw_entries = json.loads(SNAPSHOT_PATH.read_text())
|
|
25
|
+
return tuple(
|
|
26
|
+
PortingModule(
|
|
27
|
+
name=entry['name'],
|
|
28
|
+
responsibility=entry['responsibility'],
|
|
29
|
+
source_hint=entry['source_hint'],
|
|
30
|
+
status='mirrored',
|
|
31
|
+
)
|
|
32
|
+
for entry in raw_entries
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
PORTED_COMMANDS = load_command_snapshot()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@lru_cache(maxsize=1)
|
|
40
|
+
def built_in_command_names() -> frozenset[str]:
|
|
41
|
+
return frozenset(module.name for module in PORTED_COMMANDS)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def build_command_backlog() -> PortingBacklog:
|
|
45
|
+
return PortingBacklog(title='Command surface', modules=list(PORTED_COMMANDS))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def command_names() -> list[str]:
|
|
49
|
+
return [module.name for module in PORTED_COMMANDS]
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def get_command(name: str) -> PortingModule | None:
|
|
53
|
+
needle = name.lower()
|
|
54
|
+
for module in PORTED_COMMANDS:
|
|
55
|
+
if module.name.lower() == needle:
|
|
56
|
+
return module
|
|
57
|
+
return None
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def get_commands(cwd: str | None = None, include_plugin_commands: bool = True, include_skill_commands: bool = True) -> tuple[PortingModule, ...]:
|
|
61
|
+
commands = list(PORTED_COMMANDS)
|
|
62
|
+
if not include_plugin_commands:
|
|
63
|
+
commands = [module for module in commands if 'plugin' not in module.source_hint.lower()]
|
|
64
|
+
if not include_skill_commands:
|
|
65
|
+
commands = [module for module in commands if 'skills' not in module.source_hint.lower()]
|
|
66
|
+
return tuple(commands)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def find_commands(query: str, limit: int = 20) -> list[PortingModule]:
|
|
70
|
+
needle = query.lower()
|
|
71
|
+
matches = [module for module in PORTED_COMMANDS if needle in module.name.lower() or needle in module.source_hint.lower()]
|
|
72
|
+
return matches[:limit]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def execute_command(name: str, prompt: str = '') -> CommandExecution:
|
|
76
|
+
module = get_command(name)
|
|
77
|
+
if module is None:
|
|
78
|
+
return CommandExecution(name=name, source_hint='', prompt=prompt, handled=False, message=f'Unknown mirrored command: {name}')
|
|
79
|
+
action = f"Mirrored command '{module.name}' from {module.source_hint} would handle prompt {prompt!r}."
|
|
80
|
+
return CommandExecution(name=module.name, source_hint=module.source_hint, prompt=prompt, handled=True, message=action)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def render_command_index(limit: int = 20, query: str | None = None) -> str:
|
|
84
|
+
modules = find_commands(query, limit) if query else list(PORTED_COMMANDS[:limit])
|
|
85
|
+
lines = [f'Command entries: {len(PORTED_COMMANDS)}', '']
|
|
86
|
+
if query:
|
|
87
|
+
lines.append(f'Filtered by: {query}')
|
|
88
|
+
lines.append('')
|
|
89
|
+
lines.extend(f'- {module.name} — {module.source_hint}' for module in modules)
|
|
90
|
+
return '\n'.join(lines)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Python package placeholder for the archived `components` subsystem."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'components.json'
|
|
9
|
+
_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text())
|
|
10
|
+
|
|
11
|
+
ARCHIVE_NAME = _SNAPSHOT['archive_name']
|
|
12
|
+
MODULE_COUNT = _SNAPSHOT['module_count']
|
|
13
|
+
SAMPLE_FILES = tuple(_SNAPSHOT['sample_files'])
|
|
14
|
+
PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references."
|
|
15
|
+
|
|
16
|
+
__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES']
|
src/config.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configuration loading for Claw Code.
|
|
3
|
+
Supports both .claude.json and environment variables.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import logging
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True)
|
|
17
|
+
class ClaudeConfig:
|
|
18
|
+
"""Configuration for Claw Code runtime"""
|
|
19
|
+
provider: str # "ollama" or "anthropic"
|
|
20
|
+
ollama_base_url: str
|
|
21
|
+
model: str
|
|
22
|
+
max_tokens: int
|
|
23
|
+
temperature: float
|
|
24
|
+
auto_detect_vram: bool
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def load_config() -> ClaudeConfig:
|
|
28
|
+
"""Load configuration from ~/.claude.json or create defaults"""
|
|
29
|
+
config_path = Path.home() / ".claude.json"
|
|
30
|
+
|
|
31
|
+
# Default config for Ollama
|
|
32
|
+
defaults = {
|
|
33
|
+
"provider": "ollama",
|
|
34
|
+
"ollama_base_url": "http://localhost:11434",
|
|
35
|
+
"model": "auto-detect",
|
|
36
|
+
"max_tokens": 2048,
|
|
37
|
+
"temperature": 0.7,
|
|
38
|
+
"auto_detect_vram": True,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# Try to load from file
|
|
42
|
+
if config_path.exists():
|
|
43
|
+
try:
|
|
44
|
+
with open(config_path) as f:
|
|
45
|
+
file_config = json.load(f)
|
|
46
|
+
defaults.update(file_config)
|
|
47
|
+
logger.info(f"Loaded config from {config_path}")
|
|
48
|
+
except (json.JSONDecodeError, IOError) as e:
|
|
49
|
+
logger.warning(f"Failed to load config from {config_path}: {e}, using defaults")
|
|
50
|
+
|
|
51
|
+
return ClaudeConfig(
|
|
52
|
+
provider=defaults.get("provider", "ollama"),
|
|
53
|
+
ollama_base_url=defaults.get("ollama_base_url", "http://localhost:11434"),
|
|
54
|
+
model=defaults.get("model", "auto-detect"),
|
|
55
|
+
max_tokens=defaults.get("max_tokens", 2048),
|
|
56
|
+
temperature=defaults.get("temperature", 0.7),
|
|
57
|
+
auto_detect_vram=defaults.get("auto_detect_vram", True),
|
|
58
|
+
)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Python package placeholder for the archived `constants` subsystem."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'constants.json'
|
|
9
|
+
_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text())
|
|
10
|
+
|
|
11
|
+
ARCHIVE_NAME = _SNAPSHOT['archive_name']
|
|
12
|
+
MODULE_COUNT = _SNAPSHOT['module_count']
|
|
13
|
+
SAMPLE_FILES = tuple(_SNAPSHOT['sample_files'])
|
|
14
|
+
PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references."
|
|
15
|
+
|
|
16
|
+
__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES']
|
src/context.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass(frozen=True)
|
|
8
|
+
class PortContext:
|
|
9
|
+
source_root: Path
|
|
10
|
+
tests_root: Path
|
|
11
|
+
assets_root: Path
|
|
12
|
+
archive_root: Path
|
|
13
|
+
python_file_count: int
|
|
14
|
+
test_file_count: int
|
|
15
|
+
asset_file_count: int
|
|
16
|
+
archive_available: bool
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def build_port_context(base: Path | None = None) -> PortContext:
|
|
20
|
+
root = base or Path(__file__).resolve().parent.parent
|
|
21
|
+
source_root = root / 'src'
|
|
22
|
+
tests_root = root / 'tests'
|
|
23
|
+
assets_root = root / 'assets'
|
|
24
|
+
archive_root = root / 'archive' / 'claude_code_ts_snapshot' / 'src'
|
|
25
|
+
return PortContext(
|
|
26
|
+
source_root=source_root,
|
|
27
|
+
tests_root=tests_root,
|
|
28
|
+
assets_root=assets_root,
|
|
29
|
+
archive_root=archive_root,
|
|
30
|
+
python_file_count=sum(1 for path in source_root.rglob('*.py') if path.is_file()),
|
|
31
|
+
test_file_count=sum(1 for path in tests_root.rglob('*.py') if path.is_file()),
|
|
32
|
+
asset_file_count=sum(1 for path in assets_root.rglob('*') if path.is_file()),
|
|
33
|
+
archive_available=archive_root.exists(),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def render_context(context: PortContext) -> str:
|
|
38
|
+
return '\n'.join([
|
|
39
|
+
f'Source root: {context.source_root}',
|
|
40
|
+
f'Test root: {context.tests_root}',
|
|
41
|
+
f'Assets root: {context.assets_root}',
|
|
42
|
+
f'Archive root: {context.archive_root}',
|
|
43
|
+
f'Python files: {context.python_file_count}',
|
|
44
|
+
f'Test files: {context.test_file_count}',
|
|
45
|
+
f'Assets: {context.asset_file_count}',
|
|
46
|
+
f'Archive available: {context.archive_available}',
|
|
47
|
+
])
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Python package placeholder for the archived `coordinator` subsystem."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'coordinator.json'
|
|
9
|
+
_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text())
|
|
10
|
+
|
|
11
|
+
ARCHIVE_NAME = _SNAPSHOT['archive_name']
|
|
12
|
+
MODULE_COUNT = _SNAPSHOT['module_count']
|
|
13
|
+
SAMPLE_FILES = tuple(_SNAPSHOT['sample_files'])
|
|
14
|
+
PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references."
|
|
15
|
+
|
|
16
|
+
__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES']
|
src/costHook.py
ADDED
src/cost_tracker.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass
|
|
7
|
+
class CostTracker:
|
|
8
|
+
total_units: int = 0
|
|
9
|
+
events: list[str] = field(default_factory=list)
|
|
10
|
+
|
|
11
|
+
def record(self, label: str, units: int) -> None:
|
|
12
|
+
self.total_units += units
|
|
13
|
+
self.events.append(f'{label}:{units}')
|
src/deferred_init.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass(frozen=True)
|
|
7
|
+
class DeferredInitResult:
|
|
8
|
+
trusted: bool
|
|
9
|
+
plugin_init: bool
|
|
10
|
+
skill_init: bool
|
|
11
|
+
mcp_prefetch: bool
|
|
12
|
+
session_hooks: bool
|
|
13
|
+
|
|
14
|
+
def as_lines(self) -> tuple[str, ...]:
|
|
15
|
+
return (
|
|
16
|
+
f'- plugin_init={self.plugin_init}',
|
|
17
|
+
f'- skill_init={self.skill_init}',
|
|
18
|
+
f'- mcp_prefetch={self.mcp_prefetch}',
|
|
19
|
+
f'- session_hooks={self.session_hooks}',
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def run_deferred_init(trusted: bool) -> DeferredInitResult:
|
|
24
|
+
enabled = bool(trusted)
|
|
25
|
+
return DeferredInitResult(
|
|
26
|
+
trusted=trusted,
|
|
27
|
+
plugin_init=enabled,
|
|
28
|
+
skill_init=enabled,
|
|
29
|
+
mcp_prefetch=enabled,
|
|
30
|
+
session_hooks=enabled,
|
|
31
|
+
)
|
src/dialogLaunchers.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass(frozen=True)
|
|
7
|
+
class DialogLauncher:
|
|
8
|
+
name: str
|
|
9
|
+
description: str
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
DEFAULT_DIALOGS = (
|
|
13
|
+
DialogLauncher('summary', 'Launch the Markdown summary view'),
|
|
14
|
+
DialogLauncher('parity_audit', 'Launch the parity audit view'),
|
|
15
|
+
)
|
src/direct_modes.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass(frozen=True)
|
|
7
|
+
class DirectModeReport:
|
|
8
|
+
mode: str
|
|
9
|
+
target: str
|
|
10
|
+
active: bool
|
|
11
|
+
|
|
12
|
+
def as_text(self) -> str:
|
|
13
|
+
return f'mode={self.mode}\ntarget={self.target}\nactive={self.active}'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def run_direct_connect(target: str) -> DirectModeReport:
|
|
17
|
+
return DirectModeReport(mode='direct-connect', target=target, active=True)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def run_deep_link(target: str) -> DirectModeReport:
|
|
21
|
+
return DirectModeReport(mode='deep-link', target=target, active=True)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Python package placeholder for the archived `entrypoints` subsystem."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
SNAPSHOT_PATH = Path(__file__).resolve().parent.parent / 'reference_data' / 'subsystems' / 'entrypoints.json'
|
|
9
|
+
_SNAPSHOT = json.loads(SNAPSHOT_PATH.read_text())
|
|
10
|
+
|
|
11
|
+
ARCHIVE_NAME = _SNAPSHOT['archive_name']
|
|
12
|
+
MODULE_COUNT = _SNAPSHOT['module_count']
|
|
13
|
+
SAMPLE_FILES = tuple(_SNAPSHOT['sample_files'])
|
|
14
|
+
PORTING_NOTE = f"Python placeholder package for '{ARCHIVE_NAME}' with {MODULE_COUNT} archived module references."
|
|
15
|
+
|
|
16
|
+
__all__ = ['ARCHIVE_NAME', 'MODULE_COUNT', 'PORTING_NOTE', 'SAMPLE_FILES']
|