@parall/daemon 1.55.0 → 1.55.1

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.
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.55.0",
3
- "built_at": "2026-08-09T16:02:07.000Z",
2
+ "version": "1.55.1",
3
+ "built_at": "2026-08-12T14:55:20.195Z",
4
4
  "min_node_version": "20.0.0",
5
5
  "files": {
6
6
  "bb-browser-daemon.js": {
@@ -16,29 +16,29 @@
16
16
  "size": 18
17
17
  },
18
18
  "parall-browser-pod.js": {
19
- "sha256": "76ddb193bb4007f593954dd70db9a7555cd4ff230e69fb1d65b48effdb4cb8f1",
20
- "size": 2940163
19
+ "sha256": "515f2339f2eed7e942fb06d9fc020060b5598c36f234f1bcbd08ab0e6a75fab1",
20
+ "size": 2946190
21
21
  },
22
22
  "parall-channel-exec.js": {
23
23
  "sha256": "7c2a6e12483a45e9eb4a42cd7d4cdd3c4fa21dd09ac1347d9a3e177b4ddee930",
24
24
  "size": 7220
25
25
  },
26
26
  "parall-claude-agent.js": {
27
- "sha256": "40b0ce7d956b08a1d09898b6c0b4e99725df3f90dc885e9615caedb4751a8c74",
28
- "size": 2805125
27
+ "sha256": "9be3b40a7a07ffe475bc2d89a24873dfb255318fbff44001aa91b46424f74764",
28
+ "size": 2814346
29
29
  },
30
30
  "parall-codex-agent.js": {
31
- "sha256": "0d7102ec3a86125abad4de826946964faf88e401c55649280460fb71850e460f",
32
- "size": 2835829
31
+ "sha256": "1951a7dd83d82108fb9db3f58d9dd8e338c059d67656de8370053c0355b50221",
32
+ "size": 2846371
33
33
  },
34
34
  "parall-daemon.js": {
35
- "sha256": "0eb785ee505204bbf4a5c872a8cae61bc814f1400a1456cec9fa146f1958ef34",
36
- "size": 3004344
35
+ "sha256": "9b22b08ee0d9bb544bc04cde5bfb81105efc48605cbb04e34bd72fc21cdf2791",
36
+ "size": 3011156
37
37
  },
38
38
  "parall-openclaw-agent.js": {
39
39
  "sha256": "856a1c3a9ae0ffef8efe2481fa1171dbeb1d67cccb88616aa9bf16da96a69355",
40
40
  "size": 9923
41
41
  }
42
42
  },
43
- "signature": "GXPiJwnrho49eHkMv7aW6lYsT2d66zB5BN3JYHKmrWX4hRiOlPqNJ7Ti/jywf2LhTVsbCPtKLTda5H7Ft3KSDA=="
43
+ "signature": "6Qz7sggq6UHjp8N85qhLEIOUQo3HA2x0Sh0s2dkbSwti5TjfEznbi/jcYhZROXlPIV1wihB9i2eE7w+p3F6DCQ=="
44
44
  }
@@ -63704,6 +63704,13 @@ var ENDPOINTS = {
63704
63704
  PROJECTS: (orgId) => `${API_BASE}/orgs/${orgId}/projects`,
63705
63705
  PROJECT_TASK_SUMMARY: (orgId) => `${API_BASE}/orgs/${orgId}/projects/task-summary`,
63706
63706
  PROJECT: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}`,
63707
+ PROJECT_MEMBERS: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/members`,
63708
+ PROJECT_READERS: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/readers`,
63709
+ PROJECT_LIBRARY: (orgId) => `${API_BASE}/orgs/${orgId}/projects/library`,
63710
+ PROJECT_JOIN: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/join`,
63711
+ PROJECT_JOIN_REQUESTS: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/join-requests`,
63712
+ // subject is a bare user ID or a bare team ID; both are path-segment safe.
63713
+ PROJECT_MEMBER: (orgId, projectId, subject) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/members/${subject}`,
63707
63714
  // Schedules (org-scoped, platform time trigger primitive)
63708
63715
  SCHEDULES: (orgId) => `${API_BASE}/orgs/${orgId}/schedules`,
63709
63716
  SCHEDULE: (orgId, id) => `${API_BASE}/orgs/${orgId}/schedules/${id}`,
@@ -63921,6 +63928,9 @@ var ENDPOINTS = {
63921
63928
  ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
63922
63929
  // Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
63923
63930
  ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
63931
+ // Per-profile one-shot cookie seed (hosted Cloud Profiles; manager-only,
63932
+ // human-only, idle-only). Injected at the next cold start, then consumed.
63933
+ ORG_EDGE_PROFILE_COOKIES: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/cookies`,
63924
63934
  ORG_EDGE_EXEC: (orgId) => `/api/v1/orgs/${orgId}/edge/exec`,
63925
63935
  // Cloud Edge live viewer command (V1b) — api-server, gated on cap:edge-viewer.
63926
63936
  // Same request/reply shape as the v2 browser-profile viewer, on the v3 edge
@@ -64067,6 +64077,62 @@ var ProjectTaskClient = class {
64067
64077
  async deleteProject(orgId, projectId) {
64068
64078
  return this.request("DELETE", ENDPOINTS.PROJECT(orgId, projectId));
64069
64079
  }
64080
+ /** Roster with display info; readable by anyone who can read the project. */
64081
+ async getProjectMembers(orgId, projectId) {
64082
+ const res = await this.request("GET", ENDPOINTS.PROJECT_MEMBERS(orgId, projectId));
64083
+ return res.data;
64084
+ }
64085
+ /**
64086
+ * User IDs who may read the project — the assignee-eligibility set. Every
64087
+ * tier answers the roster expansion (direct, team-reached, org
64088
+ * owners/admins); visibility only shapes admission, never reach.
64089
+ */
64090
+ async getProjectReaders(orgId, projectId) {
64091
+ const res = await this.request("GET", ENDPOINTS.PROJECT_READERS(orgId, projectId));
64092
+ return res.data;
64093
+ }
64094
+ /** The join library: every discoverable project (public + restricted, plus
64095
+ * private for org owners/admins) with the caller's admission state. */
64096
+ async getProjectLibrary(orgId) {
64097
+ const res = await this.request("GET", ENDPOINTS.PROJECT_LIBRARY(orgId));
64098
+ return res.data;
64099
+ }
64100
+ /** Public-tier self-admission: writes the caller's own member row.
64101
+ * Other tiers answer `404 PROJECT_NOT_FOUND`; a duplicate answers
64102
+ * `409 MEMBER_EXISTS`. */
64103
+ async joinProject(orgId, projectId) {
64104
+ return this.request("POST", ENDPOINTS.PROJECT_JOIN(orgId, projectId));
64105
+ }
64106
+ /** Restricted-tier admission petition. A pending duplicate answers
64107
+ * `409 REQUEST_EXISTS`; membership answers `409 MEMBER_EXISTS`. */
64108
+ async createProjectJoinRequest(orgId, projectId) {
64109
+ return this.request("POST", ENDPOINTS.PROJECT_JOIN_REQUESTS(orgId, projectId));
64110
+ }
64111
+ /** Pending petitions for one project — manager standing required. */
64112
+ async listProjectJoinRequests(orgId, projectId) {
64113
+ const res = await this.request("GET", ENDPOINTS.PROJECT_JOIN_REQUESTS(orgId, projectId));
64114
+ return res.data;
64115
+ }
64116
+ /** Withdraws the caller's own pending petition. */
64117
+ async cancelProjectJoinRequest(orgId, projectId) {
64118
+ return this.request("DELETE", ENDPOINTS.PROJECT_JOIN_REQUESTS(orgId, projectId));
64119
+ }
64120
+ /**
64121
+ * Adds one subject (user ID or team ID) to the roster. Manager-only,
64122
+ * create-only: an existing row answers `409 MEMBER_EXISTS` — change roles
64123
+ * through updateProjectMember instead.
64124
+ */
64125
+ async addProjectMember(orgId, projectId, req) {
64126
+ return this.request("POST", ENDPOINTS.PROJECT_MEMBERS(orgId, projectId), req);
64127
+ }
64128
+ /** Sets one roster entry's role. Demoting the last manager answers `400 LAST_MANAGER`. */
64129
+ async updateProjectMember(orgId, projectId, subject, req) {
64130
+ return this.request("PATCH", ENDPOINTS.PROJECT_MEMBER(orgId, projectId, subject), req);
64131
+ }
64132
+ /** Removes one roster entry. Removing the last manager answers `400 LAST_MANAGER`. */
64133
+ async removeProjectMember(orgId, projectId, subject) {
64134
+ return this.request("DELETE", ENDPOINTS.PROJECT_MEMBER(orgId, projectId, subject));
64135
+ }
64070
64136
  };
64071
64137
 
64072
64138
  // ts/sdk/dist/task-label-client.js
@@ -64459,8 +64525,9 @@ var ParallClient = class _ParallClient extends TaskLabelClient {
64459
64525
  return this.request("POST", ENDPOINTS.TEAMS(orgId), req);
64460
64526
  }
64461
64527
  /**
64462
- * Renames a team. The slug cannot be changed — wiki ACL rows reference it as
64463
- * `@slug`, so the server answers 400 SLUG_IMMUTABLE if one is sent.
64528
+ * Renames a team. Renaming is an ordinary edit: ACL rows reference teams by
64529
+ * ID. Names are org-unique (case-insensitive); a duplicate answers 409
64530
+ * NAME_TAKEN.
64464
64531
  */
64465
64532
  async updateTeam(orgId, teamId, req) {
64466
64533
  return this.request("PATCH", ENDPOINTS.TEAM(orgId, teamId), req);
@@ -66089,15 +66156,18 @@ var ParallClient = class _ParallClient extends TaskLabelClient {
66089
66156
  /**
66090
66157
  * Read a clip's per-org agent exec access. Org-member readable (agents
66091
66158
  * included, so a denied agent can learn why exec answered
66092
- * `CLIP_AGENT_NOT_ALLOWED`).
66159
+ * `CLIP_AGENT_NOT_ALLOWED` / `CLIP_AGENT_CONNECTION_NOT_ALLOWED`).
66093
66160
  */
66094
66161
  async getClipAgentExecAccess(orgId, clipId) {
66095
66162
  return this.request("GET", ENDPOINTS.ORG_CLIP_EXEC_ACCESS(orgId, clipId));
66096
66163
  }
66097
66164
  /**
66098
66165
  * Replace a clip's per-org agent exec access. Human-only (agent principals
66099
- * get 403); under `all_agents` the `agent_ids` must be empty. Every granted
66100
- * id must be an active agent of this org (else `400 INVALID_INPUT`).
66166
+ * get 403); under `all_agents` both lists must be empty; pass either
66167
+ * `agent_ids` (legacy flat form every agent gets `connection_scope: 'all'`)
66168
+ * or `grants` (connection-scoped), never both. Every granted id must be an
66169
+ * active agent of this org, and every `connection_ids` entry a connection of
66170
+ * THIS clip in this org (else `400 INVALID_INPUT`).
66101
66171
  */
66102
66172
  async putClipAgentExecAccess(orgId, clipId, access) {
66103
66173
  return this.request("PUT", ENDPOINTS.ORG_CLIP_EXEC_ACCESS(orgId, clipId), access);
@@ -66183,6 +66253,41 @@ var ParallClient = class _ParallClient extends TaskLabelClient {
66183
66253
  headers: expectedVersion ? { "If-Match": `"proxy-${expectedVersion}"` } : void 0
66184
66254
  });
66185
66255
  }
66256
+ /**
66257
+ * Read a hosted Cloud Profile's one-shot cookie-seed status (manager-only:
66258
+ * hosted human maintainer or org admin). Sanitized — cookie VALUES never come
66259
+ * back, only `cookie_count` and the distinct target `domains`. `can_mutate` /
66260
+ * `lease_status` are the authoritative idle gate. Typed errors: `EDGE_NOT_HOSTED`
66261
+ * (BYOC device), `NOT_FOUND` (unknown profile).
66262
+ */
66263
+ async getEdgeProfileCookieSeed(orgId, edgeId, profileName) {
66264
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILE_COOKIES(orgId, edgeId, profileName));
66265
+ }
66266
+ /**
66267
+ * Set/replace the profile's one-shot cookie seed (the full normalized cookie
66268
+ * array every time) — IDLE ONLY: while the profile's hosted browser is running
66269
+ * the server answers 409 `EDGE_PROFILE_IN_USE`; close the viewer, wait for idle
66270
+ * scale-to-zero, and retry. The next cold start injects the cookies into the
66271
+ * profile partition and consumes the seed. Other typed errors:
66272
+ * `EDGE_COOKIE_SEED_STALE` (409 — expectedVersion lost a tab race, sent as the
66273
+ * `cookieseed-<version>` If-Match), `EDGE_DELETING` (409), and
66274
+ * `SECRETBOX_UNCONFIGURED` (503 — server cannot store cookies safely).
66275
+ */
66276
+ async setEdgeProfileCookieSeed(orgId, edgeId, profileName, req, expectedVersion) {
66277
+ return this.request("PUT", ENDPOINTS.ORG_EDGE_PROFILE_COOKIES(orgId, edgeId, profileName), req, void 0, false, {
66278
+ headers: expectedVersion ? { "If-Match": `"cookieseed-${expectedVersion}"` } : void 0
66279
+ });
66280
+ }
66281
+ /**
66282
+ * Clear the pending cookie seed (does NOT sign the profile out — cookies
66283
+ * already injected into the partition stay). Idle-only like set — 409
66284
+ * `EDGE_PROFILE_IN_USE` while the browser is live.
66285
+ */
66286
+ async clearEdgeProfileCookieSeed(orgId, edgeId, profileName, expectedVersion) {
66287
+ return this.request("DELETE", ENDPOINTS.ORG_EDGE_PROFILE_COOKIES(orgId, edgeId, profileName), void 0, void 0, false, {
66288
+ headers: expectedVersion ? { "If-Match": `"cookieseed-${expectedVersion}"` } : void 0
66289
+ });
66290
+ }
66186
66291
  /**
66187
66292
  * Execute a registry clip command on an Edge device.
66188
66293
  *
@@ -51863,6 +51863,13 @@ var ENDPOINTS = {
51863
51863
  PROJECTS: (orgId) => `${API_BASE}/orgs/${orgId}/projects`,
51864
51864
  PROJECT_TASK_SUMMARY: (orgId) => `${API_BASE}/orgs/${orgId}/projects/task-summary`,
51865
51865
  PROJECT: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}`,
51866
+ PROJECT_MEMBERS: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/members`,
51867
+ PROJECT_READERS: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/readers`,
51868
+ PROJECT_LIBRARY: (orgId) => `${API_BASE}/orgs/${orgId}/projects/library`,
51869
+ PROJECT_JOIN: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/join`,
51870
+ PROJECT_JOIN_REQUESTS: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/join-requests`,
51871
+ // subject is a bare user ID or a bare team ID; both are path-segment safe.
51872
+ PROJECT_MEMBER: (orgId, projectId, subject) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/members/${subject}`,
51866
51873
  // Schedules (org-scoped, platform time trigger primitive)
51867
51874
  SCHEDULES: (orgId) => `${API_BASE}/orgs/${orgId}/schedules`,
51868
51875
  SCHEDULE: (orgId, id) => `${API_BASE}/orgs/${orgId}/schedules/${id}`,
@@ -52080,6 +52087,9 @@ var ENDPOINTS = {
52080
52087
  ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
52081
52088
  // Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
52082
52089
  ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
52090
+ // Per-profile one-shot cookie seed (hosted Cloud Profiles; manager-only,
52091
+ // human-only, idle-only). Injected at the next cold start, then consumed.
52092
+ ORG_EDGE_PROFILE_COOKIES: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/cookies`,
52083
52093
  ORG_EDGE_EXEC: (orgId) => `/api/v1/orgs/${orgId}/edge/exec`,
52084
52094
  // Cloud Edge live viewer command (V1b) — api-server, gated on cap:edge-viewer.
52085
52095
  // Same request/reply shape as the v2 browser-profile viewer, on the v3 edge
@@ -52121,6 +52131,7 @@ var WS_EVENTS = {
52121
52131
  PONG: "pong",
52122
52132
  WATCHING: "watching",
52123
52133
  MESSAGE_NEW: "message.new",
52134
+ /** @deprecated `message.patch` is retired and never published; kept for compile compatibility. */
52124
52135
  MESSAGE_PATCH: "message.patch",
52125
52136
  MESSAGE_EDIT: "message.edit",
52126
52137
  MESSAGE_DELETE: "message.delete",
@@ -52316,6 +52327,62 @@ var ProjectTaskClient = class {
52316
52327
  async deleteProject(orgId, projectId) {
52317
52328
  return this.request("DELETE", ENDPOINTS.PROJECT(orgId, projectId));
52318
52329
  }
52330
+ /** Roster with display info; readable by anyone who can read the project. */
52331
+ async getProjectMembers(orgId, projectId) {
52332
+ const res = await this.request("GET", ENDPOINTS.PROJECT_MEMBERS(orgId, projectId));
52333
+ return res.data;
52334
+ }
52335
+ /**
52336
+ * User IDs who may read the project — the assignee-eligibility set. Every
52337
+ * tier answers the roster expansion (direct, team-reached, org
52338
+ * owners/admins); visibility only shapes admission, never reach.
52339
+ */
52340
+ async getProjectReaders(orgId, projectId) {
52341
+ const res = await this.request("GET", ENDPOINTS.PROJECT_READERS(orgId, projectId));
52342
+ return res.data;
52343
+ }
52344
+ /** The join library: every discoverable project (public + restricted, plus
52345
+ * private for org owners/admins) with the caller's admission state. */
52346
+ async getProjectLibrary(orgId) {
52347
+ const res = await this.request("GET", ENDPOINTS.PROJECT_LIBRARY(orgId));
52348
+ return res.data;
52349
+ }
52350
+ /** Public-tier self-admission: writes the caller's own member row.
52351
+ * Other tiers answer `404 PROJECT_NOT_FOUND`; a duplicate answers
52352
+ * `409 MEMBER_EXISTS`. */
52353
+ async joinProject(orgId, projectId) {
52354
+ return this.request("POST", ENDPOINTS.PROJECT_JOIN(orgId, projectId));
52355
+ }
52356
+ /** Restricted-tier admission petition. A pending duplicate answers
52357
+ * `409 REQUEST_EXISTS`; membership answers `409 MEMBER_EXISTS`. */
52358
+ async createProjectJoinRequest(orgId, projectId) {
52359
+ return this.request("POST", ENDPOINTS.PROJECT_JOIN_REQUESTS(orgId, projectId));
52360
+ }
52361
+ /** Pending petitions for one project — manager standing required. */
52362
+ async listProjectJoinRequests(orgId, projectId) {
52363
+ const res = await this.request("GET", ENDPOINTS.PROJECT_JOIN_REQUESTS(orgId, projectId));
52364
+ return res.data;
52365
+ }
52366
+ /** Withdraws the caller's own pending petition. */
52367
+ async cancelProjectJoinRequest(orgId, projectId) {
52368
+ return this.request("DELETE", ENDPOINTS.PROJECT_JOIN_REQUESTS(orgId, projectId));
52369
+ }
52370
+ /**
52371
+ * Adds one subject (user ID or team ID) to the roster. Manager-only,
52372
+ * create-only: an existing row answers `409 MEMBER_EXISTS` — change roles
52373
+ * through updateProjectMember instead.
52374
+ */
52375
+ async addProjectMember(orgId, projectId, req) {
52376
+ return this.request("POST", ENDPOINTS.PROJECT_MEMBERS(orgId, projectId), req);
52377
+ }
52378
+ /** Sets one roster entry's role. Demoting the last manager answers `400 LAST_MANAGER`. */
52379
+ async updateProjectMember(orgId, projectId, subject, req) {
52380
+ return this.request("PATCH", ENDPOINTS.PROJECT_MEMBER(orgId, projectId, subject), req);
52381
+ }
52382
+ /** Removes one roster entry. Removing the last manager answers `400 LAST_MANAGER`. */
52383
+ async removeProjectMember(orgId, projectId, subject) {
52384
+ return this.request("DELETE", ENDPOINTS.PROJECT_MEMBER(orgId, projectId, subject));
52385
+ }
52319
52386
  };
52320
52387
 
52321
52388
  // ts/sdk/dist/task-label-client.js
@@ -52708,8 +52775,9 @@ var ParallClient = class _ParallClient extends TaskLabelClient {
52708
52775
  return this.request("POST", ENDPOINTS.TEAMS(orgId), req);
52709
52776
  }
52710
52777
  /**
52711
- * Renames a team. The slug cannot be changed — wiki ACL rows reference it as
52712
- * `@slug`, so the server answers 400 SLUG_IMMUTABLE if one is sent.
52778
+ * Renames a team. Renaming is an ordinary edit: ACL rows reference teams by
52779
+ * ID. Names are org-unique (case-insensitive); a duplicate answers 409
52780
+ * NAME_TAKEN.
52713
52781
  */
52714
52782
  async updateTeam(orgId, teamId, req) {
52715
52783
  return this.request("PATCH", ENDPOINTS.TEAM(orgId, teamId), req);
@@ -54338,15 +54406,18 @@ var ParallClient = class _ParallClient extends TaskLabelClient {
54338
54406
  /**
54339
54407
  * Read a clip's per-org agent exec access. Org-member readable (agents
54340
54408
  * included, so a denied agent can learn why exec answered
54341
- * `CLIP_AGENT_NOT_ALLOWED`).
54409
+ * `CLIP_AGENT_NOT_ALLOWED` / `CLIP_AGENT_CONNECTION_NOT_ALLOWED`).
54342
54410
  */
54343
54411
  async getClipAgentExecAccess(orgId, clipId) {
54344
54412
  return this.request("GET", ENDPOINTS.ORG_CLIP_EXEC_ACCESS(orgId, clipId));
54345
54413
  }
54346
54414
  /**
54347
54415
  * Replace a clip's per-org agent exec access. Human-only (agent principals
54348
- * get 403); under `all_agents` the `agent_ids` must be empty. Every granted
54349
- * id must be an active agent of this org (else `400 INVALID_INPUT`).
54416
+ * get 403); under `all_agents` both lists must be empty; pass either
54417
+ * `agent_ids` (legacy flat form every agent gets `connection_scope: 'all'`)
54418
+ * or `grants` (connection-scoped), never both. Every granted id must be an
54419
+ * active agent of this org, and every `connection_ids` entry a connection of
54420
+ * THIS clip in this org (else `400 INVALID_INPUT`).
54350
54421
  */
54351
54422
  async putClipAgentExecAccess(orgId, clipId, access) {
54352
54423
  return this.request("PUT", ENDPOINTS.ORG_CLIP_EXEC_ACCESS(orgId, clipId), access);
@@ -54432,6 +54503,41 @@ var ParallClient = class _ParallClient extends TaskLabelClient {
54432
54503
  headers: expectedVersion ? { "If-Match": `"proxy-${expectedVersion}"` } : void 0
54433
54504
  });
54434
54505
  }
54506
+ /**
54507
+ * Read a hosted Cloud Profile's one-shot cookie-seed status (manager-only:
54508
+ * hosted human maintainer or org admin). Sanitized — cookie VALUES never come
54509
+ * back, only `cookie_count` and the distinct target `domains`. `can_mutate` /
54510
+ * `lease_status` are the authoritative idle gate. Typed errors: `EDGE_NOT_HOSTED`
54511
+ * (BYOC device), `NOT_FOUND` (unknown profile).
54512
+ */
54513
+ async getEdgeProfileCookieSeed(orgId, edgeId, profileName) {
54514
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILE_COOKIES(orgId, edgeId, profileName));
54515
+ }
54516
+ /**
54517
+ * Set/replace the profile's one-shot cookie seed (the full normalized cookie
54518
+ * array every time) — IDLE ONLY: while the profile's hosted browser is running
54519
+ * the server answers 409 `EDGE_PROFILE_IN_USE`; close the viewer, wait for idle
54520
+ * scale-to-zero, and retry. The next cold start injects the cookies into the
54521
+ * profile partition and consumes the seed. Other typed errors:
54522
+ * `EDGE_COOKIE_SEED_STALE` (409 — expectedVersion lost a tab race, sent as the
54523
+ * `cookieseed-<version>` If-Match), `EDGE_DELETING` (409), and
54524
+ * `SECRETBOX_UNCONFIGURED` (503 — server cannot store cookies safely).
54525
+ */
54526
+ async setEdgeProfileCookieSeed(orgId, edgeId, profileName, req, expectedVersion) {
54527
+ return this.request("PUT", ENDPOINTS.ORG_EDGE_PROFILE_COOKIES(orgId, edgeId, profileName), req, void 0, false, {
54528
+ headers: expectedVersion ? { "If-Match": `"cookieseed-${expectedVersion}"` } : void 0
54529
+ });
54530
+ }
54531
+ /**
54532
+ * Clear the pending cookie seed (does NOT sign the profile out — cookies
54533
+ * already injected into the partition stay). Idle-only like set — 409
54534
+ * `EDGE_PROFILE_IN_USE` while the browser is live.
54535
+ */
54536
+ async clearEdgeProfileCookieSeed(orgId, edgeId, profileName, expectedVersion) {
54537
+ return this.request("DELETE", ENDPOINTS.ORG_EDGE_PROFILE_COOKIES(orgId, edgeId, profileName), void 0, void 0, false, {
54538
+ headers: expectedVersion ? { "If-Match": `"cookieseed-${expectedVersion}"` } : void 0
54539
+ });
54540
+ }
54435
54541
  /**
54436
54542
  * Execute a registry clip command on an Edge device.
54437
54543
  *
@@ -60516,6 +60622,7 @@ function parseTweets(data) { /* ... */ }
60516
60622
  - \`tab.cookie(name)\` \xB7 \`tab.fetch(url, opts)\` (in-browser fetch, carries the session)
60517
60623
  - \`tab.eval(expr)\` (escape hatch) \xB7 \`tab.click(sel)\` \xB7 \`tab.fill(sel, text)\` \xB7 \`tab.navigate(url)\`
60518
60624
  - \`tab.waitForSelector(sel)\` \xB7 \`tab.getTitle()\` \xB7 \`tab.getURL()\` \xB7 \`tab.screenshot()\` \xB7 \`tab.close()\`
60625
+ - \`tab.setFileInput(sel, url, opts?)\` \u2014 upload a file into an \`<input type=file>\`
60519
60626
  - \`fetch\` \u2014 runtime-side HTTP, does NOT go through the browser (no session)
60520
60627
  - \`console\` \u2014 logs \xB7 \`args\` \u2014 the invocation input
60521
60628
 
@@ -60524,6 +60631,40 @@ returns structured data; eval is the last resort. Always \`tab.close()\` what yo
60524
60631
  open, and do it in a \`finally\` \u2014 an early return or a thrown fetch is exactly
60525
60632
  when the tab leaks.
60526
60633
 
60634
+ ### Uploading a file
60635
+
60636
+ \`tab.setFileInput\` takes a URL, never a path, and the runtime \u2014 not the page \u2014
60637
+ fetches the bytes. That is what makes it work where an in-page \`fetch\` +
60638
+ \`DataTransfer\` cannot: upload targets ship a Content-Security-Policy that
60639
+ forbids the page from fetching an arbitrary file host (Instagram's \`default-src\`
60640
+ allows only its own domains), and you cannot change a header on their site. The
60641
+ runtime is not a page, so no CSP applies to it \u2014 and a large video never has to
60642
+ pass through the page's memory.
60643
+
60644
+ \`\`\`js
60645
+ await tab.setFileInput("input[type=file]", videoUrl, { filename: "clip.mp4" });
60646
+ await tab.click("button[type=submit]");
60647
+ await tab.waitForSelector(".upload-complete"); // \u2190 do not skip this
60648
+ \`\`\`
60649
+
60650
+ Four rules that decide whether your clip works:
60651
+
60652
+ 1. **The URL must be fetchable with no credentials** \u2014 a public direct link or a
60653
+ signed temporary one. The runtime sends no cookies, so a Drive or Feishu link
60654
+ copied from the address bar will not work: those are HTML pages behind a
60655
+ login. If the file needs a session, use a logged-in tab to obtain a signed
60656
+ direct link first, then pass THAT here. An HTML answer is refused with
60657
+ \`EDGE_FILE_SOURCE_NOT_A_FILE\` rather than uploaded as if it were a file.
60658
+ 2. **Finish the upload inside the same command.** The browser reads the file when
60659
+ the page submits, and the runtime deletes it when your command ends. Injecting
60660
+ and returning immediately uploads nothing \u2014 wait for the site to confirm.
60661
+ 3. **Main-document inputs only.** An input inside an iframe or a shadow root is
60662
+ not addressable and returns \`EDGE_FILE_SELECTOR_MISS\`. If the page rebuilds
60663
+ the input after you inject (navigation, re-render), inject again.
60664
+ 4. **\`opts.filename\` is what the page sees**, and many sites validate by
60665
+ extension \u2014 set it when the URL has none. \`opts.timeoutMs\` bounds the
60666
+ download. One file per call; there is no multi-file form yet.
60667
+
60527
60668
  ## Develop \u2192 publish \u2192 iterate
60528
60669
 
60529
60670
  Use the platform \`parall clip\` subcommands \u2014 they reuse the credentials you
@@ -60630,18 +60771,30 @@ and the folder is just a manifest:
60630
60771
  }
60631
60772
  \`\`\`
60632
60773
 
60633
- - The \`mcp\` block takes ONLY \`server_url\` and \`auth\` (\`"none" | "bearer" |
60634
- "api_key" | "oauth"\`). Any other key is refused at publish \u2014 a credential
60635
- belongs to the installing org's own configuration, NEVER to the clip
60636
- definition.
60774
+ - The \`mcp\` block takes ONLY \`server_url\`, \`auth\` (\`"none" | "api_key" |
60775
+ "basic" | "oauth"\`, legacy \`"bearer"\` accepted) and \`auth_headers\`. Any
60776
+ other key is refused at publish \u2014 a credential belongs to the installing
60777
+ org's own configuration, NEVER to the clip definition.
60778
+ - \`auth\` is REQUIRED at publish: you know what your server speaks, and this
60779
+ one word decides what the install form asks for (\`none\` = zero input,
60780
+ \`api_key\` = key field(s), \`basic\` = username + password, \`oauth\` = a
60781
+ Connect button).
60782
+ - \`api_key\` delivers as a single \`X-API-Key\` header by default. When the
60783
+ server wants a different shape, declare \`auth_headers\` (max 4 slots, one
60784
+ admin-supplied value each): \`[{"name": "Authorization", "scheme":
60785
+ "Bearer"}]\` for Bearer tokens, \`[{"name": "api-key"}]\` for a custom
60786
+ header, or a pair like \`[{"name": "CF-Access-Client-Id"}, {"name":
60787
+ "CF-Access-Client-Secret"}]\`. Framing/platform headers (Host, Cookie,
60788
+ X-Prll-*, \u2026) are refused.
60637
60789
  - \`server_url\` must be an absolute **https** URL with no embedded credentials,
60638
60790
  query, or fragment. It is review material, frozen with the approved version.
60791
+ It stays OPTIONAL for self-hosted products where each org connects its own
60792
+ instance URL.
60639
60793
  - Do NOT put the server in the top-level \`server\` / \`auth\` manifest keys \u2014
60640
60794
  those are legacy Edge-manifest fields nothing reads. Only the \`mcp\` block
60641
60795
  declares the server.
60642
- - Both fields are optional, but what you declare is LOCKED: the installing
60643
- org's config must match it, and changing the URL or auth mode means
60644
- republishing.
60796
+ - What you declare is LOCKED: the installing org's config must match it, and
60797
+ changing the URL, auth mode, or header shape means republishing.
60645
60798
  - Entering the credential / completing OAuth is a HUMAN step in the Clip
60646
60799
  Console (the config-write endpoints are session-only \u2014 an API key cannot
60647
60800
  call them). An org can add SEVERAL connections to one MCP clip \u2014 one
@@ -60727,14 +60880,17 @@ ${lines.join("\n")}
60727
60880
  }
60728
60881
 
60729
60882
  // ts/agent-core/dist/platform-instructions.js
60730
- function buildBridgePlatformInstructions(workspaceDir, identity, capabilityFragments) {
60883
+ function buildPlatformInstructions(workspaceDir, runtimeAppendix, identity, capabilityFragments) {
60731
60884
  return renderPlatformInstructions({
60732
60885
  identity,
60733
- runtimeAppendix: PLATFORM_BRIDGE_WORKSPACE_INSTRUCTIONS,
60886
+ runtimeAppendix,
60734
60887
  capabilityFragments,
60735
60888
  skillReferences: buildSkillReferences(workspaceDir)
60736
60889
  });
60737
60890
  }
60891
+ function buildBridgePlatformInstructions(workspaceDir, identity, capabilityFragments) {
60892
+ return buildPlatformInstructions(workspaceDir, PLATFORM_BRIDGE_WORKSPACE_INSTRUCTIONS, identity, capabilityFragments);
60893
+ }
60738
60894
 
60739
60895
  // ts/agent-core/dist/prompt-fragments.js
60740
60896
  function identityFromMe(me) {
@@ -51863,6 +51863,13 @@ var ENDPOINTS = {
51863
51863
  PROJECTS: (orgId) => `${API_BASE}/orgs/${orgId}/projects`,
51864
51864
  PROJECT_TASK_SUMMARY: (orgId) => `${API_BASE}/orgs/${orgId}/projects/task-summary`,
51865
51865
  PROJECT: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}`,
51866
+ PROJECT_MEMBERS: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/members`,
51867
+ PROJECT_READERS: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/readers`,
51868
+ PROJECT_LIBRARY: (orgId) => `${API_BASE}/orgs/${orgId}/projects/library`,
51869
+ PROJECT_JOIN: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/join`,
51870
+ PROJECT_JOIN_REQUESTS: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/join-requests`,
51871
+ // subject is a bare user ID or a bare team ID; both are path-segment safe.
51872
+ PROJECT_MEMBER: (orgId, projectId, subject) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/members/${subject}`,
51866
51873
  // Schedules (org-scoped, platform time trigger primitive)
51867
51874
  SCHEDULES: (orgId) => `${API_BASE}/orgs/${orgId}/schedules`,
51868
51875
  SCHEDULE: (orgId, id) => `${API_BASE}/orgs/${orgId}/schedules/${id}`,
@@ -52080,6 +52087,9 @@ var ENDPOINTS = {
52080
52087
  ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
52081
52088
  // Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
52082
52089
  ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
52090
+ // Per-profile one-shot cookie seed (hosted Cloud Profiles; manager-only,
52091
+ // human-only, idle-only). Injected at the next cold start, then consumed.
52092
+ ORG_EDGE_PROFILE_COOKIES: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/cookies`,
52083
52093
  ORG_EDGE_EXEC: (orgId) => `/api/v1/orgs/${orgId}/edge/exec`,
52084
52094
  // Cloud Edge live viewer command (V1b) — api-server, gated on cap:edge-viewer.
52085
52095
  // Same request/reply shape as the v2 browser-profile viewer, on the v3 edge
@@ -52121,6 +52131,7 @@ var WS_EVENTS = {
52121
52131
  PONG: "pong",
52122
52132
  WATCHING: "watching",
52123
52133
  MESSAGE_NEW: "message.new",
52134
+ /** @deprecated `message.patch` is retired and never published; kept for compile compatibility. */
52124
52135
  MESSAGE_PATCH: "message.patch",
52125
52136
  MESSAGE_EDIT: "message.edit",
52126
52137
  MESSAGE_DELETE: "message.delete",
@@ -52316,6 +52327,62 @@ var ProjectTaskClient = class {
52316
52327
  async deleteProject(orgId, projectId) {
52317
52328
  return this.request("DELETE", ENDPOINTS.PROJECT(orgId, projectId));
52318
52329
  }
52330
+ /** Roster with display info; readable by anyone who can read the project. */
52331
+ async getProjectMembers(orgId, projectId) {
52332
+ const res = await this.request("GET", ENDPOINTS.PROJECT_MEMBERS(orgId, projectId));
52333
+ return res.data;
52334
+ }
52335
+ /**
52336
+ * User IDs who may read the project — the assignee-eligibility set. Every
52337
+ * tier answers the roster expansion (direct, team-reached, org
52338
+ * owners/admins); visibility only shapes admission, never reach.
52339
+ */
52340
+ async getProjectReaders(orgId, projectId) {
52341
+ const res = await this.request("GET", ENDPOINTS.PROJECT_READERS(orgId, projectId));
52342
+ return res.data;
52343
+ }
52344
+ /** The join library: every discoverable project (public + restricted, plus
52345
+ * private for org owners/admins) with the caller's admission state. */
52346
+ async getProjectLibrary(orgId) {
52347
+ const res = await this.request("GET", ENDPOINTS.PROJECT_LIBRARY(orgId));
52348
+ return res.data;
52349
+ }
52350
+ /** Public-tier self-admission: writes the caller's own member row.
52351
+ * Other tiers answer `404 PROJECT_NOT_FOUND`; a duplicate answers
52352
+ * `409 MEMBER_EXISTS`. */
52353
+ async joinProject(orgId, projectId) {
52354
+ return this.request("POST", ENDPOINTS.PROJECT_JOIN(orgId, projectId));
52355
+ }
52356
+ /** Restricted-tier admission petition. A pending duplicate answers
52357
+ * `409 REQUEST_EXISTS`; membership answers `409 MEMBER_EXISTS`. */
52358
+ async createProjectJoinRequest(orgId, projectId) {
52359
+ return this.request("POST", ENDPOINTS.PROJECT_JOIN_REQUESTS(orgId, projectId));
52360
+ }
52361
+ /** Pending petitions for one project — manager standing required. */
52362
+ async listProjectJoinRequests(orgId, projectId) {
52363
+ const res = await this.request("GET", ENDPOINTS.PROJECT_JOIN_REQUESTS(orgId, projectId));
52364
+ return res.data;
52365
+ }
52366
+ /** Withdraws the caller's own pending petition. */
52367
+ async cancelProjectJoinRequest(orgId, projectId) {
52368
+ return this.request("DELETE", ENDPOINTS.PROJECT_JOIN_REQUESTS(orgId, projectId));
52369
+ }
52370
+ /**
52371
+ * Adds one subject (user ID or team ID) to the roster. Manager-only,
52372
+ * create-only: an existing row answers `409 MEMBER_EXISTS` — change roles
52373
+ * through updateProjectMember instead.
52374
+ */
52375
+ async addProjectMember(orgId, projectId, req) {
52376
+ return this.request("POST", ENDPOINTS.PROJECT_MEMBERS(orgId, projectId), req);
52377
+ }
52378
+ /** Sets one roster entry's role. Demoting the last manager answers `400 LAST_MANAGER`. */
52379
+ async updateProjectMember(orgId, projectId, subject, req) {
52380
+ return this.request("PATCH", ENDPOINTS.PROJECT_MEMBER(orgId, projectId, subject), req);
52381
+ }
52382
+ /** Removes one roster entry. Removing the last manager answers `400 LAST_MANAGER`. */
52383
+ async removeProjectMember(orgId, projectId, subject) {
52384
+ return this.request("DELETE", ENDPOINTS.PROJECT_MEMBER(orgId, projectId, subject));
52385
+ }
52319
52386
  };
52320
52387
 
52321
52388
  // ts/sdk/dist/task-label-client.js
@@ -52708,8 +52775,9 @@ var ParallClient = class _ParallClient extends TaskLabelClient {
52708
52775
  return this.request("POST", ENDPOINTS.TEAMS(orgId), req);
52709
52776
  }
52710
52777
  /**
52711
- * Renames a team. The slug cannot be changed — wiki ACL rows reference it as
52712
- * `@slug`, so the server answers 400 SLUG_IMMUTABLE if one is sent.
52778
+ * Renames a team. Renaming is an ordinary edit: ACL rows reference teams by
52779
+ * ID. Names are org-unique (case-insensitive); a duplicate answers 409
52780
+ * NAME_TAKEN.
52713
52781
  */
52714
52782
  async updateTeam(orgId, teamId, req) {
52715
52783
  return this.request("PATCH", ENDPOINTS.TEAM(orgId, teamId), req);
@@ -54338,15 +54406,18 @@ var ParallClient = class _ParallClient extends TaskLabelClient {
54338
54406
  /**
54339
54407
  * Read a clip's per-org agent exec access. Org-member readable (agents
54340
54408
  * included, so a denied agent can learn why exec answered
54341
- * `CLIP_AGENT_NOT_ALLOWED`).
54409
+ * `CLIP_AGENT_NOT_ALLOWED` / `CLIP_AGENT_CONNECTION_NOT_ALLOWED`).
54342
54410
  */
54343
54411
  async getClipAgentExecAccess(orgId, clipId) {
54344
54412
  return this.request("GET", ENDPOINTS.ORG_CLIP_EXEC_ACCESS(orgId, clipId));
54345
54413
  }
54346
54414
  /**
54347
54415
  * Replace a clip's per-org agent exec access. Human-only (agent principals
54348
- * get 403); under `all_agents` the `agent_ids` must be empty. Every granted
54349
- * id must be an active agent of this org (else `400 INVALID_INPUT`).
54416
+ * get 403); under `all_agents` both lists must be empty; pass either
54417
+ * `agent_ids` (legacy flat form every agent gets `connection_scope: 'all'`)
54418
+ * or `grants` (connection-scoped), never both. Every granted id must be an
54419
+ * active agent of this org, and every `connection_ids` entry a connection of
54420
+ * THIS clip in this org (else `400 INVALID_INPUT`).
54350
54421
  */
54351
54422
  async putClipAgentExecAccess(orgId, clipId, access) {
54352
54423
  return this.request("PUT", ENDPOINTS.ORG_CLIP_EXEC_ACCESS(orgId, clipId), access);
@@ -54432,6 +54503,41 @@ var ParallClient = class _ParallClient extends TaskLabelClient {
54432
54503
  headers: expectedVersion ? { "If-Match": `"proxy-${expectedVersion}"` } : void 0
54433
54504
  });
54434
54505
  }
54506
+ /**
54507
+ * Read a hosted Cloud Profile's one-shot cookie-seed status (manager-only:
54508
+ * hosted human maintainer or org admin). Sanitized — cookie VALUES never come
54509
+ * back, only `cookie_count` and the distinct target `domains`. `can_mutate` /
54510
+ * `lease_status` are the authoritative idle gate. Typed errors: `EDGE_NOT_HOSTED`
54511
+ * (BYOC device), `NOT_FOUND` (unknown profile).
54512
+ */
54513
+ async getEdgeProfileCookieSeed(orgId, edgeId, profileName) {
54514
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILE_COOKIES(orgId, edgeId, profileName));
54515
+ }
54516
+ /**
54517
+ * Set/replace the profile's one-shot cookie seed (the full normalized cookie
54518
+ * array every time) — IDLE ONLY: while the profile's hosted browser is running
54519
+ * the server answers 409 `EDGE_PROFILE_IN_USE`; close the viewer, wait for idle
54520
+ * scale-to-zero, and retry. The next cold start injects the cookies into the
54521
+ * profile partition and consumes the seed. Other typed errors:
54522
+ * `EDGE_COOKIE_SEED_STALE` (409 — expectedVersion lost a tab race, sent as the
54523
+ * `cookieseed-<version>` If-Match), `EDGE_DELETING` (409), and
54524
+ * `SECRETBOX_UNCONFIGURED` (503 — server cannot store cookies safely).
54525
+ */
54526
+ async setEdgeProfileCookieSeed(orgId, edgeId, profileName, req, expectedVersion) {
54527
+ return this.request("PUT", ENDPOINTS.ORG_EDGE_PROFILE_COOKIES(orgId, edgeId, profileName), req, void 0, false, {
54528
+ headers: expectedVersion ? { "If-Match": `"cookieseed-${expectedVersion}"` } : void 0
54529
+ });
54530
+ }
54531
+ /**
54532
+ * Clear the pending cookie seed (does NOT sign the profile out — cookies
54533
+ * already injected into the partition stay). Idle-only like set — 409
54534
+ * `EDGE_PROFILE_IN_USE` while the browser is live.
54535
+ */
54536
+ async clearEdgeProfileCookieSeed(orgId, edgeId, profileName, expectedVersion) {
54537
+ return this.request("DELETE", ENDPOINTS.ORG_EDGE_PROFILE_COOKIES(orgId, edgeId, profileName), void 0, void 0, false, {
54538
+ headers: expectedVersion ? { "If-Match": `"cookieseed-${expectedVersion}"` } : void 0
54539
+ });
54540
+ }
54435
54541
  /**
54436
54542
  * Execute a registry clip command on an Edge device.
54437
54543
  *
@@ -59501,6 +59607,9 @@ function createPlatformConfigManager(opts) {
59501
59607
  };
59502
59608
  }
59503
59609
 
59610
+ // ts/agent-core/dist/generated/codex-message-delivery.js
59611
+ var PLATFORM_CODEX_MESSAGE_DELIVERY_INSTRUCTIONS = "### Codex message delivery\n\nCodex's native `commentary` and `final` prose is not a Parall message. The\nbridge records that prose only as a suppressed session step; nobody in the chat\nsees it. Tool calls made from `commentary` still execute, so use the shell/exec\ntool there to run the Parall CLI.\n\nThroughout these Parall instructions, \u201Creply\u201D, \u201Csay\u201D, \u201Cask\u201D, \u201Creport\u201D,\n\u201Cupdate\u201D, and \u201Ccommunicate\u201D mean creating a collaborator-visible Parall\nartifact through the CLI, never emitting runtime-native assistant prose.\n\nWhen the current event warrants a visible response, deliver acknowledgements,\nmeaningful progress, blockers or questions, requested status, and final results\nwith `parall messages send` or `parall dm`. Native `commentary` or `final` prose\ndoes not satisfy that communication requirement. A reply is delivered only\nafter the CLI command succeeds.\n\nDo not mirror every routine runtime commentary heartbeat into the chat. After a\nsuccessful send, native `final` output is only an audit record and does not need\nto duplicate the collaborator-visible message.";
59612
+
59504
59613
  // ts/agent-core/dist/skills/index.js
59505
59614
  import * as fs5 from "node:fs";
59506
59615
  import * as path5 from "node:path";
@@ -60516,6 +60625,7 @@ function parseTweets(data) { /* ... */ }
60516
60625
  - \`tab.cookie(name)\` \xB7 \`tab.fetch(url, opts)\` (in-browser fetch, carries the session)
60517
60626
  - \`tab.eval(expr)\` (escape hatch) \xB7 \`tab.click(sel)\` \xB7 \`tab.fill(sel, text)\` \xB7 \`tab.navigate(url)\`
60518
60627
  - \`tab.waitForSelector(sel)\` \xB7 \`tab.getTitle()\` \xB7 \`tab.getURL()\` \xB7 \`tab.screenshot()\` \xB7 \`tab.close()\`
60628
+ - \`tab.setFileInput(sel, url, opts?)\` \u2014 upload a file into an \`<input type=file>\`
60519
60629
  - \`fetch\` \u2014 runtime-side HTTP, does NOT go through the browser (no session)
60520
60630
  - \`console\` \u2014 logs \xB7 \`args\` \u2014 the invocation input
60521
60631
 
@@ -60524,6 +60634,40 @@ returns structured data; eval is the last resort. Always \`tab.close()\` what yo
60524
60634
  open, and do it in a \`finally\` \u2014 an early return or a thrown fetch is exactly
60525
60635
  when the tab leaks.
60526
60636
 
60637
+ ### Uploading a file
60638
+
60639
+ \`tab.setFileInput\` takes a URL, never a path, and the runtime \u2014 not the page \u2014
60640
+ fetches the bytes. That is what makes it work where an in-page \`fetch\` +
60641
+ \`DataTransfer\` cannot: upload targets ship a Content-Security-Policy that
60642
+ forbids the page from fetching an arbitrary file host (Instagram's \`default-src\`
60643
+ allows only its own domains), and you cannot change a header on their site. The
60644
+ runtime is not a page, so no CSP applies to it \u2014 and a large video never has to
60645
+ pass through the page's memory.
60646
+
60647
+ \`\`\`js
60648
+ await tab.setFileInput("input[type=file]", videoUrl, { filename: "clip.mp4" });
60649
+ await tab.click("button[type=submit]");
60650
+ await tab.waitForSelector(".upload-complete"); // \u2190 do not skip this
60651
+ \`\`\`
60652
+
60653
+ Four rules that decide whether your clip works:
60654
+
60655
+ 1. **The URL must be fetchable with no credentials** \u2014 a public direct link or a
60656
+ signed temporary one. The runtime sends no cookies, so a Drive or Feishu link
60657
+ copied from the address bar will not work: those are HTML pages behind a
60658
+ login. If the file needs a session, use a logged-in tab to obtain a signed
60659
+ direct link first, then pass THAT here. An HTML answer is refused with
60660
+ \`EDGE_FILE_SOURCE_NOT_A_FILE\` rather than uploaded as if it were a file.
60661
+ 2. **Finish the upload inside the same command.** The browser reads the file when
60662
+ the page submits, and the runtime deletes it when your command ends. Injecting
60663
+ and returning immediately uploads nothing \u2014 wait for the site to confirm.
60664
+ 3. **Main-document inputs only.** An input inside an iframe or a shadow root is
60665
+ not addressable and returns \`EDGE_FILE_SELECTOR_MISS\`. If the page rebuilds
60666
+ the input after you inject (navigation, re-render), inject again.
60667
+ 4. **\`opts.filename\` is what the page sees**, and many sites validate by
60668
+ extension \u2014 set it when the URL has none. \`opts.timeoutMs\` bounds the
60669
+ download. One file per call; there is no multi-file form yet.
60670
+
60527
60671
  ## Develop \u2192 publish \u2192 iterate
60528
60672
 
60529
60673
  Use the platform \`parall clip\` subcommands \u2014 they reuse the credentials you
@@ -60630,18 +60774,30 @@ and the folder is just a manifest:
60630
60774
  }
60631
60775
  \`\`\`
60632
60776
 
60633
- - The \`mcp\` block takes ONLY \`server_url\` and \`auth\` (\`"none" | "bearer" |
60634
- "api_key" | "oauth"\`). Any other key is refused at publish \u2014 a credential
60635
- belongs to the installing org's own configuration, NEVER to the clip
60636
- definition.
60777
+ - The \`mcp\` block takes ONLY \`server_url\`, \`auth\` (\`"none" | "api_key" |
60778
+ "basic" | "oauth"\`, legacy \`"bearer"\` accepted) and \`auth_headers\`. Any
60779
+ other key is refused at publish \u2014 a credential belongs to the installing
60780
+ org's own configuration, NEVER to the clip definition.
60781
+ - \`auth\` is REQUIRED at publish: you know what your server speaks, and this
60782
+ one word decides what the install form asks for (\`none\` = zero input,
60783
+ \`api_key\` = key field(s), \`basic\` = username + password, \`oauth\` = a
60784
+ Connect button).
60785
+ - \`api_key\` delivers as a single \`X-API-Key\` header by default. When the
60786
+ server wants a different shape, declare \`auth_headers\` (max 4 slots, one
60787
+ admin-supplied value each): \`[{"name": "Authorization", "scheme":
60788
+ "Bearer"}]\` for Bearer tokens, \`[{"name": "api-key"}]\` for a custom
60789
+ header, or a pair like \`[{"name": "CF-Access-Client-Id"}, {"name":
60790
+ "CF-Access-Client-Secret"}]\`. Framing/platform headers (Host, Cookie,
60791
+ X-Prll-*, \u2026) are refused.
60637
60792
  - \`server_url\` must be an absolute **https** URL with no embedded credentials,
60638
60793
  query, or fragment. It is review material, frozen with the approved version.
60794
+ It stays OPTIONAL for self-hosted products where each org connects its own
60795
+ instance URL.
60639
60796
  - Do NOT put the server in the top-level \`server\` / \`auth\` manifest keys \u2014
60640
60797
  those are legacy Edge-manifest fields nothing reads. Only the \`mcp\` block
60641
60798
  declares the server.
60642
- - Both fields are optional, but what you declare is LOCKED: the installing
60643
- org's config must match it, and changing the URL or auth mode means
60644
- republishing.
60799
+ - What you declare is LOCKED: the installing org's config must match it, and
60800
+ changing the URL, auth mode, or header shape means republishing.
60645
60801
  - Entering the credential / completing OAuth is a HUMAN step in the Clip
60646
60802
  Console (the config-write endpoints are session-only \u2014 an API key cannot
60647
60803
  call them). An org can add SEVERAL connections to one MCP clip \u2014 one
@@ -60727,14 +60883,17 @@ ${lines.join("\n")}
60727
60883
  }
60728
60884
 
60729
60885
  // ts/agent-core/dist/platform-instructions.js
60730
- function buildBridgePlatformInstructions(workspaceDir, identity, capabilityFragments) {
60886
+ function buildPlatformInstructions(workspaceDir, runtimeAppendix, identity, capabilityFragments) {
60731
60887
  return renderPlatformInstructions({
60732
60888
  identity,
60733
- runtimeAppendix: PLATFORM_BRIDGE_WORKSPACE_INSTRUCTIONS,
60889
+ runtimeAppendix,
60734
60890
  capabilityFragments,
60735
60891
  skillReferences: buildSkillReferences(workspaceDir)
60736
60892
  });
60737
60893
  }
60894
+ function buildCodexPlatformInstructions(workspaceDir, identity, capabilityFragments) {
60895
+ return buildPlatformInstructions(workspaceDir, [PLATFORM_BRIDGE_WORKSPACE_INSTRUCTIONS, PLATFORM_CODEX_MESSAGE_DELIVERY_INSTRUCTIONS].join("\n\n"), identity, capabilityFragments);
60896
+ }
60738
60897
 
60739
60898
  // ts/agent-core/dist/prompt-fragments.js
60740
60899
  function identityFromMe(me) {
@@ -63591,7 +63750,7 @@ function systemPromptCopyPath(workspaceDir) {
63591
63750
  return path11.join(workspaceDir, ".parall", "system-prompt.md");
63592
63751
  }
63593
63752
  function writeCodexSystemPrompt(workspaceDir, agentIdentity, capabilityFragments) {
63594
- const systemPrompt = buildBridgePlatformInstructions(workspaceDir, agentIdentity, capabilityFragments);
63753
+ const systemPrompt = buildCodexPlatformInstructions(workspaceDir, agentIdentity, capabilityFragments);
63595
63754
  fs10.mkdirSync(path11.join(workspaceDir, ".parall"), { recursive: true });
63596
63755
  fs10.writeFileSync(systemPromptCopyPath(workspaceDir), systemPrompt, "utf8");
63597
63756
  return systemPrompt;
@@ -354,6 +354,13 @@ var init_constants = __esm({
354
354
  PROJECTS: (orgId) => `${API_BASE}/orgs/${orgId}/projects`,
355
355
  PROJECT_TASK_SUMMARY: (orgId) => `${API_BASE}/orgs/${orgId}/projects/task-summary`,
356
356
  PROJECT: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}`,
357
+ PROJECT_MEMBERS: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/members`,
358
+ PROJECT_READERS: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/readers`,
359
+ PROJECT_LIBRARY: (orgId) => `${API_BASE}/orgs/${orgId}/projects/library`,
360
+ PROJECT_JOIN: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/join`,
361
+ PROJECT_JOIN_REQUESTS: (orgId, projectId) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/join-requests`,
362
+ // subject is a bare user ID or a bare team ID; both are path-segment safe.
363
+ PROJECT_MEMBER: (orgId, projectId, subject) => `${API_BASE}/orgs/${orgId}/projects/${projectId}/members/${subject}`,
357
364
  // Schedules (org-scoped, platform time trigger primitive)
358
365
  SCHEDULES: (orgId) => `${API_BASE}/orgs/${orgId}/schedules`,
359
366
  SCHEDULE: (orgId, id) => `${API_BASE}/orgs/${orgId}/schedules/${id}`,
@@ -571,6 +578,9 @@ var init_constants = __esm({
571
578
  ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
572
579
  // Per-profile egress proxy (hosted Cloud Profiles; manager-only, human-only).
573
580
  ORG_EDGE_PROFILE_PROXY: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/proxy`,
581
+ // Per-profile one-shot cookie seed (hosted Cloud Profiles; manager-only,
582
+ // human-only, idle-only). Injected at the next cold start, then consumed.
583
+ ORG_EDGE_PROFILE_COOKIES: (orgId, edgeId, profileName) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles/${encodeURIComponent(profileName)}/cookies`,
574
584
  ORG_EDGE_EXEC: (orgId) => `/api/v1/orgs/${orgId}/edge/exec`,
575
585
  // Cloud Edge live viewer command (V1b) — api-server, gated on cap:edge-viewer.
576
586
  // Same request/reply shape as the v2 browser-profile viewer, on the v3 edge
@@ -612,6 +622,7 @@ var init_constants = __esm({
612
622
  PONG: "pong",
613
623
  WATCHING: "watching",
614
624
  MESSAGE_NEW: "message.new",
625
+ /** @deprecated `message.patch` is retired and never published; kept for compile compatibility. */
615
626
  MESSAGE_PATCH: "message.patch",
616
627
  MESSAGE_EDIT: "message.edit",
617
628
  MESSAGE_DELETE: "message.delete",
@@ -814,6 +825,62 @@ var init_project_task_client = __esm({
814
825
  async deleteProject(orgId, projectId) {
815
826
  return this.request("DELETE", ENDPOINTS.PROJECT(orgId, projectId));
816
827
  }
828
+ /** Roster with display info; readable by anyone who can read the project. */
829
+ async getProjectMembers(orgId, projectId) {
830
+ const res = await this.request("GET", ENDPOINTS.PROJECT_MEMBERS(orgId, projectId));
831
+ return res.data;
832
+ }
833
+ /**
834
+ * User IDs who may read the project — the assignee-eligibility set. Every
835
+ * tier answers the roster expansion (direct, team-reached, org
836
+ * owners/admins); visibility only shapes admission, never reach.
837
+ */
838
+ async getProjectReaders(orgId, projectId) {
839
+ const res = await this.request("GET", ENDPOINTS.PROJECT_READERS(orgId, projectId));
840
+ return res.data;
841
+ }
842
+ /** The join library: every discoverable project (public + restricted, plus
843
+ * private for org owners/admins) with the caller's admission state. */
844
+ async getProjectLibrary(orgId) {
845
+ const res = await this.request("GET", ENDPOINTS.PROJECT_LIBRARY(orgId));
846
+ return res.data;
847
+ }
848
+ /** Public-tier self-admission: writes the caller's own member row.
849
+ * Other tiers answer `404 PROJECT_NOT_FOUND`; a duplicate answers
850
+ * `409 MEMBER_EXISTS`. */
851
+ async joinProject(orgId, projectId) {
852
+ return this.request("POST", ENDPOINTS.PROJECT_JOIN(orgId, projectId));
853
+ }
854
+ /** Restricted-tier admission petition. A pending duplicate answers
855
+ * `409 REQUEST_EXISTS`; membership answers `409 MEMBER_EXISTS`. */
856
+ async createProjectJoinRequest(orgId, projectId) {
857
+ return this.request("POST", ENDPOINTS.PROJECT_JOIN_REQUESTS(orgId, projectId));
858
+ }
859
+ /** Pending petitions for one project — manager standing required. */
860
+ async listProjectJoinRequests(orgId, projectId) {
861
+ const res = await this.request("GET", ENDPOINTS.PROJECT_JOIN_REQUESTS(orgId, projectId));
862
+ return res.data;
863
+ }
864
+ /** Withdraws the caller's own pending petition. */
865
+ async cancelProjectJoinRequest(orgId, projectId) {
866
+ return this.request("DELETE", ENDPOINTS.PROJECT_JOIN_REQUESTS(orgId, projectId));
867
+ }
868
+ /**
869
+ * Adds one subject (user ID or team ID) to the roster. Manager-only,
870
+ * create-only: an existing row answers `409 MEMBER_EXISTS` — change roles
871
+ * through updateProjectMember instead.
872
+ */
873
+ async addProjectMember(orgId, projectId, req) {
874
+ return this.request("POST", ENDPOINTS.PROJECT_MEMBERS(orgId, projectId), req);
875
+ }
876
+ /** Sets one roster entry's role. Demoting the last manager answers `400 LAST_MANAGER`. */
877
+ async updateProjectMember(orgId, projectId, subject, req) {
878
+ return this.request("PATCH", ENDPOINTS.PROJECT_MEMBER(orgId, projectId, subject), req);
879
+ }
880
+ /** Removes one roster entry. Removing the last manager answers `400 LAST_MANAGER`. */
881
+ async removeProjectMember(orgId, projectId, subject) {
882
+ return this.request("DELETE", ENDPOINTS.PROJECT_MEMBER(orgId, projectId, subject));
883
+ }
817
884
  };
818
885
  }
819
886
  });
@@ -1260,8 +1327,9 @@ var init_client = __esm({
1260
1327
  return this.request("POST", ENDPOINTS.TEAMS(orgId), req);
1261
1328
  }
1262
1329
  /**
1263
- * Renames a team. The slug cannot be changed — wiki ACL rows reference it as
1264
- * `@slug`, so the server answers 400 SLUG_IMMUTABLE if one is sent.
1330
+ * Renames a team. Renaming is an ordinary edit: ACL rows reference teams by
1331
+ * ID. Names are org-unique (case-insensitive); a duplicate answers 409
1332
+ * NAME_TAKEN.
1265
1333
  */
1266
1334
  async updateTeam(orgId, teamId, req) {
1267
1335
  return this.request("PATCH", ENDPOINTS.TEAM(orgId, teamId), req);
@@ -2890,15 +2958,18 @@ var init_client = __esm({
2890
2958
  /**
2891
2959
  * Read a clip's per-org agent exec access. Org-member readable (agents
2892
2960
  * included, so a denied agent can learn why exec answered
2893
- * `CLIP_AGENT_NOT_ALLOWED`).
2961
+ * `CLIP_AGENT_NOT_ALLOWED` / `CLIP_AGENT_CONNECTION_NOT_ALLOWED`).
2894
2962
  */
2895
2963
  async getClipAgentExecAccess(orgId, clipId) {
2896
2964
  return this.request("GET", ENDPOINTS.ORG_CLIP_EXEC_ACCESS(orgId, clipId));
2897
2965
  }
2898
2966
  /**
2899
2967
  * Replace a clip's per-org agent exec access. Human-only (agent principals
2900
- * get 403); under `all_agents` the `agent_ids` must be empty. Every granted
2901
- * id must be an active agent of this org (else `400 INVALID_INPUT`).
2968
+ * get 403); under `all_agents` both lists must be empty; pass either
2969
+ * `agent_ids` (legacy flat form every agent gets `connection_scope: 'all'`)
2970
+ * or `grants` (connection-scoped), never both. Every granted id must be an
2971
+ * active agent of this org, and every `connection_ids` entry a connection of
2972
+ * THIS clip in this org (else `400 INVALID_INPUT`).
2902
2973
  */
2903
2974
  async putClipAgentExecAccess(orgId, clipId, access) {
2904
2975
  return this.request("PUT", ENDPOINTS.ORG_CLIP_EXEC_ACCESS(orgId, clipId), access);
@@ -2984,6 +3055,41 @@ var init_client = __esm({
2984
3055
  headers: expectedVersion ? { "If-Match": `"proxy-${expectedVersion}"` } : void 0
2985
3056
  });
2986
3057
  }
3058
+ /**
3059
+ * Read a hosted Cloud Profile's one-shot cookie-seed status (manager-only:
3060
+ * hosted human maintainer or org admin). Sanitized — cookie VALUES never come
3061
+ * back, only `cookie_count` and the distinct target `domains`. `can_mutate` /
3062
+ * `lease_status` are the authoritative idle gate. Typed errors: `EDGE_NOT_HOSTED`
3063
+ * (BYOC device), `NOT_FOUND` (unknown profile).
3064
+ */
3065
+ async getEdgeProfileCookieSeed(orgId, edgeId, profileName) {
3066
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILE_COOKIES(orgId, edgeId, profileName));
3067
+ }
3068
+ /**
3069
+ * Set/replace the profile's one-shot cookie seed (the full normalized cookie
3070
+ * array every time) — IDLE ONLY: while the profile's hosted browser is running
3071
+ * the server answers 409 `EDGE_PROFILE_IN_USE`; close the viewer, wait for idle
3072
+ * scale-to-zero, and retry. The next cold start injects the cookies into the
3073
+ * profile partition and consumes the seed. Other typed errors:
3074
+ * `EDGE_COOKIE_SEED_STALE` (409 — expectedVersion lost a tab race, sent as the
3075
+ * `cookieseed-<version>` If-Match), `EDGE_DELETING` (409), and
3076
+ * `SECRETBOX_UNCONFIGURED` (503 — server cannot store cookies safely).
3077
+ */
3078
+ async setEdgeProfileCookieSeed(orgId, edgeId, profileName, req, expectedVersion) {
3079
+ return this.request("PUT", ENDPOINTS.ORG_EDGE_PROFILE_COOKIES(orgId, edgeId, profileName), req, void 0, false, {
3080
+ headers: expectedVersion ? { "If-Match": `"cookieseed-${expectedVersion}"` } : void 0
3081
+ });
3082
+ }
3083
+ /**
3084
+ * Clear the pending cookie seed (does NOT sign the profile out — cookies
3085
+ * already injected into the partition stay). Idle-only like set — 409
3086
+ * `EDGE_PROFILE_IN_USE` while the browser is live.
3087
+ */
3088
+ async clearEdgeProfileCookieSeed(orgId, edgeId, profileName, expectedVersion) {
3089
+ return this.request("DELETE", ENDPOINTS.ORG_EDGE_PROFILE_COOKIES(orgId, edgeId, profileName), void 0, void 0, false, {
3090
+ headers: expectedVersion ? { "If-Match": `"cookieseed-${expectedVersion}"` } : void 0
3091
+ });
3092
+ }
2987
3093
  /**
2988
3094
  * Execute a registry clip command on an Edge device.
2989
3095
  *
@@ -55014,6 +55120,13 @@ var init_platform_config = __esm({
55014
55120
  }
55015
55121
  });
55016
55122
 
55123
+ // ts/agent-core/dist/generated/codex-message-delivery.js
55124
+ var init_codex_message_delivery = __esm({
55125
+ "ts/agent-core/dist/generated/codex-message-delivery.js"() {
55126
+ "use strict";
55127
+ }
55128
+ });
55129
+
55017
55130
  // ts/agent-core/dist/skills/parall-platform.js
55018
55131
  var init_parall_platform = __esm({
55019
55132
  "ts/agent-core/dist/skills/parall-platform.js"() {
@@ -55088,8 +55201,10 @@ var init_skills = __esm({
55088
55201
  var init_platform_instructions2 = __esm({
55089
55202
  "ts/agent-core/dist/platform-instructions.js"() {
55090
55203
  "use strict";
55204
+ init_codex_message_delivery();
55091
55205
  init_platform_instructions();
55092
55206
  init_skills();
55207
+ init_codex_message_delivery();
55093
55208
  init_platform_instructions();
55094
55209
  }
55095
55210
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parall/daemon",
3
- "version": "1.55.0",
3
+ "version": "1.55.1",
4
4
  "description": "Parall local agent runtime — daemon supervisor + bridge runtimes, bundled as standalone JS files",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -33,11 +33,11 @@
33
33
  "@aws-sdk/client-s3": "3.984.0",
34
34
  "@pinixai/bb-browser-pro": "0.15.0",
35
35
  "ws": "^8.18.0",
36
- "@parall/agent-core": "1.55.0",
37
- "@parall/sdk": "1.55.0",
38
- "@parall/claude-agent": "1.55.0",
39
- "@parall/codex-agent": "1.55.0",
40
- "@parall/openclaw-agent": "1.55.0"
36
+ "@parall/sdk": "1.55.1",
37
+ "@parall/claude-agent": "1.55.1",
38
+ "@parall/codex-agent": "1.55.1",
39
+ "@parall/openclaw-agent": "1.55.1",
40
+ "@parall/agent-core": "1.55.1"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "^22.0.0",