fix(cli): make go install work on Go 1.27 (#4649)

* fix(cli): make go install work on Go 1.27

Pin github.com/enetx/http to v1.0.29 so enetx/http2's go1.27-tagged
DisableClientPriority read compiles. Floor the same version in generated
go.mod files so regen-merge cannot reintroduce v1.0.28.

Co-authored-by: Trevin Chow <tmchow@users.noreply.github.com>

* test(cli): cover browser-transport go.mod pin under Go 1.27

Add a browser-chrome-h2 golden/generated-output fixture for the emitted
enetx/http pin, and compile the affected generated modules — including
the go1.27-tagged http2 source — instead of string-matching go.mod.

Co-authored-by: Trevin Chow <tmchow@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Trevin Chow <tmchow@users.noreply.github.com>
This commit is contained in:
Trevin Chow
2026-09-09 05:19:08 -07:00
committed by GitHub
parent be378adf96
commit 102578c08c
19 changed files with 322 additions and 15 deletions
+1 -1
View File
@@ -289,7 +289,7 @@ jobs:
include:
- shard: h3
packages: ./internal/generator
pattern: ^(TestGenerateBrowserChromeH3Transport)$
pattern: ^(TestGenerateBrowserChromeH3Transport|TestGenerateBrowserChromeTransport|TestGenerateCookieHTMLDefaultsBrowserChromeTransport)$
- shard: generator
packages: ./internal/generator
pattern: ^(TestGenerateProjectsCompile|TestGenerateCliutilPackage|TestGenerateFreshnessHelperEmitted|TestGenerateShareEmittedWhenEnabled|TestGenerateAgentContextCommand|TestGenerateHTMLExtractionEndpoint|TestGenerateHTMLExtractionEmbeddedJSONMode|TestGenerateHTMLExtractionPerModeGating|TestGenerateStoreWithBatchResourceDoesNotDuplicateUpsertBatch|TestGenerateStoreUpsertBatchDispatchesToTypedTable|TestGenerateStoreBackfillsIndexedColumnsOnUpgrade|TestGenerateStoreQuotesNumericTableAndDerivedIdentifiers|TestGeneratedOutput_PromotedCommandCompiles|TestGeneratedHelpers_AuthWithKeyURL_Compiles|TestGenerate_CookieAuthUsesBrowserTemplate|TestGenerate_ComposedAuthUsesBrowserTemplate|TestJSONStringParamRejectsInvalidValueBeforeClient|TestGenerateGraphQLBFFUsesSemanticCommandSurface|TestGenerateWhichFallsBackToCommandTree|TestGenerateDependentSyncCompiles|TestGenerateDependentSyncReservedWordCompiles|TestGeneratedSyncTreatsAccessDeniedAsWarning|TestGenerateGraphQLCompiles|TestGenerateMCPCodeOrchestrationEmitsSearchExecute|TestGenerateMCPIntentsEmittedWhenDeclared|TestGenerateMCPEndpointToolsHiddenSuppressesEndpointTools|TestGenerateMCPMainRemoteRuntime|TestGenerateMCPMainRemoteCompiles)$
+1 -1
View File
@@ -30,7 +30,7 @@ Keep golden artifacts contract-shaped. Snapshot the specific files or output fie
Maintain `testdata/golden/fixtures/golden-api.yaml` as the purpose-built generated-CLI fixture for the Printing Press. When the machine gains deterministic generation capabilities that should survive major refactors, extend this fixture and add the smallest useful artifact comparison that proves the capability. Do not mutate this fixture for one printed CLI's edge case unless it represents a general machine behavior.
Device Sniff uses separate deterministic fixtures because device specs are protocol-native rather than OpenAPI-shaped. Use `device-sniff-ble-sample` and `device-sniff-ble-ambiguous` for BLE discovery output. Use `generate-device-ble`, `generate-device-ble-control`, `generate-device-ble-session`, and `generate-device-ble-opaque` for generated device CLI artifacts.
Device Sniff uses separate deterministic fixtures because device specs are protocol-native rather than OpenAPI-shaped. Use `device-sniff-ble-sample` and `device-sniff-ble-ambiguous` for BLE discovery output. Use `generate-device-ble`, `generate-device-ble-control`, `generate-device-ble-session`, and `generate-device-ble-opaque` for generated device CLI artifacts. Use `generate-browser-http-transport` for the browser-chrome-h2 `go.mod` emit (surf plus the `enetx/http` pin).
## Failure handling
+1 -1
View File
@@ -41,7 +41,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dlclark/regexp2 v1.12.0 // indirect
github.com/enetx/g v1.0.224 // indirect
github.com/enetx/http v1.0.28 // indirect
github.com/enetx/http v1.0.29 // indirect
github.com/enetx/http2 v1.0.26 // indirect
github.com/enetx/http3 v1.0.7 // indirect
github.com/enetx/iter v0.0.0-20250912135656-f1583323588f // indirect
+2 -2
View File
@@ -19,8 +19,8 @@ github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz
github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/enetx/g v1.0.224 h1:H/uonguFE4qG8YCn5bSpZX5Wh+wTSb+jgf3I2ZM25XM=
github.com/enetx/g v1.0.224/go.mod h1:lxhby3LjP8jOTGbxJ/PCd+2Zq1gYiSBbtL/llPhAg5c=
github.com/enetx/http v1.0.28 h1:IaNSSDFlAVVdHnYhNIR9wAN7GY4TWL/kkvYC3jOaueY=
github.com/enetx/http v1.0.28/go.mod h1:1f4mytfF/SfjATEJnynpwGS6aa1ALjb8DtmYgFVblY0=
github.com/enetx/http v1.0.29 h1:B+NVXEN7vTAVYI+kZbx06Jqh/WwhHfUT8nG6OiRpQ78=
github.com/enetx/http v1.0.29/go.mod h1:1f4mytfF/SfjATEJnynpwGS6aa1ALjb8DtmYgFVblY0=
github.com/enetx/http2 v1.0.26 h1:wy3lYGVwnIUY4Q+gyPPQCJ1a+BMXD1B7Unpyc/Csrxc=
github.com/enetx/http2 v1.0.26/go.mod h1:t54ex5HIS8V1+2j6cvEOv6umlrHsbUPFKQ54nYB58Nk=
github.com/enetx/http3 v1.0.7 h1:daFhveKBtv8rRallCjaHErzzSHIrq07ovoSvVkvhcMM=
+47
View File
@@ -0,0 +1,47 @@
package generator
import (
"fmt"
"strings"
"golang.org/x/mod/semver"
)
// safeEnetxHTTPVersion is the lowest github.com/enetx/http release whose
// http.Server includes DisableClientPriority. enetx/http2 v1.0.25+ compiles a
// go1.27-tagged file that reads that field; v1.0.28 and older omit it, so
// `go install` on Go 1.27 fails. Keep in sync with the explicit pin in
// templates/go.mod.tmpl.
const safeEnetxHTTPVersion = "v1.0.29"
// ensureSafeEnetxHTTP bumps github.com/enetx/http to safeEnetxHTTPVersion when
// the generated module resolves it below that version. surf pulls both
// enetx/http and enetx/http2; a go.mod.tmpl pin covers the browser-transport
// path, but regen-merge can reintroduce a published v1.0.28 require and tidy
// can still land on surf's own v1.0.28 floor. Bumping after tidy is exact: it
// runs only when enetx/http is in the resolved graph. No-op when the module
// is absent or already at/above safeEnetxHTTPVersion.
func ensureSafeEnetxHTTP(dir string) error {
out, err := runCommand(dir, qualityGateTimeout, "go", "list", "-m", "-f", "{{.Version}}", "github.com/enetx/http")
if err != nil {
// `go list -m` exits non-zero when enetx/http is not a dependency of
// the module — nothing to pin.
return nil
}
// go list -m writes the version to stdout; runCommand joins stdout+stderr,
// so take only the first line to ignore any progress/download messages that
// the toolchain emits to stderr (e.g. "go: downloading github.com/enetx/http …")
// in fresh-cache environments.
current := strings.SplitN(strings.TrimSpace(out), "\n", 2)[0]
current = strings.TrimSpace(current)
if !semver.IsValid(current) || semver.Compare(current, safeEnetxHTTPVersion) >= 0 {
return nil
}
if _, err := runCommand(dir, qualityGateTimeout, "go", "get", "github.com/enetx/http@"+safeEnetxHTTPVersion); err != nil {
return fmt.Errorf("bumping github.com/enetx/http to %s: %w", safeEnetxHTTPVersion, err)
}
if _, err := runCommand(dir, qualityGateTimeout, "go", "mod", "tidy"); err != nil {
return fmt.Errorf("re-running go mod tidy after github.com/enetx/http bump: %w", err)
}
return nil
}
@@ -0,0 +1,65 @@
package generator
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestEnsureSafeEnetxHTTP exercises the post-tidy enetx/http pin against real
// modules. It needs network (go get / go mod tidy), so it skips in -short.
func TestEnsureSafeEnetxHTTP(t *testing.T) {
if testing.Short() {
t.Skip("ensureSafeEnetxHTTP runs go get / go mod tidy (network)")
}
t.Run("bumps a transitively-old enetx/http to the safe version", func(t *testing.T) {
dir := t.TempDir()
require.NoError(t, os.WriteFile(filepath.Join(dir, "go.mod"),
[]byte("module enetxhttpbump\n\ngo 1.24.0\n\nrequire github.com/enetx/http v1.0.28\n"), 0o644))
require.NoError(t, os.WriteFile(filepath.Join(dir, "main.go"),
[]byte("package main\n\nimport _ \"github.com/enetx/http\"\n\nfunc main() {}\n"), 0o644))
if _, err := runCommand(dir, qualityGateTimeout, "go", "mod", "tidy"); err != nil {
t.Skipf("initial go mod tidy failed (offline?): %v", err)
}
require.NoError(t, ensureSafeEnetxHTTP(dir))
out, err := runCommand(dir, qualityGateTimeout, "go", "list", "-m", "-f", "{{.Version}}", "github.com/enetx/http")
require.NoError(t, err)
assert.Equal(t, safeEnetxHTTPVersion, out, "enetx/http should be bumped to the safe version")
before, err := os.ReadFile(filepath.Join(dir, "go.mod"))
require.NoError(t, err)
_, err = runCommand(dir, qualityGateTimeout, "go", "mod", "tidy")
require.NoError(t, err)
after, err := os.ReadFile(filepath.Join(dir, "go.mod"))
require.NoError(t, err)
assert.Equal(t, string(before), string(after), "go.mod must be tidy after the bump")
})
t.Run("no-op when enetx/http is not a dependency", func(t *testing.T) {
dir := t.TempDir()
require.NoError(t, os.WriteFile(filepath.Join(dir, "go.mod"),
[]byte("module noenetxhttp\n\ngo 1.24.0\n"), 0o644))
require.NoError(t, os.WriteFile(filepath.Join(dir, "main.go"),
[]byte("package main\n\nfunc main() {}\n"), 0o644))
require.NoError(t, ensureSafeEnetxHTTP(dir))
gomod, err := os.ReadFile(filepath.Join(dir, "go.mod"))
require.NoError(t, err)
assert.NotContains(t, string(gomod), "github.com/enetx/http",
"absent enetx/http must not gain an unused require")
})
}
func TestSafeEnetxHTTPVersionMatchesGoModTemplate(t *testing.T) {
tmpl, err := os.ReadFile(filepath.Join("templates", "go.mod.tmpl"))
require.NoError(t, err)
assert.Contains(t, string(tmpl), "github.com/enetx/http "+safeEnetxHTTPVersion,
"templates/go.mod.tmpl pin must stay in sync with safeEnetxHTTPVersion")
}
+65 -5
View File
@@ -15,6 +15,7 @@ import (
"path/filepath"
"regexp"
"strings"
"sync"
"sync/atomic"
"testing"
@@ -2585,18 +2586,66 @@ func countFiles(t *testing.T, root string) int {
}
func runGoCommand(t *testing.T, dir string, args ...string) {
t.Helper()
runGoCommandWithEnv(t, dir, nil, args...)
}
func runGoCommandWithEnv(t *testing.T, dir string, extraEnv []string, args ...string) {
t.Helper()
if testing.Short() && len(args) > 0 && (args[0] == "build" || args[0] == "test") {
t.Skip("generated CLI compile tests run in the full generated-test CI lane")
}
runGoCommandRequired(t, dir, args...)
output, err := runGoCommandOutputWithEnv(t, dir, extraEnv, args...)
require.NoError(t, err, output)
}
func requireGeneratedCompiles(t *testing.T, dir string) {
t.Helper()
requireGeneratedCompilesWithEnv(t, dir, nil)
}
func requireGeneratedCompilesWithEnv(t *testing.T, dir string, extraEnv []string) {
t.Helper()
// No-op in this test harness; module resolution is exercised via -mod=mod.
runGoCommand(t, dir, "mod", "tidy")
runGoCommand(t, dir, "build", "./...")
runGoCommandWithEnv(t, dir, extraEnv, "mod", "tidy")
runGoCommandWithEnv(t, dir, extraEnv, "build", "./...")
}
const go127Toolchain = "go1.27.0"
var (
go127Once sync.Once
go127Avail bool
go127Reason string
)
func go127ToolchainAvailable(t *testing.T) bool {
t.Helper()
go127Once.Do(func() {
cmd := exec.Command("go", "version")
cmd.Env = append(os.Environ(), "GOTOOLCHAIN="+go127Toolchain)
out, err := cmd.CombinedOutput()
if err != nil {
go127Reason = strings.TrimSpace(string(out) + " " + err.Error())
return
}
go127Avail = strings.Contains(string(out), "go1.27")
if !go127Avail {
go127Reason = strings.TrimSpace(string(out))
}
})
if !go127Avail && go127Reason != "" {
t.Logf("Go 1.27 toolchain unavailable: %s", go127Reason)
}
return go127Avail
}
func requireGeneratedCompilesGo127(t *testing.T, dir string) {
t.Helper()
if !go127ToolchainAvailable(t) {
t.Skip("Go 1.27 toolchain not available to typecheck enetx/http2's go1.27-tagged source")
}
requireGeneratedCompilesWithEnv(t, dir, []string{"GOTOOLCHAIN=" + go127Toolchain})
}
func runGoCommandRequired(t *testing.T, dir string, args ...string) {
@@ -2611,6 +2660,11 @@ func runGoCommandRequired(t *testing.T, dir string, args ...string) {
// the usual must-succeed case.
func runGoCommandOutput(t *testing.T, dir string, args ...string) (string, error) {
t.Helper()
return runGoCommandOutputWithEnv(t, dir, nil, args...)
}
func runGoCommandOutputWithEnv(t *testing.T, dir string, extraEnv []string, args ...string) (string, error) {
t.Helper()
// Generated-project compile tests exercise module resolution via -mod=mod;
// production Validate still owns the go mod tidy quality gate.
@@ -2627,6 +2681,7 @@ func runGoCommandOutput(t *testing.T, dir string, args ...string) (string, error
require.NoError(t, err)
cmd.Env = append(os.Environ(), "GOCACHE="+cacheDir)
cmd.Env = append(cmd.Env, sandboxHomeEnv(t)...)
cmd.Env = append(cmd.Env, extraEnv...)
output, err := cmd.CombinedOutput()
return string(output), err
}
@@ -2850,6 +2905,7 @@ func TestGenerateBrowserChromeTransport(t *testing.T) {
assert.Contains(t, string(gomod), "go "+currentGoDirectiveVersion()+"\n")
assert.Contains(t, string(gomod), "toolchain "+currentGoToolchainVersion())
assert.Contains(t, string(gomod), "github.com/enetx/surf")
assert.Contains(t, string(gomod), "github.com/enetx/http "+safeEnetxHTTPVersion)
clientGo, err := os.ReadFile(filepath.Join(outputDir, "internal", "client", "client.go"))
require.NoError(t, err)
@@ -2862,8 +2918,9 @@ func TestGenerateBrowserChromeTransport(t *testing.T) {
readme, err := os.ReadFile(filepath.Join(outputDir, "README.md"))
require.NoError(t, err)
assert.Contains(t, string(readme), "Chrome-compatible HTTP transport")
// The H3 sibling below compiles the same surf-backed client path; this
// test stays focused on the non-H3 rendering branch.
requireGeneratedCompiles(t, outputDir)
requireGeneratedCompilesGo127(t, outputDir)
}
func TestGenerateBrowserChromeH3Transport(t *testing.T) {
@@ -3280,12 +3337,15 @@ func TestGenerateCookieHTMLDefaultsBrowserChromeTransport(t *testing.T) {
gomod := readGeneratedFile(t, outputDir, "go.mod")
assert.Contains(t, gomod, "github.com/enetx/surf")
assert.Contains(t, gomod, "github.com/enetx/http "+safeEnetxHTTPVersion)
clientGo := readGeneratedFile(t, outputDir, "internal", "client", "client.go")
assert.Contains(t, clientGo, `"github.com/enetx/surf"`)
assert.Contains(t, clientGo, "Impersonate()")
assert.Contains(t, clientGo, "Chrome()")
assert.NotContains(t, clientGo, `req.Header.Set("User-Agent", "cookiehtml-pp-cli/0.1.0")`)
requireGeneratedCompiles(t, outputDir)
}
func TestGenerateHTMLExtractionEndpoint(t *testing.T) {
+6 -3
View File
@@ -269,15 +269,18 @@ func GenerateFromPlan(planSpec *PlanSpec, outputDir string) error {
return fmt.Errorf("running go mod tidy: %w", err)
}
// Pin golang.org/x/net and golang.org/x/text to patched releases when they
// resolved transitively below the safe versions (see ensureSafeXNet and
// ensureSafeXText).
// Pin golang.org/x/net, golang.org/x/text, and github.com/enetx/http to
// safe releases when they resolved transitively below the floors (see
// ensureSafeXNet, ensureSafeXText, and ensureSafeEnetxHTTP).
if err := ensureSafeXNet(outputDir); err != nil {
return err
}
if err := ensureSafeXText(outputDir); err != nil {
return err
}
if err := ensureSafeEnetxHTTP(outputDir); err != nil {
return err
}
return nil
}
+6
View File
@@ -65,4 +65,10 @@ require golang.org/x/sys v0.46.0
// is present, so MVS keeps the floor; tidy drops it for CLIs without surf.
require golang.org/x/crypto v0.53.0 // indirect
require github.com/quic-go/quic-go v0.60.0 // indirect
// enetx/http2 v1.0.25+ reads http.Server.DisableClientPriority under
// //go:build go1.27. Surf still floors http at v1.0.28, which lacks that
// field; pin v1.0.29 so printed CLIs `go install` on Go 1.27. Keep in
// sync with safeEnetxHTTPVersion. regen-merge: fresh wins on this path,
// so a published v1.0.28 cannot re-enter.
require github.com/enetx/http v1.0.29 // indirect
{{- end}}
+6
View File
@@ -61,6 +61,12 @@ func (g *Generator) Validate() error {
return ensureSafeXText(g.OutputDir)
},
},
{
name: "ensure safe github.com/enetx/http",
run: func() error {
return ensureSafeEnetxHTTP(g.OutputDir)
},
},
{
name: "go test ./...",
run: func() error {
@@ -232,3 +232,54 @@ require github.com/spf13/cobra v1.9.1
assert.Equal(t, "v1.9.1", gotPaths["github.com/spf13/cobra"],
"shared deps stay at fresh's version")
}
// TestRenderMergedGoModFreshWinsEnetxHTTP pins that regen-merge cannot
// reintroduce github.com/enetx/http v1.0.28 (the Go 1.27 http2 compile
// break) when the fresh tree floors v1.0.29. Fresh already wins on shared
// require paths; this case locks that rule to the pin that makes `go install`
// work on Go 1.27.
func TestRenderMergedGoModFreshWinsEnetxHTTP(t *testing.T) {
t.Parallel()
tmp := t.TempDir()
pubDir := filepath.Join(tmp, "pub")
freshDir := filepath.Join(tmp, "fresh")
require.NoError(t, os.MkdirAll(pubDir, 0o755))
require.NoError(t, os.MkdirAll(freshDir, 0o755))
pubGoMod := []byte(`module github.com/example/monorepo/library/foo
go 1.26.6
require (
github.com/enetx/http v1.0.28
github.com/enetx/http2 v1.0.26
github.com/enetx/surf v1.0.199
)
`)
freshGoMod := []byte(`module foo-pp-cli
go 1.26.6
require (
github.com/enetx/http v1.0.29
github.com/enetx/http2 v1.0.26
github.com/enetx/surf v1.0.199
)
`)
require.NoError(t, writeFileAtomic(filepath.Join(pubDir, "go.mod"), pubGoMod))
require.NoError(t, writeFileAtomic(filepath.Join(freshDir, "go.mod"), freshGoMod))
bytes, err := renderMergedGoMod(pubDir, freshDir)
require.NoError(t, err)
parsed, err := modfile.Parse("merged-go.mod", bytes, nil)
require.NoError(t, err)
gotPaths := map[string]string{}
for _, req := range parsed.Require {
gotPaths[req.Mod.Path] = req.Mod.Version
}
assert.Equal(t, "v1.0.29", gotPaths["github.com/enetx/http"],
"fresh's Go 1.27-compatible enetx/http pin must win over published v1.0.28")
assert.Equal(t, "v1.0.26", gotPaths["github.com/enetx/http2"])
}
+3 -2
View File
@@ -12,8 +12,8 @@ source-level tests and byte-level goldens can miss.
When no case is supplied, a focused default set covers endpoint templates,
MCP/code-orchestration, rich auth, GraphQL shared endpoints, learn-loop
emission, and generated BLE device variants. Pass extra case names when a fix
touches another generated variant.
emission, generated BLE device variants, and browser-transport go.mod.
Pass extra case names when a fix touches another generated variant.
USAGE
}
@@ -49,6 +49,7 @@ default_cases=(
generate-device-ble-control
generate-device-ble-session
generate-device-ble-opaque
generate-browser-http-transport
)
cases=()
@@ -0,0 +1,5 @@
# Locks the browser-transport go.mod contract: surf plus the enetx/http
# pin (and the x/crypto / quic-go floors). Standard-HTTP generate cases
# never emit this block.
browser-http-transport/go.mod
@@ -0,0 +1,2 @@
set -euo pipefail
"$BINARY" generate --spec testdata/golden/fixtures/browser-http-transport.yaml --output "$CASE_ACTUAL_DIR/browser-http-transport" --force --spec-url file://testdata/golden/fixtures/browser-http-transport.yaml --validate=false
@@ -0,0 +1,36 @@
module browser-http-transport-pp-cli
go 1.26.6
toolchain go1.26.6
require (
github.com/enetx/surf v1.0.199
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
github.com/pelletier/go-toml/v2 v2.2.4
)
require modernc.org/sqlite v1.37.0
require github.com/mark3labs/mcp-go v0.57.0
// x/sys is a DIRECT dependency even without auth: filelock_windows.go
// imports golang.org/x/sys/windows. Emitted as a direct require (no
// // indirect) so a Windows cross-compile of a freshly generated bundle
// succeeds without a manual `go mod tidy`. The version matches the
// transitive floor. NOTE (go mod tidy GOOS caveat): the import is behind
// `//go:build windows`, so tidy under GOOS=linux/darwin re-marks this
// // indirect; under GOOS=windows it stays direct.
require golang.org/x/sys v0.46.0
// Floor the HTTP/3 transitive deps pulled in only via github.com/enetx/surf
// above their vulnerable versions (osv flags module presence; govulncheck
// reachability = 0 for these REST CLIs). Emitted only when the surf transport
// is present, so MVS keeps the floor; tidy drops it for CLIs without surf.
require golang.org/x/crypto v0.53.0 // indirect
require github.com/quic-go/quic-go v0.60.0 // indirect
// enetx/http2 v1.0.25+ reads http.Server.DisableClientPriority under
// //go:build go1.27. Surf still floors http at v1.0.28, which lacks that
// field; pin v1.0.29 so printed CLIs `go install` on Go 1.27. Keep in
// sync with safeEnetxHTTPVersion. regen-merge: fresh wins on this path,
// so a published v1.0.28 cannot re-enter.
require github.com/enetx/http v1.0.29 // indirect
@@ -0,0 +1 @@
0
@@ -0,0 +1,3 @@
warning: could not derive run_id from --research-dir; phase5 dogfood acceptance will refuse to write without it
agentcookie: skipping browser-http-transport (cookie-only or no env-var auth)
Generated browser-http-transport at <ARTIFACT_DIR>/generate-browser-http-transport/browser-http-transport
+21
View File
@@ -0,0 +1,21 @@
name: browser-http-transport
description: |
Golden fixture for the browser-chrome-h2 go.mod emit: surf plus the
enetx/http pin required so printed CLIs `go install` on Go 1.27.
Existing generate-* cases use standard HTTP and never snapshot this
require block.
version: 1.0.0
base_url: https://www.example.com
http_transport: browser-chrome-h2
auth:
type: none
resources:
posts:
description: Browse posts
endpoints:
list:
method: GET
path: /
description: List posts
learn:
disabled: true