@1agh/maude 1.3.0 → 1.4.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/apps/studio/annotation-edit-base.ts +36 -0
- package/apps/studio/annotations-layer.tsx +13 -2
- package/apps/studio/api.ts +51 -2
- package/apps/studio/canvas-build.ts +49 -8
- package/apps/studio/canvas-edit.ts +77 -0
- package/apps/studio/canvas-lib.tsx +25 -10
- package/apps/studio/canvas-list-watch.ts +33 -2
- package/apps/studio/client/app.jsx +99 -4
- package/apps/studio/client/canvas-url.js +39 -1
- package/apps/studio/client/panels/TimelinePanel.jsx +75 -62
- package/apps/studio/client/photo-knobs.jsx +3 -3
- package/apps/studio/client/styles/3-shell-maude.css +1 -0
- package/apps/studio/collab/awareness-bridge.ts +65 -14
- package/apps/studio/comments-overlay.tsx +86 -2
- package/apps/studio/context.ts +93 -1
- package/apps/studio/dist/client.bundle.js +619 -619
- package/apps/studio/dist/comment-mount.js +2 -2
- package/apps/studio/dist/styles.css +1 -1
- package/apps/studio/git/accepted-guard.ts +36 -0
- package/apps/studio/hmr-broadcast.ts +34 -1
- package/apps/studio/http.ts +15 -1
- package/apps/studio/managed-projects.ts +22 -0
- package/apps/studio/server.ts +3 -0
- package/apps/studio/sync/accepted-link.ts +3 -0
- package/apps/studio/sync/file-plane.ts +15 -0
- package/apps/studio/sync/index.ts +138 -12
- package/apps/studio/sync/presentation.ts +30 -0
- package/apps/studio/sync/status.ts +5 -1
- package/apps/studio/sync/transaction-client.ts +29 -0
- package/apps/studio/use-tool-mode.tsx +44 -0
- package/apps/studio/whats-new.json +72 -0
- package/apps/studio/ws.ts +9 -2
- package/package.json +8 -8
- package/plugins/design/templates/_shell.html +48 -7
- package/plugins/flow/.claude-plugin/config.schema.json +15 -2
- package/plugins/flow/README.md +1 -1
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
useContext,
|
|
19
19
|
useEffect,
|
|
20
20
|
useMemo,
|
|
21
|
+
useRef,
|
|
21
22
|
useState,
|
|
22
23
|
} from 'react';
|
|
23
24
|
|
|
@@ -53,6 +54,9 @@ export type ShapeKind = 'square' | 'rounded' | 'circle' | 'diamond' | 'triangle'
|
|
|
53
54
|
*/
|
|
54
55
|
export type CanvasMode = 'preview' | 'edit';
|
|
55
56
|
|
|
57
|
+
/** Document event two provider instances keep one active tool through. */
|
|
58
|
+
export const TOOL_SYNC_EVENT = 'maude:tool-sync';
|
|
59
|
+
|
|
56
60
|
/** The resting tool each mode arms (and returns to via `resetTool`). */
|
|
57
61
|
export const MODE_DEFAULT_TOOL: Readonly<Record<CanvasMode, Tool>> = Object.freeze({
|
|
58
62
|
preview: 'browse',
|
|
@@ -231,6 +235,46 @@ export function ToolProvider({
|
|
|
231
235
|
// FigJam look); sharp squares stay one popover click away.
|
|
232
236
|
const [shapeKind, setShapeKind] = useState<ShapeKind>('rounded');
|
|
233
237
|
|
|
238
|
+
// ONE ACTIVE TOOL PER CANVAS DOCUMENT, across provider instances.
|
|
239
|
+
//
|
|
240
|
+
// A UI canvas carries TWO providers: the comment-mount layer's (it owns the
|
|
241
|
+
// comment drop) and canvas-lib's own (it owns the palette) — separate
|
|
242
|
+
// bundles, so separate contexts. They used to converge only through a tool
|
|
243
|
+
// KEYDOWN, which both routers see; a palette CLICK reached canvas-lib's
|
|
244
|
+
// provider alone. So "Comment" in the palette lit up while the comment
|
|
245
|
+
// layer stayed in browse, and clicking the canvas dropped nothing — you had
|
|
246
|
+
// to know to press C (plan T31/L11). A change here is announced on the
|
|
247
|
+
// document and every other instance adopts it. The boot posture is NOT
|
|
248
|
+
// announced (the two instances deliberately boot differently — see
|
|
249
|
+
// `initial`); only a change after mount is.
|
|
250
|
+
const syncId = useRef(Math.random().toString(36).slice(2));
|
|
251
|
+
const toolRef = useRef(tool);
|
|
252
|
+
toolRef.current = tool;
|
|
253
|
+
const announced = useRef(false);
|
|
254
|
+
useEffect(() => {
|
|
255
|
+
if (!announced.current) {
|
|
256
|
+
announced.current = true;
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (typeof document === 'undefined') return;
|
|
260
|
+
document.dispatchEvent(
|
|
261
|
+
new CustomEvent(TOOL_SYNC_EVENT, { detail: { tool, from: syncId.current } })
|
|
262
|
+
);
|
|
263
|
+
}, [tool]);
|
|
264
|
+
useEffect(() => {
|
|
265
|
+
if (typeof document === 'undefined') return;
|
|
266
|
+
const onSync = (e: Event) => {
|
|
267
|
+
const d = (e as CustomEvent<{ tool?: unknown; from?: unknown }>).detail;
|
|
268
|
+
if (!d || d.from === syncId.current || typeof d.tool !== 'string') return;
|
|
269
|
+
// Already there: nothing to do, and — for a sticky-locked tool — not
|
|
270
|
+
// touching it keeps the lock.
|
|
271
|
+
if (d.tool === toolRef.current) return;
|
|
272
|
+
setTool(d.tool as Tool);
|
|
273
|
+
};
|
|
274
|
+
document.addEventListener(TOOL_SYNC_EVENT, onSync);
|
|
275
|
+
return () => document.removeEventListener(TOOL_SYNC_EVENT, onSync);
|
|
276
|
+
}, [setTool]);
|
|
277
|
+
|
|
234
278
|
// Cursor sync — applied inside the canvas (this hook runs in the canvas
|
|
235
279
|
// context). The active tool's cursor is set on <body> AND forced across the
|
|
236
280
|
// whole canvas working area via an `!important` rule, so the custom cursor
|
|
@@ -1,6 +1,78 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./whats-new.schema.json",
|
|
3
3
|
"entries": [
|
|
4
|
+
{
|
|
5
|
+
"id": "design-system-on-every-desktop",
|
|
6
|
+
"version": "1.4.0",
|
|
7
|
+
"date": "2026-09-16",
|
|
8
|
+
"kind": "improvement",
|
|
9
|
+
"title": "Your team’s design system on your desktop too",
|
|
10
|
+
"summary": "When you open a team project on the desktop, its design system now appears in the Design System section — tokens, specimens and all — the same as on the machine that made it. Specimens someone adds show up for everyone.",
|
|
11
|
+
"surface": "design-ui"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "sync-reliability-sept",
|
|
15
|
+
"version": "1.4.0",
|
|
16
|
+
"date": "2026-09-16",
|
|
17
|
+
"kind": "fix",
|
|
18
|
+
"title": "Steadier syncing in shared projects",
|
|
19
|
+
"summary": "Renaming a folder no longer makes you miss a teammate’s later edits to the canvases inside it; replacing an image keeps showing the new one on your screen; a file the workspace can’t store right now is named in the Sync panel and delivers by itself when it can; and a too-big file you remove stops being reported.",
|
|
20
|
+
"surface": "design-ui"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": "edits-follow-moves",
|
|
24
|
+
"version": "1.4.0",
|
|
25
|
+
"date": "2026-09-16",
|
|
26
|
+
"kind": "improvement",
|
|
27
|
+
"title": "Your edit follows a canvas a teammate moved",
|
|
28
|
+
"summary": "If a teammate moves a canvas — or renames its folder — while you are editing it offline, your change now lands at the canvas’s new place for everyone instead of waiting for review. Deleting a canvas you were editing still asks you what to keep.",
|
|
29
|
+
"surface": "design-ui"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "edit-own-comments",
|
|
33
|
+
"version": "1.4.0",
|
|
34
|
+
"date": "2026-09-16",
|
|
35
|
+
"kind": "feature",
|
|
36
|
+
"title": "Fix a typo in your own comment",
|
|
37
|
+
"summary": "Open a comment you wrote and choose Edit — change the text and save; everyone sees the new wording and the replies stay. On a Maude Cloud project in the browser, your comments and replies now carry your name instead of the workspace’s.",
|
|
38
|
+
"surface": "design-ui"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "live-canvases-long-sessions",
|
|
42
|
+
"version": "1.3.1",
|
|
43
|
+
"date": "2026-09-15",
|
|
44
|
+
"kind": "fix",
|
|
45
|
+
"title": "Canvases stay live in long sessions",
|
|
46
|
+
"summary": "A canvas open in your browser on a Maude Cloud project kept working for about 15 minutes and then quietly stopped showing teammates’ changes until you reloaded the page — it now stays live however long you work. And editing a design system’s tokens.css restyles every open canvas that uses it, straight away.",
|
|
47
|
+
"surface": "design-ui"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"id": "team-access-and-presence",
|
|
51
|
+
"version": "1.3.1",
|
|
52
|
+
"date": "2026-09-15",
|
|
53
|
+
"kind": "fix",
|
|
54
|
+
"title": "Lost access? Maude asks you to sign in again",
|
|
55
|
+
"summary": "If an owner removes your access or your sign-in expires, the Sync panel now tells you to sign in again — instead of \"check your connection\" — and keeps your changes on this computer until you do. Signing in again sends them. And when a teammate closes a canvas, their avatar and cursor now leave everyone else’s screen straight away.",
|
|
56
|
+
"surface": "design-ui"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"id": "comment-tool-and-live-tree",
|
|
60
|
+
"version": "1.3.1",
|
|
61
|
+
"date": "2026-09-15",
|
|
62
|
+
"kind": "fix",
|
|
63
|
+
"title": "The Comment tool works from the toolbar; new images and folders show up for everyone at once",
|
|
64
|
+
"summary": "Picking Comment in the canvas toolbar now lets you click an element to comment — before, only the C key did. An image saved next to your canvases appears in the file tree straight away, on your machine and your teammates’. A folder you create or move outside Maude, or move in the tree, reaches the team in seconds instead of on the next launch.",
|
|
65
|
+
"surface": "design-ui"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"id": "inspector-keeps-number-types",
|
|
69
|
+
"version": "1.3.1",
|
|
70
|
+
"date": "2026-09-15",
|
|
71
|
+
"kind": "fix",
|
|
72
|
+
"title": "Editing a number in the inspector keeps it a number",
|
|
73
|
+
"summary": "Changing a value like an artboard height or a video’s length used to turn it into text in the canvas source — some components then misread it. Numbers and on/off values now stay what they were, and leaving a value unchanged no longer rewrites the file.",
|
|
74
|
+
"surface": "design-ui"
|
|
75
|
+
},
|
|
4
76
|
{
|
|
5
77
|
"id": "artboard-rename-and-files",
|
|
6
78
|
"version": "1.3.0",
|
package/apps/studio/ws.ts
CHANGED
|
@@ -36,6 +36,9 @@ export type WsData =
|
|
|
36
36
|
* a desktop, which is what makes every broadcast below reach everybody
|
|
37
37
|
* exactly as it always did. */
|
|
38
38
|
session: string;
|
|
39
|
+
/** WHO opened this socket, as the proxy vouched it — Cloud Phase 27.
|
|
40
|
+
* `''` on a desktop, where the project's git identity is the person. */
|
|
41
|
+
user?: string;
|
|
39
42
|
}
|
|
40
43
|
| {
|
|
41
44
|
id: string;
|
|
@@ -446,8 +449,12 @@ export function createWs(
|
|
|
446
449
|
else if (msg.type === 'tabs' && Array.isArray(msg.tabs)) inspect.setOpenTabs(msg.tabs);
|
|
447
450
|
else if (msg.type === 'select' && msg.selection) inspect.setSelected(msg.selection);
|
|
448
451
|
else if (msg.type === 'clear-select') inspect.setSelected(null);
|
|
449
|
-
else if (msg.type === 'comments-add' && msg.payload)
|
|
450
|
-
|
|
452
|
+
else if (msg.type === 'comments-add' && msg.payload) {
|
|
453
|
+
// In a cell the author is the vouched member, never a claim in the
|
|
454
|
+
// frame and never the cell's own git identity (the machine).
|
|
455
|
+
const vouched = ws.data.kind === 'inspector' ? ws.data.user : '';
|
|
456
|
+
await api.commentsAdd(vouched ? { ...msg.payload, author: vouched } : msg.payload);
|
|
457
|
+
} else if (msg.type === 'comments-patch' && msg.id)
|
|
451
458
|
await api.commentsPatch(msg.id, msg.patch || {});
|
|
452
459
|
else if (msg.type === 'comments-delete' && msg.id) await api.commentsDelete(msg.id);
|
|
453
460
|
else if (msg.type === 'comments-request' && typeof msg.file === 'string') {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1agh/maude",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.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": {
|
|
@@ -56,13 +56,13 @@
|
|
|
56
56
|
"test:e2e:desktop:parity:cloud": "pnpm --filter @maude/desktop-e2e e2e:parity:cloud"
|
|
57
57
|
},
|
|
58
58
|
"optionalDependencies": {
|
|
59
|
-
"@1agh/maude-darwin-arm64": "1.
|
|
60
|
-
"@1agh/maude-darwin-x64": "1.
|
|
61
|
-
"@1agh/maude-linux-arm64": "1.
|
|
62
|
-
"@1agh/maude-linux-arm64-musl": "1.
|
|
63
|
-
"@1agh/maude-linux-x64": "1.
|
|
64
|
-
"@1agh/maude-linux-x64-musl": "1.
|
|
65
|
-
"@1agh/maude-win32-x64": "1.
|
|
59
|
+
"@1agh/maude-darwin-arm64": "1.4.0",
|
|
60
|
+
"@1agh/maude-darwin-x64": "1.4.0",
|
|
61
|
+
"@1agh/maude-linux-arm64": "1.4.0",
|
|
62
|
+
"@1agh/maude-linux-arm64-musl": "1.4.0",
|
|
63
|
+
"@1agh/maude-linux-x64": "1.4.0",
|
|
64
|
+
"@1agh/maude-linux-x64-musl": "1.4.0",
|
|
65
|
+
"@1agh/maude-win32-x64": "1.4.0"
|
|
66
66
|
},
|
|
67
67
|
"files": [
|
|
68
68
|
"cli",
|
|
@@ -205,7 +205,7 @@
|
|
|
205
205
|
// module, its tokens, its components CSS and its meta as separate
|
|
206
206
|
// requests. Getting the document through and nothing else is what
|
|
207
207
|
// "refused to connect" looks like from the outside.
|
|
208
|
-
|
|
208
|
+
let cap = params.get('t') || '';
|
|
209
209
|
// THE BASE THIS DOCUMENT WAS SERVED FROM, not the origin root.
|
|
210
210
|
//
|
|
211
211
|
// The fleet's canvas origin puts the project in the PATH
|
|
@@ -223,7 +223,7 @@
|
|
|
223
223
|
return cap ? abs + (abs.includes('?') ? '&' : '?') + 't=' + encodeURIComponent(cap) : abs;
|
|
224
224
|
};
|
|
225
225
|
const canvasQuery = shaParam ? ('?sha=' + encodeURIComponent(shaParam)) : '';
|
|
226
|
-
|
|
226
|
+
let canvasUrl = canvasRel ? withCap('/' + designRel + '/' + canvasRel + canvasQuery) : null;
|
|
227
227
|
const myFileKey = canvasRel ? (designRel + '/' + canvasRel) : null;
|
|
228
228
|
// True while an `ai-activity` entry is live for THIS canvas (an agent is
|
|
229
229
|
// running /design:edit|new on it). Mirrors ai-banner's gate: parent relays
|
|
@@ -250,6 +250,19 @@
|
|
|
250
250
|
// The panel just optimistically applied an edit → skip the redundant
|
|
251
251
|
// follow-up module reload (set here, parent-verified).
|
|
252
252
|
lastCssOptimisticAt = Date.now();
|
|
253
|
+
} else if (m.dgn === 'canvas-cap') {
|
|
254
|
+
// A re-minted capability (it expires; app.jsx refreshes it). Every
|
|
255
|
+
// URL built from here on carries it, and asking for this shell
|
|
256
|
+
// document with it re-plants the origin's cookie — the one module
|
|
257
|
+
// imports, assets and the live sockets fall back to. Without this an
|
|
258
|
+
// open canvas stopped loading and updating once its first capability
|
|
259
|
+
// expired. Only a well-formed token, and only in the cloud (a
|
|
260
|
+
// desktop canvas never had one).
|
|
261
|
+
const t = m.t;
|
|
262
|
+
if (!cap || typeof t !== 'string' || t.length > 4096 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(t)) return;
|
|
263
|
+
cap = t;
|
|
264
|
+
if (canvasRel) canvasUrl = withCap('/' + designRel + '/' + canvasRel + canvasQuery);
|
|
265
|
+
fetch(withCap('/_canvas-shell.html'), { cache: 'no-store', credentials: 'same-origin' }).catch(() => {});
|
|
253
266
|
}
|
|
254
267
|
});
|
|
255
268
|
|
|
@@ -394,12 +407,22 @@
|
|
|
394
407
|
if (msg.type !== 'canvas-hmr') return;
|
|
395
408
|
if (msg.mode === 'css') {
|
|
396
409
|
const v = msg.version || Date.now();
|
|
397
|
-
// Match by
|
|
398
|
-
|
|
410
|
+
// Match by PATH when we have one; otherwise refresh all. By path,
|
|
411
|
+
// not by file name: every design system has a `tokens.css`, and
|
|
412
|
+
// a change to one canvas's imported `system/<a>/tokens.css`
|
|
413
|
+
// "matched" the shell's link to `system/<b>/tokens.css` — which
|
|
414
|
+
// swapped the wrong sheet and skipped the reload below that the
|
|
415
|
+
// changed one needed (plan T31/L16).
|
|
416
|
+
const changed = msg.file ? '/' + msg.file : '';
|
|
399
417
|
let matched = false;
|
|
400
418
|
for (const link of document.querySelectorAll('link[rel="stylesheet"]')) {
|
|
401
419
|
const href = link.getAttribute('href') || '';
|
|
402
|
-
if (!
|
|
420
|
+
if (!href) continue;
|
|
421
|
+
let linkPath = '';
|
|
422
|
+
try {
|
|
423
|
+
linkPath = decodeURIComponent(new URL(href, location.href).pathname);
|
|
424
|
+
} catch {}
|
|
425
|
+
if (!changed || linkPath.endsWith(changed)) {
|
|
403
426
|
const base = href.split('?')[0];
|
|
404
427
|
link.setAttribute('href', base + '?v=' + v);
|
|
405
428
|
matched = true;
|
|
@@ -416,7 +439,21 @@
|
|
|
416
439
|
if (!matched && msg.file && canvasRel) {
|
|
417
440
|
const cssDir = msg.file.replace(/[^/]+$/, '');
|
|
418
441
|
const canvasDir = canvasRel.replace(/[^/]+$/, '');
|
|
419
|
-
if (cssDir === canvasDir)
|
|
442
|
+
if (cssDir === canvasDir) {
|
|
443
|
+
location.reload();
|
|
444
|
+
} else {
|
|
445
|
+
// …and a stylesheet imported from ANYWHERE else (a design
|
|
446
|
+
// system's tokens.css) is inlined the same way. The module's
|
|
447
|
+
// style tag names what it inlined; re-import so it re-injects.
|
|
448
|
+
// (Canvas script could add names here, but that can only
|
|
449
|
+
// FORCE a reload — the safe direction.)
|
|
450
|
+
var bundled = document.querySelector('style[data-canvas-css="bundled"]');
|
|
451
|
+
var names = bundled && bundled.dataset.canvasCssSources ? bundled.dataset.canvasCssSources.split('|') : [];
|
|
452
|
+
if (names.indexOf(msg.file) !== -1) {
|
|
453
|
+
if (window.__maudeCanvasRuntime && window.__maudeCanvasRuntime.remount) softReload(v);
|
|
454
|
+
else location.reload();
|
|
455
|
+
}
|
|
456
|
+
}
|
|
420
457
|
}
|
|
421
458
|
} else if (msg.mode === 'module' || msg.mode === 'hard') {
|
|
422
459
|
// Only reload when the change touches *this* canvas (or `_lib`).
|
|
@@ -443,7 +480,11 @@
|
|
|
443
480
|
// direction; it can never suppress one.)
|
|
444
481
|
var hasComps = false;
|
|
445
482
|
try { hasComps = !!(window.__maude_comps__ && window.__maude_comps__().length); } catch (err) { hasComps = false; }
|
|
446
|
-
|
|
483
|
+
// …but NEVER a sync write (`remote`): it can carry a
|
|
484
|
+
// teammate's change merged under this person's own edit (a
|
|
485
|
+
// lost race re-applied onto theirs), and skipping it left
|
|
486
|
+
// their change off this canvas until a manual reload.
|
|
487
|
+
if (!hasComps && !msg.remote && Date.now() - lastCssOptimisticAt < 1500) return;
|
|
447
488
|
}
|
|
448
489
|
// Phase 30 (F4) — prefer an in-place hot-swap for ANY canvas-body
|
|
449
490
|
// (`module`) change whenever the canvas runtime is mounted: the
|
|
@@ -475,7 +475,7 @@
|
|
|
475
475
|
"tracker": {
|
|
476
476
|
"type": "object",
|
|
477
477
|
"additionalProperties": false,
|
|
478
|
-
"description": "Issue / task tracker. Used by /flow:done, /flow:bug-rca, /flow:bug-fix to optionally create or update tickets.",
|
|
478
|
+
"description": "Issue / task tracker. Used by /flow:done, /flow:bug-rca, /flow:bug-fix and /flow:status to optionally read, create or update tickets. `orbit` additionally routes /flow:plan (find or create the task), /flow:execute (working-state reports) and /flow:done (close-time artifact push, warn-only) through the `orbit-backend` skill.",
|
|
479
479
|
"properties": {
|
|
480
480
|
"provider": {
|
|
481
481
|
"type": "string",
|
|
@@ -487,13 +487,26 @@
|
|
|
487
487
|
"notion",
|
|
488
488
|
"asana",
|
|
489
489
|
"shortcut",
|
|
490
|
+
"orbit",
|
|
490
491
|
"none"
|
|
491
492
|
],
|
|
492
493
|
"default": "none"
|
|
493
494
|
},
|
|
494
495
|
"mcp": {
|
|
495
496
|
"type": "string",
|
|
496
|
-
"description": "MCP tool name prefix used to call the provider (e.g. `mcp__claude_ai_ClickUp`, `mcp__github`). Generic commands resolve tool names by appending the operation (`<mcp>_<op>`). Omit if no MCP server is configured — commands will print payloads for manual handling."
|
|
497
|
+
"description": "MCP tool name prefix used to call the provider (e.g. `mcp__claude_ai_ClickUp`, `mcp__github`, `mcp__orbit`). Generic commands resolve tool names by appending the operation (`<mcp>_<op>`). Omit if no MCP server is configured — commands will print payloads for manual handling."
|
|
498
|
+
},
|
|
499
|
+
"baseUrl": {
|
|
500
|
+
"type": "string",
|
|
501
|
+
"format": "uri",
|
|
502
|
+
"pattern": "^https?://",
|
|
503
|
+
"description": "Base URL of a self-hosted tracker instance — used by `provider: orbit` (e.g. `https://orbit.example.com`); other providers ignore it. A committed pointer, never a secret: it names the MCP endpoint the project's `.mcp.json` entry targets (`<baseUrl>/api/mcp`) and the task links (`<baseUrl>/t/ORB-123`)."
|
|
504
|
+
},
|
|
505
|
+
"tokenEnv": {
|
|
506
|
+
"type": "string",
|
|
507
|
+
"pattern": "^[A-Z_][A-Z0-9_]*$",
|
|
508
|
+
"default": "ORBIT_MCP_TOKEN",
|
|
509
|
+
"description": "Name of the environment variable holding the per-machine bearer token for the tracker's MCP server — used by `provider: orbit`; other providers ignore it. Only the variable NAME is stored here; the token lives in the user's environment and `.mcp.json` references it as `${<tokenEnv>}`. Flow commands check whether it is set — they never read, print or write its value."
|
|
497
510
|
},
|
|
498
511
|
"defaults": {
|
|
499
512
|
"type": "object",
|
package/plugins/flow/README.md
CHANGED
|
@@ -40,6 +40,6 @@ For the full catalog (group definitions, member descriptions, rename history), s
|
|
|
40
40
|
|
|
41
41
|
## Skills
|
|
42
42
|
|
|
43
|
-
`workflow-state`, `ddr-keeper`, `scenario`, `agent-browser`, `agent-device`, `codebase-intelligence`, `a11y-checker`, `question-protocol`, `make-skill-template`, `claude-md-keeper`, `debugging-rules`, `a11y-rules`, `motion-rules`, `responsive-rules`, `testing-rules`, `skill-loader
|
|
43
|
+
`workflow-state`, `ddr-keeper`, `scenario`, `agent-browser`, `agent-device`, `codebase-intelligence`, `a11y-checker`, `question-protocol`, `make-skill-template`, `claude-md-keeper`, `debugging-rules`, `a11y-rules`, `motion-rules`, `responsive-rules`, `testing-rules`, `skill-loader`, `orbit-backend` (the `orbit` tracker provider's contract).
|
|
44
44
|
|
|
45
45
|
See [`skills/`](./skills/) for the full list and per-skill SKILL.md files.
|