spawn/fixtures/digitalocean/create-server.json
L 65a81edc57
fix: add unique spawn IDs to prevent history record corruption (#2235)
* fix: add unique spawn IDs to prevent history record corruption

History records were matched by heuristic ("most recent record for this
cloud without a connection"), which caused saveVmConnection and
saveLaunchCmd to overwrite the wrong record during concurrent or failed
spawns.

Fix: every SpawnRecord now has a unique `id` (UUID). All history
operations (saveVmConnection, saveLaunchCmd, removeRecord,
markRecordDeleted, mergeLastConnection) match by id when available,
falling back to the old heuristic for pre-migration records.

The orchestrator (TS path) now creates the history record AFTER server
creation succeeds, not before — so failed provisions don't leave orphan
entries.

Also adds "Remove from history" option to the spawn ls action picker,
restoring the ability to soft-delete entries without destroying the VM.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: add 18 unit tests for spawn ID history behavior

Tests cover:
- generateSpawnId returns unique UUIDs
- saveSpawnRecord auto-generates id when not provided
- saveVmConnection matches by spawnId (not heuristic)
- saveVmConnection does not cross-contaminate concurrent spawns
- saveVmConnection falls back to heuristic without spawnId
- saveLaunchCmd matches by spawnId (not heuristic)
- saveLaunchCmd falls back without spawnId
- removeRecord matches by id, not by timestamp+agent+cloud
- removeRecord handles duplicate timestamps correctly
- removeRecord falls back for legacy records without id
- markRecordDeleted targets correct record by id
- mergeLastConnection uses spawn_id from last-connection.json
- mergeLastConnection falls back to heuristic without spawn_id

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* style: enable biome import sorting with grouped imports

Adds organizeImports to biome assist config with groups:
1. Type imports
2. Node built-ins
3. Third-party packages
4. @openrouter/* packages
5. Aliases

Auto-fixed import order and lint issues across all TypeScript files,
including .claude/skills/ and packages/cli/src/.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-05 23:27:03 -08:00

263 lines
6.6 KiB
JSON

{
"droplet": {
"backup_ids": [],
"created_at": "2026-02-11T03:07:33Z",
"disk": 10,
"disk_info": [
{
"size": {
"amount": 10,
"unit": "gib"
},
"type": "local"
}
],
"features": ["droplet_agent"],
"id": 550842125,
"image": {
"created_at": "2025-08-08T15:11:27Z",
"description": "Ubuntu 24.04 (LTS) x64",
"distribution": "Ubuntu",
"id": 195932981,
"min_disk_size": 7,
"name": "24.04 (LTS) x64",
"public": true,
"regions": [
"nyc3",
"nyc1",
"sfo1",
"nyc2",
"ams2",
"sgp1",
"lon1",
"ams3",
"fra1",
"tor1",
"sfo2",
"blr1",
"sfo3",
"syd1",
"atl1",
"ric1"
],
"size_gigabytes": 3.76,
"slug": "ubuntu-24-04-x64",
"status": "available",
"tags": [],
"type": "base"
},
"kernel": null,
"locked": false,
"memory": 512,
"name": "spawn-record-1770779252",
"networks": {
"v4": [],
"v6": []
},
"next_backup_window": null,
"region": {
"available": true,
"features": ["backups", "ipv6", "metadata", "install_agent", "storage", "image_transfer"],
"name": "New York 3",
"sizes": [
"s-1vcpu-512mb-10gb",
"s-1vcpu-1gb",
"s-1vcpu-1gb-amd",
"s-1vcpu-1gb-intel",
"s-1vcpu-1gb-35gb-intel",
"s-1vcpu-2gb",
"s-1vcpu-2gb-amd",
"s-1vcpu-2gb-intel",
"s-1vcpu-2gb-70gb-intel",
"s-2vcpu-2gb",
"s-2vcpu-2gb-amd",
"s-2vcpu-2gb-intel",
"s-2vcpu-2gb-90gb-intel",
"s-2vcpu-4gb",
"s-2vcpu-4gb-amd",
"s-2vcpu-4gb-intel",
"s-2vcpu-4gb-120gb-intel",
"s-2vcpu-8gb-amd",
"c-2",
"c2-2vcpu-4gb",
"s-2vcpu-8gb-160gb-intel",
"s-4vcpu-8gb",
"s-4vcpu-8gb-amd",
"s-4vcpu-8gb-intel",
"c5-2vcpu-4gb",
"g-2vcpu-8gb",
"s-4vcpu-8gb-240gb-intel",
"gd-2vcpu-8gb",
"g-2vcpu-8gb-intel",
"gd-2vcpu-8gb-intel",
"s-4vcpu-16gb-amd",
"m-2vcpu-16gb",
"c-4",
"g6_5-2vcpu-8gb",
"g5_5-2vcpu-8gb-intel",
"c2-4vcpu-8gb",
"s-4vcpu-16gb-320gb-intel",
"s-8vcpu-16gb",
"m-2vcpu-16gb-intel",
"m3-2vcpu-16gb",
"c-4-intel",
"m3-2vcpu-16gb-intel",
"s-8vcpu-16gb-amd",
"s-8vcpu-16gb-intel",
"c2-4vcpu-8gb-intel",
"c5-4vcpu-8gb",
"g-4vcpu-16gb",
"s-8vcpu-16gb-480gb-intel",
"so-2vcpu-16gb-intel",
"so-2vcpu-16gb",
"m6-2vcpu-16gb",
"gd-4vcpu-16gb",
"so1_5-2vcpu-16gb-intel",
"g-4vcpu-16gb-intel",
"gd-4vcpu-16gb-intel",
"c5-4vcpu-8gb-intel",
"so1_5-2vcpu-16gb",
"s-8vcpu-32gb-amd",
"m-4vcpu-32gb",
"c-8",
"g6_5-4vcpu-16gb",
"g5_5-4vcpu-16gb-intel",
"c2-8vcpu-16gb",
"s-8vcpu-32gb-640gb-intel",
"m-4vcpu-32gb-intel",
"m3-4vcpu-32gb",
"c-8-intel",
"m3-4vcpu-32gb-intel",
"c2-8vcpu-16gb-intel",
"c5-8vcpu-16gb",
"g-8vcpu-32gb",
"so-4vcpu-32gb-intel",
"so-4vcpu-32gb",
"m6-4vcpu-32gb",
"gd-8vcpu-32gb",
"so1_5-4vcpu-32gb-intel",
"g-8vcpu-32gb-intel",
"gd-8vcpu-32gb-intel",
"c5-8vcpu-16gb-intel",
"so1_5-4vcpu-32gb",
"m-8vcpu-64gb",
"c-16",
"g6_5-8vcpu-32gb",
"g5_5-8vcpu-32gb-intel",
"c2-16vcpu-32gb",
"m-8vcpu-64gb-intel",
"m3-8vcpu-64gb",
"c-16-intel",
"m3-8vcpu-64gb-intel",
"c2-16vcpu-32gb-intel",
"c5-16vcpu-32gb",
"g-16vcpu-64gb",
"so-8vcpu-64gb-intel",
"so-8vcpu-64gb",
"m6-8vcpu-64gb",
"gd-16vcpu-64gb",
"so1_5-8vcpu-64gb-intel",
"g-16vcpu-64gb-intel",
"gd-16vcpu-64gb-intel",
"c5-16vcpu-32gb-intel",
"so1_5-8vcpu-64gb",
"m-16vcpu-128gb",
"c-32",
"g6_5-16vcpu-64gb",
"g5_5-16vcpu-64gb-intel",
"c2-32vcpu-64gb",
"m-16vcpu-128gb-intel",
"m3-16vcpu-128gb",
"c-32-intel",
"m3-16vcpu-128gb-intel",
"c2-32vcpu-64gb-intel",
"c5-32vcpu-64gb",
"c-48",
"m-24vcpu-192gb",
"g-32vcpu-128gb",
"so-16vcpu-128gb-intel",
"so-16vcpu-128gb",
"m6-16vcpu-128gb",
"gd-32vcpu-128gb",
"so1_5-16vcpu-128gb-intel",
"c2-48vcpu-96gb",
"m-24vcpu-192gb-intel",
"g-32vcpu-128gb-intel",
"m3-24vcpu-192gb",
"g-40vcpu-160gb",
"gd-32vcpu-128gb-intel",
"c5-32vcpu-64gb-intel",
"so1_5-16vcpu-128gb",
"c-48-intel",
"m3-24vcpu-192gb-intel",
"m-32vcpu-256gb",
"gd-40vcpu-160gb",
"g6_5-32vcpu-128gb",
"c2-48vcpu-96gb-intel",
"g5_5-32vcpu-128gb-intel",
"c5-48vcpu-96gb",
"so-24vcpu-192gb-intel",
"so-24vcpu-192gb",
"m6-24vcpu-192gb",
"m-32vcpu-256gb-intel",
"c-60-intel",
"m3-32vcpu-256gb",
"so1_5-24vcpu-192gb-intel",
"m3-32vcpu-256gb-intel",
"g6_5-40vcpu-160gb",
"g-48vcpu-192gb-intel",
"gd-48vcpu-192gb-intel",
"c5-48vcpu-96gb-intel",
"so1_5-24vcpu-192gb",
"so-32vcpu-256gb-intel",
"so-32vcpu-256gb",
"m6-32vcpu-256gb",
"g5_5-48vcpu-192gb-intel",
"so1_5-32vcpu-256gb-intel",
"m-48vcpu-384gb-intel",
"c5-60vcpu-120gb-intel",
"so1_5-32vcpu-256gb",
"m3-48vcpu-384gb-intel",
"g5_5-60vcpu-240gb-intel"
],
"slug": "nyc3"
},
"size": {
"available": true,
"description": "Basic",
"disk": 10,
"disk_info": [
{
"size": {
"amount": 10,
"unit": "gib"
},
"type": "local"
}
],
"memory": 512,
"networking_throughput": 2000,
"price_hourly": 0.00595,
"price_monthly": 4,
"regions": ["ams3", "blr1", "fra1", "lon1", "nyc1", "nyc2", "nyc3", "sfo2", "sfo3", "sgp1", "syd1", "tor1"],
"slug": "s-1vcpu-512mb-10gb",
"transfer": 0.5,
"vcpus": 1
},
"size_slug": "s-1vcpu-512mb-10gb",
"snapshot_ids": [],
"status": "new",
"tags": [],
"vcpus": 1,
"volume_ids": []
},
"links": {
"actions": [
{
"href": "/v2/actions/3038067722",
"id": 3038067722,
"rel": "create"
}
]
}
}