@parall/parall 1.24.0 → 1.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parall/parall",
3
- "version": "1.24.0",
3
+ "version": "1.26.0",
4
4
  "description": "OpenClaw channel plugin for Parall IM",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -15,8 +15,8 @@
15
15
  "openclaw.plugin.json"
16
16
  ],
17
17
  "dependencies": {
18
- "@parall/agent-core": "1.24.0",
19
- "@parall/sdk": "1.24.0"
18
+ "@parall/agent-core": "1.26.0",
19
+ "@parall/sdk": "1.26.0"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@types/node": "^22.0.0",
@@ -36,7 +36,7 @@
36
36
  }
37
37
  },
38
38
  "scripts": {
39
- "build": "tsc -b",
39
+ "build": "tsc -b && node scripts/generate-skills.mjs",
40
40
  "test": "node --test test/*.test.mjs"
41
41
  }
42
42
  }
@@ -118,6 +118,32 @@ parall dm "Alice" --file /tmp/report.pdf --text "Report attached"
118
118
 
119
119
  `--file` and `--attachment` are mutually exclusive. `--text` can be combined with either.
120
120
 
121
+ ## Approvals
122
+
123
+ When a CLI command returns a `PERMISSION_DENIED` error, the output includes a `Tip:` line with an approval-request template — copy it and fill in the remaining placeholders (`--chat`, `--title`, `--reason`). The `Tip:` only appears for commonly approvable actions (archive, delete, restore); for other actions, use `parall approvals actions` to check if it's approvable.
124
+
125
+ ```bash
126
+ # Request approval (use action and resource_uri from the error)
127
+ parall approvals request --action chat.archive --resource prll://cht_xxx --chat prll://cht_yyy --title "Archive old channel" --reason "No activity in 6 months"
128
+
129
+ # Check a specific approval's status
130
+ parall approvals get prll://apr_xxx
131
+
132
+ # Wait for a decision (blocks until approved/rejected/timeout)
133
+ parall approvals wait prll://apr_xxx --timeout 300
134
+
135
+ # List all your pending approvals
136
+ parall approvals list
137
+
138
+ # List available approvable actions
139
+ parall approvals actions
140
+
141
+ # Cancel a pending request you made
142
+ parall approvals cancel prll://apr_xxx
143
+ ```
144
+
145
+ Only request approval after receiving an actual `PERMISSION_DENIED` error — never preemptively. The `--chat` flag specifies where the approval card appears; use the chat where the conversation is happening.
146
+
121
147
  ## Reference URIs
122
148
 
123
149
  Every entity is addressable with a `prll://` URI. Common prefixes you'll see in events, messages, and schedule descriptions:
@@ -37,7 +37,7 @@ parall schedules create \
37
37
  --name "Followup" \
38
38
  --description "Remind the user about the PR review if still pending" \
39
39
  --target-ids prll://usr_xxx \
40
- --run-at 2026-04-19T15:00:00Z
40
+ --run-at <FUTURE_RFC3339_TIME>
41
41
  ```
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`).
@@ -75,7 +75,7 @@ Your job is to interpret the description and act:
75
75
 
76
76
  1. Read the description and any `prll://` refs it contains
77
77
  2. Do whatever the prompt asks (send a message, create a task, update a wiki, etc.) — there is no canonical response format
78
- 3. Optional: if the fire is genuinely a no-op and you don't want to produce any artifact, use `no-reply` (from `parall-platform` skill) to stay silent for this turn
78
+ 3. Optional: if the fire is genuinely a no-op and you don't want to produce any artifact, use `no-reply` (from parall-platform skill) to stay silent for this turn
79
79
 
80
80
  Do not treat schedule fires as "tasks assigned to you" — there's no status to transition, no acknowledgment required. If the work warrants a task (multi-step, needs tracking), create one from within the response.
81
81
 
@@ -28,7 +28,7 @@ parall wiki sync <slug>
28
28
  ```
29
29
 
30
30
  This downloads wiki files to a local directory. The output includes the
31
- **absolute mount path** for each wiki (e.g. `synced → /data/.openclaw/workspace/kb`).
31
+ **absolute mount path** for each wiki (e.g. `synced → /path/to/workspace/kb`).
32
32
 
33
33
  ### Step 2: Find the mount path
34
34
 
@@ -81,18 +81,43 @@ function applyToOpenClawConfig(
81
81
  models.providers = providers;
82
82
  existing.models = models;
83
83
 
84
- // Deep-merge agents.defaults (preserve existing fields, overlay platform)
84
+ // Strip keys OpenClaw doesn't recognize from agents.defaults platform-only
85
+ // keys like thinking_effort are consumed by agent-core's PlatformConfigManager.
86
+ // See: OpenClaw agents.defaults config schema.
87
+ const OPENCLAW_AGENTS_DEFAULTS_KEYS = new Set(["model", "maxTokens", "compaction"]);
88
+
89
+ // Unconditionally sanitize existing defaults to self-heal already-poisoned
90
+ // openclaw.json files (e.g. mode=self agents that were poisoned while in
91
+ // platform mode).
92
+ const agents = (existing.agents ?? {}) as Record<string, unknown>;
93
+ const existingDefaults = (agents.defaults ?? {}) as Record<string, unknown>;
94
+ const cleanedExisting: Record<string, unknown> = {};
95
+ for (const [k, v] of Object.entries(existingDefaults)) {
96
+ if (OPENCLAW_AGENTS_DEFAULTS_KEYS.has(k)) {
97
+ cleanedExisting[k] = v;
98
+ }
99
+ }
100
+
101
+ // Overlay platform defaults (filtered) when present.
85
102
  const platformAgents = (platformConfig.agents ?? {}) as Record<string, unknown>;
86
- if (platformAgents.defaults !== undefined) {
87
- const agents = (existing.agents ?? {}) as Record<string, unknown>;
88
- const existingDefaults = (agents.defaults ?? {}) as Record<string, unknown>;
89
- agents.defaults = {
90
- ...existingDefaults,
91
- ...(platformAgents.defaults as Record<string, unknown>),
92
- };
93
- existing.agents = agents;
103
+ const rawDefaults = platformAgents.defaults;
104
+ if (
105
+ rawDefaults !== undefined &&
106
+ rawDefaults !== null &&
107
+ typeof rawDefaults === "object" &&
108
+ !Array.isArray(rawDefaults)
109
+ ) {
110
+ const raw = rawDefaults as Record<string, unknown>;
111
+ for (const [k, v] of Object.entries(raw)) {
112
+ if (OPENCLAW_AGENTS_DEFAULTS_KEYS.has(k)) {
113
+ cleanedExisting[k] = v;
114
+ }
115
+ }
94
116
  }
95
117
 
118
+ agents.defaults = cleanedExisting;
119
+ existing.agents = agents;
120
+
96
121
  // No plugin tools to allow — all operations go through CLI.
97
122
 
98
123
  // Atomic write