mirror of
https://github.com/gnekt/My-Brain-Is-Full-Crew.git
synced 2026-08-26 02:04:43 +00:00
feat(codex): use gpt-5.5 models (#41)
Map Codex high usage to gpt-5.5 high and lower-cost tiers to gpt-5.5 low. Harden frontmatter parsing so LF and CRLF checkouts generate equivalent adapter output.
This commit is contained in:
@@ -250,7 +250,7 @@ adapter_translate_agents() {
|
|||||||
echo "---"
|
echo "---"
|
||||||
echo "name: $name"
|
echo "name: $name"
|
||||||
# Copy description block (may be folded YAML with continuation lines)
|
# Copy description block (may be folded YAML with continuation lines)
|
||||||
awk '/^---$/{n++; next} n==1 && /^description:/{print; in_desc=1; next} n==1 && in_desc && /^[[:space:]]/{print; next} n==1 && in_desc && !/^[[:space:]]/{in_desc=0} n>=2{exit}' "$agent"
|
awk '{ sub(/\r$/, "") } /^---$/{n++; next} n==1 && /^description:/{print; in_desc=1; next} n==1 && in_desc && /^[[:space:]]/{print; next} n==1 && in_desc && !/^[[:space:]]/{in_desc=0} n>=2{exit}' "$agent"
|
||||||
echo "tools: $tools"
|
echo "tools: $tools"
|
||||||
echo "model: $model"
|
echo "model: $model"
|
||||||
echo "---"
|
echo "---"
|
||||||
|
|||||||
@@ -296,13 +296,16 @@ adapter_translate_skills() {
|
|||||||
|
|
||||||
# _cc_toml_quote_key <name>
|
# _cc_toml_quote_key <name>
|
||||||
# Emits the TOML table key for [mcp_servers.<name>].
|
# Emits the TOML table key for [mcp_servers.<name>].
|
||||||
# Codex CLI requires MCP server names to match ^[a-zA-Z0-9_-]+$, so any
|
# Safe identifiers can be emitted bare; names with spaces or punctuation must
|
||||||
# character outside that set is replaced with a hyphen before writing.
|
# be quoted and escaped so the original MCP server name is preserved.
|
||||||
_cc_toml_quote_key() {
|
_cc_toml_quote_key() {
|
||||||
local name="$1"
|
local name="$1"
|
||||||
# Sanitize: replace any character not in [a-zA-Z0-9_-] with a hyphen
|
if [[ "$name" =~ ^[A-Za-z0-9_-]+$ ]]; then
|
||||||
local safe_name="${name//[^a-zA-Z0-9_-]/-}"
|
printf '[mcp_servers.%s]' "$name"
|
||||||
printf '[mcp_servers.%s]' "$safe_name"
|
else
|
||||||
|
local escaped; escaped="$(_cc_toml_escape_string "$name")"
|
||||||
|
printf '[mcp_servers."%s"]' "$escaped"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# _cc_toml_escape_string <value>
|
# _cc_toml_escape_string <value>
|
||||||
@@ -345,16 +348,16 @@ adapter_translate_config() {
|
|||||||
echo ''
|
echo ''
|
||||||
echo '# Inherit uses the top-level defaults; named profiles override them explicitly.'
|
echo '# Inherit uses the top-level defaults; named profiles override them explicitly.'
|
||||||
echo '[profiles.quality]'
|
echo '[profiles.quality]'
|
||||||
echo 'model = "gpt-5.4"'
|
echo 'model = "gpt-5.5"'
|
||||||
echo 'model_reasoning_effort = "high"'
|
echo 'model_reasoning_effort = "high"'
|
||||||
echo ''
|
echo ''
|
||||||
echo '[profiles.balanced]'
|
echo '[profiles.balanced]'
|
||||||
echo 'model = "gpt-5.4-mini"'
|
echo 'model = "gpt-5.5"'
|
||||||
echo 'model_reasoning_effort = "medium"'
|
echo 'model_reasoning_effort = "low"'
|
||||||
echo ''
|
echo ''
|
||||||
echo '[profiles.budget]'
|
echo '[profiles.budget]'
|
||||||
echo 'model = "gpt-5.3-codex-spark"'
|
echo 'model = "gpt-5.5"'
|
||||||
echo 'model_reasoning_effort = "medium"'
|
echo 'model_reasoning_effort = "low"'
|
||||||
echo ''
|
echo ''
|
||||||
echo '[agents]'
|
echo '[agents]'
|
||||||
echo 'max_depth = 1'
|
echo 'max_depth = 1'
|
||||||
@@ -491,6 +494,7 @@ adapter_translate_config() {
|
|||||||
_cc_extract_description() {
|
_cc_extract_description() {
|
||||||
local file="$1"
|
local file="$1"
|
||||||
awk '
|
awk '
|
||||||
|
{ sub(/\r$/, "") }
|
||||||
/^---$/ { fm++; next }
|
/^---$/ { fm++; next }
|
||||||
fm == 1 && /^description:[[:space:]]*>/ {
|
fm == 1 && /^description:[[:space:]]*>/ {
|
||||||
# Folded-block style: value starts on next indented lines
|
# Folded-block style: value starts on next indented lines
|
||||||
@@ -539,10 +543,9 @@ _cc_toml_escape_dquote_string() {
|
|||||||
_cc_model_to_codex() {
|
_cc_model_to_codex() {
|
||||||
local model="$1"
|
local model="$1"
|
||||||
case "$model" in
|
case "$model" in
|
||||||
|
gpt-5.4|gpt-5.4-mini|gpt-5.3-codex-spark) echo "gpt-5.5" ;;
|
||||||
*/*|gpt-*) echo "$model" ;;
|
*/*|gpt-*) echo "$model" ;;
|
||||||
low) echo "gpt-5.3-codex-spark" ;;
|
low|mid|high) echo "gpt-5.5" ;;
|
||||||
mid) echo "gpt-5.4-mini" ;;
|
|
||||||
high) echo "gpt-5.4" ;;
|
|
||||||
*) echo "$model" ;;
|
*) echo "$model" ;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@@ -552,8 +555,9 @@ _cc_model_to_codex() {
|
|||||||
_cc_model_reasoning_effort() {
|
_cc_model_reasoning_effort() {
|
||||||
local model="$1"
|
local model="$1"
|
||||||
case "$model" in
|
case "$model" in
|
||||||
high) echo "high" ;;
|
high|gpt-5.4) echo "high" ;;
|
||||||
*) echo "medium" ;;
|
low|mid|gpt-5.4-mini|gpt-5.3-codex-spark) echo "low" ;;
|
||||||
|
*) echo "medium" ;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ adapter_translate_agents() {
|
|||||||
echo "---"
|
echo "---"
|
||||||
echo "name: $name"
|
echo "name: $name"
|
||||||
# Copy description block (may be folded YAML)
|
# Copy description block (may be folded YAML)
|
||||||
awk '/^---$/{n++; next} n==1 && /^description:/{print; in_desc=1; next} n==1 && in_desc && /^[[:space:]]/{print; next} n==1 && in_desc && !/^[[:space:]]/{in_desc=0} n>=2{exit}' "$agent"
|
awk '{ sub(/\r$/, "") } /^---$/{n++; next} n==1 && /^description:/{print; in_desc=1; next} n==1 && in_desc && /^[[:space:]]/{print; next} n==1 && in_desc && !/^[[:space:]]/{in_desc=0} n>=2{exit}' "$agent"
|
||||||
echo "tools:"
|
echo "tools:"
|
||||||
printf '%s' "$tools_yaml"
|
printf '%s' "$tools_yaml"
|
||||||
echo "model: $model_out"
|
echo "model: $model_out"
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ rewrite_platform_paths() {
|
|||||||
parse_frontmatter() {
|
parse_frontmatter() {
|
||||||
local file="$1" key="$2"
|
local file="$1" key="$2"
|
||||||
awk -v key="$key" '
|
awk -v key="$key" '
|
||||||
|
{ sub(/\r$/, "") }
|
||||||
/^---$/ { fm++; next }
|
/^---$/ { fm++; next }
|
||||||
fm == 1 {
|
fm == 1 {
|
||||||
# Match "key: value" — strip leading whitespace, capture value after first ":"
|
# Match "key: value" — strip leading whitespace, capture value after first ":"
|
||||||
@@ -123,6 +124,7 @@ parse_hook_yaml() {
|
|||||||
agent_body() {
|
agent_body() {
|
||||||
local file="$1"
|
local file="$1"
|
||||||
awk '
|
awk '
|
||||||
|
{ sub(/\r$/, "") }
|
||||||
fm < 2 && /^---$/ { fm++; next }
|
fm < 2 && /^---$/ { fm++; next }
|
||||||
fm >= 2 { print }
|
fm >= 2 { print }
|
||||||
' "$file"
|
' "$file"
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ adapter_translate_agents() {
|
|||||||
{
|
{
|
||||||
echo "---"
|
echo "---"
|
||||||
# Copy description block verbatim (may be folded YAML with continuation lines)
|
# Copy description block verbatim (may be folded YAML with continuation lines)
|
||||||
awk '/^---$/{n++; next} n==1 && /^description:/{print; in_desc=1; next} n==1 && in_desc && /^[[:space:]]/{print; next} n==1 && in_desc && !/^[[:space:]]/{in_desc=0} n>=2{exit}' "$agent"
|
awk '{ sub(/\r$/, "") } /^---$/{n++; next} n==1 && /^description:/{print; in_desc=1; next} n==1 && in_desc && /^[[:space:]]/{print; next} n==1 && in_desc && !/^[[:space:]]/{in_desc=0} n>=2{exit}' "$agent"
|
||||||
echo "mode: $mode_out"
|
echo "mode: $mode_out"
|
||||||
echo "model: $model_out"
|
echo "model: $model_out"
|
||||||
if [[ -z "$perms" ]]; then
|
if [[ -z "$perms" ]]; then
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ servers:
|
|||||||
url: "https://gmail.mcp.claude.com/mcp"
|
url: "https://gmail.mcp.claude.com/mcp"
|
||||||
env: {}
|
env: {}
|
||||||
exclude: []
|
exclude: []
|
||||||
- name: Google-Calendar
|
- name: Google Calendar
|
||||||
type: http
|
type: http
|
||||||
url: "https://gcal.mcp.claude.com/mcp"
|
url: "https://gcal.mcp.claude.com/mcp"
|
||||||
env: {}
|
env: {}
|
||||||
|
|||||||
@@ -90,6 +90,35 @@ EOF
|
|||||||
return $result
|
return $result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_translate_agents_supports_crlf_frontmatter() {
|
||||||
|
local src; src="$(mktemp -d)"
|
||||||
|
local dst; dst="$(mktemp -d)"
|
||||||
|
mkdir -p "$src/agents"
|
||||||
|
printf '%s\r\n' \
|
||||||
|
'---' \
|
||||||
|
'name: scribe' \
|
||||||
|
'description: >' \
|
||||||
|
' Test scribe' \
|
||||||
|
' across line endings' \
|
||||||
|
'model: mid' \
|
||||||
|
'mode: subagent' \
|
||||||
|
'capabilities: [read, write, edit]' \
|
||||||
|
'---' \
|
||||||
|
'' \
|
||||||
|
'You are the Scribe.' > "$src/agents/scribe.md"
|
||||||
|
adapter_translate_agents "$src/agents" "$dst"
|
||||||
|
local out="$dst/.claude/agents/scribe.md"
|
||||||
|
local result=0
|
||||||
|
grep -q '^name: scribe' "$out" || { echo "name missing"; result=1; }
|
||||||
|
grep -q '^description: >' "$out" || { echo "description header missing"; result=1; }
|
||||||
|
grep -q '^ Test scribe' "$out" || { echo "description continuation missing"; result=1; }
|
||||||
|
grep -q '^model: sonnet' "$out" || { echo "model not mapped from CRLF frontmatter"; result=1; }
|
||||||
|
grep -q '^tools: Read, Glob, Grep, Write, Edit' "$out" || { echo "tools not mapped from CRLF capabilities"; result=1; }
|
||||||
|
grep -q '^You are the Scribe' "$out" || { echo "body missing"; result=1; }
|
||||||
|
rm -rf "$src" "$dst"
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
test_translate_agents_bash_capability() {
|
test_translate_agents_bash_capability() {
|
||||||
local src; src="$(mktemp -d)"
|
local src; src="$(mktemp -d)"
|
||||||
local dst; dst="$(mktemp -d)"
|
local dst; dst="$(mktemp -d)"
|
||||||
|
|||||||
@@ -21,6 +21,28 @@ _python_cmd() {
|
|||||||
echo ""
|
echo ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Model mapping tests
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
test_cc_model_mapping_uses_gpt55_with_requested_reasoning() {
|
||||||
|
local result=0
|
||||||
|
[[ "$(_cc_model_to_codex "high")" == "gpt-5.5" ]] || { echo "high tier model mapping failed"; result=1; }
|
||||||
|
[[ "$(_cc_model_reasoning_effort "high")" == "high" ]] || { echo "high tier reasoning mapping failed"; result=1; }
|
||||||
|
[[ "$(_cc_model_to_codex "mid")" == "gpt-5.5" ]] || { echo "mid tier model mapping failed"; result=1; }
|
||||||
|
[[ "$(_cc_model_reasoning_effort "mid")" == "low" ]] || { echo "mid tier reasoning mapping failed"; result=1; }
|
||||||
|
[[ "$(_cc_model_to_codex "low")" == "gpt-5.5" ]] || { echo "low tier model mapping failed"; result=1; }
|
||||||
|
[[ "$(_cc_model_reasoning_effort "low")" == "low" ]] || { echo "low tier reasoning mapping failed"; result=1; }
|
||||||
|
[[ "$(_cc_model_to_codex "gpt-5.4")" == "gpt-5.5" ]] || { echo "legacy gpt-5.4 model mapping failed"; result=1; }
|
||||||
|
[[ "$(_cc_model_reasoning_effort "gpt-5.4")" == "high" ]] || { echo "legacy gpt-5.4 reasoning mapping failed"; result=1; }
|
||||||
|
[[ "$(_cc_model_to_codex "gpt-5.4-mini")" == "gpt-5.5" ]] || { echo "legacy gpt-5.4-mini model mapping failed"; result=1; }
|
||||||
|
[[ "$(_cc_model_reasoning_effort "gpt-5.4-mini")" == "low" ]] || { echo "legacy gpt-5.4-mini reasoning mapping failed"; result=1; }
|
||||||
|
[[ "$(_cc_model_to_codex "gpt-5.3-codex-spark")" == "gpt-5.5" ]] || { echo "legacy gpt-5.3-codex-spark model mapping failed"; result=1; }
|
||||||
|
[[ "$(_cc_model_reasoning_effort "gpt-5.3-codex-spark")" == "low" ]] || { echo "legacy gpt-5.3-codex-spark reasoning mapping failed"; result=1; }
|
||||||
|
[[ "$(_cc_model_to_codex "openai/custom")" == "openai/custom" ]] || { echo "qualified passthrough failed"; result=1; }
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Dispatcher tests
|
# Dispatcher tests
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -470,12 +492,14 @@ EOF
|
|||||||
local result=0
|
local result=0
|
||||||
[[ "$content" == *'sandbox_workspace_write.network_access = false'* ]] || { echo "network_access default missing"; result=1; }
|
[[ "$content" == *'sandbox_workspace_write.network_access = false'* ]] || { echo "network_access default missing"; result=1; }
|
||||||
[[ "$content" == *'[profiles.quality]'* ]] || { echo "profiles.quality missing"; result=1; }
|
[[ "$content" == *'[profiles.quality]'* ]] || { echo "profiles.quality missing"; result=1; }
|
||||||
[[ "$content" == *'model = "gpt-5.4"'* ]] || { echo "quality model missing"; result=1; }
|
[[ "$content" == *'model = "gpt-5.5"'* ]] || { echo "quality model missing"; result=1; }
|
||||||
[[ "$content" == *'model_reasoning_effort = "high"'* ]] || { echo "quality reasoning effort missing"; result=1; }
|
[[ "$content" == *'model_reasoning_effort = "high"'* ]] || { echo "quality reasoning effort missing"; result=1; }
|
||||||
[[ "$content" == *'[profiles.balanced]'* ]] || { echo "profiles.balanced missing"; result=1; }
|
[[ "$content" == *'[profiles.balanced]'* ]] || { echo "profiles.balanced missing"; result=1; }
|
||||||
[[ "$content" == *'model = "gpt-5.4-mini"'* ]] || { echo "balanced model missing"; result=1; }
|
[[ "$content" == *'model = "gpt-5.5"'* ]] || { echo "balanced model missing"; result=1; }
|
||||||
|
[[ "$content" == *'model_reasoning_effort = "low"'* ]] || { echo "balanced reasoning effort missing"; result=1; }
|
||||||
[[ "$content" == *'[profiles.budget]'* ]] || { echo "profiles.budget missing"; result=1; }
|
[[ "$content" == *'[profiles.budget]'* ]] || { echo "profiles.budget missing"; result=1; }
|
||||||
[[ "$content" == *'model = "gpt-5.3-codex-spark"'* ]] || { echo "budget model missing"; result=1; }
|
[[ "$content" == *'model = "gpt-5.5"'* ]] || { echo "budget model missing"; result=1; }
|
||||||
|
[[ "$content" == *'model_reasoning_effort = "low"'* ]] || { echo "budget reasoning effort missing"; result=1; }
|
||||||
rm -rf "$src" "$dst"
|
rm -rf "$src" "$dst"
|
||||||
return $result
|
return $result
|
||||||
}
|
}
|
||||||
@@ -818,6 +842,39 @@ AGENTEOF
|
|||||||
return $result
|
return $result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_cc_translate_agent_toml_supports_crlf_frontmatter() {
|
||||||
|
local src; src="$(mktemp -d)"
|
||||||
|
local dst; dst="$(mktemp -d)"
|
||||||
|
mkdir -p "$src/agents"
|
||||||
|
printf '%s\r\n' \
|
||||||
|
'---' \
|
||||||
|
'name: myagent' \
|
||||||
|
'description: >' \
|
||||||
|
' First line of description' \
|
||||||
|
' across line endings.' \
|
||||||
|
'mode: subagent' \
|
||||||
|
'capabilities: [read]' \
|
||||||
|
'model: low' \
|
||||||
|
'---' \
|
||||||
|
'' \
|
||||||
|
'Body text here.' > "$src/agents/myagent.md"
|
||||||
|
|
||||||
|
adapter_translate_agent_toml "$src/agents/myagent.md" "$dst"
|
||||||
|
|
||||||
|
local result=0
|
||||||
|
local toml_file="$dst/.codex/agents/myagent.toml"
|
||||||
|
[[ -f "$toml_file" ]] || { echo "myagent.toml not created"; result=1; return $result; }
|
||||||
|
grep -q '^name = "myagent"$' "$toml_file" || { echo "name not parsed from CRLF frontmatter"; result=1; }
|
||||||
|
grep -q '^model = "gpt-5.5"$' "$toml_file" || { echo "model not mapped from CRLF frontmatter"; result=1; }
|
||||||
|
grep -q '^model_reasoning_effort = "low"$' "$toml_file" || { echo "reasoning not mapped from CRLF frontmatter"; result=1; }
|
||||||
|
grep -q 'First line of description' "$toml_file" || { echo "description missing first CRLF line"; result=1; }
|
||||||
|
grep -q 'across line endings' "$toml_file" || { echo "description missing continuation CRLF line"; result=1; }
|
||||||
|
grep -q 'Body text here.' "$toml_file" || { echo "body missing"; result=1; }
|
||||||
|
|
||||||
|
rm -rf "$src" "$dst"
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
test_cc_translate_agent_toml_no_platform_paths_in_output() {
|
test_cc_translate_agent_toml_no_platform_paths_in_output() {
|
||||||
# .platform/ and DISPATCHER.md must not appear in the generated TOML
|
# .platform/ and DISPATCHER.md must not appear in the generated TOML
|
||||||
local src; src="$(mktemp -d)"
|
local src; src="$(mktemp -d)"
|
||||||
@@ -1076,14 +1133,14 @@ test_cc_adapter_build_real_agent_corpus_has_required_fields_and_metadata() {
|
|||||||
|| { echo 'postman.toml should be workspace-write'; result=1; }
|
|| { echo 'postman.toml should be workspace-write'; result=1; }
|
||||||
grep -q '^sandbox_mode = "workspace-write"$' "$dst/.codex/agents/architect.toml" \
|
grep -q '^sandbox_mode = "workspace-write"$' "$dst/.codex/agents/architect.toml" \
|
||||||
|| { echo 'architect.toml should be workspace-write'; result=1; }
|
|| { echo 'architect.toml should be workspace-write'; result=1; }
|
||||||
grep -q '^model = "gpt-5.4"$' "$dst/.codex/agents/architect.toml" \
|
grep -q '^model = "gpt-5.5"$' "$dst/.codex/agents/architect.toml" \
|
||||||
|| { echo 'architect.toml should map to gpt-5.4'; result=1; }
|
|| { echo 'architect.toml should map to gpt-5.5'; result=1; }
|
||||||
grep -q '^model_reasoning_effort = "high"$' "$dst/.codex/agents/architect.toml" \
|
grep -q '^model_reasoning_effort = "high"$' "$dst/.codex/agents/architect.toml" \
|
||||||
|| { echo 'architect.toml should map to high reasoning effort'; result=1; }
|
|| { echo 'architect.toml should map to high reasoning effort'; result=1; }
|
||||||
grep -q '^model = "gpt-5.4-mini"$' "$dst/.codex/agents/scribe.toml" \
|
grep -q '^model = "gpt-5.5"$' "$dst/.codex/agents/scribe.toml" \
|
||||||
|| { echo 'scribe.toml should map to gpt-5.4-mini'; result=1; }
|
|| { echo 'scribe.toml should map to gpt-5.5'; result=1; }
|
||||||
grep -q '^model_reasoning_effort = "medium"$' "$dst/.codex/agents/scribe.toml" \
|
grep -q '^model_reasoning_effort = "low"$' "$dst/.codex/agents/scribe.toml" \
|
||||||
|| { echo 'scribe.toml should map to medium reasoning effort'; result=1; }
|
|| { echo 'scribe.toml should map to low reasoning effort'; result=1; }
|
||||||
|
|
||||||
rm -rf "$dst"
|
rm -rf "$dst"
|
||||||
return $result
|
return $result
|
||||||
|
|||||||
@@ -106,6 +106,34 @@ HEREDOC
|
|||||||
return $result
|
return $result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_gemini_translate_agents_supports_crlf_frontmatter() {
|
||||||
|
local src; src="$(mktemp -d)"
|
||||||
|
local dst; dst="$(mktemp -d)"
|
||||||
|
mkdir -p "$src/agents"
|
||||||
|
printf '%s\r\n' \
|
||||||
|
'---' \
|
||||||
|
'name: scribe' \
|
||||||
|
'description: >' \
|
||||||
|
' Test scribe' \
|
||||||
|
' across line endings' \
|
||||||
|
'model: mid' \
|
||||||
|
'capabilities: [read, write, edit]' \
|
||||||
|
'---' \
|
||||||
|
'' \
|
||||||
|
'You are the Scribe.' > "$src/agents/scribe.md"
|
||||||
|
adapter_translate_agents "$src/agents" "$dst"
|
||||||
|
local out="$dst/.gemini/agents/scribe.md"
|
||||||
|
local result=0
|
||||||
|
grep -q '^name: scribe' "$out" || { echo "name missing"; result=1; }
|
||||||
|
grep -q '^description: >' "$out" || { echo "description header missing"; result=1; }
|
||||||
|
grep -q '^ Test scribe' "$out" || { echo "description continuation missing"; result=1; }
|
||||||
|
grep -q '^model: gemini-2.5-flash' "$out" || { echo "model not mapped from CRLF frontmatter"; result=1; }
|
||||||
|
grep -q '^ *- read_file' "$out" || { echo "tools not mapped from CRLF capabilities"; result=1; }
|
||||||
|
grep -q '^You are the Scribe' "$out" || { echo "body missing"; result=1; }
|
||||||
|
rm -rf "$src" "$dst"
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
test_gemini_translate_agents_bash_capability() {
|
test_gemini_translate_agents_bash_capability() {
|
||||||
local src; src="$(mktemp -d)"
|
local src; src="$(mktemp -d)"
|
||||||
local dst; dst="$(mktemp -d)"
|
local dst; dst="$(mktemp -d)"
|
||||||
|
|||||||
@@ -22,6 +22,29 @@ EOF
|
|||||||
[[ "$result" == "scribe" ]] || { echo "expected 'scribe', got '$result'"; return 1; }
|
[[ "$result" == "scribe" ]] || { echo "expected 'scribe', got '$result'"; return 1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_parse_frontmatter_and_body_support_crlf() {
|
||||||
|
local fixture; fixture="$(mktemp)"
|
||||||
|
printf '%s\r\n' \
|
||||||
|
'---' \
|
||||||
|
'name: architect' \
|
||||||
|
'model: high' \
|
||||||
|
'capabilities: [read, write]' \
|
||||||
|
'---' \
|
||||||
|
'You are the Architect.' > "$fixture"
|
||||||
|
local name model capabilities body
|
||||||
|
name="$(parse_frontmatter "$fixture" name)"
|
||||||
|
model="$(parse_frontmatter "$fixture" model)"
|
||||||
|
capabilities="$(parse_capabilities "$fixture")"
|
||||||
|
body="$(agent_body "$fixture")"
|
||||||
|
rm "$fixture"
|
||||||
|
local result=0
|
||||||
|
[[ "$name" == "architect" ]] || { echo "expected name architect, got '$name'"; result=1; }
|
||||||
|
[[ "$model" == "high" ]] || { echo "expected model high, got '$model'"; result=1; }
|
||||||
|
[[ "$capabilities" == "read write" ]] || { echo "expected capabilities 'read write', got '$capabilities'"; result=1; }
|
||||||
|
[[ "$body" == "You are the Architect." ]] || { echo "expected CRLF body, got '$body'"; result=1; }
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
test_parse_frontmatter_list() {
|
test_parse_frontmatter_list() {
|
||||||
local fixture; fixture="$(mktemp)"
|
local fixture; fixture="$(mktemp)"
|
||||||
cat > "$fixture" <<'EOF'
|
cat > "$fixture" <<'EOF'
|
||||||
|
|||||||
@@ -149,6 +149,35 @@ EOF
|
|||||||
return $result
|
return $result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_oc_translate_agents_supports_crlf_frontmatter() {
|
||||||
|
local src; src="$(mktemp -d)"
|
||||||
|
local dst; dst="$(mktemp -d)"
|
||||||
|
mkdir -p "$src/agents"
|
||||||
|
printf '%s\r\n' \
|
||||||
|
'---' \
|
||||||
|
'name: scribe' \
|
||||||
|
'description: >' \
|
||||||
|
' Test scribe' \
|
||||||
|
' across line endings' \
|
||||||
|
'model: mid' \
|
||||||
|
'mode: subagent' \
|
||||||
|
'capabilities: [read, write, edit]' \
|
||||||
|
'---' \
|
||||||
|
'' \
|
||||||
|
'You are the Scribe.' > "$src/agents/scribe.md"
|
||||||
|
adapter_translate_agents "$src/agents" "$dst"
|
||||||
|
local out="$dst/.opencode/agents/scribe.md"
|
||||||
|
local result=0
|
||||||
|
grep -q '^description: >' "$out" || { echo "description header missing"; result=1; }
|
||||||
|
grep -q '^ Test scribe' "$out" || { echo "description continuation missing"; result=1; }
|
||||||
|
grep -q '^mode: subagent' "$out" || { echo "mode not parsed from CRLF frontmatter"; result=1; }
|
||||||
|
grep -q '^model: anthropic/claude-sonnet-4-5' "$out" || { echo "model not mapped from CRLF frontmatter"; result=1; }
|
||||||
|
grep -q '^ edit: allow' "$out" || { echo "permissions not mapped from CRLF capabilities"; result=1; }
|
||||||
|
grep -q '^You are the Scribe' "$out" || { echo "body missing"; result=1; }
|
||||||
|
rm -rf "$src" "$dst"
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
test_oc_translate_agents_rewrites_body_paths() {
|
test_oc_translate_agents_rewrites_body_paths() {
|
||||||
local src; src="$(mktemp -d)"
|
local src; src="$(mktemp -d)"
|
||||||
local dst; dst="$(mktemp -d)"
|
local dst; dst="$(mktemp -d)"
|
||||||
|
|||||||
@@ -53,9 +53,9 @@ echo "File lists match."
|
|||||||
echo "── Per-file comparison ──"
|
echo "── Per-file comparison ──"
|
||||||
FAILED=0
|
FAILED=0
|
||||||
while IFS= read -r f; do
|
while IFS= read -r f; do
|
||||||
if ! diff -q "$SNAPSHOT_DIR/$f" "$DIST_DIR/$f" >/dev/null 2>&1; then
|
if ! diff --strip-trailing-cr -q "$SNAPSHOT_DIR/$f" "$DIST_DIR/$f" >/dev/null 2>&1; then
|
||||||
echo "DIFF: $f"
|
echo "DIFF: $f"
|
||||||
diff "$SNAPSHOT_DIR/$f" "$DIST_DIR/$f" | head -20
|
diff --strip-trailing-cr "$SNAPSHOT_DIR/$f" "$DIST_DIR/$f" | head -20
|
||||||
FAILED=$((FAILED + 1))
|
FAILED=$((FAILED + 1))
|
||||||
fi
|
fi
|
||||||
done < "$SNAP_LIST"
|
done < "$SNAP_LIST"
|
||||||
|
|||||||
Reference in New Issue
Block a user