This repository was archived by the owner on Oct 8, 2026. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathcodegen-call
More file actions
executable file
·355 lines (331 loc) · 11.5 KB
/
Copy pathcodegen-call
File metadata and controls
executable file
·355 lines (331 loc) · 11.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
#!/usr/bin/env bash
# codegen-call — one-shot structured LLM call binary.
#
# Usage:
# codegen-call --harness=claude_code \
# --model=<m> --effort=<e> \
# --system-prompt @<abs-path> \
# [--json-schema @<abs-path>] \
# [--allowed-tools=<comma-list>] \
# [--settings @<abs-path>] \
# [--agents @<abs-path>] \
# PROMPT
#
# Flags:
# --version print "codegen-call 0.1.0" and exit 0
# --harness=<h> REQUIRED: claude_code
# --model=<m> REQUIRED: model string
# --effort=<e> REQUIRED: effort string (low/medium/high/…)
# --system-prompt @<p> REQUIRED: @<abs-path> to system prompt file
# --json-schema @<p> OPTIONAL: @<abs-path> to JSON schema file
# --allowed-tools=<l> OPTIONAL: comma-list of tools; empty string → no tools
# --settings @<p> OPTIONAL: @<abs-path> to settings JSON (claude only)
# --agents @<p> OPTIONAL: claude only — inline agent-def JSON; identity
# travels with the def. This script never opens,
# parses, or names the agents the JSON carries — pure
# passthrough (mirrors --settings).
# --agent=<v> OPTIONAL: generic passthrough value; when set, the
# --system-prompt requirement below is waived (the
# invoking harness supplies identity another way).
# This script performs zero validation of the value
# and never special-cases it — pure passthrough.
# --resume=<sid> OPTIONAL: generic passthrough value; a prior
# session id to resume. This script performs zero
# validation of the value and never special-cases
# it — pure passthrough (mirrors --agent).
# --session-id=<sid> OPTIONAL: generic passthrough value; a caller-minted
# session id to pin a NEW (cold) call to, so a future
# --resume can recover it even if the harness process
# is killed before it ever reports its own session id.
# This script performs zero validation of the value
# and never special-cases it — pure passthrough
# (mirrors --agent / --resume). Mutually exclusive
# with --resume in practice (caller's choice, not
# enforced here).
# --print-argv OPTIONAL: dry-run — parse + validate every flag,
# build the full harness argv, print it one arg per
# line on stdout, exit 0. Never execs the LLM.
# PROMPT REQUIRED positional arg (last arg or after --)
#
# Exit codes:
# 0 — envelope emitted on stdout (even on LLM-level failure)
# 1 — dispatch infra failure (harness binary error, jq failure, etc.)
# 2 — usage/config error (missing required arg, bad harness, missing file)
# 127 — harness binary not found (propagated from dispatch)
#
# Consumer role-definition contract:
# An agent role, for the purposes of this call, is defined entirely by the
# identity flags passed on the command line — there is no built-in notion
# of a role name inside this script:
# --system-prompt @<path> REPLACE semantics: the file content IS the
# whole agent identity for this call (no
# layering, no merge with any prior prompt)
# --model / --effort which model + effort tier runs the call
# --harness claude_code — which CLI executes it
# --allowed-tools tool allowlist for this call, if the harness
# supports scoping tools per invocation
# --settings @<path> claude only — enforcement/hook bundle overlay
# --agents @<path> claude only — inline agent-def JSON; identity
# travels with the def
# No agent name is hardcoded anywhere in this file or its dispatch targets.
# A consumer wanting a new kind of agent supplies these flags with its own
# values; that is a zero-change operation from this script's point of view.
# This is a strict one-way boundary: this file never references, imports,
# or special-cases any consumer-defined agent identity, and there is no
# flag here that appends to or layers on top of an existing system prompt
# — every call gets exactly one, whole, replacing system prompt.
set -euo pipefail
# Resolve the codegen root so that both direct invocations (from repo) and
# installed copies (~/.local/bin/) can locate the harnesses/ directory.
# Priority:
# 1. SCRIPT_DIR has a harnesses/ subdir → use it (direct / test invocation)
# 2. OCG_CODEGEN_DIR env var set → use it (installed copy with env)
# 3. Fall back to SCRIPT_DIR → error will surface from dispatch check
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
if [[ ! -d "$SCRIPT_DIR/harnesses" ]] && [[ -n "${OCG_CODEGEN_DIR:-}" ]]; then
SCRIPT_DIR="$OCG_CODEGEN_DIR"
fi
# Effort-canonical helper resolution mirrors the SCRIPT_DIR logic above, but
# checked at file granularity: a test root can carry a partial harnesses/
# tree (e.g. only harnesses/claude/) without harnesses/shared/, which would
# make the dir-level check above resolve to the wrong root.
_effort_canonical_dir="$SCRIPT_DIR"
if [[ ! -f "$_effort_canonical_dir/harnesses/shared/effort-canonical.sh" ]] && [[ -n "${OCG_CODEGEN_DIR:-}" ]]; then
_effort_canonical_dir="$OCG_CODEGEN_DIR"
fi
# shellcheck source=harnesses/shared/effort-canonical.sh
source "$_effort_canonical_dir/harnesses/shared/effort-canonical.sh"
SHOW_VERSION=""
HARNESS=""
MODEL=""
EFFORT=""
SYSTEM_PROMPT_PATH=""
JSON_SCHEMA_PATH=""
ALLOWED_TOOLS=""
ALLOWED_TOOLS_SET=""
SETTINGS_PATH=""
AGENTS_PATH=""
AGENT=""
RESUME=""
SESSION_ID=""
PRINT_ARGV=""
PROMPT=""
usage() {
printf 'Usage: codegen-call --harness=claude_code --model=<m> --effort=<e> [--system-prompt @<path>] [--agent=<v>] [--agents @<path>] [--resume=<sid>] [--session-id=<sid>] [--json-schema @<path>] [--allowed-tools=<list>] [--settings @<path>] [--print-argv] PROMPT\n' >&2
exit 2
}
while [[ $# -gt 0 ]]; do
case "$1" in
--version)
SHOW_VERSION="1"
shift
;;
--harness=*)
HARNESS="${1#--harness=}"
shift
;;
--harness)
HARNESS="$2"
shift 2
;;
--model=*)
MODEL="${1#--model=}"
shift
;;
--model)
MODEL="$2"
shift 2
;;
--effort=*)
EFFORT="${1#--effort=}"
shift
;;
--effort)
EFFORT="$2"
shift 2
;;
--system-prompt=*)
SYSTEM_PROMPT_PATH="${1#--system-prompt=}"
shift
;;
--system-prompt)
SYSTEM_PROMPT_PATH="$2"
shift 2
;;
--json-schema=*)
JSON_SCHEMA_PATH="${1#--json-schema=}"
shift
;;
--json-schema)
JSON_SCHEMA_PATH="$2"
shift 2
;;
--allowed-tools=*)
ALLOWED_TOOLS="${1#--allowed-tools=}"
ALLOWED_TOOLS_SET="1"
shift
;;
--allowed-tools)
ALLOWED_TOOLS="$2"
ALLOWED_TOOLS_SET="1"
shift 2
;;
--settings=*)
SETTINGS_PATH="${1#--settings=}"
shift
;;
--settings)
SETTINGS_PATH="$2"
shift 2
;;
--agents=*)
AGENTS_PATH="${1#--agents=}"
shift
;;
--agents)
AGENTS_PATH="$2"
shift 2
;;
--agent=*)
AGENT="${1#--agent=}"
shift
;;
--agent)
AGENT="$2"
shift 2
;;
--resume=*)
RESUME="${1#--resume=}"
shift
;;
--resume)
RESUME="$2"
shift 2
;;
--session-id=*)
SESSION_ID="${1#--session-id=}"
shift
;;
--session-id)
SESSION_ID="$2"
shift 2
;;
--print-argv)
PRINT_ARGV="1"
shift
;;
--)
shift
PROMPT="$*"
break
;;
--*)
printf 'codegen-call: unknown flag %q\n' "$1" >&2
usage
;;
*)
if [[ -z "$PROMPT" ]]; then
PROMPT="$1"
else
PROMPT="$PROMPT $1"
fi
shift
;;
esac
done
# Handle --version first (no other args required)
if [[ -n "$SHOW_VERSION" ]]; then
printf 'codegen-call 0.1.0\n'
exit 0
fi
# Validate required args
if [[ -z "$HARNESS" ]]; then
printf 'codegen-call: --harness is required\n' >&2
usage
fi
if [[ "$HARNESS" != "claude_code" ]]; then
printf 'codegen-call: --harness must be "claude_code", got %q\n' "$HARNESS" >&2
usage
fi
if [[ -z "$MODEL" ]]; then
printf 'codegen-call: --model is required\n' >&2
usage
fi
if [[ -z "$EFFORT" ]]; then
printf 'codegen-call: --effort is required\n' >&2
usage
fi
if ! codegen_validate_effort "$EFFORT"; then
usage
fi
if [[ -z "$AGENT" ]] && [[ -z "$SYSTEM_PROMPT_PATH" ]]; then
printf 'codegen-call: --system-prompt @<path> is required\n' >&2
usage
fi
if [[ -z "$PROMPT" ]]; then
printf 'codegen-call: PROMPT is required\n' >&2
usage
fi
# Parse @<path> values and read file contents
_read_at_path() {
local flag_name="$1"
local value="$2"
local path
if [[ "$value" != @* ]]; then
printf 'codegen-call: %s value must start with @ (got %q)\n' "$flag_name" "$value" >&2
exit 2
fi
path="${value#@}"
if [[ ! -f "$path" ]]; then
printf 'codegen-call: %s file not found: %s\n' "$flag_name" "$path" >&2
exit 2
fi
printf '%s' "$path"
}
# Resolve system-prompt path (optional when --agent is set)
SYSTEM_PROMPT_CONTENT=""
if [[ -n "$SYSTEM_PROMPT_PATH" ]]; then
SP_PATH="$(_read_at_path "--system-prompt" "$SYSTEM_PROMPT_PATH")"
SYSTEM_PROMPT_CONTENT="$(cat "$SP_PATH")"
fi
# Resolve json-schema path (optional)
JSON_SCHEMA_CONTENT=""
JSON_SCHEMA_ABS_PATH=""
if [[ -n "$JSON_SCHEMA_PATH" ]]; then
JSON_SCHEMA_ABS_PATH="$(_read_at_path "--json-schema" "$JSON_SCHEMA_PATH")"
JSON_SCHEMA_CONTENT="$(cat "$JSON_SCHEMA_ABS_PATH")"
fi
# Resolve settings path (optional)
SETTINGS_ABS_PATH=""
if [[ -n "$SETTINGS_PATH" ]]; then
SETTINGS_ABS_PATH="$(_read_at_path "--settings" "$SETTINGS_PATH")"
fi
# Resolve agents path (optional, claude only)
AGENTS_ABS_PATH=""
if [[ -n "$AGENTS_PATH" ]]; then
AGENTS_ABS_PATH="$(_read_at_path "--agents" "$AGENTS_PATH")"
fi
# Map harness name to dispatch directory
DISPATCH_DIR="claude"
# Export env vars for dispatch script
export CODEGEN_CALL_HARNESS="$HARNESS"
export CODEGEN_CALL_MODEL="$MODEL"
export CODEGEN_CALL_EFFORT="$EFFORT"
export CODEGEN_CALL_SYSTEM_PROMPT="$SYSTEM_PROMPT_CONTENT"
export CODEGEN_CALL_JSON_SCHEMA="$JSON_SCHEMA_CONTENT"
export CODEGEN_CALL_JSON_SCHEMA_PATH="$JSON_SCHEMA_ABS_PATH"
export CODEGEN_CALL_ALLOWED_TOOLS="${ALLOWED_TOOLS:-}"
export CODEGEN_CALL_ALLOWED_TOOLS_SET="${ALLOWED_TOOLS_SET:-}"
export CODEGEN_CALL_SETTINGS_PATH="$SETTINGS_ABS_PATH"
export CODEGEN_CALL_AGENTS_PATH="$AGENTS_ABS_PATH"
export CODEGEN_CALL_AGENT="$AGENT"
export CODEGEN_CALL_RESUME="$RESUME"
export CODEGEN_CALL_SESSION_ID="$SESSION_ID"
export CODEGEN_CALL_PRINT_ARGV="${PRINT_ARGV:-}"
export CODEGEN_CALL_PROMPT="$PROMPT"
DISPATCH="$SCRIPT_DIR/harnesses/$DISPATCH_DIR/call-dispatch.sh"
if [[ ! -x "$DISPATCH" ]]; then
printf 'codegen-call: dispatch script not found or not executable: %s\n' "$DISPATCH" >&2
exit 2
fi
exec "$DISPATCH"