@parall/daemon 1.38.0 → 1.40.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.
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.38.0",
3
- "built_at": "2026-07-06T10:59:40.316Z",
2
+ "version": "1.40.0",
3
+ "built_at": "2026-07-09T08:34:15.226Z",
4
4
  "min_node_version": "20.0.0",
5
5
  "files": {
6
6
  "bb-browser-daemon.js": {
@@ -16,25 +16,25 @@
16
16
  "size": 18
17
17
  },
18
18
  "parall-browser-pod.js": {
19
- "sha256": "9426af841c2011c341e28e03a0176da146e6c30da88878cc2e70f3211512e7e8",
20
- "size": 1697014
19
+ "sha256": "d3980c23446eeed7fd912cda4a198aee354387e3c5c4b2c7cc9bd1b24e3a1dcf",
20
+ "size": 1698869
21
21
  },
22
22
  "parall-claude-agent.js": {
23
- "sha256": "11436cabd17a19f2af8eb433a506efc6342efb76fbe25c8c882aea13220b5350",
24
- "size": 1616948
23
+ "sha256": "354ba346da7db4c5ced616c27bc0b04936b0231f1e78dd317c44cea4119d92eb",
24
+ "size": 1624014
25
25
  },
26
26
  "parall-codex-agent.js": {
27
- "sha256": "5d28aecbd029c64cd1402f748e12ae6bdf502ab38a21b95bb546407469e4d826",
28
- "size": 1647758
27
+ "sha256": "ad82b60f2758e8173f8124e71d6399a119764eccd51e73ddcbb2cff5e52ca5e9",
28
+ "size": 1654824
29
29
  },
30
30
  "parall-daemon.js": {
31
- "sha256": "0470fa07cce7477c70c075eb939e9e14b6dab40cfa4a6f609974c68f28537923",
32
- "size": 1717086
31
+ "sha256": "3d1bf453aedd04a896ca20970c92e7646fa7c76fba06d057e1f4a729cb153e2f",
32
+ "size": 1719122
33
33
  },
34
34
  "parall-openclaw-agent.js": {
35
35
  "sha256": "505433b4bf3a4b8dbb7b96978d8693d6c48079f4513282ff1ee59a6d13b3eddf",
36
36
  "size": 9801
37
37
  }
38
38
  },
39
- "signature": "bfGTE2slDSlantJRoa8j9CEENod1u89vVzhn0aFI29c+V9Lj2IuXdage/Mu3vfr+kDUYCisH9DPqBD6o7X4kDA=="
39
+ "signature": "Qjl/CNbyfJt4UfV4DxlPWA1/E3U+uppQdFASA+oV7h6b66j7NT+v57Ib4rNYcRSAtoj71e6Fx0e1ATvXLPeqDA=="
40
40
  }
@@ -35165,6 +35165,7 @@ var ENDPOINTS = {
35165
35165
  AGENT_MONITOR: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/monitor`,
35166
35166
  AGENT_ME: (orgId) => `${API_BASE}/orgs/${orgId}/agents/me`,
35167
35167
  AGENT_NEW_SESSION: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/new-session`,
35168
+ AGENT_DEEP_RESET: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/deep-reset`,
35168
35169
  AGENT_SESSIONS: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions`,
35169
35170
  AGENT_SESSION: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}`,
35170
35171
  AGENT_SESSION_STEPS: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}/steps`,
@@ -35422,7 +35423,13 @@ var ENDPOINTS = {
35422
35423
  // the machine control-plane request/reply bridge that lives in api-server.
35423
35424
  BROWSER_PROFILE_VIEWER_COMMAND: (orgId, profileId) => `${API_BASE}/orgs/${orgId}/browser-profiles/${profileId}/viewer/command`,
35424
35425
  // Clip registry (global, served by clip-service → Pinix Hub proxy)
35425
- CLIP_REGISTRY: () => `${CLIP_BASE}/registry/clips`
35426
+ CLIP_REGISTRY: () => `${CLIP_BASE}/registry/clips`,
35427
+ // Edge device endpoints
35428
+ ORG_EDGE_DEVICES: (orgId) => `/api/v1/orgs/${orgId}/edge/devices`,
35429
+ ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
35430
+ ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
35431
+ CLIP_CONNECTIONS: (orgId, clipId) => `/api/v1/orgs/${orgId}/clip-registry/${clipId}/connections`,
35432
+ CLIP_CONNECTION: (orgId, connId) => `/api/v1/orgs/${orgId}/clip-connections/${connId}`
35426
35433
  };
35427
35434
 
35428
35435
  // ts/sdk/dist/client.js
@@ -36058,6 +36065,17 @@ var ParallClient = class _ParallClient {
36058
36065
  async requestNewAgentSession(orgId, agentId) {
36059
36066
  return this.request("POST", ENDPOINTS.AGENT_NEW_SESSION(orgId, agentId));
36060
36067
  }
36068
+ /**
36069
+ * Wipe a managed agent's entity state — sandbox filesystem, AGENT.md,
36070
+ * long-term memory — while keeping the conversation line and channel
36071
+ * binding. The destructive counterpart of New Session under the
36072
+ * conversation/entity split (managed/parel agents only; 409 NOT_MIGRATED
36073
+ * for agents still on the legacy surface, 409 SHARED_AGENT for
36074
+ * multi-org memberships).
36075
+ */
36076
+ async deepResetAgent(orgId, agentId) {
36077
+ return this.request("POST", ENDPOINTS.AGENT_DEEP_RESET(orgId, agentId));
36078
+ }
36061
36079
  async createAgentSession(orgId, agentId, req) {
36062
36080
  return this.request("POST", ENDPOINTS.AGENT_SESSIONS(orgId, agentId), req);
36063
36081
  }
@@ -37167,6 +37185,26 @@ var ParallClient = class _ParallClient {
37167
37185
  const resp = await this.request("GET", url);
37168
37186
  return resp.data;
37169
37187
  }
37188
+ // ---- Edge devices ----
37189
+ async listEdgeDevices(orgId) {
37190
+ return this.request("GET", ENDPOINTS.ORG_EDGE_DEVICES(orgId));
37191
+ }
37192
+ async getEdgeOnboarding(orgId) {
37193
+ return this.request("GET", ENDPOINTS.ORG_EDGE_ONBOARDING(orgId));
37194
+ }
37195
+ async listEdgeProfiles(orgId, edgeId) {
37196
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
37197
+ }
37198
+ // ---- Clip connections ----
37199
+ async listClipConnections(orgId, clipId) {
37200
+ return this.request("GET", ENDPOINTS.CLIP_CONNECTIONS(orgId, clipId));
37201
+ }
37202
+ async createClipConnection(orgId, clipId, input) {
37203
+ return this.request("POST", ENDPOINTS.CLIP_CONNECTIONS(orgId, clipId), input);
37204
+ }
37205
+ async deleteClipConnection(orgId, connId) {
37206
+ return this.request("DELETE", ENDPOINTS.CLIP_CONNECTION(orgId, connId));
37207
+ }
37170
37208
  };
37171
37209
  function normalizeWikiChangeset(changeset) {
37172
37210
  return {
@@ -26711,6 +26711,10 @@ function buildSendMessageHint(event) {
26711
26711
  <system-reminder>To reply on ${where}, run: \`parall comments add --target "${event.replyTargetUri}" --body "..."\` (read the thread first with \`parall comments list --target "${event.replyTargetUri}"\`). To message someone instead, use \`parall messages send\` / \`parall dm\`. Your plain text output is not delivered.</system-reminder>`;
26712
26712
  }
26713
26713
  if (event.targetId.startsWith("cht_")) {
26714
+ if (event.threadRootId) {
26715
+ return `
26716
+ <system-reminder>To reply in this thread, run \`parall messages send prll://${event.targetId} --thread-root-id ${sanitizeMeta(event.threadRootId)} --text-file - <<'EOF'\` \u2026 \`EOF\` \u2014 the quoted heredoc keeps \`$\`, backticks and apostrophes literal (plain \`--text "$1,000"\` sends \`,000\`). Your plain text output is not delivered to the chat.</system-reminder>`;
26717
+ }
26714
26718
  return `
26715
26719
  <system-reminder>To reply, run \`parall messages send prll://${event.targetId} --text-file - <<'EOF'\` \u2026 \`EOF\` \u2014 the quoted heredoc keeps \`$\`, backticks and apostrophes literal (plain \`--text "$1,000"\` sends \`,000\`). Your plain text output is not delivered to the chat.</system-reminder>`;
26716
26720
  }
@@ -26803,6 +26807,10 @@ Don't wait for instructions. If you see the next step, take it. If something is
26803
26807
  ambiguous, clarify once and proceed. If you're blocked, say what's blocking you
26804
26808
  \u2014 don't go silent. Initiative is expected.
26805
26809
 
26810
+ Use schedules as self-reminders \u2014 re-checking blocked work, chasing unanswered
26811
+ requests, verifying something landed. When a thing needs future attention and
26812
+ nothing will prompt it, schedule it (load the \`parall-schedules\` skill).
26813
+
26806
26814
  ### Work in the open
26807
26815
  Nothing you do exists until the system can see it. Your progress, decisions,
26808
26816
  blockers, and results need to live in tasks, comments, messages, or wiki pages
@@ -26811,13 +26819,92 @@ who picks up where you left off. Leave traces as you go, not at the end.
26811
26819
 
26812
26820
  For non-trivial work: create or claim a task, mark it \`in_progress\`, comment
26813
26821
  when status materially changes, close it when done, and link the origin that
26814
- triggered it. Details: load the \`parall-tasks\` skill.
26822
+ triggered it. Decompose multi-step work into subtasks and keep their statuses
26823
+ current \u2014 progress should be auditable without watching the work happen.
26824
+ Details: load the \`parall-tasks\` skill.
26825
+
26826
+ ### Done means landed
26827
+ Producing output does not complete a task. Work counts as done only when it has
26828
+ cleared its remaining gates \u2014 review, merge, deployment, the requester's
26829
+ verification. Until then keep the status honest (\`in_progress\` or
26830
+ \`in_review\`), name the remaining gate in a comment, and chase it (schedule a
26831
+ self-reminder if nothing else will prompt follow-up). Never mark done what a
26832
+ human still has to accept.
26833
+
26834
+ ### Sessions, forks, and what survives
26835
+ Sessions end and context compacts. Anything that must survive \u2014 decisions,
26836
+ progress, constraints \u2014 belongs in tasks, comments, or wiki. Future sessions
26837
+ read the workspace, not this conversation.
26838
+
26839
+ Some events are handled by parallel fork sessions \u2014 short-lived copies of the
26840
+ same agent identity with separate context. In a fork: leave a written trace of
26841
+ what was done or deliberately not done (other sessions cannot see fork
26842
+ context), and do not start long-running processes \u2014 they die with the fork.
26843
+ When an event is marked fork-handled: do not re-handle it; verify its outcome
26844
+ instead of assuming it.
26815
26845
 
26816
26846
  ### Communicate like a teammate
26817
26847
  Match the conversation \u2014 concise in chat, thorough in docs, plain language over
26818
26848
  jargon. Say what matters; stop when you're done. Don't narrate every tool call
26819
26849
  or pad replies to seem thorough.
26820
26850
 
26851
+ Match the language of the person you're replying to. If someone writes in
26852
+ Chinese, reply in Chinese. If in English, reply in English. Never force a
26853
+ language switch unless explicitly asked.
26854
+
26855
+ Do not promise delivery times ("in an hour", "by tonight") unless the work is
26856
+ driven by an explicit schedule. Scope visibly; report when actually done.
26857
+
26858
+ ### Keep topics in threads
26859
+ Check for a \`[Thread: prll://msg_xxx]\` line before interpreting a message.
26860
+ Present \u2192 that thread is the context; reply there, passing the same root as
26861
+ \`--thread-root-id\`. Absent \u2192 the message belongs to the main conversation:
26862
+ never treat it as continuing your most recent thread. The sender's newest
26863
+ message is the anchor \u2014 never route a reply back into an older thread just
26864
+ because the topic used to live there.
26865
+
26866
+ Reply where the event lives: a thread message gets a thread reply, a
26867
+ top-level message gets a top-level reply. But in group chats, your later
26868
+ follow-up on that topic \u2014 progress updates, analysis, links, verification you
26869
+ post afterwards \u2014 belongs in a thread rooted at the topic's message
26870
+ (\`parall messages send <chat> --thread-root-id <msgId> --text-file -\`), so
26871
+ the main channel stays scannable. Post follow-up at top level only when
26872
+ starting a genuinely new topic, making a channel-wide announcement, or when
26873
+ explicitly asked. Never post the same update in both the thread and the main
26874
+ channel \u2014 thread replies surface in the thread panel; no need to duplicate
26875
+ for visibility.
26876
+
26877
+ In DMs, reply top-level by default; use a thread only to continue one that
26878
+ already exists.
26879
+
26880
+ ### Group chats: mentions and unaddressed work
26881
+ An @mention is a direct request \u2014 act on it. A group message delivered to you
26882
+ without an @mention means the chat's routing lets you see the conversation:
26883
+ decide whether a reply adds value; silence is the default.
26884
+
26885
+ A message without an @mention is not an open invitation. Judge from context
26886
+ who the work belongs to \u2014 the named domain, the topic's owner, whoever is
26887
+ already on it. If it belongs to someone else, leave it. If genuinely unclear,
26888
+ ask or claim in one line ("taking this unless someone else has it") before
26889
+ starting \u2014 asking first beats duplicated or misdirected work.
26890
+
26891
+ ### Verify before you act
26892
+ Events can be redelivered \u2014 before acting, check whether it was already
26893
+ handled (your own recent replies, task comments); if handled, do nothing.
26894
+ Sends can fail silently, and creates can error after succeeding server-side \u2014
26895
+ check the chat or entity before retrying. Never blind-retry a mutating call.
26896
+
26897
+ ### Gather the full picture first
26898
+ When a request is vague, an entity may already exist, or work may already be
26899
+ underway \u2014 gather context before acting: search (\`parall search "..."\`),
26900
+ check existing tasks/chats/wiki, read the surrounding conversation. Act on the
26901
+ full picture, not the fragment that arrived in the event.
26902
+
26903
+ ### Report only work that ran
26904
+ If a scheduled job, scan, or tool call did not actually run \u2014 restarted
26905
+ session, missing credentials, silent failure \u2014 say so plainly. Never fabricate
26906
+ or approximate results of work that did not execute.
26907
+
26821
26908
  ### Respect what's shared
26822
26909
  You have broad latitude inside your own work. But actions that are visible to
26823
26910
  others, hard to reverse, or touch shared state \u2014 sending DMs, editing shared
@@ -26916,6 +27003,15 @@ session already has continuity, so skip the fetch unless something is unclear.
26916
27003
  Same pattern for any other entity referenced in the event: \`tasks get\`,
26917
27004
  \`projects get\`, \`users get\`, \`chats get\`. Follow the reflink, don't ask.
26918
27005
 
27006
+ ### Find context with search first
27007
+
27008
+ Reach for unified semantic search before paging chat history:
27009
+
27010
+ parall search "pricing decision june" [--limit 10]
27011
+
27012
+ It spans messages, tasks, and wiki. Page \`messages list\` only for the verbatim
27013
+ recent flow of one chat, not for discovery.
27014
+
26919
27015
  ### File attachments
26920
27016
 
26921
27017
  Messages may include attachments. They appear in events as:
@@ -27005,6 +27101,8 @@ Keep \`--text "..."\` for short literals with no \`$\`, backtick, or apostrophe.
27005
27101
 
27006
27102
  The bridge injects Parall context via environment variables. The static credentials \`PRLL_API_URL\`, \`PRLL_API_KEY\`, and \`PRLL_ORG_ID\` are always set. \`PRLL_CONTEXT_FILE\` points to a per-session JSON file that the gateway updates each dispatch with \`session_id\`, \`chat_id\`, \`trigger_message_id\`, \`no_reply\`, and \`step_id\` (updated per tool call). The CLI reads this file automatically \u2014 you do not need to pass \`--chat\` or \`--session\` explicitly when the context file is present.
27007
27103
 
27104
+ CLI errors are agent-readable \u2014 read them; they usually name the next step.
27105
+
27008
27106
  ## Attachments
27009
27107
 
27010
27108
  Image attachments are pre-downloaded under \`.parall/attachments/<messageId>/\`. Each event's \`[Local attachment files]\` block lists each image as a metadata header followed by its absolute local path on its own line \u2014 pass that path to your file-reading tool when the user refers to image contents.
@@ -27031,29 +27129,6 @@ When you try an action (e.g., archive a chat) and receive a PERMISSION_DENIED er
27031
27129
  5. List available actions: \`parall approvals actions\`
27032
27130
 
27033
27131
  Only request approval when you've actually been denied permission. Don't request approval preemptively.
27034
-
27035
- ## Threads
27036
-
27037
- Messages may arrive with a \`[Thread: prll://msg_xxx]\` line in the event block, indicating the message is a reply inside a thread rooted at \`msg_xxx\`.
27038
-
27039
- ### When to use threads
27040
- - Replying to a specific message or continuing a focused sub-conversation
27041
- - Keeping detailed discussion (logs, debugging, follow-ups) out of the main channel flow
27042
- - When someone starts a thread with you, reply in the same thread
27043
-
27044
- ### When NOT to use threads
27045
- - Broadcasting status updates or announcements \u2014 use top-level messages
27046
- - Starting a new topic \u2014 post at top level, let others thread if needed
27047
-
27048
- ### CLI usage
27049
- - The \`msg_xxx\` from the \`[Thread: prll://msg_xxx]\` line is the thread root ID \u2014 pass it as \`--thread-root-id\`
27050
- - Reply in a thread: \`parall messages send <chatId> --text-file /tmp/reply.md --thread-root-id <msgId>\`
27051
- - Read thread replies: \`parall messages list <chatId> --thread-root-id <msgId>\`
27052
-
27053
- ### Thread etiquette
27054
- - If your trigger message is in a thread, reply in that thread by default
27055
- - Don't duplicate thread content to the channel unless explicitly asked
27056
- - Keep thread replies focused on the original topic
27057
27132
  `;
27058
27133
  function extractShellCommand(input) {
27059
27134
  if (!input || typeof input !== "object")
@@ -27100,6 +27175,11 @@ function isParallNoReplyCommand(command) {
27100
27175
  return sub?.[0] === "no-reply";
27101
27176
  }
27102
27177
 
27178
+ // ts/agent-core/dist/dispatch-adapter.js
27179
+ function buildErrorStepContent(message) {
27180
+ return { text: message, suppressed: false, status: "error" };
27181
+ }
27182
+
27103
27183
  // ts/agent-core/dist/logger.js
27104
27184
  function createLogger(prefix) {
27105
27185
  return {
@@ -27200,6 +27280,7 @@ var ENDPOINTS = {
27200
27280
  AGENT_MONITOR: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/monitor`,
27201
27281
  AGENT_ME: (orgId) => `${API_BASE}/orgs/${orgId}/agents/me`,
27202
27282
  AGENT_NEW_SESSION: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/new-session`,
27283
+ AGENT_DEEP_RESET: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/deep-reset`,
27203
27284
  AGENT_SESSIONS: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions`,
27204
27285
  AGENT_SESSION: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}`,
27205
27286
  AGENT_SESSION_STEPS: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}/steps`,
@@ -27457,7 +27538,13 @@ var ENDPOINTS = {
27457
27538
  // the machine control-plane request/reply bridge that lives in api-server.
27458
27539
  BROWSER_PROFILE_VIEWER_COMMAND: (orgId, profileId) => `${API_BASE}/orgs/${orgId}/browser-profiles/${profileId}/viewer/command`,
27459
27540
  // Clip registry (global, served by clip-service → Pinix Hub proxy)
27460
- CLIP_REGISTRY: () => `${CLIP_BASE}/registry/clips`
27541
+ CLIP_REGISTRY: () => `${CLIP_BASE}/registry/clips`,
27542
+ // Edge device endpoints
27543
+ ORG_EDGE_DEVICES: (orgId) => `/api/v1/orgs/${orgId}/edge/devices`,
27544
+ ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
27545
+ ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
27546
+ CLIP_CONNECTIONS: (orgId, clipId) => `/api/v1/orgs/${orgId}/clip-registry/${clipId}/connections`,
27547
+ CLIP_CONNECTION: (orgId, connId) => `/api/v1/orgs/${orgId}/clip-connections/${connId}`
27461
27548
  };
27462
27549
  var WS_EVENTS = {
27463
27550
  // Client -> Server
@@ -28177,6 +28264,17 @@ var ParallClient = class _ParallClient {
28177
28264
  async requestNewAgentSession(orgId, agentId) {
28178
28265
  return this.request("POST", ENDPOINTS.AGENT_NEW_SESSION(orgId, agentId));
28179
28266
  }
28267
+ /**
28268
+ * Wipe a managed agent's entity state — sandbox filesystem, AGENT.md,
28269
+ * long-term memory — while keeping the conversation line and channel
28270
+ * binding. The destructive counterpart of New Session under the
28271
+ * conversation/entity split (managed/parel agents only; 409 NOT_MIGRATED
28272
+ * for agents still on the legacy surface, 409 SHARED_AGENT for
28273
+ * multi-org memberships).
28274
+ */
28275
+ async deepResetAgent(orgId, agentId) {
28276
+ return this.request("POST", ENDPOINTS.AGENT_DEEP_RESET(orgId, agentId));
28277
+ }
28180
28278
  async createAgentSession(orgId, agentId, req) {
28181
28279
  return this.request("POST", ENDPOINTS.AGENT_SESSIONS(orgId, agentId), req);
28182
28280
  }
@@ -29286,6 +29384,26 @@ var ParallClient = class _ParallClient {
29286
29384
  const resp = await this.request("GET", url);
29287
29385
  return resp.data;
29288
29386
  }
29387
+ // ---- Edge devices ----
29388
+ async listEdgeDevices(orgId) {
29389
+ return this.request("GET", ENDPOINTS.ORG_EDGE_DEVICES(orgId));
29390
+ }
29391
+ async getEdgeOnboarding(orgId) {
29392
+ return this.request("GET", ENDPOINTS.ORG_EDGE_ONBOARDING(orgId));
29393
+ }
29394
+ async listEdgeProfiles(orgId, edgeId) {
29395
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
29396
+ }
29397
+ // ---- Clip connections ----
29398
+ async listClipConnections(orgId, clipId) {
29399
+ return this.request("GET", ENDPOINTS.CLIP_CONNECTIONS(orgId, clipId));
29400
+ }
29401
+ async createClipConnection(orgId, clipId, input) {
29402
+ return this.request("POST", ENDPOINTS.CLIP_CONNECTIONS(orgId, clipId), input);
29403
+ }
29404
+ async deleteClipConnection(orgId, connId) {
29405
+ return this.request("DELETE", ENDPOINTS.CLIP_CONNECTION(orgId, connId));
29406
+ }
29289
29407
  };
29290
29408
  function normalizeWikiChangeset(changeset) {
29291
29409
  return {
@@ -30772,7 +30890,7 @@ var ParallAgentGateway = class {
30772
30890
  step_type: "text",
30773
30891
  target_type: target.target_type,
30774
30892
  target_id: target.target_id,
30775
- content: { text: runtimeEvent.message, suppressed: false },
30893
+ content: buildErrorStepContent(runtimeEvent.message),
30776
30894
  projection: false
30777
30895
  });
30778
30896
  break;
@@ -32699,20 +32817,20 @@ parall projects list
32699
32817
 
32700
32818
  ## Watching Tasks
32701
32819
 
32702
- Subscribe to a task to receive notifications when others comment on it.
32820
+ Watchers receive dispatch events for a task's new comments. Acting on a task
32821
+ auto-subscribes you \u2014 creating it, being assigned, commenting, being
32822
+ @mentioned, or substantively editing it (description / assignee). Handle or
32823
+ dismiss those comment events deliberately.
32703
32824
 
32704
32825
  \`\`\`bash
32705
- # Watch a task (you'll receive dispatch events for new comments)
32706
- parall tasks watch prll://tsk_xxx
32707
-
32708
- # Unwatch
32709
- parall tasks unwatch prll://tsk_xxx
32710
-
32711
- # List who is watching
32712
- parall tasks watchers prll://tsk_xxx
32826
+ parall tasks watch prll://tsk_xxx # follow a task without acting on it
32827
+ parall tasks unwatch prll://tsk_xxx # opt out of a task's comment events
32828
+ parall tasks watchers prll://tsk_xxx # list who is watching
32713
32829
  \`\`\`
32714
32830
 
32715
- Note: task creators are automatically watching their tasks.
32831
+ Creators and assignees are locked subscribers \u2014 \`unwatch\` returns 409 for
32832
+ them until the role changes (e.g. reassignment); it works for every other
32833
+ watcher.
32716
32834
 
32717
32835
  ## Responding to Task Assignments
32718
32836
 
@@ -32721,7 +32839,9 @@ When you receive \`[Event: task.assigned]\`:
32721
32839
  1. Acknowledge with a comment: \`tasks comments add prll://tsk_xxx --body "On it"\`
32722
32840
  2. Update status: \`tasks update prll://tsk_xxx --status in_progress\`
32723
32841
  3. Do the work
32724
- 4. Report results via comment and update status to \`done\`
32842
+ 4. Report results in a comment. If a gate remains \u2014 review, merge, deploy,
32843
+ requester acceptance \u2014 set \`in_review\` and name the gate; set \`done\`
32844
+ only once the work has actually landed
32725
32845
 
32726
32846
  ## Responding to Task Comments
32727
32847
 
@@ -32908,6 +33028,18 @@ parall wiki reset <wiki> # discard ALL local edits, restore last-synced state
32908
33028
  parall wiki status <wiki> # local changes + your changesets, anytime
32909
33029
  \`\`\`
32910
33030
 
33031
+ ## Changeset Discipline
33032
+
33033
+ - Creation is fail-closed \u2014 without explicit CLI confirmation of success,
33034
+ assume nothing was created; check before retrying to avoid duplicates.
33035
+ - Read the outcome feedback after proposing changes; do not assume a merge
33036
+ happened.
33037
+ - Terminal changesets (merged / closed) are immutable \u2014 open a new changeset
33038
+ instead of re-merging or re-closing.
33039
+ - Respect path scopes \u2014 some wiki paths are access-restricted.
33040
+ PERMISSION_DENIED on a path means it is not yours to edit; follow the
33041
+ error, don't work around it.
33042
+
32911
33043
  CLI success output is JSON on stdout (human summary on stderr); errors state
32912
33044
  the reason and the next step \u2014 follow them. \`parall wiki --help\` for the
32913
33045
  full command list.
@@ -32953,6 +33085,14 @@ parall schedules create \\
32953
33085
 
32954
33086
  \`--target-ids\` is who receives the fire (usually yourself when you're self-scheduling; another agent or human when delegating). \`--attached-to-uri\` optionally anchors the schedule to a task / chat / project / wiki page \u2014 when that resource is archived or deleted, the schedule auto-cancels (\`cancel_reason=attached_gone\`).
32955
33087
 
33088
+ ### Reminders for someone else
33089
+
33090
+ When someone asks you to remind them (or a third person), put that person in
33091
+ \`--target-ids\` \u2014 the fire is delivered to its targets, so a reminder
33092
+ targeting only yourself never reaches them. The schedule record stays yours as
33093
+ creator (there is no owner transfer); add yourself as an additional target
33094
+ only if you also need to act at fire time.
33095
+
32956
33096
  ## Listing / inspecting
32957
33097
 
32958
33098
  \`\`\`bash
@@ -33088,47 +33228,37 @@ CLI command results are JSON on stdout; mutation commands may emit auxiliary hin
33088
33228
  // ts/agent-core/dist/skills/parall-clips.js
33089
33229
  var PARALL_CLIPS_SKILL = `# Parall Clips
33090
33230
 
33091
- Clips are capability extensions \u2014 packaged toolkits that give you extra commands (e.g. GitHub operations, web search, code analysis). Clips installed in the org are available for any agent to invoke via the CLI.
33231
+ Clips are packaged capabilities that let agents operate external systems \u2014
33232
+ APIs and websites \u2014 through named commands installed in the org.
33092
33233
 
33093
- ## Discovering available clips
33234
+ ## Discover
33094
33235
 
33095
33236
  \`\`\`bash
33096
- # List all clips installed in the org
33097
- parall clip list
33098
-
33099
- # Show detailed info about a clip (manifest, commands, version)
33100
- parall clip info <alias>
33237
+ parall clip list # clips installed in this org
33238
+ parall clip info <alias> # commands, params, version
33101
33239
  \`\`\`
33102
33240
 
33103
- ## Invoking a clip command
33241
+ ## Invoke
33104
33242
 
33105
33243
  \`\`\`bash
33106
- # Invoke a command on a clip by alias
33107
- parall clip invoke <alias> <command> [input]
33108
-
33109
- # input is optional \u2014 when provided, it can be a JSON string or plain text
33110
- parall clip invoke github-tools list-repos '{"org": "acme"}'
33111
- parall clip invoke web-search search "latest Node.js LTS version"
33112
-
33113
- # Custom timeout (default 30s)
33114
- parall clip invoke github-tools create-issue '{"title": "Bug report"}' --timeout 60000
33244
+ parall clip invoke <alias> <command> [input] [--timeout <ms>] # timeout default 30s
33245
+ # input: JSON string or plain text, per the command's params in \`info\`
33246
+ parall clip invoke github-tools list-repos '{"org":"acme"}'
33115
33247
  \`\`\`
33116
33248
 
33117
- ## How clips work
33118
-
33119
- 1. An org admin installs a clip from the Pinix registry or creates a custom one
33120
- 2. \`parall clip list\` shows every clip installed in the org
33121
- 3. You can only **invoke** clips that an admin has **bound to you** \u2014 invoking an unbound clip returns a "not bound" error. Ask an admin to bind the clip if you need it.
33122
- 4. Each clip exposes one or more named commands with typed input/output
33123
-
33124
- ## When to use clips
33249
+ Results are JSON on stdout; failures print an error.
33125
33250
 
33126
- - Check \`parall clip list\` when a task requires capabilities beyond your built-in tools (e.g. GitHub API, external services, specialized analysis)
33127
- - Use \`parall clip info <alias>\` to discover available commands and their expected input format
33128
- - If \`parall clip invoke\` reports the clip isn't bound to you, that clip exists in the org but hasn't been granted to you \u2014 ask an admin to bind it
33129
- - Clip invocations return JSON output on success or an error message on failure
33251
+ ## Behavior rules
33130
33252
 
33131
- CLI command results are JSON on stdout.
33253
+ - An authorization error (clip not bound to you) is a fail-fast: ask the
33254
+ clip's owner or an admin to bind it \u2014 do not retry or work around it.
33255
+ - If the executing runtime is offline or the call times out, report that
33256
+ plainly; do not queue, and never fabricate a result for a run that errored.
33257
+ - A clip may act through a person's real logged-in account \u2014 outward,
33258
+ irreversible, or spending actions (post, order, delete, pay) get the same
33259
+ caution as any shared-state change: confirm when intent isn't explicit.
33260
+ - Reach for \`parall clip list\` whenever a task needs capabilities beyond
33261
+ built-in tools.
33132
33262
  `;
33133
33263
 
33134
33264
  // ts/agent-core/dist/skills/index.js
@@ -26711,6 +26711,10 @@ function buildSendMessageHint(event) {
26711
26711
  <system-reminder>To reply on ${where}, run: \`parall comments add --target "${event.replyTargetUri}" --body "..."\` (read the thread first with \`parall comments list --target "${event.replyTargetUri}"\`). To message someone instead, use \`parall messages send\` / \`parall dm\`. Your plain text output is not delivered.</system-reminder>`;
26712
26712
  }
26713
26713
  if (event.targetId.startsWith("cht_")) {
26714
+ if (event.threadRootId) {
26715
+ return `
26716
+ <system-reminder>To reply in this thread, run \`parall messages send prll://${event.targetId} --thread-root-id ${sanitizeMeta(event.threadRootId)} --text-file - <<'EOF'\` \u2026 \`EOF\` \u2014 the quoted heredoc keeps \`$\`, backticks and apostrophes literal (plain \`--text "$1,000"\` sends \`,000\`). Your plain text output is not delivered to the chat.</system-reminder>`;
26717
+ }
26714
26718
  return `
26715
26719
  <system-reminder>To reply, run \`parall messages send prll://${event.targetId} --text-file - <<'EOF'\` \u2026 \`EOF\` \u2014 the quoted heredoc keeps \`$\`, backticks and apostrophes literal (plain \`--text "$1,000"\` sends \`,000\`). Your plain text output is not delivered to the chat.</system-reminder>`;
26716
26720
  }
@@ -26803,6 +26807,10 @@ Don't wait for instructions. If you see the next step, take it. If something is
26803
26807
  ambiguous, clarify once and proceed. If you're blocked, say what's blocking you
26804
26808
  \u2014 don't go silent. Initiative is expected.
26805
26809
 
26810
+ Use schedules as self-reminders \u2014 re-checking blocked work, chasing unanswered
26811
+ requests, verifying something landed. When a thing needs future attention and
26812
+ nothing will prompt it, schedule it (load the \`parall-schedules\` skill).
26813
+
26806
26814
  ### Work in the open
26807
26815
  Nothing you do exists until the system can see it. Your progress, decisions,
26808
26816
  blockers, and results need to live in tasks, comments, messages, or wiki pages
@@ -26811,13 +26819,92 @@ who picks up where you left off. Leave traces as you go, not at the end.
26811
26819
 
26812
26820
  For non-trivial work: create or claim a task, mark it \`in_progress\`, comment
26813
26821
  when status materially changes, close it when done, and link the origin that
26814
- triggered it. Details: load the \`parall-tasks\` skill.
26822
+ triggered it. Decompose multi-step work into subtasks and keep their statuses
26823
+ current \u2014 progress should be auditable without watching the work happen.
26824
+ Details: load the \`parall-tasks\` skill.
26825
+
26826
+ ### Done means landed
26827
+ Producing output does not complete a task. Work counts as done only when it has
26828
+ cleared its remaining gates \u2014 review, merge, deployment, the requester's
26829
+ verification. Until then keep the status honest (\`in_progress\` or
26830
+ \`in_review\`), name the remaining gate in a comment, and chase it (schedule a
26831
+ self-reminder if nothing else will prompt follow-up). Never mark done what a
26832
+ human still has to accept.
26833
+
26834
+ ### Sessions, forks, and what survives
26835
+ Sessions end and context compacts. Anything that must survive \u2014 decisions,
26836
+ progress, constraints \u2014 belongs in tasks, comments, or wiki. Future sessions
26837
+ read the workspace, not this conversation.
26838
+
26839
+ Some events are handled by parallel fork sessions \u2014 short-lived copies of the
26840
+ same agent identity with separate context. In a fork: leave a written trace of
26841
+ what was done or deliberately not done (other sessions cannot see fork
26842
+ context), and do not start long-running processes \u2014 they die with the fork.
26843
+ When an event is marked fork-handled: do not re-handle it; verify its outcome
26844
+ instead of assuming it.
26815
26845
 
26816
26846
  ### Communicate like a teammate
26817
26847
  Match the conversation \u2014 concise in chat, thorough in docs, plain language over
26818
26848
  jargon. Say what matters; stop when you're done. Don't narrate every tool call
26819
26849
  or pad replies to seem thorough.
26820
26850
 
26851
+ Match the language of the person you're replying to. If someone writes in
26852
+ Chinese, reply in Chinese. If in English, reply in English. Never force a
26853
+ language switch unless explicitly asked.
26854
+
26855
+ Do not promise delivery times ("in an hour", "by tonight") unless the work is
26856
+ driven by an explicit schedule. Scope visibly; report when actually done.
26857
+
26858
+ ### Keep topics in threads
26859
+ Check for a \`[Thread: prll://msg_xxx]\` line before interpreting a message.
26860
+ Present \u2192 that thread is the context; reply there, passing the same root as
26861
+ \`--thread-root-id\`. Absent \u2192 the message belongs to the main conversation:
26862
+ never treat it as continuing your most recent thread. The sender's newest
26863
+ message is the anchor \u2014 never route a reply back into an older thread just
26864
+ because the topic used to live there.
26865
+
26866
+ Reply where the event lives: a thread message gets a thread reply, a
26867
+ top-level message gets a top-level reply. But in group chats, your later
26868
+ follow-up on that topic \u2014 progress updates, analysis, links, verification you
26869
+ post afterwards \u2014 belongs in a thread rooted at the topic's message
26870
+ (\`parall messages send <chat> --thread-root-id <msgId> --text-file -\`), so
26871
+ the main channel stays scannable. Post follow-up at top level only when
26872
+ starting a genuinely new topic, making a channel-wide announcement, or when
26873
+ explicitly asked. Never post the same update in both the thread and the main
26874
+ channel \u2014 thread replies surface in the thread panel; no need to duplicate
26875
+ for visibility.
26876
+
26877
+ In DMs, reply top-level by default; use a thread only to continue one that
26878
+ already exists.
26879
+
26880
+ ### Group chats: mentions and unaddressed work
26881
+ An @mention is a direct request \u2014 act on it. A group message delivered to you
26882
+ without an @mention means the chat's routing lets you see the conversation:
26883
+ decide whether a reply adds value; silence is the default.
26884
+
26885
+ A message without an @mention is not an open invitation. Judge from context
26886
+ who the work belongs to \u2014 the named domain, the topic's owner, whoever is
26887
+ already on it. If it belongs to someone else, leave it. If genuinely unclear,
26888
+ ask or claim in one line ("taking this unless someone else has it") before
26889
+ starting \u2014 asking first beats duplicated or misdirected work.
26890
+
26891
+ ### Verify before you act
26892
+ Events can be redelivered \u2014 before acting, check whether it was already
26893
+ handled (your own recent replies, task comments); if handled, do nothing.
26894
+ Sends can fail silently, and creates can error after succeeding server-side \u2014
26895
+ check the chat or entity before retrying. Never blind-retry a mutating call.
26896
+
26897
+ ### Gather the full picture first
26898
+ When a request is vague, an entity may already exist, or work may already be
26899
+ underway \u2014 gather context before acting: search (\`parall search "..."\`),
26900
+ check existing tasks/chats/wiki, read the surrounding conversation. Act on the
26901
+ full picture, not the fragment that arrived in the event.
26902
+
26903
+ ### Report only work that ran
26904
+ If a scheduled job, scan, or tool call did not actually run \u2014 restarted
26905
+ session, missing credentials, silent failure \u2014 say so plainly. Never fabricate
26906
+ or approximate results of work that did not execute.
26907
+
26821
26908
  ### Respect what's shared
26822
26909
  You have broad latitude inside your own work. But actions that are visible to
26823
26910
  others, hard to reverse, or touch shared state \u2014 sending DMs, editing shared
@@ -26916,6 +27003,15 @@ session already has continuity, so skip the fetch unless something is unclear.
26916
27003
  Same pattern for any other entity referenced in the event: \`tasks get\`,
26917
27004
  \`projects get\`, \`users get\`, \`chats get\`. Follow the reflink, don't ask.
26918
27005
 
27006
+ ### Find context with search first
27007
+
27008
+ Reach for unified semantic search before paging chat history:
27009
+
27010
+ parall search "pricing decision june" [--limit 10]
27011
+
27012
+ It spans messages, tasks, and wiki. Page \`messages list\` only for the verbatim
27013
+ recent flow of one chat, not for discovery.
27014
+
26919
27015
  ### File attachments
26920
27016
 
26921
27017
  Messages may include attachments. They appear in events as:
@@ -27005,6 +27101,8 @@ Keep \`--text "..."\` for short literals with no \`$\`, backtick, or apostrophe.
27005
27101
 
27006
27102
  The bridge injects Parall context via environment variables. The static credentials \`PRLL_API_URL\`, \`PRLL_API_KEY\`, and \`PRLL_ORG_ID\` are always set. \`PRLL_CONTEXT_FILE\` points to a per-session JSON file that the gateway updates each dispatch with \`session_id\`, \`chat_id\`, \`trigger_message_id\`, \`no_reply\`, and \`step_id\` (updated per tool call). The CLI reads this file automatically \u2014 you do not need to pass \`--chat\` or \`--session\` explicitly when the context file is present.
27007
27103
 
27104
+ CLI errors are agent-readable \u2014 read them; they usually name the next step.
27105
+
27008
27106
  ## Attachments
27009
27107
 
27010
27108
  Image attachments are pre-downloaded under \`.parall/attachments/<messageId>/\`. Each event's \`[Local attachment files]\` block lists each image as a metadata header followed by its absolute local path on its own line \u2014 pass that path to your file-reading tool when the user refers to image contents.
@@ -27031,29 +27129,6 @@ When you try an action (e.g., archive a chat) and receive a PERMISSION_DENIED er
27031
27129
  5. List available actions: \`parall approvals actions\`
27032
27130
 
27033
27131
  Only request approval when you've actually been denied permission. Don't request approval preemptively.
27034
-
27035
- ## Threads
27036
-
27037
- Messages may arrive with a \`[Thread: prll://msg_xxx]\` line in the event block, indicating the message is a reply inside a thread rooted at \`msg_xxx\`.
27038
-
27039
- ### When to use threads
27040
- - Replying to a specific message or continuing a focused sub-conversation
27041
- - Keeping detailed discussion (logs, debugging, follow-ups) out of the main channel flow
27042
- - When someone starts a thread with you, reply in the same thread
27043
-
27044
- ### When NOT to use threads
27045
- - Broadcasting status updates or announcements \u2014 use top-level messages
27046
- - Starting a new topic \u2014 post at top level, let others thread if needed
27047
-
27048
- ### CLI usage
27049
- - The \`msg_xxx\` from the \`[Thread: prll://msg_xxx]\` line is the thread root ID \u2014 pass it as \`--thread-root-id\`
27050
- - Reply in a thread: \`parall messages send <chatId> --text-file /tmp/reply.md --thread-root-id <msgId>\`
27051
- - Read thread replies: \`parall messages list <chatId> --thread-root-id <msgId>\`
27052
-
27053
- ### Thread etiquette
27054
- - If your trigger message is in a thread, reply in that thread by default
27055
- - Don't duplicate thread content to the channel unless explicitly asked
27056
- - Keep thread replies focused on the original topic
27057
27132
  `;
27058
27133
  function extractShellCommand(input) {
27059
27134
  if (!input || typeof input !== "object")
@@ -27100,6 +27175,11 @@ function isParallNoReplyCommand(command) {
27100
27175
  return sub?.[0] === "no-reply";
27101
27176
  }
27102
27177
 
27178
+ // ts/agent-core/dist/dispatch-adapter.js
27179
+ function buildErrorStepContent(message) {
27180
+ return { text: message, suppressed: false, status: "error" };
27181
+ }
27182
+
27103
27183
  // ts/agent-core/dist/logger.js
27104
27184
  function createLogger(prefix) {
27105
27185
  return {
@@ -27200,6 +27280,7 @@ var ENDPOINTS = {
27200
27280
  AGENT_MONITOR: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/monitor`,
27201
27281
  AGENT_ME: (orgId) => `${API_BASE}/orgs/${orgId}/agents/me`,
27202
27282
  AGENT_NEW_SESSION: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/new-session`,
27283
+ AGENT_DEEP_RESET: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/deep-reset`,
27203
27284
  AGENT_SESSIONS: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions`,
27204
27285
  AGENT_SESSION: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}`,
27205
27286
  AGENT_SESSION_STEPS: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}/steps`,
@@ -27457,7 +27538,13 @@ var ENDPOINTS = {
27457
27538
  // the machine control-plane request/reply bridge that lives in api-server.
27458
27539
  BROWSER_PROFILE_VIEWER_COMMAND: (orgId, profileId) => `${API_BASE}/orgs/${orgId}/browser-profiles/${profileId}/viewer/command`,
27459
27540
  // Clip registry (global, served by clip-service → Pinix Hub proxy)
27460
- CLIP_REGISTRY: () => `${CLIP_BASE}/registry/clips`
27541
+ CLIP_REGISTRY: () => `${CLIP_BASE}/registry/clips`,
27542
+ // Edge device endpoints
27543
+ ORG_EDGE_DEVICES: (orgId) => `/api/v1/orgs/${orgId}/edge/devices`,
27544
+ ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
27545
+ ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
27546
+ CLIP_CONNECTIONS: (orgId, clipId) => `/api/v1/orgs/${orgId}/clip-registry/${clipId}/connections`,
27547
+ CLIP_CONNECTION: (orgId, connId) => `/api/v1/orgs/${orgId}/clip-connections/${connId}`
27461
27548
  };
27462
27549
  var WS_EVENTS = {
27463
27550
  // Client -> Server
@@ -28177,6 +28264,17 @@ var ParallClient = class _ParallClient {
28177
28264
  async requestNewAgentSession(orgId, agentId) {
28178
28265
  return this.request("POST", ENDPOINTS.AGENT_NEW_SESSION(orgId, agentId));
28179
28266
  }
28267
+ /**
28268
+ * Wipe a managed agent's entity state — sandbox filesystem, AGENT.md,
28269
+ * long-term memory — while keeping the conversation line and channel
28270
+ * binding. The destructive counterpart of New Session under the
28271
+ * conversation/entity split (managed/parel agents only; 409 NOT_MIGRATED
28272
+ * for agents still on the legacy surface, 409 SHARED_AGENT for
28273
+ * multi-org memberships).
28274
+ */
28275
+ async deepResetAgent(orgId, agentId) {
28276
+ return this.request("POST", ENDPOINTS.AGENT_DEEP_RESET(orgId, agentId));
28277
+ }
28180
28278
  async createAgentSession(orgId, agentId, req) {
28181
28279
  return this.request("POST", ENDPOINTS.AGENT_SESSIONS(orgId, agentId), req);
28182
28280
  }
@@ -29286,6 +29384,26 @@ var ParallClient = class _ParallClient {
29286
29384
  const resp = await this.request("GET", url);
29287
29385
  return resp.data;
29288
29386
  }
29387
+ // ---- Edge devices ----
29388
+ async listEdgeDevices(orgId) {
29389
+ return this.request("GET", ENDPOINTS.ORG_EDGE_DEVICES(orgId));
29390
+ }
29391
+ async getEdgeOnboarding(orgId) {
29392
+ return this.request("GET", ENDPOINTS.ORG_EDGE_ONBOARDING(orgId));
29393
+ }
29394
+ async listEdgeProfiles(orgId, edgeId) {
29395
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
29396
+ }
29397
+ // ---- Clip connections ----
29398
+ async listClipConnections(orgId, clipId) {
29399
+ return this.request("GET", ENDPOINTS.CLIP_CONNECTIONS(orgId, clipId));
29400
+ }
29401
+ async createClipConnection(orgId, clipId, input) {
29402
+ return this.request("POST", ENDPOINTS.CLIP_CONNECTIONS(orgId, clipId), input);
29403
+ }
29404
+ async deleteClipConnection(orgId, connId) {
29405
+ return this.request("DELETE", ENDPOINTS.CLIP_CONNECTION(orgId, connId));
29406
+ }
29289
29407
  };
29290
29408
  function normalizeWikiChangeset(changeset) {
29291
29409
  return {
@@ -30772,7 +30890,7 @@ var ParallAgentGateway = class {
30772
30890
  step_type: "text",
30773
30891
  target_type: target.target_type,
30774
30892
  target_id: target.target_id,
30775
- content: { text: runtimeEvent.message, suppressed: false },
30893
+ content: buildErrorStepContent(runtimeEvent.message),
30776
30894
  projection: false
30777
30895
  });
30778
30896
  break;
@@ -32699,20 +32817,20 @@ parall projects list
32699
32817
 
32700
32818
  ## Watching Tasks
32701
32819
 
32702
- Subscribe to a task to receive notifications when others comment on it.
32820
+ Watchers receive dispatch events for a task's new comments. Acting on a task
32821
+ auto-subscribes you \u2014 creating it, being assigned, commenting, being
32822
+ @mentioned, or substantively editing it (description / assignee). Handle or
32823
+ dismiss those comment events deliberately.
32703
32824
 
32704
32825
  \`\`\`bash
32705
- # Watch a task (you'll receive dispatch events for new comments)
32706
- parall tasks watch prll://tsk_xxx
32707
-
32708
- # Unwatch
32709
- parall tasks unwatch prll://tsk_xxx
32710
-
32711
- # List who is watching
32712
- parall tasks watchers prll://tsk_xxx
32826
+ parall tasks watch prll://tsk_xxx # follow a task without acting on it
32827
+ parall tasks unwatch prll://tsk_xxx # opt out of a task's comment events
32828
+ parall tasks watchers prll://tsk_xxx # list who is watching
32713
32829
  \`\`\`
32714
32830
 
32715
- Note: task creators are automatically watching their tasks.
32831
+ Creators and assignees are locked subscribers \u2014 \`unwatch\` returns 409 for
32832
+ them until the role changes (e.g. reassignment); it works for every other
32833
+ watcher.
32716
32834
 
32717
32835
  ## Responding to Task Assignments
32718
32836
 
@@ -32721,7 +32839,9 @@ When you receive \`[Event: task.assigned]\`:
32721
32839
  1. Acknowledge with a comment: \`tasks comments add prll://tsk_xxx --body "On it"\`
32722
32840
  2. Update status: \`tasks update prll://tsk_xxx --status in_progress\`
32723
32841
  3. Do the work
32724
- 4. Report results via comment and update status to \`done\`
32842
+ 4. Report results in a comment. If a gate remains \u2014 review, merge, deploy,
32843
+ requester acceptance \u2014 set \`in_review\` and name the gate; set \`done\`
32844
+ only once the work has actually landed
32725
32845
 
32726
32846
  ## Responding to Task Comments
32727
32847
 
@@ -32908,6 +33028,18 @@ parall wiki reset <wiki> # discard ALL local edits, restore last-synced state
32908
33028
  parall wiki status <wiki> # local changes + your changesets, anytime
32909
33029
  \`\`\`
32910
33030
 
33031
+ ## Changeset Discipline
33032
+
33033
+ - Creation is fail-closed \u2014 without explicit CLI confirmation of success,
33034
+ assume nothing was created; check before retrying to avoid duplicates.
33035
+ - Read the outcome feedback after proposing changes; do not assume a merge
33036
+ happened.
33037
+ - Terminal changesets (merged / closed) are immutable \u2014 open a new changeset
33038
+ instead of re-merging or re-closing.
33039
+ - Respect path scopes \u2014 some wiki paths are access-restricted.
33040
+ PERMISSION_DENIED on a path means it is not yours to edit; follow the
33041
+ error, don't work around it.
33042
+
32911
33043
  CLI success output is JSON on stdout (human summary on stderr); errors state
32912
33044
  the reason and the next step \u2014 follow them. \`parall wiki --help\` for the
32913
33045
  full command list.
@@ -32953,6 +33085,14 @@ parall schedules create \\
32953
33085
 
32954
33086
  \`--target-ids\` is who receives the fire (usually yourself when you're self-scheduling; another agent or human when delegating). \`--attached-to-uri\` optionally anchors the schedule to a task / chat / project / wiki page \u2014 when that resource is archived or deleted, the schedule auto-cancels (\`cancel_reason=attached_gone\`).
32955
33087
 
33088
+ ### Reminders for someone else
33089
+
33090
+ When someone asks you to remind them (or a third person), put that person in
33091
+ \`--target-ids\` \u2014 the fire is delivered to its targets, so a reminder
33092
+ targeting only yourself never reaches them. The schedule record stays yours as
33093
+ creator (there is no owner transfer); add yourself as an additional target
33094
+ only if you also need to act at fire time.
33095
+
32956
33096
  ## Listing / inspecting
32957
33097
 
32958
33098
  \`\`\`bash
@@ -33088,47 +33228,37 @@ CLI command results are JSON on stdout; mutation commands may emit auxiliary hin
33088
33228
  // ts/agent-core/dist/skills/parall-clips.js
33089
33229
  var PARALL_CLIPS_SKILL = `# Parall Clips
33090
33230
 
33091
- Clips are capability extensions \u2014 packaged toolkits that give you extra commands (e.g. GitHub operations, web search, code analysis). Clips installed in the org are available for any agent to invoke via the CLI.
33231
+ Clips are packaged capabilities that let agents operate external systems \u2014
33232
+ APIs and websites \u2014 through named commands installed in the org.
33092
33233
 
33093
- ## Discovering available clips
33234
+ ## Discover
33094
33235
 
33095
33236
  \`\`\`bash
33096
- # List all clips installed in the org
33097
- parall clip list
33098
-
33099
- # Show detailed info about a clip (manifest, commands, version)
33100
- parall clip info <alias>
33237
+ parall clip list # clips installed in this org
33238
+ parall clip info <alias> # commands, params, version
33101
33239
  \`\`\`
33102
33240
 
33103
- ## Invoking a clip command
33241
+ ## Invoke
33104
33242
 
33105
33243
  \`\`\`bash
33106
- # Invoke a command on a clip by alias
33107
- parall clip invoke <alias> <command> [input]
33108
-
33109
- # input is optional \u2014 when provided, it can be a JSON string or plain text
33110
- parall clip invoke github-tools list-repos '{"org": "acme"}'
33111
- parall clip invoke web-search search "latest Node.js LTS version"
33112
-
33113
- # Custom timeout (default 30s)
33114
- parall clip invoke github-tools create-issue '{"title": "Bug report"}' --timeout 60000
33244
+ parall clip invoke <alias> <command> [input] [--timeout <ms>] # timeout default 30s
33245
+ # input: JSON string or plain text, per the command's params in \`info\`
33246
+ parall clip invoke github-tools list-repos '{"org":"acme"}'
33115
33247
  \`\`\`
33116
33248
 
33117
- ## How clips work
33118
-
33119
- 1. An org admin installs a clip from the Pinix registry or creates a custom one
33120
- 2. \`parall clip list\` shows every clip installed in the org
33121
- 3. You can only **invoke** clips that an admin has **bound to you** \u2014 invoking an unbound clip returns a "not bound" error. Ask an admin to bind the clip if you need it.
33122
- 4. Each clip exposes one or more named commands with typed input/output
33123
-
33124
- ## When to use clips
33249
+ Results are JSON on stdout; failures print an error.
33125
33250
 
33126
- - Check \`parall clip list\` when a task requires capabilities beyond your built-in tools (e.g. GitHub API, external services, specialized analysis)
33127
- - Use \`parall clip info <alias>\` to discover available commands and their expected input format
33128
- - If \`parall clip invoke\` reports the clip isn't bound to you, that clip exists in the org but hasn't been granted to you \u2014 ask an admin to bind it
33129
- - Clip invocations return JSON output on success or an error message on failure
33251
+ ## Behavior rules
33130
33252
 
33131
- CLI command results are JSON on stdout.
33253
+ - An authorization error (clip not bound to you) is a fail-fast: ask the
33254
+ clip's owner or an admin to bind it \u2014 do not retry or work around it.
33255
+ - If the executing runtime is offline or the call times out, report that
33256
+ plainly; do not queue, and never fabricate a result for a run that errored.
33257
+ - A clip may act through a person's real logged-in account \u2014 outward,
33258
+ irreversible, or spending actions (post, order, delete, pay) get the same
33259
+ caution as any shared-state change: confirm when intent isn't explicit.
33260
+ - Reach for \`parall clip list\` whenever a task needs capabilities beyond
33261
+ built-in tools.
33132
33262
  `;
33133
33263
 
33134
33264
  // ts/agent-core/dist/skills/index.js
@@ -266,6 +266,7 @@ var init_constants = __esm({
266
266
  AGENT_MONITOR: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/monitor`,
267
267
  AGENT_ME: (orgId) => `${API_BASE}/orgs/${orgId}/agents/me`,
268
268
  AGENT_NEW_SESSION: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/new-session`,
269
+ AGENT_DEEP_RESET: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/deep-reset`,
269
270
  AGENT_SESSIONS: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions`,
270
271
  AGENT_SESSION: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}`,
271
272
  AGENT_SESSION_STEPS: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}/steps`,
@@ -523,7 +524,13 @@ var init_constants = __esm({
523
524
  // the machine control-plane request/reply bridge that lives in api-server.
524
525
  BROWSER_PROFILE_VIEWER_COMMAND: (orgId, profileId) => `${API_BASE}/orgs/${orgId}/browser-profiles/${profileId}/viewer/command`,
525
526
  // Clip registry (global, served by clip-service → Pinix Hub proxy)
526
- CLIP_REGISTRY: () => `${CLIP_BASE}/registry/clips`
527
+ CLIP_REGISTRY: () => `${CLIP_BASE}/registry/clips`,
528
+ // Edge device endpoints
529
+ ORG_EDGE_DEVICES: (orgId) => `/api/v1/orgs/${orgId}/edge/devices`,
530
+ ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
531
+ ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
532
+ CLIP_CONNECTIONS: (orgId, clipId) => `/api/v1/orgs/${orgId}/clip-registry/${clipId}/connections`,
533
+ CLIP_CONNECTION: (orgId, connId) => `/api/v1/orgs/${orgId}/clip-connections/${connId}`
527
534
  };
528
535
  WS_EVENTS = {
529
536
  // Client -> Server
@@ -1284,6 +1291,17 @@ var init_client = __esm({
1284
1291
  async requestNewAgentSession(orgId, agentId) {
1285
1292
  return this.request("POST", ENDPOINTS.AGENT_NEW_SESSION(orgId, agentId));
1286
1293
  }
1294
+ /**
1295
+ * Wipe a managed agent's entity state — sandbox filesystem, AGENT.md,
1296
+ * long-term memory — while keeping the conversation line and channel
1297
+ * binding. The destructive counterpart of New Session under the
1298
+ * conversation/entity split (managed/parel agents only; 409 NOT_MIGRATED
1299
+ * for agents still on the legacy surface, 409 SHARED_AGENT for
1300
+ * multi-org memberships).
1301
+ */
1302
+ async deepResetAgent(orgId, agentId) {
1303
+ return this.request("POST", ENDPOINTS.AGENT_DEEP_RESET(orgId, agentId));
1304
+ }
1287
1305
  async createAgentSession(orgId, agentId, req) {
1288
1306
  return this.request("POST", ENDPOINTS.AGENT_SESSIONS(orgId, agentId), req);
1289
1307
  }
@@ -2393,6 +2411,26 @@ var init_client = __esm({
2393
2411
  const resp = await this.request("GET", url);
2394
2412
  return resp.data;
2395
2413
  }
2414
+ // ---- Edge devices ----
2415
+ async listEdgeDevices(orgId) {
2416
+ return this.request("GET", ENDPOINTS.ORG_EDGE_DEVICES(orgId));
2417
+ }
2418
+ async getEdgeOnboarding(orgId) {
2419
+ return this.request("GET", ENDPOINTS.ORG_EDGE_ONBOARDING(orgId));
2420
+ }
2421
+ async listEdgeProfiles(orgId, edgeId) {
2422
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
2423
+ }
2424
+ // ---- Clip connections ----
2425
+ async listClipConnections(orgId, clipId) {
2426
+ return this.request("GET", ENDPOINTS.CLIP_CONNECTIONS(orgId, clipId));
2427
+ }
2428
+ async createClipConnection(orgId, clipId, input) {
2429
+ return this.request("POST", ENDPOINTS.CLIP_CONNECTIONS(orgId, clipId), input);
2430
+ }
2431
+ async deleteClipConnection(orgId, connId) {
2432
+ return this.request("DELETE", ENDPOINTS.CLIP_CONNECTION(orgId, connId));
2433
+ }
2396
2434
  };
2397
2435
  ApiError = class extends Error {
2398
2436
  status;
@@ -29324,6 +29362,7 @@ var init_gateway_base = __esm({
29324
29362
  "use strict";
29325
29363
  init_dist();
29326
29364
  init_event_format();
29365
+ init_dispatch_adapter();
29327
29366
  init_gateway_lane_flow();
29328
29367
  init_lane_ledger();
29329
29368
  init_routing();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parall/daemon",
3
- "version": "1.38.0",
3
+ "version": "1.40.0",
4
4
  "description": "Parall local agent runtime — daemon supervisor + bridge runtimes, bundled as standalone JS files",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -32,11 +32,11 @@
32
32
  "dependencies": {
33
33
  "@aws-sdk/client-s3": "3.984.0",
34
34
  "@pinixai/bb-browser-pro": "0.15.0",
35
- "@parall/agent-core": "1.38.0",
36
- "@parall/sdk": "1.38.0",
37
- "@parall/claude-agent": "1.38.0",
38
- "@parall/codex-agent": "1.38.0",
39
- "@parall/openclaw-agent": "1.38.0"
35
+ "@parall/sdk": "1.40.0",
36
+ "@parall/agent-core": "1.40.0",
37
+ "@parall/claude-agent": "1.40.0",
38
+ "@parall/codex-agent": "1.40.0",
39
+ "@parall/openclaw-agent": "1.40.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/node": "^22.0.0",