tandem-cli 0.5.1__tar.gz → 0.5.2__tar.gz
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.
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/PKG-INFO +9 -1
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/README.md +8 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/formats.md +10 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/plugin/.claude-plugin/plugin.json +1 -1
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/pyproject.toml +1 -1
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/harness/claude_code.py +17 -4
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_parse.py +7 -1
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_sync.py +8 -3
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_toolmap.py +13 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/uv.lock +1 -1
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/.claude-plugin/marketplace.json +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/.github/workflows/ci.yml +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/.gitignore +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/LICENSE +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/configuration.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/development.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/how-it-works.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/plans/2026-07-29-native-tool-call-translation.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/plans/2026-07-31-codex-subagents.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/plans/2026-08-01-plugin-marketplace-install.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/plans/2026-08-01-sandbox-consent-and-manual-routing.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/plans/2026-08-02-plugin-auto-install.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/plans/2026-08-03-manual-default-model-passthrough.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/plans/2026-08-06-harness-startup-args.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/plans/2026-08-09-meta-harness-frame.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/plans/2026-08-09-readme-restructure.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/plans/2026-08-10-idle-flip-status-probe.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/plans/2026-08-10-retire-interstitial-prompt.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/plans/2026-08-13-pr1-nharness-core.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/plans/2026-08-13-pr2-opencode-adapter.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/specs/2026-07-29-native-tool-call-translation-design.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/specs/2026-07-31-codex-subagents-design.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/specs/2026-08-02-plugin-auto-install-design.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/specs/2026-08-03-manual-default-model-passthrough-design.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/specs/2026-08-06-harness-startup-args-design.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/specs/2026-08-09-meta-harness-frame-design.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/specs/2026-08-09-model-pin-recovery-design.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/specs/2026-08-09-readme-restructure-design.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/specs/2026-08-10-remove-interstitial-prompt-design.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/specs/2026-08-13-opencode-harness-design.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/subagents.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/superpowers/plans/2026-07-29-tandem-shell.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/superpowers/plans/2026-08-11-process-warmup-live-validation.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/superpowers/plans/2026-08-11-process-warmup.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/superpowers/plans/2026-08-12-process-warmup-pipelined.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/superpowers/specs/2026-07-29-tandem-shell-design.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/superpowers/specs/2026-08-10-idle-flip-status-probe.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/superpowers/specs/2026-08-11-process-warmup-design.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/superpowers/specs/2026-08-12-process-warmup-pipelined-design.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/why.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/plugin/README.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/plugin/agents/codex-worker.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/plugin/agents/gpt.md +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/plugin/hooks/hooks.json +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/__init__.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/cli.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/compat.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/config.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/constants.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/converter.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/doctor.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/events.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/flip.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/frame.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/harness/__init__.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/harness/base.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/harness/codex.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/harness/opencode.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/hookroute.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/memory_sync.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/modelcat.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/ops.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/paths.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/pinstash.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/plugin_setup.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/ptyrun.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/ratelimit.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/runner.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/state.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/summarize.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/sync.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/tailer.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/toolmap.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/util.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/src/tandem/warm.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/conftest.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/golden/claude-probe.jsonl +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/golden/codex-probe.jsonl +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_cli.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_config.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_converter.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_current_formats.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_flip.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_frame.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_hookroute.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_memory_doctor.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_modelcat.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_opencode.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_opencode_oracle.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_ops.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_participants.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_paths_compat.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_pinstash.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_plugin.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_plugin_setup.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_ptyrun.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_ratelimit.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_runner.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_state.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_sub.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_tail.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_usage.py +0 -0
- {tandem_cli-0.5.1 → tandem_cli-0.5.2}/tests/test_warm.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: tandem-cli
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.2
|
|
4
4
|
Summary: Run Claude Code, Codex CLI, and opencode in one shared coding session with live trace sync.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Bhavya6187/tandem
|
|
6
6
|
Project-URL: Repository, https://github.com/Bhavya6187/tandem
|
|
@@ -102,6 +102,14 @@ at each start, and could lose a claude → codex flip to `already has an
|
|
|
102
102
|
active writer`. All three are fixed, and codex's list-shaped tool outputs
|
|
103
103
|
now reach the other side as text with their exit codes intact.
|
|
104
104
|
|
|
105
|
+
**0.5.2 stops claude complaining about synced turns.** claude 2.1.261
|
|
106
|
+
restores a session's model on resume from its last assistant entry, and a
|
|
107
|
+
claude session that had never run a turn of its own (claude → codex →
|
|
108
|
+
opencode → claude) opened with `Session model <synced> could not be
|
|
109
|
+
restored … using fable instead`. Synced entries now carry claude's own
|
|
110
|
+
`<synthetic>` tag until claude has run, which its resume skips; the synced
|
|
111
|
+
turns still render and still reach the model.
|
|
112
|
+
|
|
105
113
|
## Why tandem?
|
|
106
114
|
|
|
107
115
|
- **Keep going when a model hits its limit.** The tab bar shows each
|
|
@@ -76,6 +76,14 @@ at each start, and could lose a claude → codex flip to `already has an
|
|
|
76
76
|
active writer`. All three are fixed, and codex's list-shaped tool outputs
|
|
77
77
|
now reach the other side as text with their exit codes intact.
|
|
78
78
|
|
|
79
|
+
**0.5.2 stops claude complaining about synced turns.** claude 2.1.261
|
|
80
|
+
restores a session's model on resume from its last assistant entry, and a
|
|
81
|
+
claude session that had never run a turn of its own (claude → codex →
|
|
82
|
+
opencode → claude) opened with `Session model <synced> could not be
|
|
83
|
+
restored … using fable instead`. Synced entries now carry claude's own
|
|
84
|
+
`<synthetic>` tag until claude has run, which its resume skips; the synced
|
|
85
|
+
turns still render and still reach the model.
|
|
86
|
+
|
|
79
87
|
## Why tandem?
|
|
80
88
|
|
|
81
89
|
- **Keep going when a model hits its limit.** The tab bar shows each
|
|
@@ -60,6 +60,16 @@ validation rather than being silently declared compatible.
|
|
|
60
60
|
tandem drops it like any other non-text assistant block.
|
|
61
61
|
- Resume: `claude --resume <sessionId>` (from the same cwd). A new session
|
|
62
62
|
can be pinned to a chosen id with `claude --session-id <uuid>`.
|
|
63
|
+
- 2.1.261 restores the session model on resume from the last assistant
|
|
64
|
+
entry whose `message.model` is a string other than `"<synthetic>"`
|
|
65
|
+
(claude's own tag on model-less stubs such as API-error messages) and
|
|
66
|
+
warns `Session model X could not be restored (not a model this version
|
|
67
|
+
of Claude Code recognizes) — using <default> instead` when that value is
|
|
68
|
+
not a model it knows. Tandem-rendered assistant entries therefore copy
|
|
69
|
+
the model claude last used in that transcript, and carry `"<synthetic>"`
|
|
70
|
+
until claude has run at all (a zero-turn claude flipped back into). The
|
|
71
|
+
`"<synced>"` placeholder tandem ≤0.5.1 wrote there drew the warning;
|
|
72
|
+
entries carrying it are still skipped when tandem derives the model.
|
|
63
73
|
- Turn boundary: a `user` entry with string content starts a turn; an
|
|
64
74
|
`assistant` line with `stop_reason: "end_turn"` ends it. The `Stop` hook
|
|
65
75
|
(injectable per-invocation via `--settings '<json>'`) fires at turn end.
|
|
@@ -127,6 +127,18 @@ _CLAUDE_ENTRY_TYPES = {
|
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
|
|
130
|
+
# claude's own tag for an assistant entry no model produced (its API-error
|
|
131
|
+
# stubs carry it). `claude --resume` (2.1.261) restores the session model from
|
|
132
|
+
# the last assistant entry and warns "Session model X could not be restored"
|
|
133
|
+
# for anything it does not recognise; "<synthetic>" is the one value that scan
|
|
134
|
+
# skips, so rendered entries carry it until claude itself has run and a real
|
|
135
|
+
# model can be copied instead (live-verified 2026-09-05: no warning, synced
|
|
136
|
+
# turns still render and reach the model).
|
|
137
|
+
SYNTHETIC_MODEL = "<synthetic>"
|
|
138
|
+
# what tandem <= 0.5.1 wrote in that slot; still skipped when deriving
|
|
139
|
+
LEGACY_SYNCED_MODEL = "<synced>"
|
|
140
|
+
|
|
141
|
+
|
|
130
142
|
class ClaudeCodeAdapter(HarnessAdapter):
|
|
131
143
|
id = "claude"
|
|
132
144
|
display_name = "Claude Code"
|
|
@@ -434,7 +446,7 @@ class ClaudeCodeAdapter(HarnessAdapter):
|
|
|
434
446
|
st["run_msg_id"] = f"msg_tandem_{entry['uuid'][:8]}"
|
|
435
447
|
return {
|
|
436
448
|
"role": "assistant",
|
|
437
|
-
"model": st.get("model") or
|
|
449
|
+
"model": st.get("model") or SYNTHETIC_MODEL,
|
|
438
450
|
"id": st["run_msg_id"],
|
|
439
451
|
"type": "message",
|
|
440
452
|
"content": content,
|
|
@@ -487,14 +499,15 @@ class ClaudeCodeAdapter(HarnessAdapter):
|
|
|
487
499
|
|
|
488
500
|
def derive_last_model(self, transcript: Path) -> str | None:
|
|
489
501
|
"""Model of the last main-thread assistant entry with a real model
|
|
490
|
-
name. Skips
|
|
491
|
-
|
|
502
|
+
name. Skips tandem's own tags (SYNTHETIC_MODEL now, the older
|
|
503
|
+
"<synced>"), claude's synthetic stubs, and sidechain entries
|
|
504
|
+
(subagents may run on a different model)."""
|
|
492
505
|
model = None
|
|
493
506
|
for obj in self._tail_objects(transcript):
|
|
494
507
|
if obj.get("type") != "assistant" or obj.get("isSidechain"):
|
|
495
508
|
continue
|
|
496
509
|
m = (obj.get("message") or {}).get("model")
|
|
497
|
-
if m and m
|
|
510
|
+
if m and m not in (SYNTHETIC_MODEL, LEGACY_SYNCED_MODEL):
|
|
498
511
|
model = m
|
|
499
512
|
return model
|
|
500
513
|
|
|
@@ -140,7 +140,10 @@ class TestDeriveLastModel:
|
|
|
140
140
|
])
|
|
141
141
|
assert get_adapter("claude").derive_last_model(p) == "claude-fable-5"
|
|
142
142
|
|
|
143
|
-
def
|
|
143
|
+
def test_placeholder_and_sidechain_models_skipped(self, tmp_path):
|
|
144
|
+
# "<synced>" is the placeholder older tandem wrote; "<synthetic>" is
|
|
145
|
+
# claude's own tag for model-less assistant entries (its API-error
|
|
146
|
+
# stubs) and what tandem writes now — neither is a model claude ran
|
|
144
147
|
p = self.write(tmp_path, [
|
|
145
148
|
{"type": "assistant", "uuid": "a1",
|
|
146
149
|
"message": {"role": "assistant", "model": "claude-fable-5",
|
|
@@ -151,6 +154,9 @@ class TestDeriveLastModel:
|
|
|
151
154
|
{"type": "assistant", "uuid": "a2",
|
|
152
155
|
"message": {"role": "assistant", "model": "<synced>",
|
|
153
156
|
"content": []}},
|
|
157
|
+
{"type": "assistant", "uuid": "a3",
|
|
158
|
+
"message": {"role": "assistant", "model": "<synthetic>",
|
|
159
|
+
"content": []}},
|
|
154
160
|
])
|
|
155
161
|
assert get_adapter("claude").derive_last_model(p) == "claude-fable-5"
|
|
156
162
|
|
|
@@ -159,8 +159,12 @@ class TestSyncCodexToClaude:
|
|
|
159
159
|
assert synced
|
|
160
160
|
assert all(e["message"]["model"] == "claude-fable-5" for e in synced)
|
|
161
161
|
|
|
162
|
-
def
|
|
163
|
-
|
|
162
|
+
def test_synthetic_model_tag_when_claude_never_ran(self, env_factory):
|
|
163
|
+
"""Fresh-shadow case: no real model to copy. Entries carry claude's
|
|
164
|
+
own "<synthetic>" tag, which its --resume model-restore scan skips
|
|
165
|
+
(live-verified on 2.1.261); the old "<synced>" placeholder drew
|
|
166
|
+
"Session model <synced> could not be restored" on every zero-turn
|
|
167
|
+
claude session flipped back into."""
|
|
164
168
|
env = env_factory(active="codex")
|
|
165
169
|
for obj in self.codex_lines():
|
|
166
170
|
write_line(env.source_file, obj)
|
|
@@ -168,7 +172,8 @@ class TestSyncCodexToClaude:
|
|
|
168
172
|
loop.drain()
|
|
169
173
|
synced = [e for e in read_jsonl(env.claude_shadow)
|
|
170
174
|
if e.get("type") == "assistant"]
|
|
171
|
-
assert
|
|
175
|
+
assert synced
|
|
176
|
+
assert all(e["message"]["model"] == "<synthetic>" for e in synced)
|
|
172
177
|
|
|
173
178
|
def test_leaf_rederived_from_file(self, env_factory):
|
|
174
179
|
"""If claude itself appended entries (it was active earlier), new
|
|
@@ -464,6 +464,19 @@ class TestClaudeToolRendering:
|
|
|
464
464
|
], ctx)
|
|
465
465
|
assert all(e["message"]["model"] == "claude-fable-5" for e in entries)
|
|
466
466
|
|
|
467
|
+
def test_render_uses_claudes_synthetic_tag_when_no_model_is_known(self):
|
|
468
|
+
# claude --resume (2.1.261) restores the session model from the last
|
|
469
|
+
# assistant entry and warns "Session model X could not be restored"
|
|
470
|
+
# for anything it does not recognise; "<synthetic>" is claude's own
|
|
471
|
+
# tag for model-less assistant entries and the one value its scan
|
|
472
|
+
# skips, so it is what a shadow with no claude turn yet must carry
|
|
473
|
+
ctx = _ctx("codex->claude")
|
|
474
|
+
entries = get_adapter("claude").render_events([
|
|
475
|
+
AssistantMessage(source="codex", text="hi"),
|
|
476
|
+
call("Bash", {"command": "ls"}, source="codex", call_id="c9"),
|
|
477
|
+
], ctx)
|
|
478
|
+
assert all(e["message"]["model"] == "<synthetic>" for e in entries)
|
|
479
|
+
|
|
467
480
|
def test_is_error_flag_rides(self):
|
|
468
481
|
ctx = _ctx("codex->claude")
|
|
469
482
|
entries = get_adapter("claude").render_events([
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/plans/2026-08-01-sandbox-consent-and-manual-routing.md
RENAMED
|
File without changes
|
|
File without changes
|
{tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/plans/2026-08-03-manual-default-model-passthrough.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/specs/2026-07-29-native-tool-call-translation-design.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/specs/2026-08-10-remove-interstitial-prompt-design.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/superpowers/plans/2026-08-12-process-warmup-pipelined.md
RENAMED
|
File without changes
|
{tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/superpowers/specs/2026-07-29-tandem-shell-design.md
RENAMED
|
File without changes
|
{tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/superpowers/specs/2026-08-10-idle-flip-status-probe.md
RENAMED
|
File without changes
|
{tandem_cli-0.5.1 → tandem_cli-0.5.2}/docs/superpowers/specs/2026-08-11-process-warmup-design.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|