@inetafrica/open-claudia 3.0.34 → 3.0.35
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/CHANGELOG.md +7 -0
- package/channels/spaces/client.js +118 -8
- package/package.json +2 -2
- package/test-provider-language.js +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v3.0.35 — Spaces comments are readable rich text, not a run-on wall
|
|
4
|
+
|
|
5
|
+
- **The bot's Spaces replies rendered as unreadable walls.** `buildCommentContent` posted the entire reply as one text node inside one paragraph. Spaces comments are TipTap/ProseMirror docs: inside a single text node newlines don't render, so paragraphs, numbered lists and `---` separators collapsed into one run-on blob — and the model's markdown (`**bold**`, `*italic*`, backticks) printed its asterisks literally.
|
|
6
|
+
- **Outgoing comments now convert markdown → a real ProseMirror doc.** Blank lines become paragraphs, single newlines hardBreaks; `**`/`*`/`` ` `` become bold/italic/code marks (word-bounded, so snake_case identifiers stay plain); `-`/`1.` runs become real bullet/ordered lists; `#`–`###` become headings; ``` fences become code blocks; `---` becomes a divider. Every emitted node type was verified against the Spaces frontend editor schema (StarterKit + HorizontalRule + CodeBlockLowlight), so nothing renders broken.
|
|
7
|
+
- **Mention chips unchanged.** The proven tag-chip shape still leads the first paragraph, so notification fan-out and the "@Name text…" lead-in behave exactly as before. `flattenContent` also learned `codeBlock`/`horizontalRule` so the bot reads its own comments back cleanly.
|
|
8
|
+
- **Agent-space / OpenClaw:** no new deps, no new env, no schema change. Covered by new `test-spaces-comment-content.js` in the pretest chain. Bots pick this up on their next upgrade, together with v3.0.34's /upgrade redelivery guard.
|
|
9
|
+
|
|
3
10
|
## v3.0.34 — /upgrade no longer triggers a rollout storm
|
|
4
11
|
|
|
5
12
|
- **One `/upgrade` used to mean up to five rollouts.** On AgentSpace pods the control plane answers `/upgrade` by rolling the deployment, which SIGTERMs the bot mid-turn. Telegram long-polling keeps no persisted offset, so the still-unconfirmed `/upgrade` update was redelivered to the freshly booted pod — which triggered *another* rollout, and so on. Observed on rahilcoder 2026-07-17: deployment revisions 47–51 (five rollouts in three minutes) from a single command; every earlier `/upgrade` had silently double-fired the same way (revs 42/43, 45/46).
|
|
@@ -89,8 +89,9 @@ function flattenContent(node) {
|
|
|
89
89
|
if (t === "text") return node.text || "";
|
|
90
90
|
if (t === "mention") return `@${node.attrs?.label || node.attrs?.id || ""}`;
|
|
91
91
|
if (t === "hardBreak") return "\n";
|
|
92
|
+
if (t === "horizontalRule") return "---\n";
|
|
92
93
|
const inner = (node.content || []).map(flattenContent).join("");
|
|
93
|
-
if (["paragraph", "heading", "listItem", "blockquote"].includes(t)) return inner + "\n";
|
|
94
|
+
if (["paragraph", "heading", "listItem", "blockquote", "codeBlock"].includes(t)) return inner + "\n";
|
|
94
95
|
return inner;
|
|
95
96
|
}
|
|
96
97
|
|
|
@@ -98,17 +99,126 @@ function contentText(raw) {
|
|
|
98
99
|
return flattenContent(raw).trim();
|
|
99
100
|
}
|
|
100
101
|
|
|
102
|
+
// Inline markdown → ProseMirror inline nodes. Supports `code`, **bold** and
|
|
103
|
+
// *italic*/_italic_ (word-bounded, so snake_case identifiers and stray
|
|
104
|
+
// asterisks in prose survive untouched). One level only — chat comments
|
|
105
|
+
// don't need nesting, and a wrong guess renders worse than plain text.
|
|
106
|
+
const INLINE_TOKEN_RE = /(`[^`\n]+`)|(\*\*(?=\S)[^*\n]*?\S\*\*)|(\*(?=\S)[^*\n]*?\S\*)|((?<![\w`])_(?=\S)[^_\n]*?\S_(?![\w`]))/g;
|
|
107
|
+
function inlineNodes(text) {
|
|
108
|
+
const out = [];
|
|
109
|
+
const push = (t, marks) => { if (t) out.push(marks ? { type: "text", text: t, marks } : { type: "text", text: t }); };
|
|
110
|
+
let last = 0;
|
|
111
|
+
let m;
|
|
112
|
+
INLINE_TOKEN_RE.lastIndex = 0;
|
|
113
|
+
while ((m = INLINE_TOKEN_RE.exec(text))) {
|
|
114
|
+
push(text.slice(last, m.index));
|
|
115
|
+
if (m[1]) push(m[1].slice(1, -1), [{ type: "code" }]);
|
|
116
|
+
else if (m[2]) push(m[2].slice(2, -2), [{ type: "bold" }]);
|
|
117
|
+
else if (m[3]) push(m[3].slice(1, -1), [{ type: "italic" }]);
|
|
118
|
+
else push(m[4].slice(1, -1), [{ type: "italic" }]);
|
|
119
|
+
last = m.index + m[0].length;
|
|
120
|
+
}
|
|
121
|
+
push(text.slice(last));
|
|
122
|
+
return out;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Block-level markdown → ProseMirror blocks. The model writes markdown; Spaces
|
|
126
|
+
// renders TipTap docs — posting the raw text as one text node collapses every
|
|
127
|
+
// newline and prints the asterisks literally (the unreadable-wall bug). Only
|
|
128
|
+
// node types present in the Spaces editor schema (StarterKit + HorizontalRule
|
|
129
|
+
// + CodeBlockLowlight) are emitted, so nothing renders broken.
|
|
130
|
+
function markdownBlocks(text) {
|
|
131
|
+
const blocks = [];
|
|
132
|
+
const lines = String(text || "").replace(/\r\n/g, "\n").split("\n");
|
|
133
|
+
let para = [];
|
|
134
|
+
const flushPara = () => {
|
|
135
|
+
if (!para.length) return;
|
|
136
|
+
const content = [];
|
|
137
|
+
para.forEach((ln, idx) => {
|
|
138
|
+
if (idx > 0) content.push({ type: "hardBreak" });
|
|
139
|
+
content.push(...inlineNodes(ln));
|
|
140
|
+
});
|
|
141
|
+
para = [];
|
|
142
|
+
if (content.length) blocks.push({ type: "paragraph", content });
|
|
143
|
+
};
|
|
144
|
+
let i = 0;
|
|
145
|
+
while (i < lines.length) {
|
|
146
|
+
const trimmed = lines[i].trim();
|
|
147
|
+
if (!trimmed) { flushPara(); i += 1; continue; }
|
|
148
|
+
if (/^(-{3,}|\*{3,}|_{3,})$/.test(trimmed)) { flushPara(); blocks.push({ type: "horizontalRule" }); i += 1; continue; }
|
|
149
|
+
if (trimmed.startsWith("```")) {
|
|
150
|
+
flushPara();
|
|
151
|
+
const language = trimmed.slice(3).trim();
|
|
152
|
+
const buf = [];
|
|
153
|
+
i += 1;
|
|
154
|
+
while (i < lines.length && !lines[i].trim().startsWith("```")) { buf.push(lines[i]); i += 1; }
|
|
155
|
+
i += 1;
|
|
156
|
+
blocks.push({
|
|
157
|
+
type: "codeBlock",
|
|
158
|
+
attrs: { language: language || null },
|
|
159
|
+
...(buf.length ? { content: [{ type: "text", text: buf.join("\n") }] } : {}),
|
|
160
|
+
});
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (/^[-*•]\s+/.test(trimmed)) {
|
|
164
|
+
flushPara();
|
|
165
|
+
const items = [];
|
|
166
|
+
while (i < lines.length && /^[-*•]\s+/.test(lines[i].trim())) {
|
|
167
|
+
const inner = inlineNodes(lines[i].trim().replace(/^[-*•]\s+/, ""));
|
|
168
|
+
items.push({ type: "listItem", content: [inner.length ? { type: "paragraph", content: inner } : { type: "paragraph" }] });
|
|
169
|
+
i += 1;
|
|
170
|
+
}
|
|
171
|
+
blocks.push({ type: "bulletList", content: items });
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (/^\d+[.)]\s+/.test(trimmed)) {
|
|
175
|
+
flushPara();
|
|
176
|
+
const start = parseInt(trimmed, 10);
|
|
177
|
+
const items = [];
|
|
178
|
+
while (i < lines.length && /^\d+[.)]\s+/.test(lines[i].trim())) {
|
|
179
|
+
const inner = inlineNodes(lines[i].trim().replace(/^\d+[.)]\s+/, ""));
|
|
180
|
+
items.push({ type: "listItem", content: [inner.length ? { type: "paragraph", content: inner } : { type: "paragraph" }] });
|
|
181
|
+
i += 1;
|
|
182
|
+
}
|
|
183
|
+
blocks.push({ type: "orderedList", attrs: { start: Number.isNaN(start) ? 1 : start }, content: items });
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
const heading = trimmed.match(/^(#{1,3})\s+(.*)$/);
|
|
187
|
+
if (heading) {
|
|
188
|
+
flushPara();
|
|
189
|
+
const inner = inlineNodes(heading[2]);
|
|
190
|
+
blocks.push({ type: "heading", attrs: { level: heading[1].length }, ...(inner.length ? { content: inner } : {}) });
|
|
191
|
+
i += 1;
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
para.push(lines[i]);
|
|
195
|
+
i += 1;
|
|
196
|
+
}
|
|
197
|
+
flushPara();
|
|
198
|
+
return blocks;
|
|
199
|
+
}
|
|
200
|
+
|
|
101
201
|
// Build the stringified ProseMirror doc for an outgoing comment. Optional
|
|
102
202
|
// leading @mention chips (each {userId,label}) drive Spaces' notification
|
|
103
|
-
// fan-out; the tool proved this exact node shape renders as tag chips.
|
|
203
|
+
// fan-out; the tool proved this exact node shape renders as tag chips. Chips
|
|
204
|
+
// are prepended into the first paragraph so the visual "@Name text…" lead-in
|
|
205
|
+
// stays identical to the pre-markdown behaviour.
|
|
104
206
|
function buildCommentContent(text, mentions = []) {
|
|
105
|
-
const
|
|
207
|
+
const chips = [];
|
|
106
208
|
for (const m of mentions) {
|
|
107
|
-
|
|
108
|
-
|
|
209
|
+
chips.push({ type: "mention", attrs: { id: m.userId, label: m.label, mentionSuggestionChar: "@" } });
|
|
210
|
+
chips.push({ type: "text", text: " " });
|
|
211
|
+
}
|
|
212
|
+
const blocks = markdownBlocks(text);
|
|
213
|
+
if (chips.length) {
|
|
214
|
+
if (blocks.length && blocks[0].type === "paragraph") {
|
|
215
|
+
blocks[0].content = [...chips, ...(blocks[0].content || [])];
|
|
216
|
+
} else {
|
|
217
|
+
blocks.unshift({ type: "paragraph", content: chips });
|
|
218
|
+
}
|
|
109
219
|
}
|
|
110
|
-
if (
|
|
111
|
-
return JSON.stringify({ type: "doc", content:
|
|
220
|
+
if (!blocks.length) blocks.push({ type: "paragraph" });
|
|
221
|
+
return JSON.stringify({ type: "doc", content: blocks });
|
|
112
222
|
}
|
|
113
223
|
|
|
114
224
|
class SpacesClient {
|
|
@@ -201,4 +311,4 @@ class SpacesClient {
|
|
|
201
311
|
}
|
|
202
312
|
}
|
|
203
313
|
|
|
204
|
-
module.exports = { SpacesClient, flattenContent, contentText, buildCommentContent, asArray };
|
|
314
|
+
module.exports = { SpacesClient, flattenContent, contentText, buildCommentContent, markdownBlocks, inlineNodes, asArray };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inetafrica/open-claudia",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.35",
|
|
4
4
|
"description": "An always-on, provider-agnostic coding-agent harness for Claude Code and OpenAI Codex via chat",
|
|
5
5
|
"main": "bot.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"scripts": {
|
|
10
10
|
"setup": "node setup.js",
|
|
11
11
|
"start": "node bot.js",
|
|
12
|
-
"pretest": "node test-provider-fixture.js && node test-provider-core-prompt.js && node test-provider-prompt-parity.js && node test-provider-env-isolation.js && node test-provider-resume-parity.js && node test-provider-bootstrap.js && node test-provider-registry.js && node test-provider-stream-decoder.js && node test-provider-events.js && node test-provider-claude.js && node test-provider-codex.js && node test-provider-runner.js && node test-provider-run-lifecycle.js && node test-provider-gateway.js && node test-provider-side-chat.js && node test-single-runtime.js && node test-provider-migration-backup.js && node test-provider-state-migration.js && node test-provider-session-history.js && node test-provider-session-commands.js && node test-provider-compaction.js && node test-provider-scheduler.js && node test-cursor-removal.js && node test-utility-provider-policy.js && node test-provider-subagent.js && node test-provider-recall.js && node test-provider-pack-review.js && node test-memory-mutation-queue.js && node test-provider-dream.js && node test-provider-enforcer.js && node test-provider-tool-hooks.js && node test-provider-boot-matrix.js && node test-provider-capabilities.js && node test-provider-language.js && node test-provider-coupling-audit.js && node test-provider-parity-e2e.js && node test-kazee-channel-health.js && node test-prompt-budget.js && node test-agency-ledger.js && node test-agency-deliberate.js && node test-guardrail.js",
|
|
12
|
+
"pretest": "node test-provider-fixture.js && node test-provider-core-prompt.js && node test-provider-prompt-parity.js && node test-provider-env-isolation.js && node test-provider-resume-parity.js && node test-provider-bootstrap.js && node test-provider-registry.js && node test-provider-stream-decoder.js && node test-provider-events.js && node test-provider-claude.js && node test-provider-codex.js && node test-provider-runner.js && node test-provider-run-lifecycle.js && node test-provider-gateway.js && node test-provider-side-chat.js && node test-single-runtime.js && node test-provider-migration-backup.js && node test-provider-state-migration.js && node test-provider-session-history.js && node test-provider-session-commands.js && node test-provider-compaction.js && node test-provider-scheduler.js && node test-cursor-removal.js && node test-utility-provider-policy.js && node test-provider-subagent.js && node test-provider-recall.js && node test-provider-pack-review.js && node test-memory-mutation-queue.js && node test-provider-dream.js && node test-provider-enforcer.js && node test-provider-tool-hooks.js && node test-provider-boot-matrix.js && node test-provider-capabilities.js && node test-provider-language.js && node test-provider-coupling-audit.js && node test-provider-parity-e2e.js && node test-kazee-channel-health.js && node test-prompt-budget.js && node test-agency-ledger.js && node test-agency-deliberate.js && node test-guardrail.js && node test-spaces-comment-content.js",
|
|
13
13
|
"test": "OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node -e \"require('./vault'); console.log('OK')\" && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-runner-watchdog-static.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-usage-accounting.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-engine.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-graph.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-discoverer.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-project-transcripts-smoke.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-abilities.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-ability-extraction.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-ability-couse.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-ability-transfer.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-ability-tiers.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-ability-merge-guard.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-learning-e2e.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-pack-nesting.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-journal-dedupe.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-read-signal.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tools.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tool-graph.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tool-guard.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tooling-mode.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-tool-manifest.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-evolution.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-approval-async.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-unified-identity.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-queue-routing.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-persona-packs.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-speaker-persona.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-persona-pipeline.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-recall-relationship-gate.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-relationship.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-enforcer.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-identity-prune.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-kazee-message-id.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-delivery-contract.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-run-lock.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-web-sessions.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-telegram-poll-recovery.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-telegram-409-grace.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-telegram-conflict-heal-guard.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-single-instance.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-streaming-split.js && OPEN_CLAUDIA_TEST=1 WORKSPACE=/tmp/open-claudia-test CLAUDE_PATH=./test-fixtures/fake-agent-cli.js FAKE_AGENT_KIND=claude AGENT_ENV_PASSTHROUGH=FAKE_AGENT_KIND node test-spaces-autoenable.js"
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
@@ -32,15 +32,15 @@ assert.doesNotMatch(setup, /Your Claude Code bot is connected|Description=Claude
|
|
|
32
32
|
|
|
33
33
|
const pkg = JSON.parse(read("package.json"));
|
|
34
34
|
assert.match(pkg.description, /provider-agnostic coding-agent harness/i);
|
|
35
|
-
// 3.0.
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
assert.strictEqual(pkg.version, "3.0.
|
|
35
|
+
// 3.0.35 approved by Sumeet 2026-07-17 ("yes will this also ship the issue of
|
|
36
|
+
// new lines not showing properly?"): Spaces comments become real ProseMirror
|
|
37
|
+
// docs. buildCommentContent used to post the whole reply as ONE text node in
|
|
38
|
+
// ONE paragraph, so TipTap collapsed every newline and printed markdown
|
|
39
|
+
// asterisks literally — the unreadable-wall screenshot from the euvy bot
|
|
40
|
+
// thread. Now markdown converts to paragraphs/hardBreaks, bold/italic/code
|
|
41
|
+
// marks, bullet/ordered lists, headings, code blocks and dividers — all node
|
|
42
|
+
// types verified present in the Spaces editor schema.
|
|
43
|
+
assert.strictEqual(pkg.version, "3.0.35", "release version must remain unchanged without explicit approval");
|
|
44
44
|
for (const keyword of ["claude", "codex", "coding-agent", "provider-agnostic"]) {
|
|
45
45
|
assert.ok(pkg.keywords.includes(keyword), `package keyword missing: ${keyword}`);
|
|
46
46
|
}
|