|
1 | | -"""Turn captured endpoints into an ergonomic Python client, using the AI. |
| 1 | +"""Turn captured endpoints into an ergonomic Python client, using an AI. |
2 | 2 |
|
3 | | -`mimic gen <host>` builds a digest of what mimic saw on the wire and pipes it |
4 | | -to `claude -p` (Claude Code, headless). Claude writes a real, editable client |
| 3 | +`mimic gen <host>` builds a digest of what mimic saw on the wire and sends it |
| 4 | +to an AI generator. The AI writes a real, editable client |
5 | 5 | class — named methods, body templates, response handling, and the multi-step |
6 | 6 | chaining that mobile APIs often need — on top of mimic.App. |
7 | 7 | """ |
@@ -57,25 +57,31 @@ def build_prompt(host, endpoints): |
57 | 57 | return PROMPT.format(host=host, digest=build_digest(endpoints)) |
58 | 58 |
|
59 | 59 |
|
60 | | -def generate(host, endpoints, model="sonnet"): |
61 | | - """Run `claude -p` on the prompt and return the generated Python source.""" |
| 60 | +def generate(host, endpoints, model="sonnet", generator="claude"): |
| 61 | + """Run the AI generator on the prompt and return the generated Python source.""" |
62 | 62 | prompt = build_prompt(host, endpoints) |
63 | 63 | try: |
64 | | - proc = subprocess.run( |
65 | | - ["claude", "-p", "--model", model], |
66 | | - input=prompt, |
67 | | - capture_output=True, |
68 | | - text=True, |
69 | | - timeout=300, |
70 | | - ) |
| 64 | + if generator == "opencode": |
| 65 | + proc = subprocess.run( |
| 66 | + ["opencode", "run", prompt], |
| 67 | + capture_output=True, text=True, timeout=300, |
| 68 | + ) |
| 69 | + else: |
| 70 | + proc = subprocess.run( |
| 71 | + ["claude", "-p", "--model", model], |
| 72 | + input=prompt, capture_output=True, text=True, timeout=300, |
| 73 | + ) |
71 | 74 | except FileNotFoundError: |
72 | | - sys.exit("`claude` CLI not found — install Claude Code, or run `mimic gen --prompt-only` and paste the prompt yourself") |
| 75 | + sys.exit( |
| 76 | + f"`{generator}` CLI not found — install it, " |
| 77 | + "or use `mimic gen --prompt-only`" |
| 78 | + ) |
73 | 79 | if proc.returncode != 0: |
74 | | - sys.exit(f"claude -p failed:\n{proc.stderr}") |
| 80 | + sys.exit(f"{generator} failed:\n{proc.stderr}") |
75 | 81 | return _strip_fences(proc.stdout) |
76 | 82 |
|
77 | 83 |
|
78 | 84 | def _strip_fences(text): |
79 | | - """Claude sometimes wraps output in ```python fences despite instructions.""" |
| 85 | + """AI generators sometimes wrap output in ```python fences.""" |
80 | 86 | m = re.search(r"```(?:python)?\n(.*?)```", text, re.S) |
81 | 87 | return (m.group(1) if m else text).strip() + "\n" |
0 commit comments