@parall/parall 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.
@@ -26723,6 +26723,10 @@ function buildSendMessageHint(event) {
26723
26723
  <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>`;
26724
26724
  }
26725
26725
  if (event.targetId.startsWith("cht_")) {
26726
+ if (event.threadRootId) {
26727
+ return `
26728
+ <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>`;
26729
+ }
26726
26730
  return `
26727
26731
  <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>`;
26728
26732
  }
@@ -26815,6 +26819,10 @@ Don't wait for instructions. If you see the next step, take it. If something is
26815
26819
  ambiguous, clarify once and proceed. If you're blocked, say what's blocking you
26816
26820
  \u2014 don't go silent. Initiative is expected.
26817
26821
 
26822
+ Use schedules as self-reminders \u2014 re-checking blocked work, chasing unanswered
26823
+ requests, verifying something landed. When a thing needs future attention and
26824
+ nothing will prompt it, schedule it (load the \`parall-schedules\` skill).
26825
+
26818
26826
  ### Work in the open
26819
26827
  Nothing you do exists until the system can see it. Your progress, decisions,
26820
26828
  blockers, and results need to live in tasks, comments, messages, or wiki pages
@@ -26823,13 +26831,92 @@ who picks up where you left off. Leave traces as you go, not at the end.
26823
26831
 
26824
26832
  For non-trivial work: create or claim a task, mark it \`in_progress\`, comment
26825
26833
  when status materially changes, close it when done, and link the origin that
26826
- triggered it. Details: load the \`parall-tasks\` skill.
26834
+ triggered it. Decompose multi-step work into subtasks and keep their statuses
26835
+ current \u2014 progress should be auditable without watching the work happen.
26836
+ Details: load the \`parall-tasks\` skill.
26837
+
26838
+ ### Done means landed
26839
+ Producing output does not complete a task. Work counts as done only when it has
26840
+ cleared its remaining gates \u2014 review, merge, deployment, the requester's
26841
+ verification. Until then keep the status honest (\`in_progress\` or
26842
+ \`in_review\`), name the remaining gate in a comment, and chase it (schedule a
26843
+ self-reminder if nothing else will prompt follow-up). Never mark done what a
26844
+ human still has to accept.
26845
+
26846
+ ### Sessions, forks, and what survives
26847
+ Sessions end and context compacts. Anything that must survive \u2014 decisions,
26848
+ progress, constraints \u2014 belongs in tasks, comments, or wiki. Future sessions
26849
+ read the workspace, not this conversation.
26850
+
26851
+ Some events are handled by parallel fork sessions \u2014 short-lived copies of the
26852
+ same agent identity with separate context. In a fork: leave a written trace of
26853
+ what was done or deliberately not done (other sessions cannot see fork
26854
+ context), and do not start long-running processes \u2014 they die with the fork.
26855
+ When an event is marked fork-handled: do not re-handle it; verify its outcome
26856
+ instead of assuming it.
26827
26857
 
26828
26858
  ### Communicate like a teammate
26829
26859
  Match the conversation \u2014 concise in chat, thorough in docs, plain language over
26830
26860
  jargon. Say what matters; stop when you're done. Don't narrate every tool call
26831
26861
  or pad replies to seem thorough.
26832
26862
 
26863
+ Match the language of the person you're replying to. If someone writes in
26864
+ Chinese, reply in Chinese. If in English, reply in English. Never force a
26865
+ language switch unless explicitly asked.
26866
+
26867
+ Do not promise delivery times ("in an hour", "by tonight") unless the work is
26868
+ driven by an explicit schedule. Scope visibly; report when actually done.
26869
+
26870
+ ### Keep topics in threads
26871
+ Check for a \`[Thread: prll://msg_xxx]\` line before interpreting a message.
26872
+ Present \u2192 that thread is the context; reply there, passing the same root as
26873
+ \`--thread-root-id\`. Absent \u2192 the message belongs to the main conversation:
26874
+ never treat it as continuing your most recent thread. The sender's newest
26875
+ message is the anchor \u2014 never route a reply back into an older thread just
26876
+ because the topic used to live there.
26877
+
26878
+ Reply where the event lives: a thread message gets a thread reply, a
26879
+ top-level message gets a top-level reply. But in group chats, your later
26880
+ follow-up on that topic \u2014 progress updates, analysis, links, verification you
26881
+ post afterwards \u2014 belongs in a thread rooted at the topic's message
26882
+ (\`parall messages send <chat> --thread-root-id <msgId> --text-file -\`), so
26883
+ the main channel stays scannable. Post follow-up at top level only when
26884
+ starting a genuinely new topic, making a channel-wide announcement, or when
26885
+ explicitly asked. Never post the same update in both the thread and the main
26886
+ channel \u2014 thread replies surface in the thread panel; no need to duplicate
26887
+ for visibility.
26888
+
26889
+ In DMs, reply top-level by default; use a thread only to continue one that
26890
+ already exists.
26891
+
26892
+ ### Group chats: mentions and unaddressed work
26893
+ An @mention is a direct request \u2014 act on it. A group message delivered to you
26894
+ without an @mention means the chat's routing lets you see the conversation:
26895
+ decide whether a reply adds value; silence is the default.
26896
+
26897
+ A message without an @mention is not an open invitation. Judge from context
26898
+ who the work belongs to \u2014 the named domain, the topic's owner, whoever is
26899
+ already on it. If it belongs to someone else, leave it. If genuinely unclear,
26900
+ ask or claim in one line ("taking this unless someone else has it") before
26901
+ starting \u2014 asking first beats duplicated or misdirected work.
26902
+
26903
+ ### Verify before you act
26904
+ Events can be redelivered \u2014 before acting, check whether it was already
26905
+ handled (your own recent replies, task comments); if handled, do nothing.
26906
+ Sends can fail silently, and creates can error after succeeding server-side \u2014
26907
+ check the chat or entity before retrying. Never blind-retry a mutating call.
26908
+
26909
+ ### Gather the full picture first
26910
+ When a request is vague, an entity may already exist, or work may already be
26911
+ underway \u2014 gather context before acting: search (\`parall search "..."\`),
26912
+ check existing tasks/chats/wiki, read the surrounding conversation. Act on the
26913
+ full picture, not the fragment that arrived in the event.
26914
+
26915
+ ### Report only work that ran
26916
+ If a scheduled job, scan, or tool call did not actually run \u2014 restarted
26917
+ session, missing credentials, silent failure \u2014 say so plainly. Never fabricate
26918
+ or approximate results of work that did not execute.
26919
+
26833
26920
  ### Respect what's shared
26834
26921
  You have broad latitude inside your own work. But actions that are visible to
26835
26922
  others, hard to reverse, or touch shared state \u2014 sending DMs, editing shared
@@ -26928,6 +27015,15 @@ session already has continuity, so skip the fetch unless something is unclear.
26928
27015
  Same pattern for any other entity referenced in the event: \`tasks get\`,
26929
27016
  \`projects get\`, \`users get\`, \`chats get\`. Follow the reflink, don't ask.
26930
27017
 
27018
+ ### Find context with search first
27019
+
27020
+ Reach for unified semantic search before paging chat history:
27021
+
27022
+ parall search "pricing decision june" [--limit 10]
27023
+
27024
+ It spans messages, tasks, and wiki. Page \`messages list\` only for the verbatim
27025
+ recent flow of one chat, not for discovery.
27026
+
26931
27027
  ### File attachments
26932
27028
 
26933
27029
  Messages may include attachments. They appear in events as:
@@ -27029,6 +27125,11 @@ function isParallNoReplyCommand(command) {
27029
27125
  return sub?.[0] === "no-reply";
27030
27126
  }
27031
27127
 
27128
+ // ../agent-core/dist/dispatch-adapter.js
27129
+ function buildErrorStepContent(message) {
27130
+ return { text: message, suppressed: false, status: "error" };
27131
+ }
27132
+
27032
27133
  // ../agent-core/dist/gateway-base.js
27033
27134
  import * as os from "node:os";
27034
27135
  import * as fs2 from "node:fs";
@@ -27116,6 +27217,7 @@ var ENDPOINTS = {
27116
27217
  AGENT_MONITOR: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/monitor`,
27117
27218
  AGENT_ME: (orgId) => `${API_BASE}/orgs/${orgId}/agents/me`,
27118
27219
  AGENT_NEW_SESSION: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/new-session`,
27220
+ AGENT_DEEP_RESET: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/deep-reset`,
27119
27221
  AGENT_SESSIONS: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions`,
27120
27222
  AGENT_SESSION: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}`,
27121
27223
  AGENT_SESSION_STEPS: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}/steps`,
@@ -27373,7 +27475,13 @@ var ENDPOINTS = {
27373
27475
  // the machine control-plane request/reply bridge that lives in api-server.
27374
27476
  BROWSER_PROFILE_VIEWER_COMMAND: (orgId, profileId) => `${API_BASE}/orgs/${orgId}/browser-profiles/${profileId}/viewer/command`,
27375
27477
  // Clip registry (global, served by clip-service → Pinix Hub proxy)
27376
- CLIP_REGISTRY: () => `${CLIP_BASE}/registry/clips`
27478
+ CLIP_REGISTRY: () => `${CLIP_BASE}/registry/clips`,
27479
+ // Edge device endpoints
27480
+ ORG_EDGE_DEVICES: (orgId) => `/api/v1/orgs/${orgId}/edge/devices`,
27481
+ ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
27482
+ ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
27483
+ CLIP_CONNECTIONS: (orgId, clipId) => `/api/v1/orgs/${orgId}/clip-registry/${clipId}/connections`,
27484
+ CLIP_CONNECTION: (orgId, connId) => `/api/v1/orgs/${orgId}/clip-connections/${connId}`
27377
27485
  };
27378
27486
  var WS_EVENTS = {
27379
27487
  // Client -> Server
@@ -28093,6 +28201,17 @@ var ParallClient = class _ParallClient {
28093
28201
  async requestNewAgentSession(orgId, agentId) {
28094
28202
  return this.request("POST", ENDPOINTS.AGENT_NEW_SESSION(orgId, agentId));
28095
28203
  }
28204
+ /**
28205
+ * Wipe a managed agent's entity state — sandbox filesystem, AGENT.md,
28206
+ * long-term memory — while keeping the conversation line and channel
28207
+ * binding. The destructive counterpart of New Session under the
28208
+ * conversation/entity split (managed/parel agents only; 409 NOT_MIGRATED
28209
+ * for agents still on the legacy surface, 409 SHARED_AGENT for
28210
+ * multi-org memberships).
28211
+ */
28212
+ async deepResetAgent(orgId, agentId) {
28213
+ return this.request("POST", ENDPOINTS.AGENT_DEEP_RESET(orgId, agentId));
28214
+ }
28096
28215
  async createAgentSession(orgId, agentId, req) {
28097
28216
  return this.request("POST", ENDPOINTS.AGENT_SESSIONS(orgId, agentId), req);
28098
28217
  }
@@ -29202,6 +29321,26 @@ var ParallClient = class _ParallClient {
29202
29321
  const resp = await this.request("GET", url);
29203
29322
  return resp.data;
29204
29323
  }
29324
+ // ---- Edge devices ----
29325
+ async listEdgeDevices(orgId) {
29326
+ return this.request("GET", ENDPOINTS.ORG_EDGE_DEVICES(orgId));
29327
+ }
29328
+ async getEdgeOnboarding(orgId) {
29329
+ return this.request("GET", ENDPOINTS.ORG_EDGE_ONBOARDING(orgId));
29330
+ }
29331
+ async listEdgeProfiles(orgId, edgeId) {
29332
+ return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
29333
+ }
29334
+ // ---- Clip connections ----
29335
+ async listClipConnections(orgId, clipId) {
29336
+ return this.request("GET", ENDPOINTS.CLIP_CONNECTIONS(orgId, clipId));
29337
+ }
29338
+ async createClipConnection(orgId, clipId, input) {
29339
+ return this.request("POST", ENDPOINTS.CLIP_CONNECTIONS(orgId, clipId), input);
29340
+ }
29341
+ async deleteClipConnection(orgId, connId) {
29342
+ return this.request("DELETE", ENDPOINTS.CLIP_CONNECTION(orgId, connId));
29343
+ }
29205
29344
  };
29206
29345
  function normalizeWikiChangeset(changeset) {
29207
29346
  return {
@@ -30688,7 +30827,7 @@ var ParallAgentGateway = class {
30688
30827
  step_type: "text",
30689
30828
  target_type: target.target_type,
30690
30829
  target_id: target.target_id,
30691
- content: { text: runtimeEvent.message, suppressed: false },
30830
+ content: buildErrorStepContent(runtimeEvent.message),
30692
30831
  projection: false
30693
30832
  });
30694
30833
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parall/parall",
3
- "version": "1.38.0",
3
+ "version": "1.40.0",
4
4
  "description": "OpenClaw channel plugin for Parall IM",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -16,8 +16,8 @@
16
16
  "openclaw.plugin.json"
17
17
  ],
18
18
  "dependencies": {
19
- "@parall/sdk": "1.38.0",
20
- "@parall/agent-core": "1.38.0"
19
+ "@parall/agent-core": "1.40.0",
20
+ "@parall/sdk": "1.40.0"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/node": "^22.0.0",
@@ -5,44 +5,34 @@ description: "Parall clip operations: list installed clips, invoke clip commands
5
5
 
6
6
  # Parall Clips
7
7
 
8
- Clips are capability extensions — 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.
8
+ Clips are packaged capabilities that let agents operate external systems
9
+ APIs and websites — through named commands installed in the org.
9
10
 
10
- ## Discovering available clips
11
+ ## Discover
11
12
 
12
13
  ```bash
13
- # List all clips installed in the org
14
- parall clip list
15
-
16
- # Show detailed info about a clip (manifest, commands, version)
17
- parall clip info <alias>
14
+ parall clip list # clips installed in this org
15
+ parall clip info <alias> # commands, params, version
18
16
  ```
19
17
 
20
- ## Invoking a clip command
18
+ ## Invoke
21
19
 
22
20
  ```bash
23
- # Invoke a command on a clip by alias
24
- parall clip invoke <alias> <command> [input]
25
-
26
- # input is optional — when provided, it can be a JSON string or plain text
27
- parall clip invoke github-tools list-repos '{"org": "acme"}'
28
- parall clip invoke web-search search "latest Node.js LTS version"
29
-
30
- # Custom timeout (default 30s)
31
- parall clip invoke github-tools create-issue '{"title": "Bug report"}' --timeout 60000
21
+ parall clip invoke <alias> <command> [input] [--timeout <ms>] # timeout default 30s
22
+ # input: JSON string or plain text, per the command's params in `info`
23
+ parall clip invoke github-tools list-repos '{"org":"acme"}'
32
24
  ```
33
25
 
34
- ## How clips work
35
-
36
- 1. An org admin installs a clip from the Pinix registry or creates a custom one
37
- 2. `parall clip list` shows every clip installed in the org
38
- 3. You can only **invoke** clips that an admin has **bound to you** — invoking an unbound clip returns a "not bound" error. Ask an admin to bind the clip if you need it.
39
- 4. Each clip exposes one or more named commands with typed input/output
40
-
41
- ## When to use clips
26
+ Results are JSON on stdout; failures print an error.
42
27
 
43
- - Check `parall clip list` when a task requires capabilities beyond your built-in tools (e.g. GitHub API, external services, specialized analysis)
44
- - Use `parall clip info <alias>` to discover available commands and their expected input format
45
- - 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 — ask an admin to bind it
46
- - Clip invocations return JSON output on success or an error message on failure
28
+ ## Behavior rules
47
29
 
48
- CLI command results are JSON on stdout.
30
+ - An authorization error (clip not bound to you) is a fail-fast: ask the
31
+ clip's owner or an admin to bind it — do not retry or work around it.
32
+ - If the executing runtime is offline or the call times out, report that
33
+ plainly; do not queue, and never fabricate a result for a run that errored.
34
+ - A clip may act through a person's real logged-in account — outward,
35
+ irreversible, or spending actions (post, order, delete, pay) get the same
36
+ caution as any shared-state change: confirm when intent isn't explicit.
37
+ - Reach for `parall clip list` whenever a task needs capabilities beyond
38
+ built-in tools.
@@ -42,6 +42,14 @@ parall schedules create \
42
42
 
43
43
  `--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 — when that resource is archived or deleted, the schedule auto-cancels (`cancel_reason=attached_gone`).
44
44
 
45
+ ### Reminders for someone else
46
+
47
+ When someone asks you to remind them (or a third person), put that person in
48
+ `--target-ids` — the fire is delivered to its targets, so a reminder
49
+ targeting only yourself never reaches them. The schedule record stays yours as
50
+ creator (there is no owner transfer); add yourself as an additional target
51
+ only if you also need to act at fire time.
52
+
45
53
  ## Listing / inspecting
46
54
 
47
55
  ```bash
@@ -63,20 +63,20 @@ parall projects list
63
63
 
64
64
  ## Watching Tasks
65
65
 
66
- Subscribe to a task to receive notifications when others comment on it.
66
+ Watchers receive dispatch events for a task's new comments. Acting on a task
67
+ auto-subscribes you — creating it, being assigned, commenting, being
68
+ @mentioned, or substantively editing it (description / assignee). Handle or
69
+ dismiss those comment events deliberately.
67
70
 
68
71
  ```bash
69
- # Watch a task (you'll receive dispatch events for new comments)
70
- parall tasks watch prll://tsk_xxx
71
-
72
- # Unwatch
73
- parall tasks unwatch prll://tsk_xxx
74
-
75
- # List who is watching
76
- parall tasks watchers prll://tsk_xxx
72
+ parall tasks watch prll://tsk_xxx # follow a task without acting on it
73
+ parall tasks unwatch prll://tsk_xxx # opt out of a task's comment events
74
+ parall tasks watchers prll://tsk_xxx # list who is watching
77
75
  ```
78
76
 
79
- Note: task creators are automatically watching their tasks.
77
+ Creators and assignees are locked subscribers `unwatch` returns 409 for
78
+ them until the role changes (e.g. reassignment); it works for every other
79
+ watcher.
80
80
 
81
81
  ## Responding to Task Assignments
82
82
 
@@ -85,7 +85,9 @@ When you receive `[Event: task.assigned]`:
85
85
  1. Acknowledge with a comment: `tasks comments add prll://tsk_xxx --body "On it"`
86
86
  2. Update status: `tasks update prll://tsk_xxx --status in_progress`
87
87
  3. Do the work
88
- 4. Report results via comment and update status to `done`
88
+ 4. Report results in a comment. If a gate remains — review, merge, deploy,
89
+ requester acceptance — set `in_review` and name the gate; set `done`
90
+ only once the work has actually landed
89
91
 
90
92
  ## Responding to Task Comments
91
93
 
@@ -176,6 +176,18 @@ parall wiki reset <wiki> # discard ALL local edits, restore last-synced state
176
176
  parall wiki status <wiki> # local changes + your changesets, anytime
177
177
  ```
178
178
 
179
+ ## Changeset Discipline
180
+
181
+ - Creation is fail-closed — without explicit CLI confirmation of success,
182
+ assume nothing was created; check before retrying to avoid duplicates.
183
+ - Read the outcome feedback after proposing changes; do not assume a merge
184
+ happened.
185
+ - Terminal changesets (merged / closed) are immutable — open a new changeset
186
+ instead of re-merging or re-closing.
187
+ - Respect path scopes — some wiki paths are access-restricted.
188
+ PERMISSION_DENIED on a path means it is not yours to edit; follow the
189
+ error, don't work around it.
190
+
179
191
  CLI success output is JSON on stdout (human summary on stderr); errors state
180
192
  the reason and the next step — follow them. `parall wiki --help` for the
181
193
  full command list.