@1agh/maude 0.51.1 → 0.52.1
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/api.ts +389 -14
- package/apps/studio/bin/_video-playwright.mjs +15 -6
- package/apps/studio/canvas-edit.ts +141 -20
- package/apps/studio/canvas-lib.tsx +61 -0
- package/apps/studio/client/app.jsx +824 -121
- package/apps/studio/client/panels/ClipInspector.jsx +409 -0
- package/apps/studio/client/panels/CloudBar.jsx +12 -2
- package/apps/studio/client/panels/TimelinePanel.jsx +1775 -430
- package/apps/studio/client/panels/timeline-media-cache.js +274 -0
- package/apps/studio/client/panels/timeline-parse.js +46 -1
- package/apps/studio/client/panels/timeline-scale.js +64 -0
- package/apps/studio/client/report-bug.jsx +15 -15
- package/apps/studio/client/styles/3-shell-maude.css +446 -3
- package/apps/studio/client/styles/4-components-maude.css +55 -0
- package/apps/studio/client/styles/4-components.css +0 -83
- package/apps/studio/clip-ops.ts +1980 -0
- package/apps/studio/cloud/endpoints.ts +88 -17
- package/apps/studio/credential-grammar.ts +100 -0
- package/apps/studio/debug-bundle.ts +12 -0
- package/apps/studio/dist/client.bundle.js +2048 -2048
- package/apps/studio/dist/styles.css +1 -1
- package/apps/studio/exporters/video.ts +49 -10
- package/apps/studio/http.ts +113 -6
- package/apps/studio/ripple.ts +335 -0
- package/apps/studio/sync/hub-link.ts +3 -3
- package/apps/studio/sync/hubs-config.ts +32 -0
- package/apps/studio/sync/workspace-signin.ts +8 -4
- package/apps/studio/test/_helpers.ts +5 -3
- package/apps/studio/test/canvas-create-api.test.ts +8 -2
- package/apps/studio/test/canvas-origin-gate.test.ts +20 -0
- package/apps/studio/test/clip-addressing.test.ts +7 -6
- package/apps/studio/test/clip-ops.test.ts +836 -0
- package/apps/studio/test/cloud-endpoints.test.ts +37 -2
- package/apps/studio/test/comments-api.test.ts +49 -0
- package/apps/studio/test/credential-grammar.test.ts +107 -0
- package/apps/studio/test/read-only-role.test.ts +95 -0
- package/apps/studio/test/ripple.test.ts +197 -0
- package/apps/studio/test/timeline-scale.test.ts +65 -0
- package/apps/studio/test/workspace-signin.test.ts +4 -1
- package/apps/studio/whats-new.json +35 -0
- package/cli/commands/share.mjs +8 -4
- package/cli/lib/ddr-to-kgai.mjs +6 -1
- package/cli/lib/ddr-to-kgai.test.mjs +1 -2
- package/cli/lib/hubs-config.mjs +15 -1
- package/cli/lib/hubs-config.test.mjs +19 -0
- package/cli/lib/share-plan.mjs +5 -1
- package/cli/lib/share-plan.test.mjs +11 -2
- package/package.json +8 -8
package/cli/lib/ddr-to-kgai.mjs
CHANGED
|
@@ -862,7 +862,12 @@ export function buildDocsBatch(aiDir, scope = {}) {
|
|
|
862
862
|
// A doc that cites DDRs is context ABOUT them.
|
|
863
863
|
for (const num of new Set([...t.matchAll(/DDR-(\d+)/g)].map((m) => m[1].padStart(3, '0')))) {
|
|
864
864
|
muts.push({ op: 'upsert_element', kind: 'decision', name: ddrRef(num, scope) });
|
|
865
|
-
muts.push({
|
|
865
|
+
muts.push({
|
|
866
|
+
op: 'add_link',
|
|
867
|
+
from: ref,
|
|
868
|
+
to: `decision:${ddrRef(num, scope)}`,
|
|
869
|
+
link: 'REFERENCES',
|
|
870
|
+
});
|
|
866
871
|
}
|
|
867
872
|
decisions.push({
|
|
868
873
|
title: `Doc: ${title}`.slice(0, 160),
|
|
@@ -102,8 +102,7 @@ test('decision names are namespaced by repo so DDR numbers do not collide cross-
|
|
|
102
102
|
const files = { 'DDR-001-a.md': '# DDR-001: Alpha\n\n**Tags:** infra\n' };
|
|
103
103
|
const a = buildDdrBatch(fixtureDir(files), { repo: 'vantage', dept: 'marketing' });
|
|
104
104
|
const b = buildDdrBatch(fixtureDir(files), { repo: 'AI-StudyMate', dept: 'dev' });
|
|
105
|
-
const nameOf = (batch) =>
|
|
106
|
-
batch.decisions[0].mutations.find((m) => m.kind === 'decision').name;
|
|
105
|
+
const nameOf = (batch) => batch.decisions[0].mutations.find((m) => m.kind === 'decision').name;
|
|
107
106
|
assert.equal(nameOf(a.batch), 'vantage/DDR-001');
|
|
108
107
|
assert.equal(nameOf(b.batch), 'AI-StudyMate/DDR-001');
|
|
109
108
|
assert.notEqual(nameOf(a.batch), nameOf(b.batch));
|
package/cli/lib/hubs-config.mjs
CHANGED
|
@@ -83,12 +83,26 @@ export function saveHubsConfig(config) {
|
|
|
83
83
|
*
|
|
84
84
|
* @param {string} url
|
|
85
85
|
* @param {string} token
|
|
86
|
+
* `role` is the ONE prior field carried across a relink (Cloud Phase 25 C2).
|
|
87
|
+
* It records what the workspace vouched for at sign-in, and this path has no
|
|
88
|
+
* fresher answer — the CLI does not sign in. Dropping it would silently show
|
|
89
|
+
* a viewer the editing UI again, which is the exact experience the flag
|
|
90
|
+
* exists to prevent; a stale value costs a redundant hidden affordance and
|
|
91
|
+
* self-corrects at the next workspace sign-in. Nothing ELSE is preserved:
|
|
92
|
+
* `adoptedAt` is a per-machine attestation that a relink is entitled to clear.
|
|
93
|
+
*
|
|
86
94
|
* @param {{ adoptedAt?: number }} [extra]
|
|
87
95
|
*/
|
|
88
96
|
export function addHub(url, token, extra = {}) {
|
|
89
97
|
const norm = normalizeUrl(url);
|
|
90
98
|
const cfg = loadHubsConfig();
|
|
91
|
-
cfg.hubs[norm]
|
|
99
|
+
const priorRole = cfg.hubs[norm]?.role;
|
|
100
|
+
cfg.hubs[norm] = {
|
|
101
|
+
token,
|
|
102
|
+
linkedAt: Date.now(),
|
|
103
|
+
...(priorRole ? { role: priorRole } : {}),
|
|
104
|
+
...extra,
|
|
105
|
+
};
|
|
92
106
|
saveHubsConfig(cfg);
|
|
93
107
|
return cfg.hubs[norm];
|
|
94
108
|
}
|
|
@@ -98,3 +98,22 @@ test('addHub keys URLs case-insensitively (same hub after host normalization)',
|
|
|
98
98
|
assert.equal(hubs['https://hub.example.com'].token, 'mau_second');
|
|
99
99
|
});
|
|
100
100
|
});
|
|
101
|
+
|
|
102
|
+
// Cloud Phase 25 C2 — the studio writes `role` into this shared file, and a
|
|
103
|
+
// CLI relink used to replace the record wholesale and drop it. Not an access
|
|
104
|
+
// hole (the cell refuses the write regardless), but it would silently show a
|
|
105
|
+
// viewer the editing UI again, which is exactly what the flag exists to stop.
|
|
106
|
+
test('a relink preserves the vouched role, and still clears per-machine attestations', () => {
|
|
107
|
+
withTmpConfig(() => {
|
|
108
|
+
addHub('https://p.cloud.maude.sh', 'mau_first', { adoptedAt: 111 });
|
|
109
|
+
// The studio stamps the role after a workspace sign-in.
|
|
110
|
+
const cfg = loadHubsConfig();
|
|
111
|
+
cfg.hubs['https://p.cloud.maude.sh'].role = 'viewer';
|
|
112
|
+
saveHubsConfig(cfg);
|
|
113
|
+
|
|
114
|
+
const after = addHub('https://p.cloud.maude.sh', 'mau_second');
|
|
115
|
+
assert.equal(after.token, 'mau_second');
|
|
116
|
+
assert.equal(after.role, 'viewer', 'the role survives a relink');
|
|
117
|
+
assert.equal(after.adoptedAt, undefined, 'a per-machine attestation does not');
|
|
118
|
+
});
|
|
119
|
+
});
|
package/cli/lib/share-plan.mjs
CHANGED
|
@@ -65,7 +65,11 @@ export function shareMarker(project, { enabled, name }) {
|
|
|
65
65
|
if (!id) throw new Error(`invalid project id: ${project}`);
|
|
66
66
|
return {
|
|
67
67
|
key: `tenants/${id}/share.json`,
|
|
68
|
-
body: JSON.stringify(
|
|
68
|
+
body: JSON.stringify(
|
|
69
|
+
{ enabled: Boolean(enabled), name: String(name ?? id).slice(0, 80) },
|
|
70
|
+
null,
|
|
71
|
+
2
|
|
72
|
+
),
|
|
69
73
|
};
|
|
70
74
|
}
|
|
71
75
|
|
|
@@ -3,7 +3,13 @@
|
|
|
3
3
|
import assert from 'node:assert/strict';
|
|
4
4
|
import test from 'node:test';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
isShareable,
|
|
8
|
+
publishPlan,
|
|
9
|
+
publishSummary,
|
|
10
|
+
shareMarker,
|
|
11
|
+
validProjectId,
|
|
12
|
+
} from './share-plan.mjs';
|
|
7
13
|
|
|
8
14
|
test('SVG is never published, however it is named', () => {
|
|
9
15
|
// Same reason the share origin refuses to SERVE one: an SVG is a document
|
|
@@ -22,7 +28,10 @@ test('a publish cannot climb out of the directory it was pointed at', () => {
|
|
|
22
28
|
['../secret.png', '/etc/x.png', 'a/../../b.png', 'ok.png', 'ui/home.png'],
|
|
23
29
|
'acme'
|
|
24
30
|
);
|
|
25
|
-
assert.deepEqual(
|
|
31
|
+
assert.deepEqual(
|
|
32
|
+
uploads.map((u) => u.from),
|
|
33
|
+
['ok.png', 'ui/home.png']
|
|
34
|
+
);
|
|
26
35
|
assert.equal(skipped.length, 3);
|
|
27
36
|
});
|
|
28
37
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1agh/maude",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.52.1",
|
|
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": {
|
|
@@ -52,13 +52,13 @@
|
|
|
52
52
|
"test:e2e:desktop:acp-cold-start": "pnpm --filter @maude/desktop-e2e e2e:acp-cold-start"
|
|
53
53
|
},
|
|
54
54
|
"optionalDependencies": {
|
|
55
|
-
"@1agh/maude-darwin-arm64": "0.
|
|
56
|
-
"@1agh/maude-darwin-x64": "0.
|
|
57
|
-
"@1agh/maude-linux-arm64": "0.
|
|
58
|
-
"@1agh/maude-linux-arm64-musl": "0.
|
|
59
|
-
"@1agh/maude-linux-x64": "0.
|
|
60
|
-
"@1agh/maude-linux-x64-musl": "0.
|
|
61
|
-
"@1agh/maude-win32-x64": "0.
|
|
55
|
+
"@1agh/maude-darwin-arm64": "0.52.1",
|
|
56
|
+
"@1agh/maude-darwin-x64": "0.52.1",
|
|
57
|
+
"@1agh/maude-linux-arm64": "0.52.1",
|
|
58
|
+
"@1agh/maude-linux-arm64-musl": "0.52.1",
|
|
59
|
+
"@1agh/maude-linux-x64": "0.52.1",
|
|
60
|
+
"@1agh/maude-linux-x64-musl": "0.52.1",
|
|
61
|
+
"@1agh/maude-win32-x64": "0.52.1"
|
|
62
62
|
},
|
|
63
63
|
"files": [
|
|
64
64
|
"cli",
|