@unoverse-platform/studio 0.1.90 → 0.1.92
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/local/plugin.ts +21 -65
- package/package.json +13 -3
- package/vendor/base/src/agent-mcp/discovery.ts +203 -0
- package/vendor/base/src/agent-mcp/handoff.ts +56 -0
- package/vendor/base/src/agent-mcp/index.ts +44 -0
- package/vendor/base/src/agent-mcp/invoke.ts +153 -0
- package/vendor/base/src/agent-mcp/lean.ts +114 -0
- package/vendor/base/src/agent-mcp/memoryContext.ts +104 -0
- package/vendor/base/src/agent-mcp/memoryIngest.ts +88 -0
- package/vendor/base/src/agent-mcp/rowComponents.ts +234 -0
- package/vendor/base/src/agent-mcp/tools.ts +134 -0
- package/vendor/base/src/agent-mcp/types.ts +138 -0
- package/vendor/base/src/auth/auth.ts +307 -0
- package/vendor/base/src/auth/authConfig.ts +73 -0
- package/vendor/base/src/boot.ts +245 -0
- package/vendor/base/src/definitions/definitions.ts +18 -0
- package/vendor/base/src/definitions/dsPackage.ts +45 -0
- package/vendor/base/src/definitions/fsCache.ts +155 -0
- package/vendor/base/src/definitions/index.ts +19 -0
- package/vendor/base/src/definitions/inputs.ts +30 -0
- package/vendor/base/src/definitions/load/compile/component.ts +80 -0
- package/vendor/base/src/definitions/load/compile/index.ts +12 -0
- package/vendor/base/src/definitions/load/compile/sections.ts +132 -0
- package/vendor/base/src/definitions/load/compile/template.ts +153 -0
- package/vendor/base/src/definitions/load/expand/includes.ts +27 -0
- package/vendor/base/src/definitions/load/expand/index.ts +17 -0
- package/vendor/base/src/definitions/load/expand/inherit.ts +169 -0
- package/vendor/base/src/definitions/load/expand/referenced.ts +164 -0
- package/vendor/base/src/definitions/load/expand/refs.ts +106 -0
- package/vendor/base/src/definitions/load/expand/walk.ts +91 -0
- package/vendor/base/src/definitions/load/load.ts +487 -0
- package/vendor/base/src/definitions/model.ts +238 -0
- package/vendor/base/src/definitions/registry/catalog.ts +659 -0
- package/vendor/base/src/definitions/registry/homes.ts +252 -0
- package/vendor/base/src/definitions/theme.ts +383 -0
- package/vendor/base/src/executor.ts +284 -0
- package/vendor/base/src/http/uwsFetchAdapter.ts +397 -0
- package/vendor/base/src/items/baseVersion.ts +96 -0
- package/vendor/base/src/items/collect.ts +246 -0
- package/vendor/base/src/items/fingerprint.ts +34 -0
- package/vendor/base/src/items/publish.ts +212 -0
- package/vendor/base/src/lint/context.mjs +56 -0
- package/vendor/base/src/lint/design/defs.mjs +46 -0
- package/vendor/base/src/lint/design/file.mjs +737 -0
- package/vendor/base/src/lint/design/index.d.mts +30 -0
- package/vendor/base/src/lint/design/index.mjs +996 -0
- package/vendor/base/src/lint/design/tokens.mjs +128 -0
- package/vendor/base/src/lint/design/vocabulary.mjs +181 -0
- package/vendor/base/src/lint/design/walk.mjs +444 -0
- package/vendor/base/src/lint/index.mjs +28 -0
- package/vendor/base/src/lint/nodes/blocks.mjs +63 -0
- package/vendor/base/src/lint/nodes/index.d.mts +28 -0
- package/vendor/base/src/lint/nodes/index.mjs +82 -0
- package/vendor/base/src/lint/nodes/load.mjs +126 -0
- package/vendor/base/src/lint/nodes/node.mjs +764 -0
- package/vendor/base/src/lint/nodes/package.mjs +112 -0
- package/vendor/base/src/lint/nodes/schema.mjs +75 -0
- package/vendor/base/src/logger.ts +33 -0
- package/vendor/base/src/manifests/compose.ts +539 -0
- package/vendor/base/src/manifests/executor/callback.ts +107 -0
- package/vendor/base/src/manifests/executor/context.ts +110 -0
- package/vendor/base/src/manifests/executor/index.ts +47 -0
- package/vendor/base/src/manifests/executor/lookup.ts +21 -0
- package/vendor/base/src/manifests/executor/memory.ts +62 -0
- package/vendor/base/src/manifests/executor/promise.ts +71 -0
- package/vendor/base/src/manifests/executor/refire.ts +34 -0
- package/vendor/base/src/manifests/executor/send.ts +65 -0
- package/vendor/base/src/manifests/executor/session.ts +46 -0
- package/vendor/base/src/manifests/executor/toolBridge.ts +266 -0
- package/vendor/base/src/manifests/index.ts +280 -0
- package/vendor/base/src/manifests/integrity.ts +93 -0
- package/vendor/base/src/manifests/rows.ts +33 -0
- package/vendor/base/src/manifests/runtime/auth/aws.ts +240 -0
- package/vendor/base/src/manifests/runtime/auth/oauth.ts +76 -0
- package/vendor/base/src/manifests/runtime/authorize.ts +159 -0
- package/vendor/base/src/manifests/runtime/channels/final.ts +171 -0
- package/vendor/base/src/manifests/runtime/channels/service.ts +138 -0
- package/vendor/base/src/manifests/runtime/channels/workflow.ts +310 -0
- package/vendor/base/src/manifests/runtime/context.ts +156 -0
- package/vendor/base/src/manifests/runtime/docstore/handlers.ts +547 -0
- package/vendor/base/src/manifests/runtime/docstore/index.ts +135 -0
- package/vendor/base/src/manifests/runtime/docstore/sectionizer.ts +184 -0
- package/vendor/base/src/manifests/runtime/docstore/store.ts +172 -0
- package/vendor/base/src/manifests/runtime/docstore/types.ts +60 -0
- package/vendor/base/src/manifests/runtime/duplex/audioLane.ts +165 -0
- package/vendor/base/src/manifests/runtime/duplex/session.ts +511 -0
- package/vendor/base/src/manifests/runtime/events.ts +223 -0
- package/vendor/base/src/manifests/runtime/helpers.ts +53 -0
- package/vendor/base/src/manifests/runtime/http/allowedHosts.ts +118 -0
- package/vendor/base/src/manifests/runtime/http/request.ts +637 -0
- package/vendor/base/src/manifests/runtime/http/response.ts +162 -0
- package/vendor/base/src/manifests/runtime/index.ts +57 -0
- package/vendor/base/src/manifests/runtime/loops/chunk.ts +98 -0
- package/vendor/base/src/manifests/runtime/loops/loop.ts +191 -0
- package/vendor/base/src/manifests/runtime/loops/paginate.ts +143 -0
- package/vendor/base/src/manifests/runtime/loops/poll.ts +169 -0
- package/vendor/base/src/manifests/runtime/narrate.ts +53 -0
- package/vendor/base/src/manifests/runtime/state.ts +171 -0
- package/vendor/base/src/manifests/runtime/templating.ts +110 -0
- package/vendor/base/src/manifests/runtime/tools/regionSkills.ts +125 -0
- package/vendor/base/src/manifests/runtime/tools/toolloop.ts +550 -0
- package/vendor/base/src/manifests/runtime/usage.ts +87 -0
- package/vendor/base/src/manifests/source.ts +196 -0
- package/vendor/base/src/manifests/watch.ts +67 -0
- package/vendor/base/src/markdown/document.ts +141 -0
- package/vendor/base/src/paths.ts +180 -0
- package/vendor/base/src/platform/audioManager.ts +100 -0
- package/vendor/base/src/platform/clientTransport.ts +65 -0
- package/vendor/base/src/platform/executionContext.ts +157 -0
- package/vendor/base/src/platform/index.ts +10 -0
- package/vendor/base/src/platform/pluginAPI.ts +146 -0
- package/vendor/base/src/platform/redis.ts +54 -0
- package/vendor/base/src/platform/serviceCalls.ts +222 -0
- package/vendor/base/src/pluginBase.ts +248 -0
- package/vendor/base/src/plugins/README.md +57 -0
- package/vendor/base/src/plugins/discovery.ts +87 -0
- package/vendor/base/src/plugins/index.ts +16 -0
- package/vendor/base/src/plugins/loader.ts +179 -0
- package/vendor/base/src/plugins/redis.ts +36 -0
- package/vendor/base/src/plugins/state.ts +53 -0
- package/vendor/base/src/registry.ts +95 -0
- package/vendor/base/src/security/permissions.ts +93 -0
- package/vendor/base/src/security/rules.ts +73 -0
- package/vendor/base/src/template/SafeExpression.ts +556 -0
- package/vendor/base/src/template/StringTemplateResolver.ts +75 -0
- package/vendor/base/src/template/index.ts +22 -0
- package/vendor/base/src/types.ts +50 -0
- package/vendor/base/src/workflow/GetMemoryService.ts +158 -0
- package/vendor/base/src/workflow/PlatformMemoryCore.ts +449 -0
- package/vendor/base/src/workflow/routing.ts +122 -0
- package/vendor/sdk/lib/core/store.ts +26 -6
- package/local/mcp.ts +0 -265
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The declarative node linter, as a LIBRARY. Rules in, findings out.
|
|
3
|
+
*
|
|
4
|
+
* It prints nothing and exits nothing, because four callers need the same rules and each
|
|
5
|
+
* presents them differently:
|
|
6
|
+
*
|
|
7
|
+
* `unoverse lint nodes` coloured lines in a terminal (scripts/lib/lint-nodes.mjs)
|
|
8
|
+
* Studio findings beside the definition you are editing
|
|
9
|
+
* POST /publish a refusal, so a broken manifest never reaches the database
|
|
10
|
+
* CI a non-zero exit
|
|
11
|
+
*
|
|
12
|
+
* It lived in scripts/ as a CLI, which meant the universe could not use it. Publishing
|
|
13
|
+
* without it is the gap LOCAL_STUDIO.md:246 names: "a malformed definition is one restart
|
|
14
|
+
* from a broken server", and a published row does not even need the restart.
|
|
15
|
+
*
|
|
16
|
+
* FOUR TIERS (docs/architecture/DECLARATIVE_NODES.md §6). This is tiers 2 and 3.
|
|
17
|
+
* 1 editor $schema pointers + .vscode yaml.schemas, no tool
|
|
18
|
+
* 2 structural every part validated against nodes/_schema/*.json
|
|
19
|
+
* 3 semantic the cross-file rules a schema cannot express
|
|
20
|
+
* 4 dry run `unoverse node test`, executes against testData, not here
|
|
21
|
+
*/
|
|
22
|
+
import { readdirSync, existsSync, statSync } from "node:fs";
|
|
23
|
+
import { join, resolve, dirname } from "node:path";
|
|
24
|
+
import { fileURLToPath } from "node:url";
|
|
25
|
+
import { problems, derivedKinds, reset, report } from "../context.mjs";
|
|
26
|
+
import { loadSchemas } from "./schema.mjs";
|
|
27
|
+
import { lintPackage } from "./package.mjs";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Lint every node package under `nodesHome`.
|
|
31
|
+
*
|
|
32
|
+
* Returns findings rather than printing them, and NEVER throws for a lint failure: a
|
|
33
|
+
* missing directory or unreadable schema is itself reported, so a caller gets one shape
|
|
34
|
+
* of answer whatever went wrong.
|
|
35
|
+
*/
|
|
36
|
+
/**
|
|
37
|
+
* Where the node schemas are, for this run.
|
|
38
|
+
*
|
|
39
|
+
* The platform's own tree carries them at `nodes/_schema/`, and every node file points at
|
|
40
|
+
* them with `$schema:` for editor squiggles. A DEVELOPER'S WORKSPACE DOES NOT: it holds only
|
|
41
|
+
* their packages, and a linter that then warned "no schema found" on every file was
|
|
42
|
+
* validating nothing while looking busy. So the schemas travel with the linter. In dist
|
|
43
|
+
* they sit beside this file (copy-lint.mjs puts them there, and the CLI vendors that
|
|
44
|
+
* folder); from source they are the monorepo's copy, five levels up.
|
|
45
|
+
*/
|
|
46
|
+
function schemaHome(home) {
|
|
47
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
48
|
+
for (const c of [join(home, "_schema"), join(here, "_schema"), resolve(here, "../../../../../apps/unoverse/nodes/_schema")])
|
|
49
|
+
if (existsSync(c)) return c;
|
|
50
|
+
return join(home, "_schema");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function lintNodes(nodesHome) {
|
|
54
|
+
const home = resolve(nodesHome);
|
|
55
|
+
reset(home, schemaHome(home));
|
|
56
|
+
|
|
57
|
+
if (!existsSync(home)) {
|
|
58
|
+
report("error", home, "no nodes directory here");
|
|
59
|
+
return { problems: [...problems], derivedKinds: new Map(), nodeCount: 0, pkgCount: 0, nodesHome: home };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
loadSchemas();
|
|
63
|
+
|
|
64
|
+
let nodeCount = 0,
|
|
65
|
+
pkgCount = 0;
|
|
66
|
+
for (const entry of readdirSync(home)) {
|
|
67
|
+
const dir = join(home, entry);
|
|
68
|
+
if (entry.startsWith("_") || entry.startsWith(".") || !statSync(dir).isDirectory()) continue;
|
|
69
|
+
if (!existsSync(join(dir, "nodes")) && !existsSync(join(dir, "package.yaml"))) continue; // pure code package
|
|
70
|
+
pkgCount++;
|
|
71
|
+
nodeCount += lintPackage(dir);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const rank = { error: 0, warn: 1, hint: 2 };
|
|
75
|
+
const sorted = [...problems].sort((a, b) => rank[a.level] - rank[b.level] || a.file.localeCompare(b.file));
|
|
76
|
+
return { problems: sorted, derivedKinds: new Map(derivedKinds), nodeCount, pkgCount, nodesHome: home };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** True when anything would fail a build. Warnings and hints inform, errors stop. */
|
|
80
|
+
export function hasErrors(result) {
|
|
81
|
+
return result.problems.some((p) => p.level === "error");
|
|
82
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading a node off disk: YAML parsing, $ref resolution, and where shared/ lives.
|
|
3
|
+
*
|
|
4
|
+
* $refs are resolved HERE rather than by the schema validator so a broken reference is a
|
|
5
|
+
* lint finding pointing at the file that made it, not a validation error deep in a
|
|
6
|
+
* composed document nobody wrote.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, existsSync, statSync } from "node:fs";
|
|
9
|
+
import { join, dirname, resolve } from "node:path";
|
|
10
|
+
import { createRequire } from "node:module";
|
|
11
|
+
import { report, rel, refCounts } from "../context.mjs";
|
|
12
|
+
|
|
13
|
+
const require_ = createRequire(import.meta.url);
|
|
14
|
+
let YAML;
|
|
15
|
+
try {
|
|
16
|
+
YAML = require_("yaml");
|
|
17
|
+
} catch {
|
|
18
|
+
throw new Error("the node linter needs yaml (npm install -D yaml)");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function readYaml(file) {
|
|
22
|
+
try {
|
|
23
|
+
const doc = YAML.parse(readFileSync(file, "utf8"));
|
|
24
|
+
if (doc && typeof doc === "object") delete doc.$schema;
|
|
25
|
+
return doc ?? {};
|
|
26
|
+
} catch (e) {
|
|
27
|
+
report("error", rel(file), `is not valid YAML: ${e.message.split("\n")[0]}`);
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Resolve a `$ref` against the package's `shared/` folder.
|
|
34
|
+
*
|
|
35
|
+
* SHORT FORM, and the one to write:
|
|
36
|
+
* url: { $ref: endpoints#responses }
|
|
37
|
+
* enum: { $ref: models#enum }
|
|
38
|
+
* toolExchange:
|
|
39
|
+
* $ref: tools # whole file
|
|
40
|
+
* maxTurns: 5 # local keys layer on top and win
|
|
41
|
+
*
|
|
42
|
+
* No path, because there was never a real path: shared fragments are package-scoped and
|
|
43
|
+
* the directory part was always thrown away. `../../shared/endpoints.yaml#/responses`
|
|
44
|
+
* still works, but it is arithmetic that buys nothing.
|
|
45
|
+
*
|
|
46
|
+
* A LONE $ref REPLACES. A $ref WITH SIBLINGS MERGES, local winning, which is what lets a
|
|
47
|
+
* node import a whole shared block and adjust one field.
|
|
48
|
+
*/
|
|
49
|
+
/**
|
|
50
|
+
* DEEP for plain objects, so overriding one field does not delete its siblings.
|
|
51
|
+
*
|
|
52
|
+
* A shallow spread made `{ $ref: x, body: { mode: 'intent' } }` REPLACE the imported body
|
|
53
|
+
* entirely: every other key — the filters, the result cap, the query itself — vanished, and
|
|
54
|
+
* the request still went out, valid and wrong. Nothing failed, because a body with fewer
|
|
55
|
+
* keys is a legal body. That is the worst shape of bug this format can produce, and the
|
|
56
|
+
* whole point of a $ref with siblings is "import a block and adjust one field".
|
|
57
|
+
*
|
|
58
|
+
* Arrays REPLACE rather than concatenating: a list is an ordered whole, and merging two
|
|
59
|
+
* would give an author no way to shorten one.
|
|
60
|
+
*/
|
|
61
|
+
function deepMerge(base, over) {
|
|
62
|
+
if (base === null || typeof base !== "object" || Array.isArray(base)) return over;
|
|
63
|
+
if (over === null || typeof over !== "object" || Array.isArray(over)) return over;
|
|
64
|
+
const out = { ...base };
|
|
65
|
+
for (const [k, v] of Object.entries(over)) out[k] = k in base ? deepMerge(base[k], v) : v;
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function resolveRefs(value, baseDir, file, seen = new Set()) {
|
|
70
|
+
if (Array.isArray(value)) return value.map((v) => resolveRefs(v, baseDir, file, seen));
|
|
71
|
+
if (!value || typeof value !== "object") return value;
|
|
72
|
+
|
|
73
|
+
const keys = Object.keys(value);
|
|
74
|
+
if (typeof value.$ref === "string") {
|
|
75
|
+
const [target, frag = ""] = value.$ref.split("#");
|
|
76
|
+
// `endpoints`, `endpoints.yaml`, or a full relative path — all the same file.
|
|
77
|
+
const stem = (target.split("/").pop() ?? "").replace(/\.ya?ml$/, "");
|
|
78
|
+
const abs = target.includes("/")
|
|
79
|
+
? resolve(baseDir, target)
|
|
80
|
+
: [join(sharedDirFor(baseDir), `${stem}.yaml`), join(sharedDirFor(baseDir), `${stem}.yml`)].find(existsSync) ??
|
|
81
|
+
join(sharedDirFor(baseDir), `${stem}.yaml`);
|
|
82
|
+
if (seen.has(value.$ref)) {
|
|
83
|
+
report("error", file, `$ref cycle at "${value.$ref}"`);
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
if (!existsSync(abs)) {
|
|
87
|
+
report("error", file, `$ref "${value.$ref}" points at a file that does not exist`);
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const doc = readYaml(abs);
|
|
91
|
+
if (doc === null) return null;
|
|
92
|
+
const hit = frag
|
|
93
|
+
.replace(/^\//, "")
|
|
94
|
+
.split("/")
|
|
95
|
+
.filter(Boolean)
|
|
96
|
+
.reduce((a, k) => (a == null ? a : a[k]), doc);
|
|
97
|
+
if (hit === undefined) {
|
|
98
|
+
report("error", file, `$ref "${value.$ref}" resolved to nothing. Check the fragment path`);
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
// Count distinct CONSUMERS, not $ref sites: one config.yaml referencing a
|
|
102
|
+
// fragment twice (enum + enumNames) is still a single consumer.
|
|
103
|
+
if (!refCounts.has(abs)) refCounts.set(abs, new Set());
|
|
104
|
+
refCounts.get(abs).add(file);
|
|
105
|
+
// Recurse with the ORIGINAL baseDir, not the fragment's own directory. A $ref stem is
|
|
106
|
+
// package-scoped (compose.ts resolves every one against pkg.shared), so re-basing onto
|
|
107
|
+
// shared/ made a nested ref look for <pkg>/../shared and report a missing file. It
|
|
108
|
+
// only stayed hidden because no shared fragment had contained a $ref before.
|
|
109
|
+
const imported = resolveRefs(hit, baseDir, file, new Set([...seen, value.$ref]));
|
|
110
|
+
if (keys.length === 1) return imported;
|
|
111
|
+
const local = Object.fromEntries(
|
|
112
|
+
keys.filter((k) => k !== "$ref").map((k) => [k, resolveRefs(value[k], baseDir, file, seen)]),
|
|
113
|
+
);
|
|
114
|
+
if (imported === null || typeof imported !== "object" || Array.isArray(imported)) {
|
|
115
|
+
report("error", file, `$ref "${value.$ref}" is not an object, so it cannot be merged with sibling keys`);
|
|
116
|
+
return local;
|
|
117
|
+
}
|
|
118
|
+
return deepMerge(imported, local);
|
|
119
|
+
}
|
|
120
|
+
return Object.fromEntries(keys.map((k) => [k, resolveRefs(value[k], baseDir, file, seen)]));
|
|
121
|
+
}
|
|
122
|
+
/** A node dir is <pkg>/nodes/<Node>, so shared/ is two levels up. */
|
|
123
|
+
export function sharedDirFor(nodeDir) {
|
|
124
|
+
return join(nodeDir, "..", "..", "shared");
|
|
125
|
+
}
|
|
126
|
+
|