@1agh/maude 0.32.0 → 0.33.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.
@@ -15,12 +15,12 @@ import { existsSync, readFileSync } from 'node:fs';
15
15
  import { homedir } from 'node:os';
16
16
  import { join } from 'node:path';
17
17
 
18
- import { resolveClaudePath } from './acp/probe.ts';
18
+ import { resolveAdapterEntry, resolveClaudePath } from './acp/probe.ts';
19
19
 
20
20
  export type ReadinessStatus = 'present' | 'missing' | 'unknown';
21
21
 
22
22
  export interface ReadinessItem {
23
- id: 'claude' | 'maude' | 'plugins' | 'agent-browser';
23
+ id: 'claude' | 'maude' | 'plugins' | 'agent-browser' | 'adapter';
24
24
  /** Short human label for the row. */
25
25
  label: string;
26
26
  /** Required items gate `ready`; optional ones never block it. */
@@ -215,6 +215,24 @@ export async function probeReadiness(): Promise<ReadinessReport> {
215
215
  : 'Optional. Install `agent-browser` for screenshot evidence during `/design:edit`.',
216
216
  });
217
217
 
218
+ // The chat bridge itself: the adapter must be resolvable on disk. This is what
219
+ // actually gates the chat panel (probeAcpAvailability → resolveAdapterEntry),
220
+ // distinct from the user-environment checks above. Shown so a build that ships
221
+ // without the staged adapter closure surfaces here instead of leaving every
222
+ // other row green while chat reports "bridge is not installed" (the v0.31–0.32
223
+ // desktop bug; see apps/desktop/scripts/stage-resources.mjs).
224
+ const adapter = resolveAdapterEntry();
225
+ items.push({
226
+ id: 'adapter',
227
+ label: 'Claude agent bridge',
228
+ required: true,
229
+ status: adapter ? 'present' : 'missing',
230
+ detail: adapter ? 'Bundled — the chat panel can spawn it.' : 'Not bundled in this build.',
231
+ remediation: adapter
232
+ ? undefined
233
+ : 'The Claude agent bridge is missing from this build — reinstall or update Maude. If you built it yourself, ensure the desktop staging step bundled `@agentclientprotocol/claude-agent-acp`.',
234
+ });
235
+
218
236
  const ready = items.filter((i) => i.required).every((i) => i.status === 'present');
219
237
  return { ready, items };
220
238
  }
@@ -41,6 +41,10 @@ describe('AcpBridge — round-trip + subscription guardrail', () => {
41
41
  const streamed = JSON.stringify(updates);
42
42
  expect(streamed).toContain('apiKey=<unset>');
43
43
  expect(streamed).not.toContain('sk-must-be-scrubbed');
44
+ // DDR-123 guardrail #2 — the bridge pins the adapter to the user's own
45
+ // `claude` (here MAUDE_CLAUDE_BIN = this bun) via CLAUDE_CODE_EXECUTABLE, so
46
+ // it never falls back to the unshipped ~210 MB native binary.
47
+ expect(streamed).toContain(`claudeExe=${process.execPath}`);
44
48
  } finally {
45
49
  await bridge.stop();
46
50
  }
@@ -36,7 +36,8 @@ acp
36
36
  text:
37
37
  `apiKey=${process.env.ANTHROPIC_API_KEY ?? '<unset>'} ` +
38
38
  `model=${process.env.ANTHROPIC_MODEL ?? '<unset>'} ` +
39
- `thinking=${process.env.MAX_THINKING_TOKENS ?? '<unset>'}`,
39
+ `thinking=${process.env.MAX_THINKING_TOKENS ?? '<unset>'} ` +
40
+ `claudeExe=${process.env.CLAUDE_CODE_EXECUTABLE ?? '<unset>'}`,
40
41
  },
41
42
  },
42
43
  });
@@ -114,9 +114,15 @@ describe('readiness — resolveOnPath', () => {
114
114
  });
115
115
 
116
116
  describe('readiness — report shape', () => {
117
- test('always returns the four items with stable ids and a boolean ready', async () => {
117
+ test('always returns the five items with stable ids and a boolean ready', async () => {
118
118
  const report = await probeReadiness();
119
- expect(report.items.map((i) => i.id)).toEqual(['claude', 'maude', 'plugins', 'agent-browser']);
119
+ expect(report.items.map((i) => i.id)).toEqual([
120
+ 'claude',
121
+ 'maude',
122
+ 'plugins',
123
+ 'agent-browser',
124
+ 'adapter',
125
+ ]);
120
126
  expect(typeof report.ready).toBe('boolean');
121
127
  });
122
128
 
@@ -124,4 +130,25 @@ describe('readiness — report shape', () => {
124
130
  const ab = (await probeReadiness()).items.find((i) => i.id === 'agent-browser')!;
125
131
  expect(ab.required).toBe(false);
126
132
  });
133
+
134
+ test('adapter row tracks the real chat gate (resolveAdapterEntry) and is required', async () => {
135
+ const saved = process.env.MAUDE_ACP_ADAPTER_ENTRY;
136
+ try {
137
+ // Point the override at a real file → the bridge is "bundled".
138
+ process.env.MAUDE_ACP_ADAPTER_ENTRY = import.meta.path;
139
+ const present = (await probeReadiness()).items.find((i) => i.id === 'adapter')!;
140
+ expect(present.required).toBe(true);
141
+ expect(present.status).toBe('present');
142
+
143
+ // Point it at a missing path → the row goes missing with remediation, the
144
+ // honest signal the v0.31–0.32 builds lacked (all other rows green, chat dead).
145
+ process.env.MAUDE_ACP_ADAPTER_ENTRY = join(tmpdir(), 'no-such-acp-adapter-xyz');
146
+ const missing = (await probeReadiness()).items.find((i) => i.id === 'adapter')!;
147
+ expect(missing.status).toBe('missing');
148
+ expect(missing.remediation).toBeDefined();
149
+ } finally {
150
+ if (saved === undefined) delete process.env.MAUDE_ACP_ADAPTER_ENTRY;
151
+ else process.env.MAUDE_ACP_ADAPTER_ENTRY = saved;
152
+ }
153
+ });
127
154
  });
@@ -1,6 +1,15 @@
1
1
  {
2
2
  "$schema": "./whats-new.schema.json",
3
3
  "entries": [
4
+ {
5
+ "id": "desktop-ai-chat-fix",
6
+ "version": "0.32.1",
7
+ "date": "2026-06-24",
8
+ "kind": "fix",
9
+ "title": "AI chat now opens in the desktop app",
10
+ "summary": "If the Assistant panel said AI editing wasn't ready even when Claude Code and the plugins were all installed, that's fixed. The desktop app now includes everything the chat needs and runs on your own installed Claude — open the Assistant (the ✦ in the menubar, or ⌘⇧A) and it just works.",
11
+ "surface": "design-ui"
12
+ },
4
13
  {
5
14
  "id": "ai-editing-readiness-check",
6
15
  "version": "0.32.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1agh/maude",
3
- "version": "0.32.0",
3
+ "version": "0.33.0",
4
4
  "description": "Marketplace of Claude Code plugins by Michal Dovrtěl: `design` (canvas-first design iteration) + `flow` (generic agentic workflow loop with .ai second brain). Ships the `maude` CLI (with `mdcc` legacy alias) to scaffold workspace, run the design dev server, and manage configs.",
5
5
  "type": "module",
6
6
  "engines": {
@@ -43,13 +43,13 @@
43
43
  "prepublishOnly": "bash scripts/check-version-parity.sh && bash apps/studio/bin/check-runtime-bundles.sh"
44
44
  },
45
45
  "optionalDependencies": {
46
- "@1agh/maude-darwin-arm64": "0.32.0",
47
- "@1agh/maude-darwin-x64": "0.32.0",
48
- "@1agh/maude-linux-arm64": "0.32.0",
49
- "@1agh/maude-linux-arm64-musl": "0.32.0",
50
- "@1agh/maude-linux-x64": "0.32.0",
51
- "@1agh/maude-linux-x64-musl": "0.32.0",
52
- "@1agh/maude-win32-x64": "0.32.0"
46
+ "@1agh/maude-darwin-arm64": "0.33.0",
47
+ "@1agh/maude-darwin-x64": "0.33.0",
48
+ "@1agh/maude-linux-arm64": "0.33.0",
49
+ "@1agh/maude-linux-arm64-musl": "0.33.0",
50
+ "@1agh/maude-linux-x64": "0.33.0",
51
+ "@1agh/maude-linux-x64-musl": "0.33.0",
52
+ "@1agh/maude-win32-x64": "0.33.0"
53
53
  },
54
54
  "files": [
55
55
  "cli",
@@ -233,6 +233,73 @@
233
233
  }
234
234
  }
235
235
  },
236
+ "orchestration": {
237
+ "type": "object",
238
+ "additionalProperties": false,
239
+ "description": "Opt-in, capability-gated bookend debate (diverge→adversarial→research). Additive: with the experimental agent-teams flag off (the default for ~all users), `auto`/`reduce` degrade to today's parallel panel + a read-only reduce-pass — nothing to configure, no premium spend. No hard dependency on experimental Claude Code features. See DDR-130.",
240
+ "properties": {
241
+ "mode": {
242
+ "type": "string",
243
+ "enum": ["auto", "reduce", "off"],
244
+ "default": "auto",
245
+ "description": "`auto` = use a live native agent-team (relay) when the CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS capability is detected, else the read-only reduce-pass; gated further by the stakes-gate + short-circuit. `reduce` = always parallel panel + reduce-pass, never a live team. `off` = today's raw single-pass / sum-of-verdicts, byte-for-byte unchanged."
246
+ },
247
+ "bookends": {
248
+ "type": "object",
249
+ "additionalProperties": false,
250
+ "description": "Per-shape opt-out. Debate fires only at the loop's bookends; the middle (execute) stays solo.",
251
+ "properties": {
252
+ "diverge": {
253
+ "type": "object",
254
+ "additionalProperties": false,
255
+ "description": "START / divergent debate (what's BEST, no artifact yet) — e.g. plan, setup-prd, setup-ds.",
256
+ "properties": {
257
+ "enabled": { "type": "boolean", "default": true }
258
+ }
259
+ },
260
+ "adversarial": {
261
+ "type": "object",
262
+ "additionalProperties": false,
263
+ "description": "END / adversarial debate (is it actually safe/done/good, artifact exists) — e.g. validate-security, design critic gate.",
264
+ "properties": {
265
+ "enabled": { "type": "boolean", "default": true }
266
+ }
267
+ },
268
+ "research": {
269
+ "type": "object",
270
+ "additionalProperties": false,
271
+ "description": "RESEARCH debate (what's TRUE — ends when evidence eliminates hypotheses) — e.g. bug-rca, ux-research.",
272
+ "properties": {
273
+ "enabled": { "type": "boolean", "default": true }
274
+ }
275
+ }
276
+ }
277
+ },
278
+ "maxSeats": {
279
+ "type": "integer",
280
+ "minimum": 2,
281
+ "maximum": 4,
282
+ "default": 4,
283
+ "description": "Hard cap on debate seats. The stakes-gate picks where in 2–4 to land (2 for reversible calls, up to 4 for irreversible / high-blast-radius)."
284
+ },
285
+ "escalationCeiling": {
286
+ "type": "number",
287
+ "minimum": 0,
288
+ "maximum": 1,
289
+ "default": 0.5,
290
+ "description": "Observability knob. If the measured short-circuit escalation rate (fraction of bookend runs that escalate from blind openings to a full debate) exceeds this, the protocol warns that the openings aren't independent enough and the escalation should be re-tuned."
291
+ },
292
+ "designTeam": {
293
+ "type": "object",
294
+ "additionalProperties": false,
295
+ "description": "`/design:critic` live-team (relay) tier. Off until its measured gate clears: ≥ `minConflicts` cross-discipline conflicting blockers AND a reduce-pass demonstrably failing to break the oscillation. Until then `/design:critic` uses the read-only reduce-pass.",
296
+ "properties": {
297
+ "enabled": { "type": "boolean", "default": false },
298
+ "minConflicts": { "type": "integer", "minimum": 2, "default": 2 }
299
+ }
300
+ }
301
+ }
302
+ },
236
303
  "security": {
237
304
  "type": "object",
238
305
  "additionalProperties": false,