Skip to content

Commit a1e84de

Browse files
hongyi-chenoz-agent
andcommitted
docs(cloud-agents): add full bundled snapshot script alongside minimal example
Per Harry's Slack OK on showing the full script ("from a security POV, definitely no issues with showing the entire script... any user who cared could easily find the script by just running a cloud agent and cat-ing it out"), include the canonical declarations script Warp invokes inside the bundled cloud agent image in addition to (not replacing) the minimal sed-based example. Changes to snapshots.mdx: * Keep the minimal sed-based example unchanged. It's a clean starting point for users adapting a custom script. * Add a new "### The full bundled script" subsection right after the Direct backend tip. It introduces the canonical script in prose, then shows it verbatim in a second bash code block. * Add a :::note flagging that OZ_SNAPSHOT_JQ defaults to /agent/tools/jq (an image-only path). External users adapting the script need to put jq on PATH or override OZ_SNAPSHOT_JQ. * Drop the previous :::note that summarized what the bundled script did extra — the same information is now visible directly in the script. Co-Authored-By: Oz <oz-agent@warp.dev>
1 parent a00d291 commit a1e84de

1 file changed

Lines changed: 79 additions & 1 deletion

File tree

  • src/content/docs/agent-platform/cloud-agents/handoff

src/content/docs/agent-platform/cloud-agents/handoff/snapshots.mdx

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,88 @@ export OZ_SNAPSHOT_DECLARATIONS_SCRIPT=/path/to/snapshot-declarations.sh
114114

115115
For a managed [Direct backend](/agent-platform/cloud-agents/self-hosting/managed-direct/) worker, set it via the worker's `environment` config so it's present when the agent process starts.
116116

117+
### The full bundled script
118+
119+
For reference, this is the canonical declarations script Warp invokes inside the bundled cloud agent image. It's a richer version of the minimal example above: it honors a colon-separated `OZ_SNAPSHOT_SCAN_ROOTS` override for operators who need to scan repos outside the default workspace, uses `jq` for canonical JSON encoding (which handles `"` and `\` escaping for you), and dedupes against repo declarations already written in the same run so repeated invocations stay additive.
120+
117121
:::note
118-
The declarations script bundled in Warp's cloud agent image is a richer version of the example above: it also honors a colon-separated `OZ_SNAPSHOT_SCAN_ROOTS` override for operators who need to scan repos outside the default workspace, uses `jq` for canonical JSON encoding instead of `sed`-based escaping, and dedupes against repo declarations already written in the same run so repeated invocations stay additive.
122+
The bundled script defaults `OZ_SNAPSHOT_JQ` to `/agent/tools/jq`, which only exists inside Warp's cloud agent image. If you adapt this script for a different image or for an unmanaged `oz agent run`, put `jq` on `PATH` or set `OZ_SNAPSHOT_JQ` to its absolute path.
119123
:::
120124

125+
```bash title="snapshot-declarations.sh"
126+
#!/bin/bash
127+
# Generates the declarations file consumed by the end-of-run snapshot upload pipeline.
128+
#
129+
# Scans one or more roots for `.git` directories and appends one JSON object per
130+
# newly-discovered repository to the declarations file.
131+
#
132+
# Scan root selection (in order of precedence):
133+
# - OZ_SNAPSHOT_SCAN_ROOTS: colon-separated list of absolute paths. Operators can use this
134+
# to target repos outside the default workspace.
135+
# - $PWD: the Rust driver sets this to the agent's workspace via `Command::current_dir`
136+
# before invoking the script, so the default scan root is always the assigned workspace.
137+
#
138+
# Output file:
139+
# - OZ_SNAPSHOT_DECLARATIONS_FILE must be set. The Rust driver sets this to a per-run path
140+
# so concurrent runs don't clobber each other.
141+
# - The file is created if missing, and appended to if it already exists. Existing lines are
142+
# never rewritten, so operator-authored declarations are preserved.
143+
# - Repeated invocations within a single run skip already-emitted repo declarations so the
144+
# upload pipeline can stay additive without duplicating identical generated entries.
145+
146+
set -euo pipefail
147+
148+
SCAN_ROOTS_RAW="${OZ_SNAPSHOT_SCAN_ROOTS:-$PWD}"
149+
IFS=':' read -r -a SCAN_ROOTS <<< "$SCAN_ROOTS_RAW"
150+
151+
if [ -z "${OZ_SNAPSHOT_DECLARATIONS_FILE:-}" ]; then
152+
echo "OZ_SNAPSHOT_DECLARATIONS_FILE must be set" >&2
153+
exit 1
154+
fi
155+
156+
DECL_FILE="$OZ_SNAPSHOT_DECLARATIONS_FILE"
157+
JQ="${OZ_SNAPSHOT_JQ:-/agent/tools/jq}"
158+
mkdir -p "$(dirname "$DECL_FILE")"
159+
touch "$DECL_FILE"
160+
161+
# Dedup set. Seed from repo declarations already emitted by this script so a repeated
162+
# invocation within the same run doesn't re-emit repos it already discovered earlier.
163+
# Keep the full canonical JSON line as the key; this lets us preserve unrelated JSONL entries
164+
# verbatim while ensuring identical generated declarations are emitted at most once.
165+
SEEN_FILE="$(mktemp)"
166+
trap 'rm -f "$SEEN_FILE"' EXIT
167+
"$JQ" --raw-input --compact-output '
168+
fromjson?
169+
| select(
170+
type == "object"
171+
and (. | keys_unsorted | sort == ["kind", "path", "version"])
172+
and .version == 1
173+
and .kind == "repo"
174+
and (.path | type == "string")
175+
)
176+
| { version: 1, kind: "repo", path: .path }
177+
' "$DECL_FILE" > "$SEEN_FILE"
178+
179+
repo_declaration_for_path() {
180+
"$JQ" --compact-output --null-input \
181+
--arg path "$1" \
182+
'{ version: 1, kind: "repo", path: $path }'
183+
}
184+
185+
for root in "${SCAN_ROOTS[@]}"; do
186+
[ -d "$root" ] || continue
187+
while IFS= read -r git_dir; do
188+
repo_root="$(cd "$(dirname "$git_dir")" && pwd)"
189+
repo_declaration="$(repo_declaration_for_path "$repo_root")"
190+
if grep -Fxq -- "$repo_declaration" "$SEEN_FILE"; then
191+
continue
192+
fi
193+
printf '%s\n' "$repo_declaration" >> "$SEEN_FILE"
194+
printf '%s\n' "$repo_declaration" >> "$DECL_FILE"
195+
done < <(find "$root" -type d -name .git -prune -print 2>/dev/null)
196+
done
197+
```
198+
121199
## Use a static declarations file
122200

123201
If the same set of repositories or files should be snapshotted on every run (for example, an unmanaged GitHub Actions job operating on a known checkout), you can skip the script entirely and pre-populate a JSONL file:

0 commit comments

Comments
 (0)