Skip to content

Add session name & tags to browsers update (kernel-go-sdk v0.66.0)#184

Open
bmsaadat wants to merge 1 commit into
mainfrom
bmsaadat/sdk-066-browser-tags-name
Open

Add session name & tags to browsers update (kernel-go-sdk v0.66.0)#184
bmsaadat wants to merge 1 commit into
mainfrom
bmsaadat/sdk-066-browser-tags-name

Conversation

@bmsaadat

@bmsaadat bmsaadat commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Bumps kernel-go-sdk v0.65.0 → v0.66.0, which adds Name/Tags to BrowserUpdateParams (PATCH /browser), and uses it to give browsers update <id-or-name> the --name / --clear-name / --tag KEY=VALUE / --clear-tags flags that #177 had left creation-only. The flags mirror the existing --clear-proxy convention and honor the SDK semantics exactly (omit = unchanged, empty = clear, tags = full replace), with validation that rejects --name/--clear-name and --tag/--clear-tags conflicts, guards against an accidental --name "", and stays correct via a SetName/SetTags flag signal even when a malformed --tag is dropped to an empty map. Also refreshes the now-stale create --name help and the update --tag cap in help/README, and adds unit tests across the new flags, clear/omit marshaling, and the malformed-tag edge cases.

Test Plan

  • go build ./..., go vet ./cmd/, gofmt — clean
  • go test ./... — passing (16 new TestBrowsersUpdate_* cases)
  • Binary exercised end-to-end: --help shows flags; every validation path errors before any API call
  • Live round-trip verified against a local Kernel (localhost:3001): 18/19 🌐 rows pass, 0 product defects — full-replace tags, --name-only does not clobber tags (omit = unchanged), clear name/tags, by-id/by-name resolution, not-found, JSON echo, name+telemetry, and the 50-tag cap (Invalid_tags: too many tags: 51 (maximum 50)). Sessions were cleaned up. The one unrun row, B3 (rename-collision between two concurrent active sessions), isn't exercisable on the local stack (it returns Capacity_exhausted for a second simultaneous browser); name uniqueness is server-enforced and the CLI only relays the error.

Manual test matrix

Status: ✅ = verified locally (path returns before any API call, or pinned by a named unit test asserting the exact forwarded params / JSON) · 🌐 = needs a live Kernel API round-trip (not yet run here).

Notes

  • Error display: pterm capitalizes the first letter (Cannot specify…, --Name requires…); the raw fmt.Errorf strings are lowercase — same error.
  • Success output: the Name: / Tags: lines echo the server's returned values, not the request. Unit tests pin the request body (✅); the displayed value is a 🌐 observation — except after a clear, where Name: - / Tags: - is correct regardless.
  • Scope: disable_default_proxy (also new in v0.66) is intentionally not exposed by this PR.

Preconditions for 🌐 rows: one session with a known starting name + tags (browsers create --name mtx-base --tag a=1 --tag team=qa); D2 needs the session to start with {a=1} then run --tag b=2; B2/B3 need a second session (--name mtx-taken) so a colliding active name exists.

A. Build / help

# Scenario Command Expected Status
A1 Builds & flags wired go build ./cmd/kernel Builds clean
A2 Help lists new flags browsers update --help Shows --name, --clear-name, --tag, --clear-tags; the --tag line carries the full-replace + "up to 50 pairs" notes
A3 Long help documents ops browsers update --help Long text lists rename/clear-name and replace/clear-tags, and the "--tag replaces the entire tag set" note

B. Set name

# Scenario Command Expected Status
B1 Set/rename browsers update <id> --name new-name Request body {"name":"new-name"} ✅; output Updated browser <id> then Name: new-name (value echoed from server response) 🌐 ✅ (request body unit-tested); 🌐 (displayed value + persistence)
B2 Rename resolves by current name browsers update old-name --name newer Resolves session by name, applies rename 🌐
B3 Rename to a name used by another active session browsers update <id> --name taken API rejects: Conflict: browser session name already exists 🌐

C. Clear name

# Scenario Command Expected Status
C1 Clear name browsers update <id> --clear-name Request body {"name":""}; output Name: - ✅ (request body unit-tested); 🌐 (persisted: get shows no name)
C2 --name "" rejected (use --clear-name) browsers update <id> --name "" Error: --name requires a non-empty value; use --clear-name to clear the name
C3 --name= (explicit empty) rejected browsers update <id> --name= Same error as C2

D. Set tags (full replace)

# Scenario Command Expected Status
D1 Replace tag set browsers update <id> --tag team=backend --tag env=prod Request body {"tags":{"team":"backend","env":"prod"}} ✅; output Tags: env=prod, team=backend (sorted; echoed from server response) 🌐 ✅ (request body unit-tested); 🌐 (displayed value + persistence)
D2 Full-replace semantics (not merge) Session has {a=1}, run --tag b=2 Resulting tags are {b=2} only — a is gone 🌐
D3 Special-char tag key round-trips browsers update <id> --tag region.us=1 Body contains "region.us":"1" ✅ (parser unit-tested); 🌐 (persisted)
D4 50-tag cap --tag ×51 API rejects over-limit (server-enforced) 🌐
D5 Tag value containing = browsers update <id> --tag url=a=b Splits on first = only → body {"tags":{"url":"a=b"}} (not dropped as malformed) ✅ (parser unit-tested: k=v=wk:"v=w"); 🌐 (persisted)

E. Clear tags

# Scenario Command Expected Status
E1 Clear all tags browsers update <id> --clear-tags Body {"tags":{}}; output Tags: - ✅ (request body unit-tested); 🌐 (persisted: get shows no tags)

F. Combined name + tags

# Scenario Command Expected Status
F1 Set name + set tags together browsers update <id> --name combo --tag k=v Body has both "name":"combo" and "tags":{"k":"v"} ✅ (unit-tested); 🌐 (persisted)
F2 Clear name + set tags browsers update <id> --clear-name --tag env=prod Body {"name":"","tags":{"env":"prod"}} ✅ (unit-tested)
F3 Set name + clear tags browsers update <id> --name renamed --clear-tags Body {"name":"renamed","tags":{}} ✅ (unit-tested)

G. Combine with existing update flags

# Scenario Command Expected Status
G1 Name/tags + proxy in one call browsers update <id> --proxy-id <pid> --name combo --tag k=v All three forwarded: proxy_id, name, tags ✅ (unit-tested); 🌐 (persisted)
G2 Name + telemetry browsers update <id> --name n --telemetry=all Name applied and telemetry summary printed 🌐
G3 Partial update does NOT clobber unrelated fields Session has tags + proxy; run --name only Only name changes; tags & proxy untouched (omit = unchanged) ✅ (omit-not-sent unit-tested); 🌐 (persisted)

H. Conflict & "at least one" validation

# Scenario Command Expected Status
H1 --name + --clear-name browsers update <id> --name x --clear-name Error: cannot specify both --name and --clear-name
H2 --tag + --clear-tags browsers update <id> --tag a=1 --clear-tags Error: cannot specify both --tag and --clear-tags
H3 No options at all browsers update <id> Error: must specify at least one of: … (full list of 10 flags, ending --name, --clear-name, --tag, or --clear-tags) — substring check
H4 Name-only satisfies "at least one" browsers update <id> --name x Proceeds (no "at least one" error)
H5 Tags-only satisfies "at least one" browsers update <id> --tag k=v Proceeds ✅ (param path); 🌐 (persisted)

I. Malformed-tag edge cases

# Scenario Command Expected Status
I1 All --tag values malformed, alone browsers update <id> --tag foo Warns Ignoring malformed tag: foo, then error no valid --tag KEY=VALUE pairs provided (not the generic "at least one")
I2 Malformed --tag + --clear-tags still conflicts browsers update <id> --tag foo --clear-tags Warns, then error cannot specify both --tag and --clear-tags (does NOT silently clear)
I3 Partially malformed list warns & continues (documented sharp edge) browsers update <id> --tag a=1 --tag bad Warns on bad, replaces tag set with {a=1} only ✅ (parser unit-tested); 🌐 (persisted)

J. ID-vs-name resolution & errors

# Scenario Command Expected Status
J1 Update by ID browsers update <cuid> --name n Resolves by ID 🌐
J2 Update by name browsers update <name> --name n2 Resolves by name 🌐
J3 Not found browsers update nonexistent --name n Clean not-found error 🌐

K. JSON output

# Scenario Command Expected Status
K1 JSON echoes persisted name/tags browsers update <id> --name n --tag k=v -o json Prints full BrowserUpdateResponse JSON including name and tags 🌐
K2 -o yaml rejected browsers update <id> --name n -o yaml Error: unsupported --output value "yaml"; use "json"…

L. Round-trip / persistence

# Scenario Command Expected Status
L1 get reflects rename update --name nbrowsers get <id> Detail table + JSON show new name 🌐
L2 get reflects tag replace update --tag k=vbrowsers get <id> Shows exactly the new tag set 🌐
L3 get/list reflect clears --clear-name/--clear-tagsget & list --query No name / no tags after clear; list --tag no longer matches 🌐
L4 list --tag filter after replace replace tags → browsers list --tag k=v Session appears under the new tag, not the old 🌐
L5 list Name column after rename --name newnamebrowsers list Name column shows newname for that session 🌐

Display asymmetry (L1–L3): update's success output prints Name: - / Tags: - after a clear, but get's detail table omits the Name/Tags rows entirely when empty. Both mean "no name / no tags" — a missing get row is not a failure.

🤖 Generated with Claude Code

Bumps kernel-go-sdk v0.65.0 -> v0.66.0, which adds Name and Tags to
BrowserUpdateParams (PATCH /browser). The `browsers update <id-or-name>`
command, which #177 left creation-only, can now patch them:

  --name <str>      set/rename the session
  --clear-name      clear the name (sends "name":"")
  --tag KEY=VALUE   replace the entire tag set (repeatable, full replace)
  --clear-tags      clear all tags (sends "tags":{})

Mirrors the existing --clear-proxy convention and honors the SDK
semantics exactly: omit = unchanged, empty = clear, tags = full replace.
Validation rejects --name/--clear-name and --tag/--clear-tags conflicts,
guards against an accidental --name "", and a SetName/SetTags flag signal
keeps the conflict and "at least one option" checks correct even when a
malformed --tag is dropped to an empty map. Updates the create --name and
update --tag help/README for accuracy, and adds unit tests across the new
flags, clear/omit marshaling, and the malformed-tag edge cases.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedgolang/​github.com/​kernel/​kernel-go-sdk@​v0.65.0 ⏵ v0.66.072 +1100100100100

View full report

@firetiger-agent

Copy link
Copy Markdown

Created a monitoring plan for this PR.

What this PR does: Lets users rename and retag running browser sessions from the CLI — browsers update now accepts --name, --clear-name, --tag, and --clear-tags alongside the existing proxy, profile, and telemetry flags.

Intended effect:

  • PATCH /browsers request volume: baseline 4,100–10,000 requests/hr; confirmed if volume remains stable with no new error pattern after the release is available.
  • PATCH /browsers error rate: baseline 0.00–0.07%; confirmed if it stays below 0.5% after the first --name/--tag calls reach the API.

Risks:

  • SDK field serialization mismatch — if SDK v0.66.0 sends name/tags in a format the API rejects, any browsers update --name or --tag call produces a 400/500; alert if PATCH /browsers/{id_or_name} error rate exceeds 0.5% for 2+ consecutive hours (source: opentelemetry/traces/api span name = '/browsers/{id_or_name}').
  • Clear semantics silently no-op--clear-name sends name: "" and --clear-tags sends tags: {}; if the API treats empty as "unchanged" rather than "clear", names/tags won't be removable; alert if any post-deploy bug report or API log shows update calls returning stale name/tag values after a clear flag.
  • Flag conflict edge cases — validation runs entirely client-side before any API call; alert if any must specify at least one or cannot specify both error appears unexpectedly in production CLI usage logs.

Status updates will be posted automatically on this PR as monitoring progresses.

View monitor

@bmsaadat bmsaadat requested a review from Sayan- June 10, 2026 22:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant