@shipeasy/openapi 2.4.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/openapi.yaml CHANGED
@@ -207,6 +207,15 @@ tags:
207
207
  **Mentions.** `@teammate` in a body raises an in-app notification for that
208
208
  person; `@shipeasy` asks Jarvis (the AI agent) to read the item and reply.
209
209
  Comments authored by Jarvis carry `authorType: system`.
210
+ - name: Investigations
211
+ parent: Ops
212
+ description: |-
213
+ Investigation records on a queue item — the structured, read-only write-ups
214
+ an AI agent produces while working it (findings / a blocking question / QA
215
+ notes), plus the `working` run rows an ack or an AI hand-off opens. This is
216
+ the AI-write seam the cockpit's detail panel renders: `list` reads what a
217
+ previous run found, `create` appends a new record, and `update` fills in the
218
+ `working` run record you were handed (findings, PR, confidence) as you work.
210
219
  - name: Projects
211
220
  description: |-
212
221
  Projects: the account-level container every other resource is scoped to.
@@ -217,14 +226,14 @@ tags:
217
226
  - name: i18n
218
227
  description: |-
219
228
  String Manager (i18n): the worker-safe REST surface — locale profiles, the
220
- insert-only key push, single-key overwrite, chunk publish, and the read-only
229
+ insert-only key push, single-key overwrite, profile publish, and the read-only
221
230
  key/draft listings.
222
231
 
223
232
  The fs/AST parts (scan, validate, install-loader, codemod) are NOT part of
224
233
  this API — they stay in the fs-having CLI/MCP.
225
234
  - name: Profiles
226
235
  parent: i18n
227
- description: Locale profiles (e.g. `en:prod`) — create, list, and publish a profile's chunks to the CDN.
236
+ description: Locale profiles (e.g. `en:prod`) — create, list, and publish a profile to the CDN.
228
237
  - name: Keys
229
238
  parent: i18n
230
239
  description: Translation keys — the insert-only push, single-key overwrite, and key listing.
@@ -1997,7 +2006,7 @@ paths:
1997
2006
 
1998
2007
  - **Minimal create** — `name` + `schema`. Initial value defaults to `{}`.
1999
2008
  - **Seeded create** — supply a flat `value` to publish the same object on every env.
2000
- - **Per-env seed** — supply a `{ env: value }` map for different per-env starting values.
2009
+ - **Per-env seed** — supply a `{ env: value }` map under `value`, or pass the env keys `dev`/`staging`/`prod` directly (each overrides `value` for that env and is published at version 1).
2001
2010
  tags:
2002
2011
  - Configs
2003
2012
  parameters:
@@ -2039,8 +2048,8 @@ paths:
2039
2048
  - name: free
2040
2049
  - name: pro
2041
2050
  perEnvSeed:
2042
- summary: Per-env seed
2043
- description: 'Pass a `{ env: value }` map to seed different initial values per env.'
2051
+ summary: Per-env seed (env keys)
2052
+ description: Pass the env keys directly to seed different initial values per env. Each overrides `value` for that env and is published at version 1.
2044
2053
  value:
2045
2054
  name: pricing.tiers
2046
2055
  schema:
@@ -2050,20 +2059,15 @@ paths:
2050
2059
  type: array
2051
2060
  required:
2052
2061
  - tiers
2053
- value:
2054
- dev:
2055
- tiers:
2056
- - name: free
2057
- - name: pro
2058
- - name: enterprise
2059
- stage:
2060
- tiers:
2061
- - name: free
2062
- - name: pro
2063
- prod:
2064
- tiers:
2065
- - name: free
2066
- - name: pro
2062
+ dev:
2063
+ tiers:
2064
+ - name: free
2065
+ - name: pro
2066
+ - name: enterprise
2067
+ prod:
2068
+ tiers:
2069
+ - name: free
2070
+ - name: pro
2067
2071
  responses:
2068
2072
  '201':
2069
2073
  description: Create a dynamic config
@@ -2216,15 +2220,13 @@ paths:
2216
2220
  operationId: updateConfig
2217
2221
  summary: Update a dynamic config
2218
2222
  description: |-
2219
- Partial update. When `value` is supplied it is **republished on every env** (new version per env). When `schema` is supplied it replaces the current schema; every existing value is re-validated.
2220
-
2221
- For env-scoped edits, use the draft/publish flow (`PUT /{id}/drafts` then `POST /{id}/publish`) instead.
2223
+ Partial update. When `value` is supplied it is **republished on every env** (new version per env). A per-env key (`dev`/`staging`/`prod`) publishes a new version to **only that env**, immediately, overriding `value` for it. When `schema` is supplied it replaces the current schema; every existing value is re-validated.
2222
2224
 
2223
2225
  **Use cases**
2224
2226
 
2225
2227
  - **Republish flat value** — `{ "value": {…} }` sets the same value on every env.
2228
+ - **Publish one env** — `{ "prod": {…} }` publishes a new version to prod only, instantly.
2226
2229
  - **Schema migration** — `{ "schema": {…} }` replaces the schema; existing values are re-validated.
2227
- - **Env-scoped edits** — use `PUT /{id}/drafts` + `POST /{id}/publish` instead of PATCH.
2228
2230
  tags:
2229
2231
  - Configs
2230
2232
  parameters:
@@ -2250,6 +2252,15 @@ paths:
2250
2252
  tiers:
2251
2253
  - name: free
2252
2254
  - name: pro
2255
+ prodOnly:
2256
+ summary: Per-env — publish prod only
2257
+ description: Publishes a new version to prod only, immediately. dev/staging untouched.
2258
+ value:
2259
+ prod:
2260
+ tiers:
2261
+ - name: free
2262
+ - name: pro
2263
+ - name: enterprise
2253
2264
  schemaOnly:
2254
2265
  summary: Schema-only update
2255
2266
  description: Replaces the schema. Existing values must still validate or the update fails.
@@ -2410,6 +2421,7 @@ paths:
2410
2421
  - VALIDATION
2411
2422
  x-cli:
2412
2423
  name: draft
2424
+ hidden: true
2413
2425
  positional:
2414
2426
  - id
2415
2427
  delete:
@@ -2469,6 +2481,7 @@ paths:
2469
2481
  - NOT_FOUND
2470
2482
  x-cli:
2471
2483
  name: discard-draft
2484
+ hidden: true
2472
2485
  positional:
2473
2486
  - id
2474
2487
  /api/admin/configs/{id}/publish:
@@ -2540,6 +2553,7 @@ paths:
2540
2553
  - VALIDATION
2541
2554
  x-cli:
2542
2555
  name: publish
2556
+ hidden: true
2543
2557
  positional:
2544
2558
  - id
2545
2559
  /api/admin/configs/{id}/activity:
@@ -2604,6 +2618,7 @@ paths:
2604
2618
  - NOT_FOUND
2605
2619
  x-cli:
2606
2620
  name: activity
2621
+ hidden: true
2607
2622
  positional:
2608
2623
  - id
2609
2624
  /api/admin/configs/{id}/schema:
@@ -2739,6 +2754,7 @@ paths:
2739
2754
  - NOT_FOUND
2740
2755
  x-cli:
2741
2756
  name: versions
2757
+ hidden: true
2742
2758
  positional:
2743
2759
  - id
2744
2760
  /api/admin/killswitches:
@@ -5531,7 +5547,7 @@ paths:
5531
5547
  **Use case:** Read what a previous agent run already found before starting
5532
5548
  your own investigation of the item.
5533
5549
  tags:
5534
- - Ops
5550
+ - Investigations
5535
5551
  parameters:
5536
5552
  - $ref: '#/components/parameters/ProjectId'
5537
5553
  - name: handle
@@ -5562,6 +5578,10 @@ paths:
5562
5578
  - UNAUTHORIZED
5563
5579
  - FORBIDDEN
5564
5580
  - NOT_FOUND
5581
+ x-cli:
5582
+ name: list
5583
+ positional:
5584
+ - handle
5565
5585
  post:
5566
5586
  operationId: createOpsInvestigation
5567
5587
  summary: Record an investigation
@@ -5577,7 +5597,7 @@ paths:
5577
5597
  markdown findings, sources inspected, confidence) so the team — and the
5578
5598
  next agent run — sees what you learned.
5579
5599
  tags:
5580
- - Ops
5600
+ - Investigations
5581
5601
  parameters:
5582
5602
  - $ref: '#/components/parameters/ProjectId'
5583
5603
  - name: handle
@@ -5635,6 +5655,85 @@ paths:
5635
5655
  - FORBIDDEN
5636
5656
  - NOT_FOUND
5637
5657
  - VALIDATION
5658
+ x-cli:
5659
+ name: create
5660
+ positional:
5661
+ - handle
5662
+ /api/admin/ops/{handle}/investigation/{investigationId}:
5663
+ patch:
5664
+ operationId: updateOpsInvestigation
5665
+ summary: Update an investigation record
5666
+ description: |-
5667
+ Update one existing investigation record in place — the write-back seam for
5668
+ the `working` run record you were handed when a run was launched. Fill in
5669
+ the `summary`/`findings`, attach the fixing PR, record your `confidence`
5670
+ and the `sources` you inspected, or flip its `kind` off `working` once the
5671
+ investigation is done. A partial patch: send only the fields you want to
5672
+ change. Safe for restricted ops keys (it never reads or deletes).
5673
+
5674
+ **Use case:** A run started with an empty `working` record; as you work,
5675
+ PATCH it with your findings so the cockpit's detail panel fills in live —
5676
+ no need to append a second record.
5677
+ tags:
5678
+ - Investigations
5679
+ parameters:
5680
+ - $ref: '#/components/parameters/ProjectId'
5681
+ - name: handle
5682
+ in: path
5683
+ required: true
5684
+ description: Per-project item number (e.g. `7`) or the full ops item id.
5685
+ schema:
5686
+ $ref: '#/components/schemas/ResourceId'
5687
+ - name: investigationId
5688
+ in: path
5689
+ required: true
5690
+ description: The investigation record id (from `POST`/`GET .../investigation` or the `runId` an ack/launch returned).
5691
+ schema:
5692
+ $ref: '#/components/schemas/ResourceId'
5693
+ requestBody:
5694
+ required: true
5695
+ content:
5696
+ application/json:
5697
+ schema:
5698
+ $ref: '#/components/schemas/UpdateOpsInvestigationRequest'
5699
+ examples:
5700
+ findings:
5701
+ summary: Fill in the run record's findings
5702
+ value:
5703
+ kind: investigated
5704
+ summary: Root cause is a stale KV read on the checkout flag.
5705
+ findings: The `checkout.cta` gate is rebuilt without a CDN purge, so…
5706
+ confidence: high
5707
+ prNumber: 4821
5708
+ prUrl: https://github.com/acme/web/pull/4821
5709
+ responses:
5710
+ '200':
5711
+ description: The updated investigation record
5712
+ content:
5713
+ application/json:
5714
+ schema:
5715
+ $ref: '#/components/schemas/OpsInvestigation'
5716
+ '400':
5717
+ $ref: '#/components/responses/BadRequest'
5718
+ '401':
5719
+ $ref: '#/components/responses/Unauthorized'
5720
+ '403':
5721
+ $ref: '#/components/responses/Forbidden'
5722
+ '404':
5723
+ $ref: '#/components/responses/NotFound'
5724
+ '422':
5725
+ $ref: '#/components/responses/UnprocessableEntity'
5726
+ x-error-codes:
5727
+ - BAD_REQUEST
5728
+ - UNAUTHORIZED
5729
+ - FORBIDDEN
5730
+ - NOT_FOUND
5731
+ - VALIDATION
5732
+ x-cli:
5733
+ name: update
5734
+ positional:
5735
+ - handle
5736
+ - investigationId
5638
5737
  /api/admin/agent-profiles:
5639
5738
  get:
5640
5739
  operationId: listOpsAgents
@@ -6599,7 +6698,7 @@ paths:
6599
6698
  description: |-
6600
6699
  Returns every locale profile in the project (e.g. `en:prod`, `fr:prod`).
6601
6700
 
6602
- **Use case:** Discover which locale profiles exist before pushing keys or publishing a chunk.
6701
+ **Use case:** Discover which locale profiles exist before pushing keys or publishing.
6603
6702
  tags:
6604
6703
  - Profiles
6605
6704
  parameters:
@@ -6768,11 +6867,13 @@ paths:
6768
6867
  name: list
6769
6868
  post:
6770
6869
  operationId: pushI18nKeys
6771
- summary: Push new i18n keys (insert-only)
6870
+ summary: Push i18n keys (insert-only, or `force` to overwrite)
6772
6871
  description: |-
6773
- Add NEW keys to a profile. Insert-only — existing keys are left untouched (overwrite one with `updateI18nKey`).
6872
+ Add NEW keys to a profile. Insert-only by default — existing keys are left untouched and reported back as `skipped`.
6774
6873
 
6775
- **Use case:** Seed newly-extracted keys without clobbering translations already in the profile.
6874
+ Pass `force: true` to overwrite the existing ones in bulk with the submitted values: they come back as `updated` instead of `skipped`. Without `force` the only overwrite paths are `updateI18nKey` (one key) and the devtools-only `upsertI18nKeys`.
6875
+
6876
+ **Use case:** Seed newly-extracted keys without clobbering translations already in the profile — or re-push a whole source-language file with `force` after the copy changed.
6776
6877
  tags:
6777
6878
  - Keys
6778
6879
  parameters:
@@ -6790,7 +6891,7 @@ paths:
6790
6891
  value: Buy now
6791
6892
  responses:
6792
6893
  '201':
6793
- description: Push new i18n keys (insert-only)
6894
+ description: Push i18n keys (insert-only, or `force` to overwrite)
6794
6895
  content:
6795
6896
  application/json:
6796
6897
  schema:
@@ -6799,8 +6900,10 @@ paths:
6799
6900
  added:
6800
6901
  - checkout.cta
6801
6902
  skipped: []
6903
+ updated: []
6802
6904
  pushed_count: 1
6803
6905
  skipped_count: 0
6906
+ updated_count: 0
6804
6907
  '400':
6805
6908
  $ref: '#/components/responses/BadRequest'
6806
6909
  '401':
@@ -6854,7 +6957,6 @@ paths:
6854
6957
  $ref: '#/components/schemas/UpsertI18nKeysResponse'
6855
6958
  example:
6856
6959
  upserted: 1
6857
- chunk: default
6858
6960
  '400':
6859
6961
  $ref: '#/components/responses/BadRequest'
6860
6962
  '401':
@@ -7321,7 +7423,7 @@ paths:
7321
7423
  operationId: publishI18nProfile
7322
7424
  summary: Publish a profile live
7323
7425
  description: |-
7324
- Publish a profile to the CDN — rebuild its KV snapshot + purge the edge. Publishing is PROFILE-WIDE: the whole profile is snapshotted into one KV blob, so the optional `chunk` in the body is an audit label only (it does not scope what ships).
7426
+ Publish a profile to the CDN — rebuild its KV snapshot + purge the edge. Publishing is PROFILE-WIDE: the whole profile is snapshotted into one KV blob, so the body takes no options.
7325
7427
 
7326
7428
  **Use case:** Ship the latest translations live after pushing/updating keys.
7327
7429
  tags:
@@ -7335,16 +7437,15 @@ paths:
7335
7437
  schema:
7336
7438
  $ref: '#/components/schemas/ResourceId'
7337
7439
  requestBody:
7338
- required: true
7440
+ required: false
7339
7441
  content:
7340
7442
  application/json:
7341
7443
  schema:
7342
7444
  $ref: '#/components/schemas/PublishI18nProfileRequest'
7343
- example:
7344
- chunk: default
7445
+ example: {}
7345
7446
  responses:
7346
7447
  '200':
7347
- description: Publish a profile chunk
7448
+ description: Publish a profile
7348
7449
  content:
7349
7450
  application/json:
7350
7451
  schema:
@@ -9217,6 +9318,9 @@ components:
9217
9318
  locked:
9218
9319
  description: If `true`, dashboard hides edit controls (e.g. the trailing public-floor entry).
9219
9320
  type: boolean
9321
+ whitelist:
9322
+ description: Cosmetic marker. When `true`, the dashboard renders this condition as the pinned, always-first "whitelist" allowlist block (a direct `email`/`user_id` `in […]` list) rather than a numbered targeting step. Purely presentational — ignored by evaluation, which treats the entry as an ordinary condition.
9323
+ type: boolean
9220
9324
  required:
9221
9325
  - id
9222
9326
  - type
@@ -9618,6 +9722,9 @@ components:
9618
9722
  locked:
9619
9723
  description: If `true`, dashboard hides edit controls (e.g. the trailing public-floor entry).
9620
9724
  type: boolean
9725
+ whitelist:
9726
+ description: Cosmetic marker. When `true`, the dashboard renders this condition as the pinned, always-first "whitelist" allowlist block (a direct `email`/`user_id` `in […]` list) rather than a numbered targeting step. Purely presentational — ignored by evaluation, which treats the entry as an ordinary condition.
9727
+ type: boolean
9621
9728
  required:
9622
9729
  - id
9623
9730
  - type
@@ -9917,6 +10024,9 @@ components:
9917
10024
  locked:
9918
10025
  description: If `true`, dashboard hides edit controls (e.g. the trailing public-floor entry).
9919
10026
  type: boolean
10027
+ whitelist:
10028
+ description: Cosmetic marker. When `true`, the dashboard renders this condition as the pinned, always-first "whitelist" allowlist block (a direct `email`/`user_id` `in […]` list) rather than a numbered targeting step. Purely presentational — ignored by evaluation, which treats the entry as an ordinary condition.
10029
+ type: boolean
9920
10030
  required:
9921
10031
  - id
9922
10032
  - type
@@ -11405,12 +11515,26 @@ components:
11405
11515
  additionalProperties: {}
11406
11516
  description: JSON Schema (draft 2020-12) describing the shape of the config value. Top-level `type` must be `'object'`; every published value is validated against this schema.
11407
11517
  value:
11518
+ type: object
11519
+ additionalProperties: {}
11408
11520
  description: 'Initial config value. Either a single JSON object applied to every env, or a `{ env: value }` map seeding per-env values. Must match `schema`. Defaults to `{}` on every env when omitted.'
11521
+ dev:
11522
+ type: object
11523
+ additionalProperties: {}
11524
+ description: Seed the **dev** env's initial value (version 1), overriding `value` for dev. Published immediately. Must match `schema`.
11525
+ staging:
11526
+ type: object
11527
+ additionalProperties: {}
11528
+ description: Seed the **staging** env's initial value (version 1), overriding `value` for staging. Published immediately. Must match `schema`.
11529
+ prod:
11530
+ type: object
11531
+ additionalProperties: {}
11532
+ description: Seed the **prod** env's initial value (version 1), overriding `value` for prod. Published immediately. Must match `schema`.
11409
11533
  required:
11410
11534
  - name
11411
11535
  - schema
11412
11536
  additionalProperties: false
11413
- description: Body for `POST /api/admin/configs`. `name` + `schema` required.
11537
+ description: Body for `POST /api/admin/configs`. `name` + `schema` required. Per-env `dev`/`staging`/`prod` values are published to that env at version 1 (overriding `value`).
11414
11538
  CreateConfigResponse:
11415
11539
  type: object
11416
11540
  properties:
@@ -11540,11 +11664,25 @@ components:
11540
11664
  type: object
11541
11665
  additionalProperties: {}
11542
11666
  value:
11543
- description: Flat value applied to **every** env. Publishes a new version per env. To target one env, use `PUT /{id}/drafts` then `POST /{id}/publish`.
11667
+ type: object
11668
+ additionalProperties: {}
11669
+ description: Flat value applied to **every** env. Publishes a new version per env. To publish one env only, pass that env's key (`dev`/`staging`/`prod`) instead.
11670
+ dev:
11671
+ type: object
11672
+ additionalProperties: {}
11673
+ description: Publish a new version to the **dev** env only, immediately (no draft). Overrides `value` for dev. Must match the effective schema.
11674
+ staging:
11675
+ type: object
11676
+ additionalProperties: {}
11677
+ description: Publish a new version to the **staging** env only, immediately (no draft). Overrides `value` for staging. Must match the effective schema.
11678
+ prod:
11679
+ type: object
11680
+ additionalProperties: {}
11681
+ description: Publish a new version to the **prod** env only, immediately (no draft). Overrides `value` for prod. Must match the effective schema.
11544
11682
  folder:
11545
11683
  $ref: '#/components/schemas/Folder'
11546
11684
  additionalProperties: false
11547
- description: Body for `PATCH /api/admin/configs/{id}`. Partial — only supplied fields change. `value` republishes on every env.
11685
+ description: Body for `PATCH /api/admin/configs/{id}`. Partial — only supplied fields change. `value` republishes on every env; per-env `dev`/`staging`/`prod` publish a new version to just that env.
11548
11686
  UpdateConfigResponse:
11549
11687
  type: object
11550
11688
  properties:
@@ -11567,6 +11705,8 @@ components:
11567
11705
  env:
11568
11706
  $ref: '#/components/schemas/Env'
11569
11707
  value:
11708
+ type: object
11709
+ additionalProperties: {}
11570
11710
  description: Draft value to stage on `env`. Validated against the config's current schema.
11571
11711
  required:
11572
11712
  - env
@@ -13123,6 +13263,11 @@ components:
13123
13263
  - lower_better
13124
13264
  - neutral
13125
13265
  description: Desired direction of movement. `higher_better` (default), `lower_better`, or `neutral` (guardrail).
13266
+ MetricDisplayUnit:
13267
+ description: Display unit (e.g. `ms`, `%`, `$`), or `null` when unitless.
13268
+ anyOf:
13269
+ - type: string
13270
+ - type: 'null'
13126
13271
  CreateMetricWithQuery:
13127
13272
  type: object
13128
13273
  properties:
@@ -13140,6 +13285,8 @@ components:
13140
13285
  $ref: '#/components/schemas/MetricDefaultMinEffectOfInterest'
13141
13286
  direction:
13142
13287
  $ref: '#/components/schemas/MetricDirection'
13288
+ unit:
13289
+ $ref: '#/components/schemas/MetricDisplayUnit'
13143
13290
  required:
13144
13291
  - name
13145
13292
  - event_name
@@ -13163,6 +13310,8 @@ components:
13163
13310
  $ref: '#/components/schemas/MetricDefaultMinEffectOfInterest'
13164
13311
  direction:
13165
13312
  $ref: '#/components/schemas/MetricDirection'
13313
+ unit:
13314
+ $ref: '#/components/schemas/MetricDisplayUnit'
13166
13315
  required:
13167
13316
  - name
13168
13317
  - event_name
@@ -13300,6 +13449,8 @@ components:
13300
13449
  $ref: '#/components/schemas/MetricDefaultMinEffectOfInterest'
13301
13450
  direction:
13302
13451
  $ref: '#/components/schemas/MetricDirection'
13452
+ unit:
13453
+ $ref: '#/components/schemas/MetricDisplayUnit'
13303
13454
  required:
13304
13455
  - query
13305
13456
  additionalProperties: false
@@ -13319,6 +13470,8 @@ components:
13319
13470
  $ref: '#/components/schemas/MetricDefaultMinEffectOfInterest'
13320
13471
  direction:
13321
13472
  $ref: '#/components/schemas/MetricDirection'
13473
+ unit:
13474
+ $ref: '#/components/schemas/MetricDisplayUnit'
13322
13475
  required:
13323
13476
  - query_ir
13324
13477
  additionalProperties: false
@@ -13336,8 +13489,10 @@ components:
13336
13489
  $ref: '#/components/schemas/MetricDefaultMinEffectOfInterest'
13337
13490
  direction:
13338
13491
  $ref: '#/components/schemas/MetricDirection'
13492
+ unit:
13493
+ $ref: '#/components/schemas/MetricDisplayUnit'
13339
13494
  additionalProperties: false
13340
- description: Update-metric variant that leaves the query untouched (metadata-only edit — folder, event, winsorisation, default minimum effect of interest, direction).
13495
+ description: Update-metric variant that leaves the query untouched (metadata-only edit — folder, event, winsorisation, default minimum effect of interest, direction, display unit).
13341
13496
  UpdateMetricRequest:
13342
13497
  oneOf:
13343
13498
  - $ref: '#/components/schemas/UpdateMetricWithQuery'
@@ -14329,6 +14484,19 @@ components:
14329
14484
  - agent
14330
14485
  additionalProperties: false
14331
14486
  description: 'The fully-resolved owner of a queue item — a person and/or an AI agent. The two halves are independent: an item may have a person, an agent, both, or neither (both `null`).'
14487
+ OpsRunAction:
14488
+ type: string
14489
+ enum:
14490
+ - link_pr
14491
+ - notify
14492
+ - status
14493
+ - superseded
14494
+ description: The final action that closed a run record — `link_pr`/`notify` are the agent's terminal ops actions, `status` a completion status flip (ready_for_qa/resolved), `superseded` a newer ack replacing an open run.
14495
+ OpsRunActionOrNull:
14496
+ anyOf:
14497
+ - $ref: '#/components/schemas/OpsRunAction'
14498
+ - type: 'null'
14499
+ description: Which final action closed the run, or `null` while it is open (or a non-run record).
14332
14500
  OpsRun:
14333
14501
  type: object
14334
14502
  properties:
@@ -14355,6 +14523,11 @@ components:
14355
14523
  - type: string
14356
14524
  - type: 'null'
14357
14525
  description: The agent-run session id recorded on the ack (dashboard deep-links to the run page), or `null`.
14526
+ sessionUrl:
14527
+ anyOf:
14528
+ - type: string
14529
+ - type: 'null'
14530
+ description: 'The run''s session-page deep link, or `null`. DERIVED (never stored): rebuilt from `sessionId` + the run''s trigger connector — Claude''s routine id (`?trigger=`), Copilot''s repo (`/tasks/`), Cursor/Jules from the id alone.'
14358
14531
  startedAt:
14359
14532
  type: string
14360
14533
  description: ISO-8601 timestamp the run started (the ack time).
@@ -14364,15 +14537,7 @@ components:
14364
14537
  - type: 'null'
14365
14538
  description: ISO-8601 timestamp the run closed, or `null` while still open.
14366
14539
  completedAction:
14367
- anyOf:
14368
- - type: string
14369
- enum:
14370
- - link_pr
14371
- - notify
14372
- - status
14373
- - superseded
14374
- - type: 'null'
14375
- description: Which final action closed the run — `link_pr`/`notify` are the agent's terminal ops actions, `status` a completion status flip (ready_for_qa/resolved), `superseded` a newer ack replacing it. `null` while the run is open.
14540
+ $ref: '#/components/schemas/OpsRunActionOrNull'
14376
14541
  prNumber:
14377
14542
  anyOf:
14378
14543
  - type: number
@@ -14389,6 +14554,7 @@ components:
14389
14554
  - connectorId
14390
14555
  - ackedBy
14391
14556
  - sessionId
14557
+ - sessionUrl
14392
14558
  - startedAt
14393
14559
  - completedAt
14394
14560
  - completedAction
@@ -14562,6 +14728,28 @@ components:
14562
14728
  - $ref: '#/components/schemas/OpsItemPriority'
14563
14729
  - type: 'null'
14564
14730
  description: Initial triage priority, or `null`.
14731
+ status:
14732
+ anyOf:
14733
+ - $ref: '#/components/schemas/OpsItemStatus'
14734
+ description: Initial lifecycle status; defaults to `open` when omitted.
14735
+ assigneeId:
14736
+ anyOf:
14737
+ - type: string
14738
+ - type: 'null'
14739
+ description: The `users.id` of the person to assign as owner at creation, or `null`.
14740
+ subscribers:
14741
+ type: array
14742
+ items:
14743
+ type: string
14744
+ format: email
14745
+ default: []
14746
+ description: Emails of teammates to subscribe to this item's Slack pings at creation.
14747
+ tags:
14748
+ type: array
14749
+ items:
14750
+ type: string
14751
+ default: []
14752
+ description: Tag names to attach at creation (get-or-created by name, deduped case-insensitively).
14565
14753
  reporterEmail:
14566
14754
  anyOf:
14567
14755
  - type: string
@@ -14631,6 +14819,28 @@ components:
14631
14819
  - $ref: '#/components/schemas/OpsItemPriority'
14632
14820
  - type: 'null'
14633
14821
  description: Initial triage priority, or `null`.
14822
+ status:
14823
+ anyOf:
14824
+ - $ref: '#/components/schemas/OpsItemStatus'
14825
+ description: Initial lifecycle status; defaults to `open` when omitted.
14826
+ assigneeId:
14827
+ anyOf:
14828
+ - type: string
14829
+ - type: 'null'
14830
+ description: The `users.id` of the person to assign as owner at creation, or `null`.
14831
+ subscribers:
14832
+ type: array
14833
+ items:
14834
+ type: string
14835
+ format: email
14836
+ default: []
14837
+ description: Emails of teammates to subscribe to this item's Slack pings at creation.
14838
+ tags:
14839
+ type: array
14840
+ items:
14841
+ type: string
14842
+ default: []
14843
+ description: Tag names to attach at creation (get-or-created by name, deduped case-insensitively).
14634
14844
  reporterEmail:
14635
14845
  anyOf:
14636
14846
  - type: string
@@ -15210,21 +15420,18 @@ components:
15210
15420
  - type: string
15211
15421
  - type: 'null'
15212
15422
  description: The agent-run session id, or `null`.
15213
- ackedBy:
15423
+ sessionUrl:
15214
15424
  anyOf:
15215
15425
  - type: string
15216
15426
  - type: 'null'
15217
- description: Email of the human who acked (run records for a human ack), or `null`.
15218
- completedAction:
15427
+ description: 'The run''s session-page deep link, or `null`. DERIVED (never stored): rebuilt from `sessionId` + the run''s trigger connector — Claude''s routine id (`?trigger=`), Copilot''s repo (`/tasks/`), Cursor/Jules from the id alone. Only `working` run records carry one.'
15428
+ ackedBy:
15219
15429
  anyOf:
15220
15430
  - type: string
15221
- enum:
15222
- - link_pr
15223
- - notify
15224
- - status
15225
- - superseded
15226
15431
  - type: 'null'
15227
- description: Which final action closed a `working` run record, or `null` (open run / non-run record).
15432
+ description: Email of the human who acked (run records for a human ack), or `null`.
15433
+ completedAction:
15434
+ $ref: '#/components/schemas/OpsRunActionOrNull'
15228
15435
  createdAt:
15229
15436
  type: string
15230
15437
  description: ISO-8601 creation timestamp.
@@ -15252,6 +15459,7 @@ components:
15252
15459
  - startedAt
15253
15460
  - completedAt
15254
15461
  - sessionId
15462
+ - sessionUrl
15255
15463
  - ackedBy
15256
15464
  - completedAction
15257
15465
  - createdAt
@@ -15368,6 +15576,94 @@ components:
15368
15576
  - kind
15369
15577
  additionalProperties: false
15370
15578
  description: Body for `POST /api/admin/ops/{handle}/investigation`. `kind` is required; include at least one content field (`summary`/`findings`/`question`/`qaNotes`) — the panel renders whatever it gets.
15579
+ UpdateOpsInvestigationRequest:
15580
+ type: object
15581
+ properties:
15582
+ kind:
15583
+ type: string
15584
+ enum:
15585
+ - investigated
15586
+ - detected
15587
+ - question
15588
+ - ready_for_qa
15589
+ - working
15590
+ - note
15591
+ description: Reclassify the record's lifecycle stage (e.g. flip a `working` run into `investigated` once findings land).
15592
+ summary:
15593
+ type: string
15594
+ maxLength: 2000
15595
+ description: One-line summary of the record.
15596
+ findings:
15597
+ type: string
15598
+ maxLength: 50000
15599
+ description: The full findings write-up (markdown).
15600
+ question:
15601
+ type: string
15602
+ maxLength: 10000
15603
+ description: A blocking question for the team (markdown).
15604
+ qaNotes:
15605
+ type: string
15606
+ maxLength: 50000
15607
+ description: How to verify the fix — QA notes (markdown).
15608
+ model:
15609
+ type: string
15610
+ maxLength: 200
15611
+ description: The model the agent ran on.
15612
+ prNumber:
15613
+ type: integer
15614
+ description: A PR the record references.
15615
+ prUrl:
15616
+ type: string
15617
+ format: uri
15618
+ maxLength: 2000
15619
+ description: HTML URL of that PR.
15620
+ sources:
15621
+ type: array
15622
+ maxItems: 200
15623
+ items:
15624
+ type: object
15625
+ properties:
15626
+ path:
15627
+ type: string
15628
+ description: Repo-relative file path inspected.
15629
+ url:
15630
+ type: string
15631
+ description: External link consulted.
15632
+ label:
15633
+ type: string
15634
+ description: Human-readable label for the source.
15635
+ additionalProperties: false
15636
+ description: One file/link inspected while producing the record.
15637
+ description: The files/links inspected.
15638
+ confidence:
15639
+ type: string
15640
+ enum:
15641
+ - low
15642
+ - medium
15643
+ - high
15644
+ description: Self-reported confidence in the record.
15645
+ tokensUsed:
15646
+ type: integer
15647
+ description: Tokens the run consumed.
15648
+ durationMs:
15649
+ type: integer
15650
+ description: Run duration in milliseconds.
15651
+ visibility:
15652
+ type: string
15653
+ enum:
15654
+ - draft
15655
+ - published
15656
+ description: Record visibility. `draft` keeps it out of the panel; `published` surfaces it.
15657
+ completedAt:
15658
+ type: string
15659
+ description: ISO-8601 timestamp the work finished. Set it (or flip `kind` off `working`) to mark a run record done.
15660
+ sessionId:
15661
+ type: string
15662
+ maxLength: 300
15663
+ description: The agent-run session id, so the dashboard can deep-link to the run.
15664
+ additionalProperties: false
15665
+ minProperties: 1
15666
+ description: Body for `PATCH /api/admin/ops/{handle}/investigation/{investigationId}` — a partial update of one existing investigation record (typically the `working` run record you were handed). Send only the fields you want to change; at least one is required.
15371
15667
  OpsAgentProfile:
15372
15668
  type: object
15373
15669
  properties:
@@ -16436,14 +16732,6 @@ components:
16436
16732
  anyOf:
16437
16733
  - type: string
16438
16734
  - type: 'null'
16439
- chunkId:
16440
- description: Owning chunk (authoring grouping) id.
16441
- type: string
16442
- chunkName:
16443
- description: Name of the owning chunk (authoring grouping), or `null` when it cannot be resolved.
16444
- anyOf:
16445
- - type: string
16446
- - type: 'null'
16447
16735
  updatedAt:
16448
16736
  description: ISO-8601 timestamp of the last edit.
16449
16737
  type: string
@@ -16458,8 +16746,6 @@ components:
16458
16746
  - variables
16459
16747
  - profileId
16460
16748
  - profileName
16461
- - chunkId
16462
- - chunkName
16463
16749
  - updatedAt
16464
16750
  - updatedBy
16465
16751
  additionalProperties: false
@@ -16480,12 +16766,6 @@ components:
16480
16766
  type: string
16481
16767
  format: uuid
16482
16768
  description: Target profile id to upsert keys into.
16483
- chunk:
16484
- description: Logical grouping the keys are filed under. Defaults to `default`.
16485
- type: string
16486
- minLength: 1
16487
- maxLength: 64
16488
- default: default
16489
16769
  keys:
16490
16770
  type: array
16491
16771
  minItems: 1
@@ -16528,12 +16808,8 @@ components:
16528
16808
  upserted:
16529
16809
  type: number
16530
16810
  description: Number of keys written (inserted or overwritten).
16531
- chunk:
16532
- type: string
16533
- description: The chunk the keys were filed under.
16534
16811
  required:
16535
16812
  - upserted
16536
- - chunk
16537
16813
  additionalProperties: false
16538
16814
  description: Result of a bulk key upsert. The affected profile's KV snapshot is rebuilt (and the CDN purged) before this returns.
16539
16815
  PushI18nKeysRequest:
@@ -16543,12 +16819,6 @@ components:
16543
16819
  type: string
16544
16820
  format: uuid
16545
16821
  description: Target profile id to add keys to.
16546
- chunk:
16547
- description: Logical grouping the new keys are filed under. Defaults to `default`.
16548
- type: string
16549
- minLength: 1
16550
- maxLength: 64
16551
- default: default
16552
16822
  keys:
16553
16823
  type: array
16554
16824
  minItems: 1
@@ -16579,12 +16849,16 @@ components:
16579
16849
  - key
16580
16850
  - value
16581
16851
  additionalProperties: false
16582
- description: Keys to add. Insert-only — existing keys are reported back as `skipped`.
16852
+ description: Keys to add. Insert-only by default — existing keys are reported back as `skipped` (set `force` to overwrite them instead).
16853
+ force:
16854
+ type: boolean
16855
+ default: false
16856
+ description: Overwrite keys that already exist with the submitted value instead of skipping them. Overwritten keys come back as `updated`. Off by default so a routine push can never clobber live translations.
16583
16857
  required:
16584
16858
  - profile_id
16585
16859
  - keys
16586
16860
  additionalProperties: false
16587
- description: 'Body for `POST /api/admin/i18n/keys`. Insert-only: keys that already exist are never overwritten — use `PUT /keys/{id}` to change a value.'
16861
+ description: 'Body for `POST /api/admin/i18n/keys`. Insert-only by default: keys that already exist are never overwritten — pass `force: true` to overwrite them in bulk, or use `PUT /keys/{id}` to change one value.'
16588
16862
  PushI18nKeysResponse:
16589
16863
  type: object
16590
16864
  properties:
@@ -16597,23 +16871,30 @@ components:
16597
16871
  type: array
16598
16872
  items:
16599
16873
  type: string
16600
- description: Key names that already existed and were left untouched.
16874
+ description: Key names that already existed and were left untouched. Always empty when `force` was set — those key names come back under `updated` instead.
16875
+ updated:
16876
+ type: array
16877
+ items:
16878
+ type: string
16879
+ description: Key names that already existed and were overwritten with the submitted value. Only ever non-empty when the push set `force`.
16601
16880
  pushed_count:
16602
16881
  type: number
16603
16882
  description: Number of keys inserted (== `added.length`).
16604
16883
  skipped_count:
16605
16884
  type: number
16606
16885
  description: Number of keys skipped (== `skipped.length`).
16607
- chunk:
16608
- description: The chunk the keys were filed under.
16609
- type: string
16886
+ updated_count:
16887
+ type: number
16888
+ description: Number of existing keys overwritten (== `updated.length`).
16610
16889
  required:
16611
16890
  - added
16612
16891
  - skipped
16892
+ - updated
16613
16893
  - pushed_count
16614
16894
  - skipped_count
16895
+ - updated_count
16615
16896
  additionalProperties: false
16616
- description: Result of an insert-only key push.
16897
+ description: Result of a key push — what was inserted, what was left alone, and (with `force`) what was overwritten.
16617
16898
  UpdateI18nKeyRequest:
16618
16899
  type: object
16619
16900
  properties:
@@ -16808,12 +17089,9 @@ components:
16808
17089
  description: Body for `POST /api/admin/i18n/drafts/{draftId}/keys`. Upserts one staged key into an open draft — inserted when new, overwritten when it already exists. `{{var}}` placeholder names are auto-derived from the value.
16809
17090
  PublishI18nProfileRequest:
16810
17091
  type: object
16811
- properties:
16812
- chunk:
16813
- description: Optional chunk label to stamp on the audit log. Publishing is profile-wide regardless — the whole profile is snapshotted into one KV blob.
16814
- type: string
17092
+ properties: {}
16815
17093
  additionalProperties: false
16816
- description: Body for `POST /api/admin/i18n/profiles/{profileId}/publish`. The `chunk` is an audit label only.
17094
+ description: Body for `POST /api/admin/i18n/profiles/{profileId}/publish`. Publishing is profile-wide — the whole profile is snapshotted into one KV blob — so the body takes no options.
16817
17095
  PublishI18nProfileResponse:
16818
17096
  type: object
16819
17097
  properties:
@@ -16824,11 +17102,6 @@ components:
16824
17102
  profile_id:
16825
17103
  type: string
16826
17104
  description: Profile that was published.
16827
- chunk:
16828
- anyOf:
16829
- - type: string
16830
- - type: 'null'
16831
- description: Audit chunk label, or `null` when none was given.
16832
17105
  published_at:
16833
17106
  type: string
16834
17107
  description: ISO-8601 timestamp of the publish.
@@ -16857,7 +17130,6 @@ components:
16857
17130
  required:
16858
17131
  - ok
16859
17132
  - profile_id
16860
- - chunk
16861
17133
  - published_at
16862
17134
  - version
16863
17135
  - key_count