@unoverse-platform/studio 0.1.109 → 0.1.111
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/bin/studio.mjs +3 -3
- package/local/authoring.ts +2 -2
- package/local/catalog.ts +8 -4
- package/local/design-home.d.mts +2 -0
- package/local/design-home.mjs +11 -0
- package/local/plugin.ts +51 -22
- package/local/sample-identity/brand.yaml +1 -1
- package/local/sample-identity/organisation.yaml +1 -1
- package/local/sample-identity/purpose.yaml +1 -1
- package/local/sample-identity/story.yaml +1 -1
- package/local/scaffold.mjs +20 -4
- package/local/source.ts +13 -7
- package/package.json +1 -1
- package/screens/DesignSystemView.tsx +1 -1
- package/screens/EmptyLibrary.tsx +1 -1
- package/screens/PromptBlocksView.tsx +1 -1
- package/src/App.tsx +5 -5
- package/vendor/base/src/definitions/load/assets.ts +2 -2
- package/vendor/base/src/definitions/registry/catalog.ts +1 -1
- package/vendor/base/src/definitions/registry/datasetSql.ts +7 -12
- package/vendor/base/src/definitions/registry/homes.ts +15 -5
- package/vendor/base/src/definitions/registry/objects.ts +1 -1
- package/vendor/base/src/definitions/registry/orgDocuments.ts +2 -2
- package/vendor/base/src/definitions/registry/orgPack.ts +3 -2
- package/vendor/base/src/definitions/registry/pipelines.ts +1 -1
- package/vendor/base/src/definitions/theme.ts +5 -6
- package/vendor/base/src/items/baseVersion.ts +1 -1
- package/vendor/base/src/items/collect.ts +1 -1
- package/vendor/base/src/lint/design/file.mjs +2 -2
- package/vendor/base/src/lint/design/index.d.mts +6 -0
- package/vendor/base/src/lint/design/index.mjs +45 -17
- package/vendor/base/src/lint/design/vocabulary.mjs +2 -2
- package/vendor/base/src/lint/nodes/blocks.mjs +3 -3
- package/vendor/base/src/lint/nodes/node.mjs +1 -1
- package/vendor/base/src/lint/objects/index.d.mts +6 -0
- package/vendor/base/src/lint/objects/index.mjs +27 -6
- package/vendor/base/src/lint/prompts/index.d.mts +6 -0
- package/vendor/base/src/lint/prompts/index.mjs +8 -3
- package/vendor/base/src/paths.ts +65 -20
- package/vendor/base/src/plugins/discovery.ts +1 -1
- package/vendor/base/src/plugins/loader.ts +5 -7
- package/vendor/base/src/security/rules.ts +6 -0
package/vendor/base/src/paths.ts
CHANGED
|
@@ -14,6 +14,12 @@ import * as path from "path";
|
|
|
14
14
|
import { fileURLToPath } from "url";
|
|
15
15
|
import { existsSync, renameSync } from "fs";
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Where the marketplace package keeps the tier, relative to the repo that holds it. Also the
|
|
19
|
+
* platform repo's marker (findHome), so it is declared before anything resolves.
|
|
20
|
+
*/
|
|
21
|
+
const MARKETPLACE_IN_REPO = path.join("packages", "marketplace", "definitions");
|
|
22
|
+
|
|
17
23
|
/**
|
|
18
24
|
* Find the content home when nobody said.
|
|
19
25
|
*
|
|
@@ -27,11 +33,17 @@ function findHome(): string {
|
|
|
27
33
|
|
|
28
34
|
let dir = path.dirname(fileURLToPath(import.meta.url));
|
|
29
35
|
for (;;) {
|
|
30
|
-
// The in-repo home
|
|
31
|
-
//
|
|
32
|
-
// 2026-
|
|
36
|
+
// The in-repo home: `apps/unoverse` in a repo that also carries the marketplace tier
|
|
37
|
+
// (`packages/marketplace/definitions`), so a stray `apps/unoverse` elsewhere cannot
|
|
38
|
+
// claim it. The marker was `apps/unoverse/design` until 2026-10-04, when the design tree
|
|
39
|
+
// was retired (orgs live in their own repos, the tier in the marketplace package, the
|
|
40
|
+
// editor schemas on the docs site); `nodes` was the marker before 2026-09-08.
|
|
41
|
+
//
|
|
42
|
+
// NEITHER MARKER IS IN AN IMAGE. `.dockerignore` excludes the marketplace tier exactly
|
|
43
|
+
// as it excluded the design tree, so a deployed universe finds nothing here and falls
|
|
44
|
+
// back below, as it always has.
|
|
33
45
|
const candidate = path.join(dir, "apps/unoverse");
|
|
34
|
-
if (existsSync(path.join(
|
|
46
|
+
if (existsSync(path.join(dir, MARKETPLACE_IN_REPO)) && existsSync(candidate)) return candidate;
|
|
35
47
|
const parent = path.dirname(dir);
|
|
36
48
|
if (parent === dir) break;
|
|
37
49
|
dir = parent;
|
|
@@ -41,8 +53,9 @@ function findHome(): string {
|
|
|
41
53
|
// produced the silent-wrong-path failures, so say so instead: every export below becomes
|
|
42
54
|
// a path under cwd, and anything reading them will fail somewhere obvious.
|
|
43
55
|
console.warn(
|
|
44
|
-
"[unoverse:base] UNOVERSE_HOME is not set and no apps/unoverse
|
|
45
|
-
"
|
|
56
|
+
"[unoverse:base] UNOVERSE_HOME is not set and no platform repo (apps/unoverse beside " +
|
|
57
|
+
"packages/marketplace/definitions) was found above this package. Falling back to the " +
|
|
58
|
+
"working directory; set UNOVERSE_HOME to the content home.",
|
|
46
59
|
);
|
|
47
60
|
return process.cwd();
|
|
48
61
|
}
|
|
@@ -51,9 +64,13 @@ let HOME = findHome();
|
|
|
51
64
|
|
|
52
65
|
/** Everything the runtime reads off disk, in one place. */
|
|
53
66
|
export interface Paths {
|
|
54
|
-
/** Node packages: the marketplace tier's nodes,
|
|
67
|
+
/** Node packages: the marketplace tier's nodes, `<marketplace>/nodes`. */
|
|
55
68
|
nodes: string;
|
|
56
|
-
/**
|
|
69
|
+
/**
|
|
70
|
+
* The design tree, `<home>/design`: one folder per org in a workspace that keeps orgs this
|
|
71
|
+
* way. ABSENT in the platform repo (retired 2026-10-04) and on a deployed universe, and every
|
|
72
|
+
* reader takes an absent tree as "no org tier here", never as an error.
|
|
73
|
+
*/
|
|
57
74
|
design: string;
|
|
58
75
|
/** Authored agent skills (SKILL.md). */
|
|
59
76
|
skills: string;
|
|
@@ -63,7 +80,13 @@ export interface Paths {
|
|
|
63
80
|
plugins: string;
|
|
64
81
|
/** LEGACY: the pre-migration node package folders. Usually absent. */
|
|
65
82
|
packages: string;
|
|
66
|
-
/**
|
|
83
|
+
/**
|
|
84
|
+
* THE MARKETPLACE TIER on disk: components, atoms, templates, styles, objects, pipelines,
|
|
85
|
+
* skills, blocks and nodes. In the monorepo it is `packages/marketplace/definitions`, the
|
|
86
|
+
* folder the marketplace package publishes, authored where it ships. Absent anywhere else
|
|
87
|
+
* (a deployed universe, a developer's project), where the tier comes from installed rows
|
|
88
|
+
* or the installed package instead. Every reader of the tier starts here.
|
|
89
|
+
*/
|
|
67
90
|
marketplace: string;
|
|
68
91
|
/**
|
|
69
92
|
* AN ORG'S OWN REPO (UNO-88). When set, the home IS this one org: its folders at the root,
|
|
@@ -100,19 +123,40 @@ export function designDir(root: string): string {
|
|
|
100
123
|
return design;
|
|
101
124
|
}
|
|
102
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Find the marketplace tier for a home: `packages/marketplace/definitions` in the repo that
|
|
128
|
+
* holds the home, which is the home itself or the nearest folder above it carrying one.
|
|
129
|
+
*
|
|
130
|
+
* ANCHORED ON THE FOLDER, like findHome, never on a depth. A home with no such folder above
|
|
131
|
+
* it (a deployed universe, a developer's project, a test's scratch home) gets the path it
|
|
132
|
+
* would have inside the home itself, which does not exist, so the tier there resolves from
|
|
133
|
+
* installed rows or the installed package exactly as it did when the tier lived elsewhere.
|
|
134
|
+
*/
|
|
135
|
+
function findMarketplace(home: string): string {
|
|
136
|
+
for (let dir = home; ; ) {
|
|
137
|
+
const candidate = path.join(dir, MARKETPLACE_IN_REPO);
|
|
138
|
+
if (existsSync(candidate)) return candidate;
|
|
139
|
+
const parent = path.dirname(dir);
|
|
140
|
+
if (parent === dir) break;
|
|
141
|
+
dir = parent;
|
|
142
|
+
}
|
|
143
|
+
return path.join(home, MARKETPLACE_IN_REPO);
|
|
144
|
+
}
|
|
145
|
+
|
|
103
146
|
function derive(home: string): Paths {
|
|
147
|
+
const marketplace = findMarketplace(home);
|
|
104
148
|
return {
|
|
105
149
|
design: designDir(home),
|
|
106
|
-
// THE MARKETPLACE TIER,
|
|
150
|
+
// THE MARKETPLACE TIER, ONE ROOT FOR EVERY KIND (`marketplace` below).
|
|
107
151
|
//
|
|
108
|
-
// Skills and blocks were authored in a `prompts/` folder beside design/,
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
nodes: path.join(
|
|
114
|
-
skills: path.join(
|
|
115
|
-
promptBlocks: path.join(
|
|
152
|
+
// Skills and blocks were authored in a `prompts/` folder beside design/, and nodes in
|
|
153
|
+
// `nodes/` beside it until 2026-09-08. Two roots for one tier is what let a surface
|
|
154
|
+
// read half of it and look right. The tier was then authored under
|
|
155
|
+
// `design/marketplace/` and copied into the marketplace package on every release; it
|
|
156
|
+
// is authored in the package now, so there is one copy and it is the one that ships.
|
|
157
|
+
nodes: path.join(marketplace, "nodes"),
|
|
158
|
+
skills: path.join(marketplace, "skills"),
|
|
159
|
+
promptBlocks: path.join(marketplace, "blocks"),
|
|
116
160
|
plugins: path.join(home, "plugins"),
|
|
117
161
|
// DELIBERATELY under the home, not at the repo root.
|
|
118
162
|
//
|
|
@@ -121,7 +165,7 @@ function derive(home: string): Paths {
|
|
|
121
165
|
// the @unoverse-platform scope with an entry point, so it found THIS package and
|
|
122
166
|
// returned ["@unoverse-platform/base"] — the runtime being offered as a node.
|
|
123
167
|
packages: path.join(home, "packages"),
|
|
124
|
-
marketplace
|
|
168
|
+
marketplace,
|
|
125
169
|
};
|
|
126
170
|
}
|
|
127
171
|
|
|
@@ -156,6 +200,8 @@ export const NODES_HOME = paths.nodes;
|
|
|
156
200
|
export const DESIGN_HOME = paths.design;
|
|
157
201
|
export const SKILLS_HOME = paths.skills;
|
|
158
202
|
export const PROMPT_BLOCKS_HOME = paths.promptBlocks;
|
|
203
|
+
/** The marketplace tier on disk (`Paths.marketplace`). */
|
|
204
|
+
export const MARKETPLACE_HOME = paths.marketplace;
|
|
159
205
|
/**
|
|
160
206
|
* Where INSTALLED items are written so the loaders can read them (items/hydrate.ts).
|
|
161
207
|
*
|
|
@@ -190,4 +236,3 @@ export function databaseOnly(): boolean {
|
|
|
190
236
|
}
|
|
191
237
|
export const PLUGINS_DIR = paths.plugins;
|
|
192
238
|
export const PACKAGES_PATH = paths.packages;
|
|
193
|
-
export const MARKETPLACE_PATH = paths.marketplace;
|
|
@@ -39,7 +39,7 @@ function scanPluginDir(dir: string, scopes: string[]): string[] {
|
|
|
39
39
|
return plugins;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
/** The marketplace tier's node packages (
|
|
42
|
+
/** The marketplace tier's node packages (packages/marketplace/definitions/nodes). */
|
|
43
43
|
export function discoverNodesHome(): string[] {
|
|
44
44
|
return scanPluginDir(NODES_HOME, ["@unoverse-platform/"]);
|
|
45
45
|
}
|
|
@@ -7,7 +7,7 @@ import * as path from "path";
|
|
|
7
7
|
import { execSync } from "child_process";
|
|
8
8
|
import { pathToFileURL } from "url";
|
|
9
9
|
import { getNodeRegistry, getPluginNodeMap, deleteNode } from "../registry.js";
|
|
10
|
-
import { PACKAGES_PATH,
|
|
10
|
+
import { PACKAGES_PATH, PLUGINS_DIR, NODES_HOME } from "../paths.js";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Resolve a package directory's entry file from its package.json.
|
|
@@ -87,18 +87,16 @@ export async function loadPlugin(pluginName: string, api: any): Promise<string[]
|
|
|
87
87
|
|
|
88
88
|
try {
|
|
89
89
|
const shortName = pluginName.replace(/@[^/]+\//, "");
|
|
90
|
-
// Resolution order: the in-Unoverse node home wins, then legacy /packages,
|
|
91
|
-
//
|
|
90
|
+
// Resolution order: the in-Unoverse node home wins, then legacy /packages, then the
|
|
91
|
+
// bare npm specifier. (A `packages-marketplace` folder was searched third until the
|
|
92
|
+
// marketplace tier took that setting's name; no checkout or image had one.)
|
|
92
93
|
const homePath = path.join(NODES_HOME, shortName);
|
|
93
94
|
const pkgPath = path.join(PACKAGES_PATH, shortName);
|
|
94
|
-
const mktPath = path.join(MARKETPLACE_PATH, shortName);
|
|
95
95
|
const resolvedPath = fs.existsSync(homePath)
|
|
96
96
|
? homePath
|
|
97
97
|
: fs.existsSync(pkgPath)
|
|
98
98
|
? pkgPath
|
|
99
|
-
:
|
|
100
|
-
? mktPath
|
|
101
|
-
: pluginName;
|
|
99
|
+
: pluginName;
|
|
102
100
|
|
|
103
101
|
const pkg = await importPluginModule(resolvedPath);
|
|
104
102
|
const plugin = pkg.default || pkg;
|
|
@@ -18,6 +18,12 @@ export interface Rule {
|
|
|
18
18
|
requires: Requirement;
|
|
19
19
|
/** Why. Required for `public` and `own-gate`, because both need a reason to be read. */
|
|
20
20
|
note?: string;
|
|
21
|
+
/**
|
|
22
|
+
* `false` keeps an author's route out of the audit trail because it changes nothing a person
|
|
23
|
+
* manages: running a node test, laying a canvas out without saving. The trail is how people
|
|
24
|
+
* manage the platform (who made, changed or deleted what), never what runs on it (UNO-103).
|
|
25
|
+
*/
|
|
26
|
+
audit?: false;
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
export const ALL = "*" as const;
|