Conversation
…tusLab#99) Upstream pinned the mitmproxy image (SCT_MITMPROXY_VERSION, rendered into both the template placeholder and the secret-provider image tags) and the rtk installer script and binary. The version lives in compose.MitmproxyVersion, with a contract test against images/mitmproxy.env mirroring cli/test/compat/mitmproxy_version.bats; the rtk block is regenerated from bash. The compose-agent.yml split (VirtusLab#99) leaves compose-all.yml declaring `agent: {}` in flow style. yaml.v3 preserves that style when children are added, rendering the populated service on one line; yq switches an empty flow collection to block style as soon as it gains content. appendContent now does the same, and only under that condition, so a non-empty flow node still keeps its style as it would under yq. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YKma722KMnAX3LcDLUYDQ5
The python stack now sets UV_SYSTEM_CERTS=1 on the agent service so uv trusts mitmproxy's intercepting CA. Upstream reworked the environment plumbing to make room for it: services.agent.environment is merged (appended to) rather than set, with the stack entries written before the agent's. SetAgentEnvironment becomes MergeAgentEnvironment and Generate follows the bash call order, which decides the entry order in the file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YKma722KMnAX3LcDLUYDQ5
Stacks now carry a JetBrains Marketplace plugin id, the counterpart of the VS Code extension for the JetBrains devcontainer path. Generate fills the `"plugins": []` array that the JetBrains customizations block declares, after CustomizeJSON has emitted it. Stacks whose language support is bundled, or whose JetBrains IDE is a standalone product with no IntelliJ plugin, contribute nothing and leave the array empty. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YKma722KMnAX3LcDLUYDQ5
, VirtusLab#96) `--features strict-network` (or SANDCAT_STRICT_NETWORK=true) replaces the project template's allow-all-GET wildcard with one `{"preset": s}` entry per resolved stack, expanded to concrete rules by the mitmproxy addon at start so the domain lists track the sandcat version. That path goes through `yq -o=json` in the bash and therefore reformats the whole file; jsonfile reproduces the layout, and a parity test covers the plain copy, strict with stacks, and strict with none. init also scaffolds an empty .sandcat/settings.local.json — the highest-precedence layer in the addon's settings merge and gitignored by the Sandcat block — and never overwrites one that exists, since it holds real credentials. The harness gains three strict-network cases: 30/30. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YKma722KMnAX3LcDLUYDQ5
Fourth supported agent. The table entry carries its extension, token help, mitmproxy addon and host config paths; the Dockerfile, home-prep and user-init fragments are captured from bash like the others, and the dump script now enumerates agents from sct_available_agents so a fifth one cannot be missed. The compose mounts follow upstream: mcp-config.json read-only, session-state read-write because Copilot CLI writes session events there and fails with EROFS otherwise. Harness and parity matrices gain copilot rows: 33/33. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YKma722KMnAX3LcDLUYDQ5
Users behind a corporate TLS interceptor can list PEM bundles under `upstream_ca_bundles` in user settings or the project's settings.local.json. init validates each (absolute, readable, contains a certificate block — the document is left untouched on any failure), bind-mounts them read-only into mitmproxy, and prepends their installation to the entrypoint. The install runs into both the OS store and certifi's bundle, because mitmproxy reads its trust store from certifi; and it is joined with `|| exit 1;` rather than `&&` so it stays outside the entrypoint's backgrounded list and fails loud. The harness never exercises this (no bundle under a throwaway HOME), so it gets a dedicated parity test with fixture bundles split across the two settings files, plus a rejection test. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YKma722KMnAX3LcDLUYDQ5
) The command restarts the agent as well when it was running: the agent uses network_mode: service:wg-client, which Docker resolves to a netns fd at start, so after wg-client restarts the agent's fd points at a torn-down namespace and every outbound connection breaks. The re-link waits for wg-client to be healthy first. Unlike the bash, the old name is kept as a hidden deprecated alias so existing scripts and docs don't break on upgrade. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YKma722KMnAX3LcDLUYDQ5
Upstream added four template files (compose-agent.yml, java-env.sh, the copilot addon and user-settings template). The hand-maintained expected list in embed_test.go would have kept passing without them, so it now walks cli/templates and requires the embedded tree to match file for file and byte for byte. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YKma722KMnAX3LcDLUYDQ5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #4 (which is stacked on #3). Restores the Go port to parity with the bash tree after the upstream merge: the harness goes from 0/27 to 33/33, and every bash-backed parity suite is green again.
One commit per upstream feature, so each can be read next to the upstream PR it tracks:
agent: {}stub--features strict-network+settings.local.jsonscaffoldupstream_ca_bundlesrestart-proxy→restartwith agent netns re-linkEverything else upstream shipped in that range was template- or image-only and flows through the embed untouched.
Things worth a look:
appendContentininternal/compose/file.go: yaml.v3 keeps a template'sagent: {}in flow style when populated, yq flips it to block. Reset only for an empty flow node, so a non-empty one still keeps its style as under yq.restart-proxyis kept as a hidden deprecated alias; the bash dropped it. Cheap, and it keeps scripts working.upstream_ca_bundlespath isn't reachable from the harness (no bundle under a throwaway HOME), so it has its own parity test with fixture bundles split across both settings files.sct_available_agents, so a fifth agent can't be missed.Merge order: this into #4's branch first (turns #4 green), then #4 →
go-port, then #3 →main.🤖 Generated with Claude Code
https://claude.ai/code/session_01YKma722KMnAX3LcDLUYDQ5