@atollhq/skill-codex 0.4.32 → 0.4.34

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atollhq/skill-codex",
3
- "version": "0.4.32",
3
+ "version": "0.4.34",
4
4
  "description": "Install the Atoll project management integration for Codex CLI",
5
5
  "bin": {
6
6
  "skill-codex": "bin/install.mjs"
@@ -18,7 +18,7 @@
18
18
  ],
19
19
  "repository": {
20
20
  "type": "git",
21
- "url": "git+https://github.com/atollhq/atoll.git",
21
+ "url": "git+https://github.com/antons-agents/atoll.git",
22
22
  "directory": "packages/skill-codex"
23
23
  },
24
24
  "dependencies": {
package/skill/SKILL.md CHANGED
@@ -44,6 +44,18 @@ Read only the references required for the current task:
44
44
  - Request and response fields, enums, and validation:
45
45
  [api-fields.md](references/api-fields.md)
46
46
 
47
+ Outbound webhooks support optional Standard Webhooks signing with a receiver
48
+ supplied canonical `whsec_` secret. Read the webhook references before creating
49
+ or updating a destination; signing secrets are write-only and automatic retry
50
+ delivery ids remain stable. Grok Automations and Hermes support this receiver
51
+ contract; see the integration reference for their setup and event caveats.
52
+
53
+ Agent creation can select an allowlisted built-in icon with `avatarPreset`.
54
+ Manage an existing guest agent icon through the member avatar endpoint: upload
55
+ a custom image with `POST`, select a built-in preset with `PATCH`, or remove it
56
+ with `DELETE`. Read [api-endpoints.md](references/api-endpoints.md) and
57
+ [api-fields.md](references/api-fields.md) for the exact contract and limits.
58
+
47
59
  For automation rule V1 actions (including create issue and send webhook), explicit project or
48
60
  organization scope, CI create-or-webhook rules, scheduled `schedule.issue_time`
49
61
  rules, event conditions, validation, safe
@@ -634,10 +634,12 @@ deferred; parent deletion returns after durable queueing.
634
634
  | Method | Endpoint | Description |
635
635
  |--------|----------|-------------|
636
636
  | POST | `/api/orgs/{id}/members/{memberId}/avatar` | Upload avatar to public `avatars` bucket (multipart, max 2MB, JPEG/PNG/WebP/GIF) |
637
+ | PATCH | `/api/orgs/{id}/members/{memberId}/avatar` | Select an allowlisted built-in agent icon preset (`{ preset }`) |
637
638
  | DELETE | `/api/orgs/{id}/members/{memberId}/avatar` | Remove avatar |
638
639
 
639
640
  Members may manage their own avatar; organization owners/admins may manage
640
- another member only inside the same path organization. Cross-organization
641
+ another member only inside the same path organization. A human may also manage
642
+ a guest agent avatar when they created the agent or own the personal agent. Cross-organization
641
643
  caller or target IDs return `404`. Upload returns
642
644
  `{ "member": { "id": "...", "avatar_url": "..." } }` with no other member
643
645
  metadata. Avatar updates use compare-and-set semantics: concurrent changes
@@ -849,9 +851,30 @@ failed without executing its actions.
849
851
  | POST | `/api/webhooks/{id}/redeliver/{deliveryId}` | Redeliver a past payload (owner/admin) |
850
852
  | POST | `/api/webhooks/{id}/test` | Send ping test event (owner/admin) |
851
853
 
852
- URL must be an HTTPS DNS hostname. IP literals, `localhost`, and `.local` hosts are rejected at creation; delivery refuses non-public DNS results and does not follow redirects. Returns webhook record plus `secret` for HMAC verification. Store the secret immediately; it is shown only once. Later lists expose only `destination_display` such as `https://example.com/…`.
853
-
854
- Payload schema version `2` is allowlisted and omits descriptions, comment bodies, and raw change values. Delivery requests include `X-Atoll-Signature`, `X-Atoll-Signature-Version`, versioned `X-Atoll-Signatures`, and `X-Atoll-Delivery-Id`. Delivery history returns safe status, `error_code`, and retry timing only—not payloads, receiver response bodies, or raw errors. Atoll retries network failures and 5xx responses after 5s and 30s, then records `status: retry_pending` with `next_retry_at`; an internal cron drains due retries every 15 minutes.
854
+ URL must be an HTTPS DNS hostname. IP literals, `localhost`, and `.local` hosts are rejected at creation; delivery refuses non-public DNS results and does not follow redirects. Returns webhook record plus `secret` for HMAC verification. Store the secret immediately; it is shown only once. Later lists expose only `destination_display` such as `https://example.com/…`; Standard Webhooks exposes only its configured boolean.
855
+
856
+ Automation action deliveries use payload schema version `3` with current
857
+ tenant-scoped issue and project fields. Subscription broadcasts and `ping`
858
+ remain schema version `2`; existing queued payloads retain their stored schema
859
+ and content. V3 includes safe sorted `trigger.changedFields`, optional
860
+ privacy-safe artifact counts, and `project: null` for projectless issues. An
861
+ artifact summary is omitted when its lookup fails, returns an invalid type, or
862
+ cannot complete within the bounded 1,000-row pagination limit. CI
863
+ actions set `issue: null`, `changedFields: []`, and retain only useful CI fields.
864
+ Both versions omit descriptions, comment bodies, and raw change values. Delivery
865
+ requests include `X-Atoll-Signature`, `X-Atoll-Signature-Version`, versioned
866
+ `X-Atoll-Signatures`, `X-Atoll-Delivery-Id`, and `Idempotency-Key`. Standard
867
+ Webhooks adds `webhook-id`, `webhook-timestamp`, and
868
+ `webhook-signature: v1,<base64>`; the signature covers
869
+ `deliveryId.timestamp.rawBody` with the decoded receiver key. Automatic retries
870
+ preserve delivery id/key with fresh timestamps/signatures; manual redelivery
871
+ uses new values, preserves v3 body content, and rewrites only legacy v2 automation bodies that contain
872
+ `data.deliveryId`. Delivery history returns safe status, `error_code`, and retry
873
+ timing only—not payloads, receiver response bodies, or raw errors. Atoll makes
874
+ one 30-second request attempt per invocation. Network failures and 5xx
875
+ responses are recorded as `status: retry_pending` with `next_retry_at`; an
876
+ internal cron drains due retries every 15 minutes. A 2xx response proves
877
+ acceptance only.
855
878
 
856
879
  ## Private Inbound Email Inbox
857
880
 
@@ -905,7 +928,7 @@ Google Chat mention cards include the task title, a safely formatted plain-text
905
928
  | GET | `/api/orgs/{id}/agents` | List agents (owner/admin) |
906
929
  | GET | `/api/orgs/{id}/agents/workforce` | Read a bounded workforce projection; org owners/admins may list all agents, project admins must pass `?projectId=...`, and individual owners may read their own agents |
907
930
  | GET | `/api/orgs/{id}/agents/manageable` | List manageable agents with visible project IDs, named accessible projects, heartbeat policy status/focus summary, API-key usage metadata, and aggregate active-key/OAuth activity |
908
- | POST | `/api/orgs/{id}/agents` | Create org agent (`{ name, role?, setupScoped? }`), project-scoped agent (`{ name, projectIds }` or legacy `{ name, projectId, projectIds? }`), or personal agent (`{ name, personal: true }`); key-minting responses include one-time `apiKey` and stable `apiKeyId` (`oauthOnly` omits both) |
931
+ | POST | `/api/orgs/{id}/agents` | Create org, project-scoped, or personal agent; optional `avatarPreset` accepts only a built-in agent icon ID, and key-minting responses include one-time `apiKey` and stable `apiKeyId` (`oauthOnly` omits both) |
909
932
  | DELETE | `/api/orgs/{id}/agents/{agentId}` | Revoke manageable agent |
910
933
  | PATCH | `/api/orgs/{id}/agents/{agentId}/projects` | Replace project access for a manageable non-personal agent |
911
934
  | POST | `/api/orgs/{id}/projects/{projectId}/agents` | Grant selected manageable agents access to a project |
@@ -153,7 +153,7 @@ Request bodies accept **camelCase** (`assigneeId`, `projectId`). Snake_case also
153
153
 
154
154
  ## Avatar Upload Response
155
155
 
156
- Successful `POST /api/orgs/{id}/members/{memberId}/avatar` requests return
156
+ Successful `POST` uploads and `PATCH` preset selections at `/api/orgs/{id}/members/{memberId}/avatar` return
157
157
  `200` with exactly:
158
158
 
159
159
  ```json
@@ -244,7 +244,7 @@ Creation endpoints may return `402` when an org reaches its billing plan limit:
244
244
 
245
245
  ## Agent Fields
246
246
 
247
- Create org-wide agents with `{ "name": "...", "role": "member", "setupScoped": false }`; org-wide creation is owner/admin-only. Create project-scoped agents with non-empty `projectIds`, for example `{ "name": "...", "projectIds": ["project-uuid"] }`; `projectId` remains accepted as a legacy/default-project alias and is merged with `projectIds`. Project-scoped agents are created as guests, and human members may only scope them to projects they can access. Create personal agents with `{ "name": "...", "personal": true }`; personal agents inherit their human owner's project access and reject explicit `projectId`/`projectIds`.
247
+ Create org-wide agents with `{ "name": "...", "role": "member", "setupScoped": false }`; org-wide creation is owner/admin-only. Create project-scoped agents with non-empty `projectIds`, for example `{ "name": "...", "projectIds": ["project-uuid"] }`; `projectId` remains accepted as a legacy/default-project alias and is merged with `projectIds`. Project-scoped agents are created as guests, and human members may only scope them to projects they can access. Create personal agents with `{ "name": "...", "personal": true }`; personal agents inherit their human owner's project access and reject explicit `projectId`/`projectIds`. Any create form may include an allowlisted `avatarPreset` ID. Arbitrary URLs are rejected. Existing agent presets are changed with `{ "preset": "codex" }` on the avatar PATCH endpoint.
248
248
 
249
249
  Key-minting agent creation responses contain the one-time raw `apiKey` and its stable `apiKeyId`. Creation with `oauthOnly: true` omits both fields.
250
250
 
@@ -539,7 +539,11 @@ characters), and legacy `close_issue` (omit `value`, targets the valid `done` ke
539
539
  The destination must be enabled, same-org, and purpose `automation` or `both`.
540
540
  Queued transport retries do not re-run the automation action. Activity exposes
541
541
  `webhook_delivery_id` plus safe latest-attempt `webhook_delivery` state.
542
- Manual redelivery uses a new header and payload delivery ID.
542
+ Automation payloads use schema v3 with current tenant-scoped project and issue
543
+ fields, safe sorted `trigger.changedFields`, and optional artifact counts; CI
544
+ uses `issue: null` and `changedFields: []`. Subscription broadcasts and `ping`
545
+ remain schema v2. Manual redelivery uses a new header and rewrites a payload
546
+ delivery ID only for legacy v2 automation bodies that contain that field.
543
547
  Already satisfied assignments, priorities, statuses, and label relationships
544
548
  succeed without duplicate mutation events. Invalid references still fail.
545
549
  Unsupported action types or malformed values return `400` and are not saved.
@@ -752,10 +756,10 @@ reject `position`.
752
756
 
753
757
  ## Webhook Fields
754
758
 
755
- Bearer secrets must contain only printable ASCII characters. Switching from none to Bearer requires a token and returns HTTP 400 if it is missing.
759
+ Bearer secrets must contain only printable ASCII characters. Switching from none to Bearer requires a token and returns HTTP 400 if it is missing. The optional `standard_webhooks` setting accepts a receiver-supplied `whsec_` secret; it is write-only and must be canonical standard Base64 after the prefix, decoding to 24-64 bytes. Lists expose only `standard_webhooks.configured`.
756
760
 
757
761
  `PATCH /api/webhooks/{id}` preserves omitted fields. A blank or omitted Bearer
758
- secret preserves the token; `auth.type: none` clears it. URL/auth changes create
762
+ secret preserves the token; `auth.type: none` clears it. URL/auth/Standard signing changes create
759
763
  a new private destination version; pending deliveries retain their pinned version.
760
764
 
761
765
  ```json
@@ -764,13 +768,17 @@ a new private destination version; pending deliveries retain their pinned versio
764
768
  "events": ["issue.created", "issue.updated"],
765
769
  "enabled": true,
766
770
  "purpose": "subscription",
767
- "auth": { "type": "none" }
771
+ "auth": { "type": "none" },
772
+ "standard_webhooks": {
773
+ "enabled": true,
774
+ "secret": "whsec_<canonical-standard-base64>"
775
+ }
768
776
  }
769
777
  ```
770
778
 
771
- URL must be an HTTPS DNS hostname. IP literals, `localhost`, and `.local` hosts are rejected at creation; delivery refuses non-public DNS results and does not follow redirects. The create response includes a `secret` for HMAC signature verification. Store it immediately; it is shown only once. Use purpose `automation` or `both` with `auth: { "type": "bearer", "secret": "..." }` for automation destinations; responses expose only `auth.type` and `auth.configured`.
779
+ URL must be an HTTPS DNS hostname. IP literals, `localhost`, and `.local` hosts are rejected at creation; delivery refuses non-public DNS results and does not follow redirects. The create response includes an Atoll-generated `secret` for HMAC signature verification. Store it immediately; it is shown only once. This is distinct from the receiver-supplied Standard Webhooks `whsec_` secret. Use purpose `automation` or `both` with `auth: { "type": "bearer", "secret": "..." }` for automation destinations; responses expose only `auth.type` and `auth.configured`.
772
780
 
773
- List responses include `destination_display` and a deprecated `url` compatibility field containing only the origin plus `/…`. Payload schema version `2` is allowlisted. Delivery requests include `X-Atoll-Signature`, `X-Atoll-Signature-Version`, versioned `X-Atoll-Signatures`, and `X-Atoll-Delivery-Id`. Delivery history includes `delivery_id`, `status`, `status_code`, `error_code`, `delivered_at`, and `next_retry_at`, never payloads, receiver response bodies, or raw errors.
781
+ List responses include `destination_display` and a deprecated `url` compatibility field containing only the origin plus `/…`. Automation action payloads use schema version `3` with current tenant-scoped project and issue fields; subscription broadcasts and `ping` remain schema version `2`. Delivery requests include `X-Atoll-Signature`, `X-Atoll-Signature-Version`, versioned `X-Atoll-Signatures`, `X-Atoll-Delivery-Id`, and `Idempotency-Key`. When Standard Webhooks is enabled, they also include `webhook-id`, `webhook-timestamp`, and `webhook-signature`. Delivery history includes `delivery_id`, `status`, `status_code`, `error_code`, `delivered_at`, and `next_retry_at`, never payloads, receiver response bodies, or raw errors.
774
782
 
775
783
  ## Private Inbox Fields
776
784
 
@@ -207,14 +207,55 @@ Config sessions and unused manual connect tokens expire after 10 minutes. Sessio
207
207
 
208
208
  `POST /api/webhooks` creates outbound webhooks. Receiver URLs must be HTTPS DNS hostnames; Atoll rejects IP literals, `localhost`, `.local` hosts, URL credentials, and fragments at creation. Delivery also resolves DNS and refuses private, loopback, link-local, documentation, multicast, and other non-public addresses; redirects are not followed.
209
209
 
210
- Webhook creation returns a raw `whsec_...` secret once. Delivery requests include:
210
+ Webhook creation returns an Atoll-generated signing `secret` once. Store it
211
+ immediately; it is distinct from the receiver-supplied Standard Webhooks
212
+ `whsec_` secret. Delivery requests include:
211
213
 
212
214
  - `X-Atoll-Signature`: `sha256=` plus an HMAC-SHA256 over the raw body, keyed by the SHA-256 hex digest of the raw secret.
213
215
  - `X-Atoll-Signature-Version`: the primary signing-key version.
214
216
  - `X-Atoll-Signatures`: versioned signatures during a bounded key-overlap window.
215
217
  - `X-Atoll-Delivery-Id`: stable delivery id for receiver-side deduplication.
216
-
217
- Webhook administration is owner/admin only. Lists return an origin-only `destination_display`; paths, queries, and signing material are never returned. Payload schema version `2` is allowlisted and omits descriptions, comment bodies, and raw change values. Delivery rows expose safe `delivery_id`, `status`, `status_code`, `error_code`, and retry timing, but not payloads, receiver response bodies, or raw errors. Network failures and 5xx responses retry quickly in-process, then persist `status: retry_pending` with `next_retry_at`; an internal drain retries due deliveries every 15 minutes.
218
+ - `Idempotency-Key`: present on every outbound delivery; it is the same logical delivery id across automatic retries, while manual redelivery uses a new id and key.
219
+ - Optional Standard Webhooks signing adds `webhook-id`, `webhook-timestamp`, and `webhook-signature: v1,<base64>` using the receiver's canonical `whsec_` secret (24-64 decoded bytes). The signature covers `deliveryId.timestamp.rawBody`. A 2xx response proves acceptance only.
220
+
221
+
222
+
223
+ ### Receiver setup
224
+
225
+ Grok Automations supports this Standard Webhooks option. Configure an
226
+ `automation` destination with the receiver-supplied `whsec_` value from Grok.
227
+ Grok validates `webhook-id`, `webhook-timestamp`, and
228
+ `webhook-signature: v1,<base64>` within a five-minute timestamp window; HTTP
229
+ 202 means accepted for processing, not completed.
230
+
231
+ Hermes supports the same Standard Webhooks `whsec_` verification on a public
232
+ HTTPS `/webhooks/<route>` endpoint. Configure the Hermes receiver route/filter
233
+ with `events: ["automation.action"]`; this is a receiver setting. In Atoll, set
234
+ the destination `purpose` to `automation` (or `both`) and trigger it with an
235
+ explicit `send_webhook` action; the Atoll destination `events` field does not
236
+ select automation actions. Hermes should allowlist and render these v3 fields
237
+ when present: `data.project`, `data.issue`, `data.automation.ruleId`,
238
+ `data.automation.ruleName`, `data.trigger.eventType`, and
239
+ `data.trigger.changedFields`. Issue payloads also include the current persisted
240
+ `id`, optional `identifier` and `url`, `title`, `status`, `priority`, `assigneeId`,
241
+ `updatedAt`, and an optional privacy-safe `artifacts` count. CI payloads set
242
+ `data.issue` to null and retain only the useful `ci` fields, so handle CI events
243
+ separately. Hermes can use `webhook-id` for one-hour deduplication. A 2xx
244
+ response is receiver acceptance, not agent completion. No live Hermes receiver
245
+ test was run; this setup guidance is based on source compatibility.
246
+
247
+ Webhook administration is owner/admin only. Lists return an origin-only
248
+ `destination_display`; paths, queries, and signing material are never returned.
249
+ Automation action payloads use schema version `3`; subscription broadcasts and
250
+ `ping` remain schema version `2`. Existing queued payloads retain their stored
251
+ schema and content. Artifact summaries are omitted when lookup fails, data is
252
+ invalid, or counting cannot complete within the bounded 1,000-row pagination
253
+ limit. Both versions omit descriptions, comment bodies, and raw change values.
254
+ Delivery rows expose safe `delivery_id`, `status`, `status_code`,
255
+ `error_code`, and retry timing, but not payloads, receiver response bodies, or
256
+ raw errors. Each invocation makes one 30-second request attempt. Network
257
+ failures and 5xx responses persist `status: retry_pending` with
258
+ `next_retry_at`; an internal drain retries due deliveries every 15 minutes.
218
259
 
219
260
  ### GitHub delivery context
220
261
 
@@ -90,3 +90,78 @@ are blocked while a current job exists. Refresh, config validation, and Codex
90
90
  preflight are non-destructive; there is no model retry or cleanup button.
91
91
  A UI port or asset failure does not stop headless execution. Do not proxy this
92
92
  loopback interface to another host. Service installation remains separate.
93
+
94
+ ### macOS service and lifecycle
95
+
96
+ Install an explicit user service only when unattended operation is required:
97
+
98
+ ```bash
99
+ atoll-runner --profile agent-a service install
100
+ atoll-runner --profile agent-a service install --ui --ui-port 4735
101
+ atoll-runner --profile agent-a service status
102
+ atoll-runner --profile agent-a service uninstall
103
+ ```
104
+
105
+ The service is macOS-only. Install writes an atomic user-owned `0600` plist
106
+ under `~/Library/LaunchAgents/` with canonical Node and runner entry paths,
107
+ the selected profile, `run`, and optional loopback UI arguments. It contains no
108
+ environment variables, API keys, Codex or lease tokens, shell command,
109
+ checkout path, or worktree path. Unknown or changed plists fail closed.
110
+ Package installation is passive and never installs or starts the service. Use
111
+ uninstall, package upgrade, `doctor`, then install for an upgrade. Uninstall
112
+ removes only the exact owned plist and leaves journals, tokens, logs, branches,
113
+ and worktrees. Status and uninstall validate the local plist and do not require
114
+ profile credentials; install remains authenticated.
115
+
116
+ SIGINT/SIGTERM closes the process-local intake gate immediately. The current
117
+ child drains for at most 30 seconds; TERM and then KILL after 10 seconds are
118
+ sent only when the journaled PID still has the same process-start identity. A
119
+ wall-clock event-loop gap above 30 seconds is a possible wake. The child is
120
+ stopped, durable lease state is reconciled, and intake reopens only after that
121
+ pass. A wake may release a worker only to finish an already durable result;
122
+ stop never releases a worker. No hosted pause request is sent. Existing-wire
123
+ response failures are bounded as `RUNNER_PROTOCOL_MISMATCH` and keep pending
124
+ mutation journals available for replay.
125
+
126
+ ### Opt-in real local smoke
127
+
128
+ This developer harness is available only from an Atoll source checkout. It is
129
+ not included in the installed npm CLI. After deterministic checks, use a clean
130
+ loopback fixture profile with no current or conflicting retained job, and run
131
+ from `packages/cli`:
132
+
133
+ Loopback remains the normal default. Repository owners may also run one bounded
134
+ production validation turn from a clean Atoll source checkout. This mode requires
135
+ an exact canonical production origin, organization, project, authenticated agent,
136
+ issue, runner host and instance, and the live project repository mapping's opaque
137
+ `repo_ref` plus repository full name. The supplied `repo_ref` is checked against
138
+ live issue routing and must never be hard-coded. The smoke derives the canonical
139
+ source root from its own script, requires a clean source checkout, rebuilds the
140
+ candidate in the invocation, and records the source root, source `HEAD`, and
141
+ worker-entry SHA-256 in bounded mode-`0600` evidence. Exact production admission
142
+ performs zero presence `PUT`/upsert operations for either connected or
143
+ disconnected targets. Registration and refresh belong to separate operator setup
144
+ outside this invocation. The invocation reads the connected runner identity
145
+ before claim and rechecks it immediately before the claim; a disconnected target
146
+ fails closed. The runner does not explicitly select a model. The Codex runtime
147
+ and local Codex configuration supply model selection. `@openai/codex` and
148
+ `@openai/codex-sdk` are pinned to package/runtime version `0.153.4`; this
149
+ version is not a model name. Use the internal AH-2088 production smoke
150
+ runbook for the owner-only command and cleanup procedure.
151
+
152
+
153
+ ```bash
154
+ cd packages/cli && bun run build
155
+ ATOLL_RUNNER_MANUAL_SMOKE=1 bun run runner:manual-smoke -- \
156
+ --profile agent-a --issue issue-uuid --repository /path/to/checkout \
157
+ --timeout-ms 300000 --evidence /absolute/path/evidence.json
158
+ ```
159
+
160
+ The smoke runs one real Codex turn through the existing runner. It creates and
161
+ retains its owned local branch and worktree while preserving the primary
162
+ checkout, and writes bounded fixture issue, host, generation, branch/worktree,
163
+ base/head SHA, thread, terminal, and time evidence outside the checkout. A
164
+ timeout is always failure; retained journal state is authoritative. It never
165
+ pushes or deletes retained state, publishes, deploys, or installs a service.
166
+ Codex Desktop visibility is a separate operator observation; deterministic tests
167
+ use a fake SDK.