| 95 | 95 | | |
| 96 | 96 | | /// What g1t tells the agent, for every session. |
| 97 | 97 | | pub fn system_prompt() -> String { |
| 98 | | − | "You work on issues in a g1t repository (g1t is a git forge), for the person who started you, with their own Claude. \ |
| 98 | + | format!( |
| 99 | + | "You work on issues in a g1t repository (g1t is a git forge), for the person who started you, with their own Claude. \ |
| 99 | 100 | | Each session's first message says which repository and issue, what kind of work, and how to reach them.\n\n\ |
| 100 | 101 | | - Run the setup in your first message before anything else: it installs the g1t CLI, has git send your token to g1t, \ |
| 101 | 102 | | clones the repository and ties the clone to this g1t session.\n\ |
| ⋯ |
| 118 | 119 | | `g1t deploy list` until it is live or failed; if it failed, read why, fix it and push again. Say where it is live in your report.\n\ |
| 119 | 120 | | - To show a screenshot in a pull request or a comment, upload it with `g1t attach FILE` and paste the Markdown it prints \ |
| 120 | 121 | | (or pass `--attach FILE` to `g1t pr create`, `g1t pr ready` or `g1t pr comment`). Never commit an image to the repository just to link it.\n\ |
| 122 | + | - The sandbox reaches the web through a proxy whose certificate the system store trusts; curl, git and the g1t CLI read that store, \ |
| 123 | + | but Chromium (Playwright, Puppeteer) reads its own. Before a headless browser opens an https page, run once: `{BROWSER_TRUST}`. \ |
| 124 | + | Never turn certificate checks off (ignore_https_errors, --ignore-certificate-errors) instead.\n\ |
| 121 | 125 | | - Never write `@g1t` in what you post on g1t: that asks g1t for another session.\n\ |
| 122 | 126 | | - When you finish, say in a few sentences what you did, what is left, and the pull request, if any. That is your report on g1t: it shows on the issue as this session's card, so never post it, \ |
| 123 | 127 | | or anything else, as a comment." |
| 124 | | − | .to_owned() |
| 128 | + | ) |
| 125 | 129 | | } |
| 126 | 130 | | |
| 131 | + | /// Copies the certificates the system store trusts (the sandbox proxy's |
| 132 | + | /// among them) into Chromium's NSS store, which it reads instead of the |
| 133 | + | /// system's. Safe to run again: each certificate keeps its nickname. |
| 134 | + | pub const BROWSER_TRUST: &str = "command -v certutil >/dev/null || { apt-get update -qq && apt-get install -y -qq libnss3-tools; } >/dev/null 2>&1; \ |
| 135 | + | mkdir -p ~/.pki/nssdb && { [ -f ~/.pki/nssdb/cert9.db ] || certutil -d sql:$HOME/.pki/nssdb -N --empty-password; } \ |
| 136 | + | && d=$(mktemp -d) && awk -v d=\"$d\" '/BEGIN CERT/{n++; f=d \"/\" n \".pem\"} n{print > f} /END CERT/{close(f)}' /etc/ssl/certs/ca-certificates.crt \ |
| 137 | + | && for f in \"$d\"/*.pem; do certutil -d sql:$HOME/.pki/nssdb -A -t C,, -n \"system-$(basename \"$f\" .pem)\" -i \"$f\"; done && rm -rf \"$d\""; |
| 138 | + | |
| 127 | 139 | | /// The agent g1t keeps on an Anthropic account. |
| 128 | 140 | | pub fn agent_body(model: &str, mcp_url: &str, skills: &[Value]) -> Value { |
| 129 | 141 | | json!({ |
| ⋯ |
| 1572 | 1584 | | assert!(system_prompt().contains("never in a URL")); |
| 1573 | 1585 | | assert!(system_prompt().contains("g1t pr checks --watch --fail-fast")); |
| 1574 | 1586 | | assert!(system_prompt().contains("g1t attach FILE"), "screenshots are attached, never committed"); |
| 1587 | + | assert!(system_prompt().contains(BROWSER_TRUST), "the browser trusts the proxy instead of skipping certificate checks"); |
| 1575 | 1588 | | } |
| 1576 | 1589 | | |
| 1577 | 1590 | | #[test] |