unoverse 0.1.164 → 0.1.166
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/lib/publish.mjs +11 -1
- package/package.json +1 -1
- package/vendor/base/items/publish.js +22 -4
- package/vendor/base/lint/design/file.mjs +21 -2
package/lib/publish.mjs
CHANGED
|
@@ -155,9 +155,19 @@ export async function publish(args) {
|
|
|
155
155
|
// Deploy is a SYNC: what left the workspace leaves the universe, said before it happens.
|
|
156
156
|
for (const r of plan.remove ?? []) console.log(` ${c.red}-${c.off} ${label(r)} ${c.dim}(no longer in this workspace — will be removed)${c.off}`);
|
|
157
157
|
|
|
158
|
+
if (plan.syncUnavailable) {
|
|
159
|
+
console.log(` ${c.yellow}⚠${c.off} this universe cannot answer the sync check yet ${c.dim}(its server predates it)${c.off}`);
|
|
160
|
+
console.log(` ${c.dim}items you deleted from the workspace were NOT reconciled. Update the universe`);
|
|
161
|
+
console.log(` ${c.dim}(unoverse update on its box), then deploy again to remove them.${c.off}`);
|
|
162
|
+
}
|
|
163
|
+
|
|
158
164
|
const toSend = plan.create.length + plan.update.length + (plan.remove?.length ?? 0);
|
|
159
165
|
if (!toSend) {
|
|
160
|
-
|
|
166
|
+
if (plan.syncUnavailable) {
|
|
167
|
+
console.log(`\n ${c.green}✓${c.off} nothing new to send ${c.dim}(deletions unchecked, see above)${c.off}\n`);
|
|
168
|
+
} else {
|
|
169
|
+
console.log(`\n ${c.green}✓${c.off} nothing to do, ${project} is up to date\n`);
|
|
170
|
+
}
|
|
161
171
|
process.exit(plan.refused.length ? 1 : 0);
|
|
162
172
|
}
|
|
163
173
|
if (flag("dry-run")) {
|
package/package.json
CHANGED
|
@@ -24,7 +24,17 @@ import { collectProject } from "./collect.js";
|
|
|
24
24
|
export async function lintForPublish(designRoot, project) {
|
|
25
25
|
const { lintDefinitions } = await import("../lint/design/index.mjs");
|
|
26
26
|
const result = lintDefinitions(designRoot);
|
|
27
|
-
|
|
27
|
+
/**
|
|
28
|
+
* SCOPED TO THE PROJECT BEING DEPLOYED, on paths that may be relative. The old
|
|
29
|
+
* check looked for "/design/" with a leading slash, which a relative path never
|
|
30
|
+
* has, so every other project's findings leaked through and a bpp comment blocked
|
|
31
|
+
* a lyceum deploy (observed live 2026-08-21). Boundary regexes hold for absolute
|
|
32
|
+
* and relative paths alike; findings outside the design tree (the tree itself,
|
|
33
|
+
* nodes, prompts) still always count.
|
|
34
|
+
*/
|
|
35
|
+
const inDesign = (f) => /(^|\/)design\//.test(f);
|
|
36
|
+
const inProject = (f) => new RegExp(`(^|/)design/${project}(/|$)`).test(f);
|
|
37
|
+
const mine = result.problems.filter((p) => !p.file || !inDesign(p.file) || inProject(p.file));
|
|
28
38
|
return { problems: mine, errors: mine.filter((p) => p.level === "error") };
|
|
29
39
|
}
|
|
30
40
|
/**
|
|
@@ -65,10 +75,18 @@ project = "", fetchImpl = fetch) {
|
|
|
65
75
|
plan.remove.push(r);
|
|
66
76
|
}
|
|
67
77
|
}
|
|
68
|
-
|
|
69
|
-
|
|
78
|
+
else {
|
|
79
|
+
// An older universe answers this op with an error: no removals proposed, the
|
|
80
|
+
// additive behavior every deploy had before — but SAID, never silent. A deploy
|
|
81
|
+
// that could not check deletions and prints "up to date" is lying by omission
|
|
82
|
+
// (observed live 2026-08-21: an hour of retests against a server that could
|
|
83
|
+
// not answer, each one claiming there was nothing to do).
|
|
84
|
+
plan.syncUnavailable = true;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
plan.syncUnavailable = true; /* unreachable universe also fails later, on the real sends */
|
|
70
89
|
}
|
|
71
|
-
catch { /* unreachable universe fails later, on the real sends */ }
|
|
72
90
|
}
|
|
73
91
|
for (const item of items) {
|
|
74
92
|
// ASK THE GATE, not the item store. `/api/items` is deliberately shut (§9.10), so a
|
|
@@ -54,8 +54,27 @@ function lintFile(file) {
|
|
|
54
54
|
// never a style the SDK resolves — token law governs the inside, not the envelope.
|
|
55
55
|
if (!isFixture(file) && !isHook(file) && !isManifest(file))
|
|
56
56
|
src.split("\n").forEach((line, i) => {
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
/**
|
|
58
|
+
* THE RULE JUDGES CODE, NEVER COMMENTARY. A comment explaining a contrast
|
|
59
|
+
* decision legitimately names the hex it rejected ("#E9F1FF dropped it to
|
|
60
|
+
* 1.14:1"), and scanning the raw line flagged exactly the best-documented
|
|
61
|
+
* files (observed live 2026-08-21: two comment hexes blocked a deploy).
|
|
62
|
+
* YAML comments start at an unquoted #, at line start or after whitespace;
|
|
63
|
+
* everything from there is prose. A quoted "#fff" VALUE stays visible to the
|
|
64
|
+
* rule, which is the whole point of the law.
|
|
65
|
+
*/
|
|
66
|
+
let code = line, inS = false, inD = false;
|
|
67
|
+
for (let j = 0; j < line.length; j++) {
|
|
68
|
+
const ch = line[j];
|
|
69
|
+
if (ch === "'" && !inD) inS = !inS;
|
|
70
|
+
else if (ch === '"' && !inS) inD = !inD;
|
|
71
|
+
else if (ch === "#" && !inS && !inD && (j === 0 || /\s/.test(line[j - 1]))) {
|
|
72
|
+
code = line.slice(0, j);
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (RAW_VALUE.test(code) && !/^\s*"?appWidth"?\s*:/.test(code))
|
|
77
|
+
report("error", file, `raw value. Token names only; add/scale a token in the org styles instead (LAW 1, docs/design/06): ${code.trim()}`, i + 1);
|
|
59
78
|
});
|
|
60
79
|
|
|
61
80
|
let json;
|