scenri 0.10.2 → 0.11.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/CHANGELOG.md +44 -0
- package/dist/{chunk-UUYMUOZQ.js → chunk-K6IELFL3.js} +51 -2
- package/dist/{chunk-FYQ5BAFA.js → chunk-YK37H6DM.js} +35 -26
- package/dist/{cli-3KKS7BE4.js → cli-GMRPOISO.js} +3 -3
- package/dist/{cli-KSKENGIR.js → cli-VBJGIJI4.js} +4 -4
- package/dist/index.js +3 -3
- package/dist/serve.js +222 -18
- package/dist/{src-QZZDZM7I.js → src-TC4UQ7H6.js} +3 -3
- package/package.json +1 -1
- package/studio-dist/assets/index-BQIy0Axd.js +107 -0
- package/studio-dist/assets/{index-ELZxH19c.css → index-BWeypLhE.css} +1 -1
- package/studio-dist/index.html +2 -2
- package/studio-dist/assets/index-DICg38Xm.js +0 -107
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.11.0](https://github.com/tonygorb/Scenri/compare/v0.10.3...v0.11.0) (2026-09-18)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* first use, a tutor that walks the real task, with First steps and Learn ([47e9775](https://github.com/tonygorb/Scenri/commit/47e977569049803f0544ce19ad0289cdc8e187f5))
|
|
9
|
+
* Learn, every lesson in one place, begun and continued with the same tutor ([1d378e1](https://github.com/tonygorb/Scenri/commit/1d378e17f22a8ebf64878d67caa0996027e5f1f6))
|
|
10
|
+
* **studio:** New lands on Create with the add panel open ([674bf9c](https://github.com/tonygorb/Scenri/commit/674bf9cbb369443e75b78586210a0b0b12c94826))
|
|
11
|
+
* **studio:** New's plus rides a gold disc ([673a17b](https://github.com/tonygorb/Scenri/commit/673a17b1e48eb491ecc2c9a1d122955d11e24d0d))
|
|
12
|
+
* **studio:** the brand menu leads with where you have been and stays one height ([e28a857](https://github.com/tonygorb/Scenri/commit/e28a8573f797f75815687239cd58c1b4d01518e7))
|
|
13
|
+
* **studio:** the new top bar ([e1d262b](https://github.com/tonygorb/Scenri/commit/e1d262b9eb21a4fd788dae8acd487096223b87c6))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* a product made from the picker is named, and Enter on a control is that control's ([7383c7b](https://github.com/tonygorb/Scenri/commit/7383c7baa6fde61dcbf060c68cb429960caee73a))
|
|
19
|
+
* a task ended on a surface is not begun there again, and an empty chip panel foot is not drawn ([2b450fd](https://github.com/tonygorb/Scenri/commit/2b450fd3b7aeb875fee5649b670f3839af0f7894))
|
|
20
|
+
* closing Learn gives the keyboard back to Help when what opened it is gone ([c12d690](https://github.com/tonygorb/Scenri/commit/c12d690fad3e7ce4d1cfaed05aa6982a97d5de4c))
|
|
21
|
+
* in the walk a chip comes in through its ask and leaves only through Back ([a0e9fea](https://github.com/tonygorb/Scenri/commit/a0e9fea7426755ba020f766f0a0678df96542e2c))
|
|
22
|
+
* **studio:** a bar menu answers the next click, even while it is closing ([7b0af47](https://github.com/tonygorb/Scenri/commit/7b0af476d0af0691be60616687955c3521171787))
|
|
23
|
+
* **studio:** a brand icon that is its own ground fills its circle ([0f356fb](https://github.com/tonygorb/Scenri/commit/0f356fbbd19e899ae41751851f873fedbce4d9b5))
|
|
24
|
+
* **studio:** a brand's circle shows its icon, or its initial, never a shrunken wordmark ([6c8415d](https://github.com/tonygorb/Scenri/commit/6c8415da61b261629cee734366a1cece630a58c4))
|
|
25
|
+
* **studio:** New pressed with the add panel open leaves it open and focuses the brief ([37050a4](https://github.com/tonygorb/Scenri/commit/37050a4e4b99f431649f97423ab6596f8ba52dad))
|
|
26
|
+
* **studio:** New wears round ends, the mark shows its box, and Clear all joins its list ([2ed412e](https://github.com/tonygorb/Scenri/commit/2ed412e1faf4d60378b0996f02373ea804b27fe9))
|
|
27
|
+
* **studio:** New's plus sits on an ink disc, and the bar no longer shrinks ([86ceaa3](https://github.com/tonygorb/Scenri/commit/86ceaa33dc16856a1c3fa2e4950360d1a77c5eec))
|
|
28
|
+
* **studio:** pointing at New's plus lights the whole button ([d3a4973](https://github.com/tonygorb/Scenri/commit/d3a4973dc8ee9a0ce090e24fd3f3f8a591c1b0f5))
|
|
29
|
+
* **studio:** the bar wears the full Scenri lockup, bare ([25efd02](https://github.com/tonygorb/Scenri/commit/25efd0292c1d0982ec1f027364489306cf294bea))
|
|
30
|
+
* **studio:** the brand list ends on a whole row ([a20da23](https://github.com/tonygorb/Scenri/commit/a20da23fd89240fd533944ad222c62144795a12e))
|
|
31
|
+
* **studio:** the brand list fades into the line under it while there is more ([18073f8](https://github.com/tonygorb/Scenri/commit/18073f8ea67157c64bbb7b676eb9aade51276614))
|
|
32
|
+
* **studio:** the brand list is ten rows tall ([df5b4e1](https://github.com/tonygorb/Scenri/commit/df5b4e1b834aabf9b4dc22338e83ce99a19550e3))
|
|
33
|
+
* **studio:** the brand list runs straight into the line under it ([402e017](https://github.com/tonygorb/Scenri/commit/402e0176e3bb7ae5cc799af77de4852e92608ba1))
|
|
34
|
+
* **studio:** the brand menu is one compact list ([1e3dc70](https://github.com/tonygorb/Scenri/commit/1e3dc7002cae58fbc8bacc567cf3a924a38a6a1c))
|
|
35
|
+
* **studio:** the brand menu is one list, and the help button leaves this branch ([2e717d1](https://github.com/tonygorb/Scenri/commit/2e717d1474f45e625e85bef36b69d3397cb20925))
|
|
36
|
+
* the tutor keeps what a moment is about in sight, and lets people go their own way ([41e667e](https://github.com/tonygorb/Scenri/commit/41e667e94a930d85bf1ad88fbba4bf00ae6f5ece))
|
|
37
|
+
* the welcome reads top to bottom, speaks plainly, and opens again from Help ([7edb94f](https://github.com/tonygorb/Scenri/commit/7edb94f289e17c1c4255cc6ef683758bc21aea17))
|
|
38
|
+
|
|
39
|
+
## [0.10.3](https://github.com/tonygorb/Scenri/compare/v0.10.2...v0.10.3) (2026-09-18)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
### Bug Fixes
|
|
43
|
+
|
|
44
|
+
* look for npm without freezing the server ([db1bde3](https://github.com/tonygorb/Scenri/commit/db1bde3e1450353bd0f62c7ecf2a2796ea2af75d))
|
|
45
|
+
* look for npm without freezing the server ([cec4b03](https://github.com/tonygorb/Scenri/commit/cec4b0327f2dd4f1846e9c9192926876db851ada))
|
|
46
|
+
|
|
3
47
|
## [0.10.2](https://github.com/tonygorb/Scenri/compare/v0.10.1...v0.10.2) (2026-09-17)
|
|
4
48
|
|
|
5
49
|
|
|
@@ -1344,6 +1344,55 @@ function createStore(db) {
|
|
|
1344
1344
|
setOverlays(id, overlays) {
|
|
1345
1345
|
db.prepare("UPDATE nodes SET overlays=? WHERE id=?").run(JSON.stringify(overlays), id);
|
|
1346
1346
|
},
|
|
1347
|
+
// first use: what the library already proves, read by the guide record
|
|
1348
|
+
/** The database's own clock, in the format every node's created_at uses. */
|
|
1349
|
+
now() {
|
|
1350
|
+
return db.prepare("SELECT strftime('%Y-%m-%d %H:%M:%f','now') AS t").get().t;
|
|
1351
|
+
},
|
|
1352
|
+
/** Whether any brand holds a finished shot, or a finished refinement, with a picture. */
|
|
1353
|
+
hasFinishedNode(kind) {
|
|
1354
|
+
return !!db.prepare("SELECT 1 FROM nodes WHERE kind=? AND status='done' AND images != '[]' LIMIT 1").get(kind);
|
|
1355
|
+
},
|
|
1356
|
+
/** Whether any brand has imported a product from a store. */
|
|
1357
|
+
hasCatalogProduct() {
|
|
1358
|
+
return !!db.prepare("SELECT 1 FROM catalog_products LIMIT 1").get();
|
|
1359
|
+
},
|
|
1360
|
+
/** A brand's shots of one kind made at or after a moment, newest first: what a guided task has made. */
|
|
1361
|
+
nodesSince(brandId, kind, since, limit = 8) {
|
|
1362
|
+
const rows = db.prepare(
|
|
1363
|
+
`SELECT id, kind, status, images, created_at FROM nodes
|
|
1364
|
+
WHERE project_id IN (SELECT id FROM projects WHERE brand_id = ?)
|
|
1365
|
+
AND kind = ? AND created_at >= ?
|
|
1366
|
+
ORDER BY created_at DESC, id DESC LIMIT ?`
|
|
1367
|
+
).all(brandId, kind, since, limit);
|
|
1368
|
+
return rows.map((r) => ({
|
|
1369
|
+
id: r.id,
|
|
1370
|
+
kind: r.kind,
|
|
1371
|
+
status: r.status,
|
|
1372
|
+
images: (() => {
|
|
1373
|
+
try {
|
|
1374
|
+
const a = JSON.parse(r.images);
|
|
1375
|
+
return Array.isArray(a) ? a.length : 0;
|
|
1376
|
+
} catch {
|
|
1377
|
+
return 0;
|
|
1378
|
+
}
|
|
1379
|
+
})(),
|
|
1380
|
+
createdAt: r.created_at
|
|
1381
|
+
}));
|
|
1382
|
+
},
|
|
1383
|
+
/** The newest presenter draft a brand started at or after a moment, never an edit session's. */
|
|
1384
|
+
presenterDraftSince(brandId, since) {
|
|
1385
|
+
const rows = db.prepare(
|
|
1386
|
+
"SELECT id, json FROM presenter_drafts WHERE brand_id = ? AND created_at >= ? ORDER BY created_at DESC, id DESC"
|
|
1387
|
+
).all(brandId, since);
|
|
1388
|
+
for (const r of rows) {
|
|
1389
|
+
try {
|
|
1390
|
+
if (!JSON.parse(r.json)?.presenterId) return r.id;
|
|
1391
|
+
} catch {
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
return null;
|
|
1395
|
+
},
|
|
1347
1396
|
// settings
|
|
1348
1397
|
getSetting(key) {
|
|
1349
1398
|
const r = db.prepare("SELECT value FROM settings WHERE key=?").get(key);
|
|
@@ -2175,5 +2224,5 @@ function createCore(homeDir = defaultHome()) {
|
|
|
2175
2224
|
}
|
|
2176
2225
|
|
|
2177
2226
|
export { ASPECT_TOLERANCE, BUDGET_EXHAUSTED, EDIT_REFERENCE_ROLE_DIRECTIVE, REFERENCE_ROLE_DIRECTIVE, SCHEMA_VERSION, STEM_MIN, SchemaTooNewError, SpendCapError, TRIGRAM_MIN, budgetSize, createCatalogStore, createCore, createStore, defaultHome, fold, ftsMatch, matchesQuery, ratioLabel, searchTerms, termMatches, uniqueProjectSlug, uniqueSetSlug, uniqueSlug };
|
|
2178
|
-
//# sourceMappingURL=chunk-
|
|
2179
|
-
//# sourceMappingURL=chunk-
|
|
2227
|
+
//# sourceMappingURL=chunk-K6IELFL3.js.map
|
|
2228
|
+
//# sourceMappingURL=chunk-K6IELFL3.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { stagingDir, versionsDir, isValidVersionDir, pruneStaged, entryOf } from './chunk-4MAFHYAD.js';
|
|
2
|
-
import {
|
|
2
|
+
import { spawn, execFile } from 'child_process';
|
|
3
3
|
import { existsSync, rmSync, mkdirSync, readFileSync, renameSync } from 'fs';
|
|
4
4
|
import { join, dirname } from 'path';
|
|
5
5
|
|
|
@@ -122,37 +122,46 @@ function createUpdateChecker(deps) {
|
|
|
122
122
|
}
|
|
123
123
|
};
|
|
124
124
|
}
|
|
125
|
-
function findNpm(opts = {}) {
|
|
125
|
+
async function findNpm(opts = {}) {
|
|
126
126
|
const env = opts.env ?? process.env;
|
|
127
127
|
const platform = opts.platform ?? process.platform;
|
|
128
|
-
const canRun = opts.canRun ??
|
|
129
|
-
|
|
130
|
-
return spawnSync(argv[0], [...argv.slice(1), "--version"], { stdio: "ignore", timeout: 1e4 }).status === 0;
|
|
131
|
-
} catch {
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
if (platform !== "win32" && canRun(["npm"])) return ["npm"];
|
|
128
|
+
const canRun = opts.canRun ?? answersVersion;
|
|
129
|
+
if (platform !== "win32" && await canRun(["npm"])) return ["npm"];
|
|
136
130
|
const ep = env.npm_execpath?.replace(/npx-cli\.js$/, "npm-cli.js");
|
|
137
|
-
if (ep && /npm-cli\.js$/.test(ep) && canRun([process.execPath, ep])) return [process.execPath, ep];
|
|
131
|
+
if (ep && /npm-cli\.js$/.test(ep) && await canRun([process.execPath, ep])) return [process.execPath, ep];
|
|
138
132
|
if (platform === "win32") {
|
|
139
|
-
const cli = windowsNpmCli();
|
|
140
|
-
if (cli && canRun([process.execPath, cli])) return [process.execPath, cli];
|
|
133
|
+
const cli = await windowsNpmCli();
|
|
134
|
+
if (cli && await canRun([process.execPath, cli])) return [process.execPath, cli];
|
|
141
135
|
}
|
|
142
136
|
return null;
|
|
143
137
|
}
|
|
138
|
+
function answersVersion(argv) {
|
|
139
|
+
return new Promise((resolve) => {
|
|
140
|
+
try {
|
|
141
|
+
const child = spawn(argv[0], [...argv.slice(1), "--version"], { stdio: "ignore", timeout: 1e4 });
|
|
142
|
+
child.on("error", () => resolve(false));
|
|
143
|
+
child.on("exit", (code) => resolve(code === 0));
|
|
144
|
+
} catch {
|
|
145
|
+
resolve(false);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
144
149
|
function windowsNpmCli() {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
return new Promise((resolve) => {
|
|
151
|
+
try {
|
|
152
|
+
execFile("where", ["npm"], { encoding: "utf8", timeout: 1e4 }, (err, stdout) => {
|
|
153
|
+
if (err || !stdout) return resolve(null);
|
|
154
|
+
for (const line of stdout.split(/\r?\n/)) {
|
|
155
|
+
if (!/npm(\.cmd)?$/i.test(line.trim())) continue;
|
|
156
|
+
const cli = join(dirname(line.trim()), "node_modules", "npm", "bin", "npm-cli.js");
|
|
157
|
+
if (existsSync(cli)) return resolve(cli);
|
|
158
|
+
}
|
|
159
|
+
resolve(null);
|
|
160
|
+
});
|
|
161
|
+
} catch {
|
|
162
|
+
resolve(null);
|
|
152
163
|
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return null;
|
|
164
|
+
});
|
|
156
165
|
}
|
|
157
166
|
function run(argv) {
|
|
158
167
|
return new Promise((resolve) => {
|
|
@@ -181,7 +190,7 @@ async function runVerify(entry) {
|
|
|
181
190
|
}
|
|
182
191
|
async function stageVersion(deps) {
|
|
183
192
|
const env = deps.env ?? process.env;
|
|
184
|
-
const npmArgv = deps.npmArgv !== void 0 ? deps.npmArgv : findNpm({ env });
|
|
193
|
+
const npmArgv = deps.npmArgv !== void 0 ? deps.npmArgv : await findNpm({ env });
|
|
185
194
|
if (!npmArgv) {
|
|
186
195
|
return { ok: false, reason: "no-npm", detail: "npm is not reachable from this process" };
|
|
187
196
|
}
|
|
@@ -247,5 +256,5 @@ async function stageVersion(deps) {
|
|
|
247
256
|
}
|
|
248
257
|
|
|
249
258
|
export { classify, createUpdateChecker, fetchDistTagLatest, findNpm, isReleaseTriplet, stageVersion };
|
|
250
|
-
//# sourceMappingURL=chunk-
|
|
251
|
-
//# sourceMappingURL=chunk-
|
|
259
|
+
//# sourceMappingURL=chunk-YK37H6DM.js.map
|
|
260
|
+
//# sourceMappingURL=chunk-YK37H6DM.js.map
|
|
@@ -463,7 +463,7 @@ async function addOrRepair(ownEntry, say, over) {
|
|
|
463
463
|
}
|
|
464
464
|
async function rememberDecline(home) {
|
|
465
465
|
try {
|
|
466
|
-
const { createCore } = await import('./src-
|
|
466
|
+
const { createCore } = await import('./src-TC4UQ7H6.js');
|
|
467
467
|
const core = createCore(home);
|
|
468
468
|
try {
|
|
469
469
|
core.store.setSetting("desktop.prompt", "declined");
|
|
@@ -530,5 +530,5 @@ function tail(path, bytes = 4096) {
|
|
|
530
530
|
}
|
|
531
531
|
|
|
532
532
|
export { addToDesktop, assetsDirFor, installDeps, runDesktopCommand, runExecFile, runOpenCommand };
|
|
533
|
-
//# sourceMappingURL=cli-
|
|
534
|
-
//# sourceMappingURL=cli-
|
|
533
|
+
//# sourceMappingURL=cli-GMRPOISO.js.map
|
|
534
|
+
//# sourceMappingURL=cli-GMRPOISO.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { stageVersion, fetchDistTagLatest, findNpm } from './chunk-
|
|
1
|
+
import { stageVersion, fetchDistTagLatest, findNpm } from './chunk-YK37H6DM.js';
|
|
2
2
|
import { readMeta } from './chunk-Y3ZPBPLP.js';
|
|
3
3
|
import { defaultHome, newestStaged, compareSemver } from './chunk-4MAFHYAD.js';
|
|
4
4
|
|
|
@@ -41,7 +41,7 @@ async function runUpdateCommand(opts) {
|
|
|
41
41
|
console.log(` ${latest} is available. Stage it with: scenri update`);
|
|
42
42
|
return 0;
|
|
43
43
|
}
|
|
44
|
-
if (!findNpm()) {
|
|
44
|
+
if (!await findNpm()) {
|
|
45
45
|
console.error(" npm is not reachable from here, so nothing can be downloaded.");
|
|
46
46
|
console.error(" Run the newest version directly with: npx scenri@latest");
|
|
47
47
|
console.error(" (or install Node.js with npm and try again)");
|
|
@@ -63,5 +63,5 @@ async function runUpdateCommand(opts) {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
export { runUpdateCommand };
|
|
66
|
-
//# sourceMappingURL=cli-
|
|
67
|
-
//# sourceMappingURL=cli-
|
|
66
|
+
//# sourceMappingURL=cli-VBJGIJI4.js.map
|
|
67
|
+
//# sourceMappingURL=cli-VBJGIJI4.js.map
|
package/dist/index.js
CHANGED
|
@@ -81,17 +81,17 @@ try {
|
|
|
81
81
|
await (await import('./serve.js')).serve();
|
|
82
82
|
break;
|
|
83
83
|
case "update": {
|
|
84
|
-
const { runUpdateCommand } = await import('./cli-
|
|
84
|
+
const { runUpdateCommand } = await import('./cli-VBJGIJI4.js');
|
|
85
85
|
process.exit(await runUpdateCommand(command));
|
|
86
86
|
break;
|
|
87
87
|
}
|
|
88
88
|
case "desktop": {
|
|
89
|
-
const { runDesktopCommand } = await import('./cli-
|
|
89
|
+
const { runDesktopCommand } = await import('./cli-GMRPOISO.js');
|
|
90
90
|
process.exit(await runDesktopCommand(command, fileURLToPath(import.meta.url)));
|
|
91
91
|
break;
|
|
92
92
|
}
|
|
93
93
|
case "open": {
|
|
94
|
-
const { runOpenCommand } = await import('./cli-
|
|
94
|
+
const { runOpenCommand } = await import('./cli-GMRPOISO.js');
|
|
95
95
|
process.exit(await runOpenCommand(fileURLToPath(import.meta.url)));
|
|
96
96
|
break;
|
|
97
97
|
}
|
package/dist/serve.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createUpdateChecker, classify,
|
|
1
|
+
import { createUpdateChecker, classify, findNpm, isReleaseTriplet, stageVersion } from './chunk-YK37H6DM.js';
|
|
2
2
|
import { shouldAdoptRunning, anotherScenriLines, portBusyLines } from './chunk-CMLJGPYC.js';
|
|
3
|
-
import { SchemaTooNewError, createCore, BUDGET_EXHAUSTED, SpendCapError, EDIT_REFERENCE_ROLE_DIRECTIVE, REFERENCE_ROLE_DIRECTIVE, ratioLabel, searchTerms, termMatches, budgetSize, SCHEMA_VERSION, ASPECT_TOLERANCE } from './chunk-
|
|
3
|
+
import { SchemaTooNewError, createCore, BUDGET_EXHAUSTED, SpendCapError, EDIT_REFERENCE_ROLE_DIRECTIVE, REFERENCE_ROLE_DIRECTIVE, ratioLabel, searchTerms, termMatches, budgetSize, SCHEMA_VERSION, ASPECT_TOLERANCE } from './chunk-K6IELFL3.js';
|
|
4
4
|
import { detectInstallKind } from './chunk-PAIAXRAC.js';
|
|
5
5
|
export { detectInstallKind } from './chunk-PAIAXRAC.js';
|
|
6
6
|
import { readMeta, repoSlug } from './chunk-Y3ZPBPLP.js';
|
|
@@ -1287,12 +1287,12 @@ function createCodexAnalyzer(opts = {}) {
|
|
|
1287
1287
|
};
|
|
1288
1288
|
}
|
|
1289
1289
|
function buildPrompt(req, refCount, problems) {
|
|
1290
|
-
const
|
|
1290
|
+
const evidence2 = refCount === 0 ? "You have no reference images. Work from the description alone." : refCount === 1 ? "One reference image is attached." : `${refCount} reference images are attached.`;
|
|
1291
1291
|
const body = req.kind === "presenter" ? presenterBody(req, refCount) : sceneBody(req);
|
|
1292
1292
|
const revision = req.priorDraft ? ` You are revising an existing record, not starting over: keep everything that is not being corrected. Current record: ${JSON.stringify(req.priorDraft)}.` : "";
|
|
1293
1293
|
const correction = req.correction ? ` The correction to apply: ${req.correction}.` : "";
|
|
1294
1294
|
const retry = problems.length ? ` Your last answer was rejected: ${problems.join(" ")} Fix exactly that and write the file again.` : "";
|
|
1295
|
-
return `${
|
|
1295
|
+
return `${evidence2}${revision}${correction} ${body} Write strict JSON, and nothing but JSON, to a file called ${OUT_FILE} in the current directory (you may run the commands needed to write it). Do not browse the web or explore files. No prose, no markdown fences, no commentary.${retry}`;
|
|
1296
1296
|
}
|
|
1297
1297
|
function presenterBody(req, refCount) {
|
|
1298
1298
|
const same = refCount > 1 ? " Every attached photograph is the same person." : "";
|
|
@@ -3248,7 +3248,7 @@ function compileBrief(brief, ctx) {
|
|
|
3248
3248
|
);
|
|
3249
3249
|
if (names.length) {
|
|
3250
3250
|
warnings.push(
|
|
3251
|
-
`${names.join(" and ")} ${names.length === 1 ? "was" : "were"} left out
|
|
3251
|
+
`${names.join(" and ")} ${names.length === 1 ? "was" : "were"} left out: ${ctx.engineCaps.displayName} reads no reference images.`
|
|
3252
3252
|
);
|
|
3253
3253
|
}
|
|
3254
3254
|
}
|
|
@@ -5207,18 +5207,18 @@ function mergeScrape(existing, scraped) {
|
|
|
5207
5207
|
async function inspectMark(buf, toPng2) {
|
|
5208
5208
|
const png = await toPng2(buf);
|
|
5209
5209
|
const meta = await sharp21(png).metadata();
|
|
5210
|
-
let
|
|
5210
|
+
let blank2 = false;
|
|
5211
5211
|
try {
|
|
5212
5212
|
const flat = await sharp21(png).flatten({ background: "#ffffff" }).toBuffer();
|
|
5213
5213
|
const stats = await sharp21(flat).stats();
|
|
5214
|
-
|
|
5214
|
+
blank2 = stats.channels.slice(0, 3).every((c) => c.min > 200);
|
|
5215
5215
|
} catch {
|
|
5216
5216
|
}
|
|
5217
5217
|
return {
|
|
5218
5218
|
longEdge: Math.max(meta.width ?? 0, meta.height ?? 0) || null,
|
|
5219
5219
|
width: meta.width ?? null,
|
|
5220
5220
|
height: meta.height ?? null,
|
|
5221
|
-
blank
|
|
5221
|
+
blank: blank2
|
|
5222
5222
|
};
|
|
5223
5223
|
}
|
|
5224
5224
|
|
|
@@ -11287,7 +11287,7 @@ function defaultShowcaseDir() {
|
|
|
11287
11287
|
|
|
11288
11288
|
// src/routes/showcase.ts
|
|
11289
11289
|
function registerShowcaseRoutes(app, deps) {
|
|
11290
|
-
const { templatesRoot } = deps;
|
|
11290
|
+
const { templatesRoot, thumbs } = deps;
|
|
11291
11291
|
const { showcase } = loadShowcase(join(templatesRoot, "showcase"));
|
|
11292
11292
|
const showcaseHeroPath = (id) => contentFile(templatesRoot, "previews", "showcase", `${id}.jpg`);
|
|
11293
11293
|
const decorateShowcase = (s) => ({
|
|
@@ -11301,7 +11301,8 @@ function registerShowcaseRoutes(app, deps) {
|
|
|
11301
11301
|
app.get("/api/showcase-previews/:file", async (req, reply) => {
|
|
11302
11302
|
const m = /^([a-z0-9-]+)\.jpg$/.exec(String(req.params.file));
|
|
11303
11303
|
if (!m || !existsSync(showcaseHeroPath(m[1]))) return reply.status(404).send({ error: "no preview" });
|
|
11304
|
-
|
|
11304
|
+
const path = showcaseHeroPath(m[1]);
|
|
11305
|
+
return serveJpegSized(req, reply, path, thumbs, fileKey("showcase", m[1], path));
|
|
11305
11306
|
});
|
|
11306
11307
|
}
|
|
11307
11308
|
|
|
@@ -11703,6 +11704,39 @@ function registerImageRoutes(app, deps) {
|
|
|
11703
11704
|
|
|
11704
11705
|
// src/release/notes.data.ts
|
|
11705
11706
|
var RELEASES = [
|
|
11707
|
+
{
|
|
11708
|
+
version: "0.11.0",
|
|
11709
|
+
date: "2026-09-18",
|
|
11710
|
+
title: "A new top bar, and a tutor that makes your first shot with you.",
|
|
11711
|
+
sections: [
|
|
11712
|
+
{
|
|
11713
|
+
heading: "Top bar",
|
|
11714
|
+
body: "The five places sit in the middle of the bar, with the one you are on underlined. New opens Create with the add panel open, and its arrow adds a product, presenter or scene instead. Activity replaces the bell: while a shot renders it shows that picture inside a filling ring, and its panel lists what is in progress and your notifications together, with Mark all read and Clear all. On a phone every panel in the bar opens as a sheet."
|
|
11715
|
+
},
|
|
11716
|
+
{
|
|
11717
|
+
heading: "Brand",
|
|
11718
|
+
body: "The brand menu is one short list, the brand you are in first and the rest A to Z, with a search once it grows long, so Settings and Shut down stay in reach. A brand's circle shows its icon, or its initial, never a shrunken wordmark."
|
|
11719
|
+
},
|
|
11720
|
+
{
|
|
11721
|
+
heading: "Learn",
|
|
11722
|
+
body: "A new install is welcomed and makes its first shot with a tutor, one step at a time: a product, a presenter, a scene, then the words. First steps on Home lists four lessons to start with and leaves once they are done, and Learn holds all five, from adding your product to refining a shot. Help sits in the corner of the page from 1024 pixels wide and in the bar below that, with Learn, the welcome, keyboard shortcuts and What's new."
|
|
11723
|
+
},
|
|
11724
|
+
{
|
|
11725
|
+
heading: "Fixes",
|
|
11726
|
+
body: "A product made from the picker goes into the brief by its name instead of as a missing product, and Enter on a focused control in Create presses that control rather than opening the selected shot."
|
|
11727
|
+
}
|
|
11728
|
+
]
|
|
11729
|
+
},
|
|
11730
|
+
{
|
|
11731
|
+
version: "0.10.3",
|
|
11732
|
+
date: "2026-09-18",
|
|
11733
|
+
sections: [
|
|
11734
|
+
{
|
|
11735
|
+
heading: "Fixes",
|
|
11736
|
+
body: "Scenri no longer stops answering for a moment right after the studio opens, while it checks whether one-click updates can run here. On Windows that pause could last several seconds, long enough for a second click on the desktop icon to start Scenri again instead of opening the one already running."
|
|
11737
|
+
}
|
|
11738
|
+
]
|
|
11739
|
+
},
|
|
11706
11740
|
{
|
|
11707
11741
|
version: "0.10.2",
|
|
11708
11742
|
date: "2026-09-17",
|
|
@@ -12530,14 +12564,22 @@ function registerUpdateRoutes(app, deps) {
|
|
|
12530
12564
|
return applyState;
|
|
12531
12565
|
};
|
|
12532
12566
|
const REQUIRED_PROTOCOL = 1;
|
|
12533
|
-
let
|
|
12567
|
+
let npmFound = false;
|
|
12568
|
+
let npmAsked = null;
|
|
12569
|
+
const npmKnown = () => {
|
|
12570
|
+
if (runtime.installKind === "dev" || !runtime.supervised || deps.stageImpl) return Promise.resolve();
|
|
12571
|
+
npmAsked ??= findNpm().then((argv) => {
|
|
12572
|
+
npmFound = argv !== null;
|
|
12573
|
+
}).catch(() => {
|
|
12574
|
+
});
|
|
12575
|
+
return npmAsked;
|
|
12576
|
+
};
|
|
12534
12577
|
const blockReason = () => {
|
|
12535
12578
|
if (runtime.installKind === "dev") return "dev";
|
|
12536
12579
|
if (!runtime.supervised) return "unsupervised";
|
|
12537
12580
|
if ((runtime.launcherProtocol ?? 1) < REQUIRED_PROTOCOL) return "launcher-too-old";
|
|
12538
12581
|
if (deps.stageImpl) return null;
|
|
12539
|
-
|
|
12540
|
-
return npmProbe ? null : "no-npm";
|
|
12582
|
+
return npmFound ? null : "no-npm";
|
|
12541
12583
|
};
|
|
12542
12584
|
const startStaging = (target) => {
|
|
12543
12585
|
applyState = { phase: "staging", version: target, error: null };
|
|
@@ -12565,12 +12607,13 @@ function registerUpdateRoutes(app, deps) {
|
|
|
12565
12607
|
};
|
|
12566
12608
|
updates.onResult(maybeAutoStage);
|
|
12567
12609
|
const bootLook = setTimeout(() => {
|
|
12568
|
-
updates.check().then(maybeAutoStage).catch(() => {
|
|
12610
|
+
npmKnown().then(() => updates.check()).then(maybeAutoStage).catch(() => {
|
|
12569
12611
|
});
|
|
12570
12612
|
}, deps.bootLookMs ?? 15e3);
|
|
12571
12613
|
bootLook.unref();
|
|
12572
12614
|
app.addHook("onClose", async () => clearTimeout(bootLook));
|
|
12573
12615
|
const updateStatus = async (force = false) => {
|
|
12616
|
+
await npmKnown();
|
|
12574
12617
|
const r = await updates.check(force);
|
|
12575
12618
|
const kind = r.latest ? classify(meta.version, r.latest) : null;
|
|
12576
12619
|
const apply = effectiveApply();
|
|
@@ -12601,6 +12644,7 @@ function registerUpdateRoutes(app, deps) {
|
|
|
12601
12644
|
if (busy > 0) {
|
|
12602
12645
|
return reply.status(409).send({ error: `work is still running (${busy} task${busy === 1 ? "" : "s"})` });
|
|
12603
12646
|
}
|
|
12647
|
+
await npmKnown();
|
|
12604
12648
|
const block = blockReason();
|
|
12605
12649
|
if (block)
|
|
12606
12650
|
return reply.status(409).send({ error: `one-click update cannot run here (${block})`, blockReason: block });
|
|
@@ -12745,6 +12789,165 @@ function registerSystemRoutes(app, deps) {
|
|
|
12745
12789
|
});
|
|
12746
12790
|
}
|
|
12747
12791
|
|
|
12792
|
+
// src/routes/guide.ts
|
|
12793
|
+
var TASKS = ["first-shot", "refine", "product", "presenter", "scene"];
|
|
12794
|
+
var MILESTONES = ["shot", "refine", "product", "presenter", "scene"];
|
|
12795
|
+
var KEY = "guide";
|
|
12796
|
+
var isTask = (t) => TASKS.includes(t);
|
|
12797
|
+
var isMilestone = (m) => MILESTONES.includes(m);
|
|
12798
|
+
var num2 = (n) => typeof n === "number" && Number.isFinite(n) && n >= 0 ? n : 0;
|
|
12799
|
+
function blank(eligible) {
|
|
12800
|
+
return { v: 2, eligible, welcome: null, hidden: null, done: {}, dismissed: [], active: null };
|
|
12801
|
+
}
|
|
12802
|
+
function parse2(raw) {
|
|
12803
|
+
if (!raw) return null;
|
|
12804
|
+
try {
|
|
12805
|
+
const j = JSON.parse(raw);
|
|
12806
|
+
if (typeof j.eligible !== "boolean") return null;
|
|
12807
|
+
if (j.v !== 2) return null;
|
|
12808
|
+
const done = {};
|
|
12809
|
+
if (j.done && typeof j.done === "object") {
|
|
12810
|
+
for (const [k, at] of Object.entries(j.done)) if (isMilestone(k) && typeof at === "string") done[k] = at;
|
|
12811
|
+
}
|
|
12812
|
+
const a = j.active;
|
|
12813
|
+
const b = a?.baseline;
|
|
12814
|
+
const active = a && isTask(a.task) && typeof a.brandId === "string" && typeof a.since === "string" ? {
|
|
12815
|
+
task: a.task,
|
|
12816
|
+
brandId: a.brandId,
|
|
12817
|
+
since: a.since,
|
|
12818
|
+
baseline: { products: num2(b?.products), presenters: num2(b?.presenters), scenes: num2(b?.scenes) },
|
|
12819
|
+
...a.paused === true ? { paused: true } : {}
|
|
12820
|
+
} : null;
|
|
12821
|
+
return {
|
|
12822
|
+
v: 2,
|
|
12823
|
+
eligible: j.eligible,
|
|
12824
|
+
welcome: j.welcome === "taken" || j.welcome === "declined" ? j.welcome : null,
|
|
12825
|
+
hidden: typeof j.hidden === "boolean" ? j.hidden : null,
|
|
12826
|
+
done,
|
|
12827
|
+
dismissed: Array.isArray(j.dismissed) ? j.dismissed.filter(isTask) : [],
|
|
12828
|
+
active
|
|
12829
|
+
};
|
|
12830
|
+
} catch {
|
|
12831
|
+
return null;
|
|
12832
|
+
}
|
|
12833
|
+
}
|
|
12834
|
+
function write(store, r) {
|
|
12835
|
+
store.setSetting(KEY, JSON.stringify(r));
|
|
12836
|
+
}
|
|
12837
|
+
function stampGuide(store, version) {
|
|
12838
|
+
if (store.getSetting(KEY) !== null) return;
|
|
12839
|
+
const eligible = store.listBrands().length === 0;
|
|
12840
|
+
if (eligible) {
|
|
12841
|
+
if (!store.getSetting("install.firstVersion")) store.setSetting("install.firstVersion", version);
|
|
12842
|
+
const seen = store.getSetting("whatsnew.seen");
|
|
12843
|
+
if (!seen || compareSemver(seen, version) < 0) store.setSetting("whatsnew.seen", version);
|
|
12844
|
+
}
|
|
12845
|
+
write(store, blank(eligible));
|
|
12846
|
+
}
|
|
12847
|
+
function countsOf(core, brandId) {
|
|
12848
|
+
const brand = core.store.getBrand(brandId);
|
|
12849
|
+
if (!brand) return null;
|
|
12850
|
+
const json = brand.json;
|
|
12851
|
+
const characters = Array.isArray(json?.characters) ? json.characters : [];
|
|
12852
|
+
return {
|
|
12853
|
+
presenters: characters.filter((c) => c?.origin === "custom" && !c?.supersededBy).length,
|
|
12854
|
+
scenes: Array.isArray(json?.scenes) ? json.scenes.length : 0,
|
|
12855
|
+
products: core.catalog.listLibraryProducts(brandId, json).length
|
|
12856
|
+
};
|
|
12857
|
+
}
|
|
12858
|
+
var ownPresenter = (b) => (b.json?.characters ?? []).some((c) => c?.origin === "custom" && !c?.supersededBy);
|
|
12859
|
+
function evidence(core, m) {
|
|
12860
|
+
const { store } = core;
|
|
12861
|
+
switch (m) {
|
|
12862
|
+
case "shot":
|
|
12863
|
+
return store.hasFinishedNode("generation");
|
|
12864
|
+
case "refine":
|
|
12865
|
+
return store.hasFinishedNode("edit");
|
|
12866
|
+
case "presenter":
|
|
12867
|
+
return store.listBrands().some(ownPresenter);
|
|
12868
|
+
case "scene":
|
|
12869
|
+
return store.listBrands().some((b) => (b.json?.scenes ?? []).length > 0);
|
|
12870
|
+
case "product":
|
|
12871
|
+
return store.hasCatalogProduct() || store.listBrands().some((b) => (b.json?.products ?? []).length > 0);
|
|
12872
|
+
}
|
|
12873
|
+
}
|
|
12874
|
+
function load2(store) {
|
|
12875
|
+
return parse2(store.getSetting(KEY)) ?? blank(false);
|
|
12876
|
+
}
|
|
12877
|
+
function readGuide(core, env) {
|
|
12878
|
+
const r = load2(core.store);
|
|
12879
|
+
let changed = false;
|
|
12880
|
+
const at = (/* @__PURE__ */ new Date()).toISOString();
|
|
12881
|
+
for (const m of MILESTONES) {
|
|
12882
|
+
if (!r.done[m] && evidence(core, m)) {
|
|
12883
|
+
r.done[m] = at;
|
|
12884
|
+
changed = true;
|
|
12885
|
+
}
|
|
12886
|
+
}
|
|
12887
|
+
if (r.active && !core.store.getBrand(r.active.brandId)) {
|
|
12888
|
+
r.active = null;
|
|
12889
|
+
changed = true;
|
|
12890
|
+
}
|
|
12891
|
+
if (changed) write(core.store, r);
|
|
12892
|
+
const a = r.active;
|
|
12893
|
+
const nodeKind = a?.task === "first-shot" ? "generation" : a?.task === "refine" ? "edit" : null;
|
|
12894
|
+
const eligible = r.eligible && env.SCENRI_NO_GUIDE !== "1";
|
|
12895
|
+
return {
|
|
12896
|
+
eligible,
|
|
12897
|
+
welcome: r.welcome,
|
|
12898
|
+
hidden: r.hidden ?? !eligible,
|
|
12899
|
+
done: r.done,
|
|
12900
|
+
dismissed: r.dismissed,
|
|
12901
|
+
active: a,
|
|
12902
|
+
activeNodes: a && nodeKind ? core.store.nodesSince(a.brandId, nodeKind, a.since) : [],
|
|
12903
|
+
activeDraftId: a?.task === "presenter" ? core.store.presenterDraftSince(a.brandId, a.since) : null,
|
|
12904
|
+
counts: a ? countsOf(core, a.brandId) : null
|
|
12905
|
+
};
|
|
12906
|
+
}
|
|
12907
|
+
function applyIntent(core, body) {
|
|
12908
|
+
const b = body ?? {};
|
|
12909
|
+
const r = load2(core.store);
|
|
12910
|
+
if ("welcome" in b) {
|
|
12911
|
+
if (b.welcome !== "taken" && b.welcome !== "declined") return "welcome is taken or declined";
|
|
12912
|
+
r.welcome = b.welcome;
|
|
12913
|
+
} else if ("start" in b) {
|
|
12914
|
+
const s = b.start ?? {};
|
|
12915
|
+
if (!isTask(s.task)) return "unknown task";
|
|
12916
|
+
if (typeof s.brandId !== "string") return "brandId required";
|
|
12917
|
+
const baseline = countsOf(core, s.brandId);
|
|
12918
|
+
if (!baseline) return "brand not found";
|
|
12919
|
+
const held = r.active;
|
|
12920
|
+
if (held && held.paused && held.task === s.task && held.brandId === s.brandId) {
|
|
12921
|
+
const { paused: _, ...going } = held;
|
|
12922
|
+
r.active = going;
|
|
12923
|
+
} else r.active = { task: s.task, brandId: s.brandId, since: core.store.now(), baseline };
|
|
12924
|
+
r.dismissed = r.dismissed.filter((t) => t !== s.task);
|
|
12925
|
+
} else if ("finish" in b) {
|
|
12926
|
+
if (!isTask(b.finish)) return "unknown task";
|
|
12927
|
+
if (r.active?.task === b.finish) r.active = null;
|
|
12928
|
+
} else if ("dismiss" in b) {
|
|
12929
|
+
if (!isTask(b.dismiss)) return "unknown task";
|
|
12930
|
+
if (!r.dismissed.includes(b.dismiss)) r.dismissed.push(b.dismiss);
|
|
12931
|
+
if (r.active?.task === b.dismiss) r.active = { ...r.active, paused: true };
|
|
12932
|
+
} else if ("hidden" in b) {
|
|
12933
|
+
if (typeof b.hidden !== "boolean") return "hidden is true or false";
|
|
12934
|
+
r.hidden = b.hidden;
|
|
12935
|
+
} else return "unknown intent";
|
|
12936
|
+
write(core.store, r);
|
|
12937
|
+
return null;
|
|
12938
|
+
}
|
|
12939
|
+
function registerGuideRoutes(app, deps) {
|
|
12940
|
+
const { core } = deps;
|
|
12941
|
+
const env = deps.env ?? process.env;
|
|
12942
|
+
stampGuide(core.store, deps.version);
|
|
12943
|
+
app.get("/api/guide", async () => readGuide(core, env));
|
|
12944
|
+
app.post("/api/guide", async (req, reply) => {
|
|
12945
|
+
const error = applyIntent(core, req.body);
|
|
12946
|
+
if (error) return reply.status(400).send({ error });
|
|
12947
|
+
return readGuide(core, env);
|
|
12948
|
+
});
|
|
12949
|
+
}
|
|
12950
|
+
|
|
12748
12951
|
// src/routes/desktop.ts
|
|
12749
12952
|
function registerDesktopRoutes(app, deps) {
|
|
12750
12953
|
const { core, runtime } = deps;
|
|
@@ -12759,7 +12962,7 @@ function registerDesktopRoutes(app, deps) {
|
|
|
12759
12962
|
record: null
|
|
12760
12963
|
};
|
|
12761
12964
|
}
|
|
12762
|
-
const { installDeps } = await import('./cli-
|
|
12965
|
+
const { installDeps } = await import('./cli-GMRPOISO.js');
|
|
12763
12966
|
const { desktopStatus } = await import('./install-VXJPLYWM.js');
|
|
12764
12967
|
return desktopStatus(installDeps(runtime.entry));
|
|
12765
12968
|
});
|
|
@@ -12767,7 +12970,7 @@ function registerDesktopRoutes(app, deps) {
|
|
|
12767
12970
|
if (!runtime.entry) {
|
|
12768
12971
|
return { ok: false, reason: "unsupported", message: "Desktop shortcuts are not available on this system yet." };
|
|
12769
12972
|
}
|
|
12770
|
-
const { addToDesktop } = await import('./cli-
|
|
12973
|
+
const { addToDesktop } = await import('./cli-GMRPOISO.js');
|
|
12771
12974
|
return addToDesktop(runtime.entry);
|
|
12772
12975
|
});
|
|
12773
12976
|
app.get("/api/desktop", async () => {
|
|
@@ -13060,7 +13263,7 @@ function buildServer(opts) {
|
|
|
13060
13263
|
const { demoProducts } = loadDemoProducts(join(templatesRoot, "demo-products"));
|
|
13061
13264
|
const demoProductById = demoProductResolver(demoProducts);
|
|
13062
13265
|
registerDemoProductRoutes(app, { templatesRoot, demoProducts, demoProductById, thumbs });
|
|
13063
|
-
registerShowcaseRoutes(app, { templatesRoot });
|
|
13266
|
+
registerShowcaseRoutes(app, { templatesRoot, thumbs });
|
|
13064
13267
|
app.get("/api/formats", async () => FORMATS);
|
|
13065
13268
|
function briefInputsOnly(brief) {
|
|
13066
13269
|
const {
|
|
@@ -14240,6 +14443,7 @@ function buildServer(opts) {
|
|
|
14240
14443
|
return drained;
|
|
14241
14444
|
});
|
|
14242
14445
|
registerSystemRoutes(app, { core, thumbs });
|
|
14446
|
+
registerGuideRoutes(app, { core, version: meta.version });
|
|
14243
14447
|
registerDesktopRoutes(app, {
|
|
14244
14448
|
core,
|
|
14245
14449
|
runtime,
|
|
@@ -14407,7 +14611,7 @@ async function run() {
|
|
|
14407
14611
|
}
|
|
14408
14612
|
}
|
|
14409
14613
|
const ownEntry = fileURLToPath(import.meta.url);
|
|
14410
|
-
const { addToDesktop, installDeps } = await import('./cli-
|
|
14614
|
+
const { addToDesktop, installDeps } = await import('./cli-GMRPOISO.js');
|
|
14411
14615
|
const { refreshLauncher } = await import('./refresh-5HBDLLLB.js');
|
|
14412
14616
|
const { askOnTerminal, offerDesktop, shouldOfferDesktop } = await import('./offer-W6NJXMWT.js');
|
|
14413
14617
|
const { launcherInstalled } = await import('./paths-6ZXRZUHY.js');
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { ASPECT_TOLERANCE, BUDGET_EXHAUSTED, EDIT_REFERENCE_ROLE_DIRECTIVE, REFERENCE_ROLE_DIRECTIVE, SCHEMA_VERSION, STEM_MIN, SchemaTooNewError, SpendCapError, TRIGRAM_MIN, budgetSize, createCatalogStore, createCore, createStore, defaultHome, fold, ftsMatch, matchesQuery, ratioLabel, searchTerms, termMatches, uniqueProjectSlug, uniqueSetSlug, uniqueSlug } from './chunk-
|
|
2
|
-
//# sourceMappingURL=src-
|
|
3
|
-
//# sourceMappingURL=src-
|
|
1
|
+
export { ASPECT_TOLERANCE, BUDGET_EXHAUSTED, EDIT_REFERENCE_ROLE_DIRECTIVE, REFERENCE_ROLE_DIRECTIVE, SCHEMA_VERSION, STEM_MIN, SchemaTooNewError, SpendCapError, TRIGRAM_MIN, budgetSize, createCatalogStore, createCore, createStore, defaultHome, fold, ftsMatch, matchesQuery, ratioLabel, searchTerms, termMatches, uniqueProjectSlug, uniqueSetSlug, uniqueSlug } from './chunk-K6IELFL3.js';
|
|
2
|
+
//# sourceMappingURL=src-TC4UQ7H6.js.map
|
|
3
|
+
//# sourceMappingURL=src-TC4UQ7H6.js.map
|