@theharshitsingh/hc 0.2.0 → 0.2.2
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.
- package/hconv/adapters/codex.py +11 -2
- package/hconv/adapters/opencode.py +8 -2
- package/hconv/cli.py +3 -1
- package/package.json +2 -2
package/hconv/adapters/codex.py
CHANGED
|
@@ -19,7 +19,13 @@ from ..common import (AssistantMessage, Session, ToolCall, ToolResult,
|
|
|
19
19
|
|
|
20
20
|
SESSIONS = Path(os.path.expanduser("~/.codex/sessions"))
|
|
21
21
|
INDEX = Path(os.path.expanduser("~/.codex/session_index.jsonl"))
|
|
22
|
-
CLI_VERSION = "0.
|
|
22
|
+
CLI_VERSION = "0.144.5"
|
|
23
|
+
# codex >= 0.144 registers every rollout in its threads db (state_5.sqlite),
|
|
24
|
+
# building the row from session_meta. model_provider is NOT NULL there; if the
|
|
25
|
+
# meta omits it the row backfills as "" and TUI resume dies with
|
|
26
|
+
# "Model provider `` not found". ponytail: hardcoded stock provider, read the
|
|
27
|
+
# user's config.toml if custom providers ever matter.
|
|
28
|
+
MODEL_PROVIDER = "openai"
|
|
23
29
|
|
|
24
30
|
# Claude tool vocabulary -> Codex's. (Cosmetic: history is context, not re-run.)
|
|
25
31
|
INBOUND_NAMES = {"Bash": "shell", "Edit": "apply_patch", "Write": "apply_patch",
|
|
@@ -176,9 +182,12 @@ class CodexAdapter(Adapter):
|
|
|
176
182
|
tool_card(calls[r.call_id], r, ts)
|
|
177
183
|
|
|
178
184
|
meta = {"timestamp": session.started_at, "type": "session_meta",
|
|
179
|
-
"payload": {"id": session.session_id, "
|
|
185
|
+
"payload": {"id": session.session_id, "session_id": session.session_id,
|
|
186
|
+
"timestamp": session.started_at,
|
|
180
187
|
"cwd": dest_cwd, "originator": "codex-cli",
|
|
181
188
|
"cli_version": CLI_VERSION, "instructions": None,
|
|
189
|
+
"source": "cli", "thread_source": "user",
|
|
190
|
+
"model_provider": MODEL_PROVIDER,
|
|
182
191
|
**({"git": {"branch": session.git_branch}} if session.git_branch else {})}}
|
|
183
192
|
dest = self.dest_path(session, dest_cwd)
|
|
184
193
|
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
@@ -9,7 +9,9 @@ splits it back into our ToolCall + ToolResult, write() fuses them.
|
|
|
9
9
|
Read is direct + read-only (the dead source harness never has to run). Write does
|
|
10
10
|
NOT poke the live DB (FK to project, WAL, drizzle schema drift = corruption risk);
|
|
11
11
|
it emits the canonical `{info, messages}` interchange file that `opencode import`
|
|
12
|
-
validates and ingests
|
|
12
|
+
validates and ingests. Session ids must be ses_-prefixed (`opencode -s` enforces
|
|
13
|
+
the prefix; import does not), so foreign ids are mapped to a deterministic
|
|
14
|
+
ses_<sha1> and the CLI prints the mapped id in the resume hint.
|
|
13
15
|
|
|
14
16
|
Times on disk are epoch-milliseconds ints; the common records carry ISO strings
|
|
15
17
|
(what Codex/Claude use), so we convert on the boundary in both directions.
|
|
@@ -164,7 +166,11 @@ class OpenCodeAdapter(Adapter):
|
|
|
164
166
|
return IMPORTS / f"{session.session_id}.json"
|
|
165
167
|
|
|
166
168
|
def write(self, session: Session, dest_cwd: str) -> Path:
|
|
167
|
-
|
|
169
|
+
# opencode session ids must start with ses_; map foreign ids
|
|
170
|
+
# deterministically so re-importing upserts instead of duplicating.
|
|
171
|
+
sid = (session.session_id if session.session_id.startswith("ses_")
|
|
172
|
+
else _id("ses_", session.session_id))
|
|
173
|
+
session.extra["dest_session_id"] = sid
|
|
168
174
|
model = _default_model()
|
|
169
175
|
results = {r.call_id: r for r in session.records
|
|
170
176
|
if isinstance(r, ToolResult)}
|
package/hconv/cli.py
CHANGED
|
@@ -29,7 +29,9 @@ def cmd_convert(a):
|
|
|
29
29
|
print(f"records: {len(session.records)} ({n_tool} tool calls)")
|
|
30
30
|
print(f"dest : {dest}")
|
|
31
31
|
if a.write:
|
|
32
|
-
|
|
32
|
+
# a dest harness may map the id to its own format (opencode: ses_...)
|
|
33
|
+
sid = session.extra.get("dest_session_id", session.session_id)
|
|
34
|
+
cwd = a.dest_cwd or a.cwd
|
|
33
35
|
resume = {"codex": f"codex resume {sid}",
|
|
34
36
|
"claude": f"claude --resume {sid}",
|
|
35
37
|
"opencode": f"opencode import {dest} && opencode -s {sid}"}[a.to]
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theharshitsingh/hc",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Relocate a coding-agent session across harnesses (Codex <-> Claude Code) and resume it natively.",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"homepage": "https://hc.
|
|
6
|
+
"homepage": "https://hc.agentlab.in",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "git+https://github.com/harshitsinghbhandari/harness-convert.git"
|