latticesql 4.3.0 → 4.3.2
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/dist/cli.js +176 -77
- package/dist/desktop-entry.js +172 -73
- package/dist/gui-assets/ort/ort-wasm-simd-threaded.asyncify.mjs +112 -0
- package/dist/gui-assets/ort/ort-wasm-simd-threaded.jsep.mjs +106 -0
- package/dist/gui-assets/ort/ort-wasm-simd-threaded.mjs +59 -0
- package/dist/index.cjs +130 -39
- package/dist/index.js +176 -77
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -23495,12 +23495,12 @@ var getNodeModulesParentDirs;
|
|
|
23495
23495
|
var init_getNodeModulesParentDirs = __esm({
|
|
23496
23496
|
"node_modules/@aws-sdk/core/dist-es/submodules/client/util-user-agent-node/getNodeModulesParentDirs.js"() {
|
|
23497
23497
|
"use strict";
|
|
23498
|
-
getNodeModulesParentDirs = (
|
|
23498
|
+
getNodeModulesParentDirs = (dirname19) => {
|
|
23499
23499
|
const cwd = process.cwd();
|
|
23500
|
-
if (!
|
|
23500
|
+
if (!dirname19) {
|
|
23501
23501
|
return [cwd];
|
|
23502
23502
|
}
|
|
23503
|
-
const normalizedPath = normalize(
|
|
23503
|
+
const normalizedPath = normalize(dirname19);
|
|
23504
23504
|
const parts = normalizedPath.split(sep3);
|
|
23505
23505
|
const nodeModulesIndex = parts.indexOf("node_modules");
|
|
23506
23506
|
const parentDir = nodeModulesIndex !== -1 ? parts.slice(0, nodeModulesIndex).join(sep3) : normalizedPath;
|
|
@@ -23578,8 +23578,8 @@ var init_getTypeScriptUserAgentPair = __esm({
|
|
|
23578
23578
|
tscVersion = null;
|
|
23579
23579
|
return void 0;
|
|
23580
23580
|
}
|
|
23581
|
-
const
|
|
23582
|
-
const nodeModulesParentDirs = getNodeModulesParentDirs(
|
|
23581
|
+
const dirname19 = typeof __dirname !== "undefined" ? __dirname : void 0;
|
|
23582
|
+
const nodeModulesParentDirs = getNodeModulesParentDirs(dirname19);
|
|
23583
23583
|
let versionFromApp;
|
|
23584
23584
|
for (const nodeModulesParentDir of nodeModulesParentDirs) {
|
|
23585
23585
|
try {
|
|
@@ -62153,9 +62153,9 @@ init_summarize();
|
|
|
62153
62153
|
init_http2();
|
|
62154
62154
|
import { createServer } from "http";
|
|
62155
62155
|
import { spawn as spawn2 } from "child_process";
|
|
62156
|
-
import { existsSync as
|
|
62156
|
+
import { existsSync as existsSync32 } from "fs";
|
|
62157
62157
|
import { WebSocketServer, WebSocket } from "ws";
|
|
62158
|
-
import { dirname as
|
|
62158
|
+
import { dirname as dirname17, resolve as resolve16 } from "path";
|
|
62159
62159
|
|
|
62160
62160
|
// src/gui/active-db.ts
|
|
62161
62161
|
init_adapter();
|
|
@@ -64001,12 +64001,16 @@ var tokensCss = `
|
|
|
64001
64001
|
surface (a bare input on a modal, the Database wizard, User Config, etc.):
|
|
64002
64002
|
dark text on a white field with a light border. Placeholders use the
|
|
64003
64003
|
muted token. Affects every input/select/textarea across the GUI. */
|
|
64004
|
-
|
|
64004
|
+
/* Text-like fields only \u2014 radios/checkboxes keep their native rendering
|
|
64005
|
+
(the box/border treatment mangles them). The accent color tints the native
|
|
64006
|
+
controls so checked radios/checkboxes are on-brand blue. */
|
|
64007
|
+
input:not([type='radio']):not([type='checkbox']):not([type='range']), select, textarea {
|
|
64005
64008
|
color: var(--text);
|
|
64006
64009
|
background: var(--surface);
|
|
64007
64010
|
border: 1px solid var(--border);
|
|
64008
64011
|
border-radius: 6px;
|
|
64009
64012
|
}
|
|
64013
|
+
input[type='radio'], input[type='checkbox'] { accent-color: var(--accent); }
|
|
64010
64014
|
input::placeholder, textarea::placeholder {
|
|
64011
64015
|
color: var(--text-muted);
|
|
64012
64016
|
opacity: 1;
|
|
@@ -64991,7 +64995,7 @@ var teamsCss = ` /* \u2500\u2500 Teams (Project Config + User Config) \u2500\
|
|
|
64991
64995
|
color: var(--text); font-weight: 500;
|
|
64992
64996
|
text-transform: uppercase; letter-spacing: 0.04em;
|
|
64993
64997
|
}
|
|
64994
|
-
.modal .field input, .modal .field textarea {
|
|
64998
|
+
.modal .field input:not([type='radio']):not([type='checkbox']), .modal .field textarea {
|
|
64995
64999
|
width: 100%; padding: 6px 8px;
|
|
64996
65000
|
background: var(--surface); color: var(--text);
|
|
64997
65001
|
border: 1px solid var(--border-strong);
|
|
@@ -65001,6 +65005,20 @@ var teamsCss = ` /* \u2500\u2500 Teams (Project Config + User Config) \u2500\
|
|
|
65001
65005
|
color: var(--text-muted);
|
|
65002
65006
|
}
|
|
65003
65007
|
.modal .field textarea { min-height: 60px; font-family: ui-monospace, monospace; font-size: 12px; }
|
|
65008
|
+
/* New-workspace "Kind" selector \u2014 clean cards, blue-highlighted selection. */
|
|
65009
|
+
.wiz-kind-opts { display: flex; gap: 10px; margin-top: 6px; flex-wrap: wrap; }
|
|
65010
|
+
.wiz-kind-card {
|
|
65011
|
+
flex: 1 1 0; min-width: 132px; display: flex; align-items: center; gap: 9px;
|
|
65012
|
+
padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px;
|
|
65013
|
+
background: var(--surface); cursor: pointer;
|
|
65014
|
+
transition: border-color 0.12s ease, background 0.12s ease;
|
|
65015
|
+
}
|
|
65016
|
+
.wiz-kind-card:hover { border-color: var(--border-strong); }
|
|
65017
|
+
.wiz-kind-card:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
|
|
65018
|
+
.wiz-kind-card input { margin: 0; flex: 0 0 auto; }
|
|
65019
|
+
.wiz-kind-name { font-size: 13px; color: var(--text); text-transform: none; letter-spacing: 0; }
|
|
65020
|
+
.wiz-kind-sub { color: var(--text-muted); font-size: 11px; margin-left: 2px; }
|
|
65021
|
+
.wiz-kind-card:has(input:checked) .wiz-kind-name { color: var(--accent-deep); font-weight: 500; }
|
|
65004
65022
|
.modal .copy-token {
|
|
65005
65023
|
padding: 8px 10px; background: var(--surface-2); border: 1px solid var(--border);
|
|
65006
65024
|
border-radius: 4px; font-family: ui-monospace, monospace; font-size: 12px;
|
|
@@ -66246,6 +66264,9 @@ var bootJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
|
|
|
66246
66264
|
initRailDragDrop();
|
|
66247
66265
|
renderComposer();
|
|
66248
66266
|
initThreadControls();
|
|
66267
|
+
// Warm up on-device voice in the background shortly after boot so dictation
|
|
66268
|
+
// is ready on first use \u2014 no visible model-loading step, ever.
|
|
66269
|
+
if (typeof voicePreload === 'function') setTimeout(voicePreload, 1500);
|
|
66249
66270
|
checkNativeSetup();
|
|
66250
66271
|
// App is fully populated \u2014 reveal it (Feature C).
|
|
66251
66272
|
hideAppLoading();
|
|
@@ -70009,9 +70030,14 @@ var dashboardJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
|
70009
70030
|
}
|
|
70010
70031
|
var d = displayFor(table);
|
|
70011
70032
|
// The tab shows the open RECORD's name (e.g. an entity row), not the
|
|
70012
|
-
// object/table name.
|
|
70033
|
+
// object/table name. Guard: only retitle a RECORD ('item:') tab \u2014 never the
|
|
70034
|
+
// shared Brain Graph ('graph') tab, even if a record render briefly runs
|
|
70035
|
+
// while the hash still resolves to the graph (which would rename \u{1F9E0}).
|
|
70013
70036
|
if (typeof setTabTitle === 'function') {
|
|
70014
|
-
|
|
70037
|
+
var fsItemKey = tabKeyForHash(location.hash);
|
|
70038
|
+
if (fsItemKey && fsItemKey.indexOf('item:') === 0) {
|
|
70039
|
+
setTabTitle(fsItemKey, fsDisplayName(row) || d.label);
|
|
70040
|
+
}
|
|
70015
70041
|
}
|
|
70016
70042
|
// Files + artifacts get the two-view document layout (formatted display +
|
|
70017
70043
|
// a View Source toggle) with a Version History + Delete dropdown \u2014 not the
|
|
@@ -70081,7 +70107,10 @@ var dashboardJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
|
70081
70107
|
// The tab shows the FILE's name (e.g. "Properties Dashboard"), not the
|
|
70082
70108
|
// object name ("Files").
|
|
70083
70109
|
if (typeof setTabTitle === 'function') {
|
|
70084
|
-
|
|
70110
|
+
var fsDocKey = tabKeyForHash(location.hash);
|
|
70111
|
+
if (fsDocKey && fsDocKey.indexOf('item:') === 0) {
|
|
70112
|
+
setTabTitle(fsDocKey, fsDisplayName(row) || d.label);
|
|
70113
|
+
}
|
|
70085
70114
|
}
|
|
70086
70115
|
var mode = fileViewMode[id] || 'display';
|
|
70087
70116
|
// Actions live in a dropdown menu next to the title; View source / Version
|
|
@@ -72288,15 +72317,18 @@ var dataModelJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
|
72288
72317
|
return '' +
|
|
72289
72318
|
nameField +
|
|
72290
72319
|
'<div class="field"><label>Kind</label>' +
|
|
72291
|
-
'<div
|
|
72292
|
-
'<label
|
|
72293
|
-
'<input type="radio" name="wiz-kind" value="local"' + (kind === 'local' ? ' checked' : '') + ' />
|
|
72320
|
+
'<div class="wiz-kind-opts">' +
|
|
72321
|
+
'<label class="wiz-kind-card">' +
|
|
72322
|
+
'<input type="radio" name="wiz-kind" value="local"' + (kind === 'local' ? ' checked' : '') + ' />' +
|
|
72323
|
+
'<span class="wiz-kind-name">New local <span class="wiz-kind-sub">SQLite</span></span>' +
|
|
72294
72324
|
'</label>' +
|
|
72295
|
-
'<label
|
|
72296
|
-
'<input type="radio" name="wiz-kind" value="cloud"' + (kind === 'cloud' ? ' checked' : '') + ' />
|
|
72325
|
+
'<label class="wiz-kind-card">' +
|
|
72326
|
+
'<input type="radio" name="wiz-kind" value="cloud"' + (kind === 'cloud' ? ' checked' : '') + ' />' +
|
|
72327
|
+
'<span class="wiz-kind-name">New cloud <span class="wiz-kind-sub">Postgres</span></span>' +
|
|
72297
72328
|
'</label>' +
|
|
72298
|
-
'<label
|
|
72299
|
-
'<input type="radio" name="wiz-kind" value="join"' + (kind === 'join' ? ' checked' : '') + ' />
|
|
72329
|
+
'<label class="wiz-kind-card">' +
|
|
72330
|
+
'<input type="radio" name="wiz-kind" value="join"' + (kind === 'join' ? ' checked' : '') + ' />' +
|
|
72331
|
+
'<span class="wiz-kind-name">Join a team <span class="wiz-kind-sub">invite</span></span>' +
|
|
72300
72332
|
'</label>' +
|
|
72301
72333
|
'</div>' +
|
|
72302
72334
|
'<p style="font-size:11px;color:var(--text-muted);margin:6px 0 0">' +
|
|
@@ -74441,6 +74473,14 @@ var voiceLocalJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
|
|
|
74441
74473
|
return _voiceWorker;
|
|
74442
74474
|
}
|
|
74443
74475
|
|
|
74476
|
+
// Warm up the voice worker + model in the BACKGROUND on launch, so dictation is
|
|
74477
|
+
// ready by the time the user records and any first-run weight fetch happens
|
|
74478
|
+
// silently up front (never mid-recording, never with a visible "downloading"
|
|
74479
|
+
// state). Idempotent + best-effort \u2014 a failure just leaves the mic to lazy-init.
|
|
74480
|
+
function voicePreload() {
|
|
74481
|
+
try { getVoiceWorker(); } catch (_) { /* best-effort */ }
|
|
74482
|
+
}
|
|
74483
|
+
|
|
74444
74484
|
function voicePreferredDevice() {
|
|
74445
74485
|
// WebGPU when the browser exposes it, else WASM. The worker downgrades to
|
|
74446
74486
|
// wasm itself if the runtime can't honor webgpu, so this is just a hint.
|
|
@@ -74462,14 +74502,14 @@ var voiceLocalJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
|
|
|
74462
74502
|
_voiceWorkerReady = false;
|
|
74463
74503
|
}
|
|
74464
74504
|
|
|
74465
|
-
//
|
|
74466
|
-
//
|
|
74467
|
-
//
|
|
74468
|
-
|
|
74469
|
-
|
|
74470
|
-
|
|
74471
|
-
|
|
74472
|
-
|
|
74505
|
+
// Model loading is SILENT \u2014 the user never sees a "downloading voice model"
|
|
74506
|
+
// state. The worker + model are warmed up in the background on launch (see
|
|
74507
|
+
// voicePreload), and the ORT runtime ships bundled, so by the time anyone
|
|
74508
|
+
// records, dictation is ready. We intentionally surface no loading progress in
|
|
74509
|
+
// the composer; if a first-run weight fetch is still in flight, the existing
|
|
74510
|
+
// "Transcribing\u2026" placeholder covers it.
|
|
74511
|
+
function onVoiceProgress(_file, _progress) {
|
|
74512
|
+
/* intentionally silent \u2014 no visible voice-model loading UI */
|
|
74473
74513
|
}
|
|
74474
74514
|
|
|
74475
74515
|
// Decode a recorded audio blob to mono 16 kHz PCM (Float32Array), entirely in
|
|
@@ -75473,12 +75513,33 @@ var sourcesJs = `
|
|
|
75473
75513
|
'<span class="src-name">' + escapeHtml(name) + '</span></div></li>';
|
|
75474
75514
|
}).join('') + '</ul>'
|
|
75475
75515
|
: '';
|
|
75516
|
+
// Preserve expanded folders across this re-render so an in-progress
|
|
75517
|
+
// ingest (which re-renders the sidebar) never snaps an open folder shut.
|
|
75518
|
+
// Capture each expanded folder's path + its lazily-loaded children markup,
|
|
75519
|
+
// then re-attach + re-open them after the rebuild (no re-fetch, no flicker).
|
|
75520
|
+
var openFolders = {};
|
|
75521
|
+
host.querySelectorAll('.src-folder[data-loaded="1"]').forEach(function (li) {
|
|
75522
|
+
var ul0 = li.querySelector(':scope > .src-children');
|
|
75523
|
+
if (ul0 && !ul0.hidden) openFolders[li.getAttribute('data-path')] = ul0.innerHTML;
|
|
75524
|
+
});
|
|
75476
75525
|
if (!rootsHtml && !looseHtml) {
|
|
75477
75526
|
host.innerHTML = '<div class="src-empty">No files yet.</div>';
|
|
75478
75527
|
return;
|
|
75479
75528
|
}
|
|
75480
75529
|
host.innerHTML = rootsHtml + looseHtml;
|
|
75481
75530
|
wireSourceTree(host);
|
|
75531
|
+
host.querySelectorAll('.src-folder').forEach(function (li) {
|
|
75532
|
+
var saved = openFolders[li.getAttribute('data-path')];
|
|
75533
|
+
if (saved == null) return;
|
|
75534
|
+
var ul1 = li.querySelector(':scope > .src-children');
|
|
75535
|
+
var caret = li.querySelector(':scope > .src-row > .src-caret');
|
|
75536
|
+
if (!ul1) return;
|
|
75537
|
+
ul1.innerHTML = saved;
|
|
75538
|
+
ul1.hidden = false;
|
|
75539
|
+
li.setAttribute('data-loaded', '1');
|
|
75540
|
+
if (caret) caret.textContent = '\u25BE';
|
|
75541
|
+
wireSourceTree(ul1);
|
|
75542
|
+
});
|
|
75482
75543
|
})
|
|
75483
75544
|
.catch(function () { host.innerHTML = ''; });
|
|
75484
75545
|
}
|
|
@@ -79921,8 +79982,16 @@ async function dispatchIngestRoute(req, res, ctx) {
|
|
|
79921
79982
|
|
|
79922
79983
|
// src/gui/sources-routes.ts
|
|
79923
79984
|
init_user_config();
|
|
79924
|
-
import {
|
|
79925
|
-
|
|
79985
|
+
import {
|
|
79986
|
+
statSync as statSync10,
|
|
79987
|
+
readdirSync as readdirSync8,
|
|
79988
|
+
readFileSync as readFileSync24,
|
|
79989
|
+
writeFileSync as writeFileSync9,
|
|
79990
|
+
existsSync as existsSync26,
|
|
79991
|
+
mkdirSync as mkdirSync11,
|
|
79992
|
+
rmSync
|
|
79993
|
+
} from "fs";
|
|
79994
|
+
import { resolve as resolve12, join as join30, basename as basename13, sep as sep8, dirname as dirname15 } from "path";
|
|
79926
79995
|
import { execFile } from "child_process";
|
|
79927
79996
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
79928
79997
|
init_http2();
|
|
@@ -79930,20 +79999,49 @@ var MAX_LIST_ENTRIES = 2e3;
|
|
|
79930
79999
|
var MAX_INGEST_FILES = 500;
|
|
79931
80000
|
var MAX_INGEST_DEPTH = 8;
|
|
79932
80001
|
var SKIP_DIRS = /* @__PURE__ */ new Set([".git", "node_modules", ".DS_Store", "__pycache__", ".venv", "venv"]);
|
|
79933
|
-
function rootsFile() {
|
|
79934
|
-
return join30(
|
|
80002
|
+
function rootsFile(configPath) {
|
|
80003
|
+
return join30(dirname15(configPath), "sources.json");
|
|
80004
|
+
}
|
|
80005
|
+
function migrateGlobalRootsIfNeeded(configPath) {
|
|
80006
|
+
const wsFile = rootsFile(configPath);
|
|
80007
|
+
if (existsSync26(wsFile)) return;
|
|
80008
|
+
const globalFile = join30(configDir(), "sources.json");
|
|
80009
|
+
if (globalFile === wsFile || !existsSync26(globalFile)) return;
|
|
80010
|
+
let roots;
|
|
80011
|
+
try {
|
|
80012
|
+
const parsed = JSON.parse(readFileSync24(globalFile, "utf8"));
|
|
80013
|
+
if (!Array.isArray(parsed.roots) || parsed.roots.length === 0) return;
|
|
80014
|
+
roots = parsed.roots;
|
|
80015
|
+
} catch {
|
|
80016
|
+
return;
|
|
80017
|
+
}
|
|
80018
|
+
try {
|
|
80019
|
+
mkdirSync11(dirname15(wsFile), { recursive: true });
|
|
80020
|
+
writeFileSync9(wsFile, JSON.stringify({ roots }, null, 2), "utf8");
|
|
80021
|
+
} catch {
|
|
80022
|
+
return;
|
|
80023
|
+
}
|
|
80024
|
+
try {
|
|
80025
|
+
rmSync(globalFile, { force: true });
|
|
80026
|
+
} catch {
|
|
80027
|
+
try {
|
|
80028
|
+
writeFileSync9(globalFile, JSON.stringify({ roots: [] }, null, 2), "utf8");
|
|
80029
|
+
} catch {
|
|
80030
|
+
}
|
|
80031
|
+
}
|
|
79935
80032
|
}
|
|
79936
|
-
function readRoots() {
|
|
80033
|
+
function readRoots(configPath) {
|
|
80034
|
+
migrateGlobalRootsIfNeeded(configPath);
|
|
79937
80035
|
try {
|
|
79938
|
-
const raw = readFileSync24(rootsFile(), "utf8");
|
|
80036
|
+
const raw = readFileSync24(rootsFile(configPath), "utf8");
|
|
79939
80037
|
const parsed = JSON.parse(raw);
|
|
79940
80038
|
return Array.isArray(parsed.roots) ? parsed.roots : [];
|
|
79941
80039
|
} catch {
|
|
79942
80040
|
return [];
|
|
79943
80041
|
}
|
|
79944
80042
|
}
|
|
79945
|
-
function writeRoots(roots) {
|
|
79946
|
-
writeFileSync9(rootsFile(), JSON.stringify({ roots }, null, 2), "utf8");
|
|
80043
|
+
function writeRoots(configPath, roots) {
|
|
80044
|
+
writeFileSync9(rootsFile(configPath), JSON.stringify({ roots }, null, 2), "utf8");
|
|
79947
80045
|
}
|
|
79948
80046
|
function safeResolveInside2(target, roots) {
|
|
79949
80047
|
const abs = resolve12(target);
|
|
@@ -80033,14 +80131,14 @@ async function ingestFolder(abs, ingestFile) {
|
|
|
80033
80131
|
return { ingested, skipped };
|
|
80034
80132
|
}
|
|
80035
80133
|
async function dispatchSourcesRoute(req, res, deps) {
|
|
80036
|
-
const { pathname, method, ingestFile } = deps;
|
|
80134
|
+
const { pathname, method, ingestFile, configPath } = deps;
|
|
80037
80135
|
if (!pathname.startsWith("/api/sources/")) return false;
|
|
80038
80136
|
if (!localFileOpenEnabled()) {
|
|
80039
80137
|
sendJson(res, { enabled: false });
|
|
80040
80138
|
return true;
|
|
80041
80139
|
}
|
|
80042
80140
|
if (pathname === "/api/sources/roots" && method === "GET") {
|
|
80043
|
-
sendJson(res, { enabled: true, roots: readRoots() });
|
|
80141
|
+
sendJson(res, { enabled: true, roots: readRoots(configPath) });
|
|
80044
80142
|
return true;
|
|
80045
80143
|
}
|
|
80046
80144
|
if (pathname === "/api/sources/roots" && method === "POST") {
|
|
@@ -80066,12 +80164,12 @@ async function dispatchSourcesRoute(req, res, deps) {
|
|
|
80066
80164
|
sendJson(res, { error: `path not found: ${abs}` }, 400);
|
|
80067
80165
|
return true;
|
|
80068
80166
|
}
|
|
80069
|
-
const roots = readRoots();
|
|
80167
|
+
const roots = readRoots(configPath);
|
|
80070
80168
|
let root6 = roots.find((r6) => resolve12(r6.path) === abs);
|
|
80071
80169
|
if (!root6) {
|
|
80072
80170
|
root6 = { id: randomUUID4(), path: abs, kind, name: basename13(abs) || abs };
|
|
80073
80171
|
roots.push(root6);
|
|
80074
|
-
writeRoots(roots);
|
|
80172
|
+
writeRoots(configPath, roots);
|
|
80075
80173
|
}
|
|
80076
80174
|
let result;
|
|
80077
80175
|
if (kind === "folder") result = await ingestFolder(abs, ingestFile);
|
|
@@ -80082,8 +80180,8 @@ async function dispatchSourcesRoute(req, res, deps) {
|
|
|
80082
80180
|
const delMatch = /^\/api\/sources\/roots\/([^/]+)$/.exec(pathname);
|
|
80083
80181
|
if (delMatch && method === "DELETE") {
|
|
80084
80182
|
const id = decodeURIComponent(delMatch[1] ?? "");
|
|
80085
|
-
const roots = readRoots().filter((r6) => r6.id !== id);
|
|
80086
|
-
writeRoots(roots);
|
|
80183
|
+
const roots = readRoots(configPath).filter((r6) => r6.id !== id);
|
|
80184
|
+
writeRoots(configPath, roots);
|
|
80087
80185
|
sendJson(res, { ok: true });
|
|
80088
80186
|
return true;
|
|
80089
80187
|
}
|
|
@@ -80101,7 +80199,7 @@ async function dispatchSourcesRoute(req, res, deps) {
|
|
|
80101
80199
|
sendJson(res, { error: "path is required" }, 400);
|
|
80102
80200
|
return true;
|
|
80103
80201
|
}
|
|
80104
|
-
const abs = safeResolveInside2(target, readRoots());
|
|
80202
|
+
const abs = safeResolveInside2(target, readRoots(configPath));
|
|
80105
80203
|
if (!abs) {
|
|
80106
80204
|
sendJson(res, { error: "path is outside any registered source root" }, 403);
|
|
80107
80205
|
return true;
|
|
@@ -80116,7 +80214,7 @@ async function dispatchSourcesRoute(req, res, deps) {
|
|
|
80116
80214
|
if (pathname === "/api/sources/ingest-folder" && method === "POST") {
|
|
80117
80215
|
const body = await readJson(req).catch(() => ({}));
|
|
80118
80216
|
const target = typeof body.path === "string" ? body.path : "";
|
|
80119
|
-
const abs = safeResolveInside2(target, readRoots());
|
|
80217
|
+
const abs = safeResolveInside2(target, readRoots(configPath));
|
|
80120
80218
|
if (!abs) {
|
|
80121
80219
|
sendJson(res, { error: "path is outside any registered source root" }, 403);
|
|
80122
80220
|
return true;
|
|
@@ -80130,7 +80228,7 @@ async function dispatchSourcesRoute(req, res, deps) {
|
|
|
80130
80228
|
// src/gui/import-routes.ts
|
|
80131
80229
|
init_adapter();
|
|
80132
80230
|
init_http2();
|
|
80133
|
-
import { existsSync as
|
|
80231
|
+
import { existsSync as existsSync27, readFileSync as readFileSync25, statSync as statSync11 } from "fs";
|
|
80134
80232
|
import { isAbsolute as isAbsolute4, join as join31 } from "path";
|
|
80135
80233
|
init_native_entities();
|
|
80136
80234
|
function badRequest(message) {
|
|
@@ -80164,7 +80262,7 @@ async function readImportSourceFromFile(db, fileId, latticeRoot) {
|
|
|
80164
80262
|
);
|
|
80165
80263
|
if (!row) throw badRequest("Unknown import file: " + fileId);
|
|
80166
80264
|
const path3 = localPathOf2(row, latticeRoot);
|
|
80167
|
-
if (!path3 || !
|
|
80265
|
+
if (!path3 || !existsSync27(path3)) {
|
|
80168
80266
|
throw badRequest("The import file\u2019s bytes are not available locally.");
|
|
80169
80267
|
}
|
|
80170
80268
|
const sizeBytes = statSync11(path3).size;
|
|
@@ -80459,7 +80557,7 @@ init_dispatch();
|
|
|
80459
80557
|
init_column_descriptions();
|
|
80460
80558
|
init_mutations();
|
|
80461
80559
|
init_native_entities();
|
|
80462
|
-
import { createReadStream as createReadStream3, existsSync as
|
|
80560
|
+
import { createReadStream as createReadStream3, existsSync as existsSync28, realpathSync as realpathSync2, statSync as statSync12 } from "fs";
|
|
80463
80561
|
import { extname as extname3, join as join32, normalize as normalize2, sep as sep9 } from "path";
|
|
80464
80562
|
|
|
80465
80563
|
// src/gui/count-many.ts
|
|
@@ -80667,7 +80765,7 @@ async function handleReadRoutes(req, res, ctx, deps) {
|
|
|
80667
80765
|
const base = deps.guiAssetsDir.replace(/[/\\]+$/, "");
|
|
80668
80766
|
const target = normalize2(join32(base, rel));
|
|
80669
80767
|
const within = target === base || target.startsWith(base + sep9);
|
|
80670
|
-
if (!within || !
|
|
80768
|
+
if (!within || !existsSync28(target) || !statSync12(target).isFile()) {
|
|
80671
80769
|
sendJson(res, { error: "asset not found" }, 404);
|
|
80672
80770
|
return true;
|
|
80673
80771
|
}
|
|
@@ -81875,16 +81973,16 @@ async function handleHistoryRoutes(req, res, ctx, deps) {
|
|
|
81875
81973
|
// src/gui/workspaces-routes.ts
|
|
81876
81974
|
init_http2();
|
|
81877
81975
|
import { resolve as resolve13 } from "path";
|
|
81878
|
-
import { existsSync as
|
|
81976
|
+
import { existsSync as existsSync29, rmSync as rmSync2 } from "fs";
|
|
81879
81977
|
init_workspace();
|
|
81880
81978
|
init_lattice_root();
|
|
81881
81979
|
init_user_config();
|
|
81882
81980
|
function cleanupWorkspaceFiles(root6, ws) {
|
|
81883
81981
|
if (!ws.configPath && ws.kind === "local") {
|
|
81884
|
-
|
|
81982
|
+
rmSync2(workspaceDir(root6, ws.dir), { recursive: true, force: true });
|
|
81885
81983
|
} else if (ws.kind === "cloud") {
|
|
81886
|
-
if (ws.configPath &&
|
|
81887
|
-
|
|
81984
|
+
if (ws.configPath && existsSync29(ws.configPath)) {
|
|
81985
|
+
rmSync2(ws.configPath, { force: true });
|
|
81888
81986
|
}
|
|
81889
81987
|
const labelMatch = /^\$\{LATTICE_DB:([A-Za-z0-9._-]+)\}$/.exec(ws.db.trim());
|
|
81890
81988
|
const label = labelMatch?.[1];
|
|
@@ -82087,15 +82185,15 @@ async function handleWorkspacesRoutes(req, res, ctx, deps) {
|
|
|
82087
82185
|
// src/gui/databases-routes.ts
|
|
82088
82186
|
init_http2();
|
|
82089
82187
|
import { basename as basename15, resolve as resolve15 } from "path";
|
|
82090
|
-
import { existsSync as
|
|
82188
|
+
import { existsSync as existsSync31 } from "fs";
|
|
82091
82189
|
init_parser();
|
|
82092
82190
|
|
|
82093
82191
|
// src/gui/config-paths.ts
|
|
82094
82192
|
init_parser();
|
|
82095
|
-
import { basename as basename14, dirname as
|
|
82193
|
+
import { basename as basename14, dirname as dirname16, join as join33, resolve as resolve14 } from "path";
|
|
82096
82194
|
import {
|
|
82097
|
-
existsSync as
|
|
82098
|
-
mkdirSync as
|
|
82195
|
+
existsSync as existsSync30,
|
|
82196
|
+
mkdirSync as mkdirSync12,
|
|
82099
82197
|
readFileSync as readFileSync26,
|
|
82100
82198
|
readdirSync as readdirSync9,
|
|
82101
82199
|
unlinkSync as unlinkSync5,
|
|
@@ -82103,10 +82201,10 @@ import {
|
|
|
82103
82201
|
} from "fs";
|
|
82104
82202
|
import { parseDocument as parseDocument7 } from "yaml";
|
|
82105
82203
|
function resolveOutputDirForConfig(configPath) {
|
|
82106
|
-
const base =
|
|
82204
|
+
const base = dirname16(resolve14(configPath));
|
|
82107
82205
|
for (const dir of ["context", ".", "generated"]) {
|
|
82108
82206
|
const abs = resolve14(base, dir);
|
|
82109
|
-
if (
|
|
82207
|
+
if (existsSync30(join33(abs, ".lattice", "manifest.json"))) return abs;
|
|
82110
82208
|
}
|
|
82111
82209
|
return resolve14(base, "context");
|
|
82112
82210
|
}
|
|
@@ -82115,7 +82213,7 @@ function friendlyConfigName(parsedName, configPath) {
|
|
|
82115
82213
|
return basename14(configPath).replace(/\.(ya?ml)$/, "");
|
|
82116
82214
|
}
|
|
82117
82215
|
function listConfigs(activeConfigPath) {
|
|
82118
|
-
const dir =
|
|
82216
|
+
const dir = dirname16(activeConfigPath);
|
|
82119
82217
|
const entries = [];
|
|
82120
82218
|
for (const fname of readdirSync9(dir)) {
|
|
82121
82219
|
if (!fname.endsWith(".yml") && !fname.endsWith(".yaml")) continue;
|
|
@@ -82144,17 +82242,17 @@ function listConfigs(activeConfigPath) {
|
|
|
82144
82242
|
return entries.sort((a6, b6) => a6.label.localeCompare(b6.label));
|
|
82145
82243
|
}
|
|
82146
82244
|
function createBlankConfig(activeConfigPath, dbName) {
|
|
82147
|
-
const dir =
|
|
82245
|
+
const dir = dirname16(activeConfigPath);
|
|
82148
82246
|
const slug = dbName.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
82149
82247
|
if (!slug) throw new Error("Workspace name must contain at least one alphanumeric character");
|
|
82150
82248
|
const configPath = join33(dir, `${slug}.config.yml`);
|
|
82151
|
-
if (
|
|
82249
|
+
if (existsSync30(configPath)) throw new Error(`Config already exists: ${slug}.config.yml`);
|
|
82152
82250
|
const yaml = `db: ./data/${slug}.db
|
|
82153
82251
|
|
|
82154
82252
|
entities: {}
|
|
82155
82253
|
`;
|
|
82156
82254
|
writeFileSync10(configPath, yaml, "utf8");
|
|
82157
|
-
|
|
82255
|
+
mkdirSync12(join33(dir, "data"), { recursive: true });
|
|
82158
82256
|
return configPath;
|
|
82159
82257
|
}
|
|
82160
82258
|
function sqliteFileForConfig(configPath) {
|
|
@@ -82163,18 +82261,18 @@ function sqliteFileForConfig(configPath) {
|
|
|
82163
82261
|
if (!raw) return null;
|
|
82164
82262
|
if (isPostgresUrl(raw) || raw.startsWith("${LATTICE_DB:")) return null;
|
|
82165
82263
|
if (raw === ":memory:" || raw.startsWith("file:")) return null;
|
|
82166
|
-
return resolve14(
|
|
82264
|
+
return resolve14(dirname16(configPath), raw);
|
|
82167
82265
|
}
|
|
82168
82266
|
function deleteDatabaseFiles(targetConfigPath) {
|
|
82169
82267
|
const sqliteFile = sqliteFileForConfig(targetConfigPath);
|
|
82170
82268
|
unlinkSync5(targetConfigPath);
|
|
82171
82269
|
let deletedDbFile = null;
|
|
82172
|
-
if (sqliteFile &&
|
|
82270
|
+
if (sqliteFile && existsSync30(sqliteFile)) {
|
|
82173
82271
|
unlinkSync5(sqliteFile);
|
|
82174
82272
|
deletedDbFile = sqliteFile;
|
|
82175
82273
|
for (const suffix of ["-wal", "-shm", "-journal"]) {
|
|
82176
82274
|
const sidecar = sqliteFile + suffix;
|
|
82177
|
-
if (
|
|
82275
|
+
if (existsSync30(sidecar)) unlinkSync5(sidecar);
|
|
82178
82276
|
}
|
|
82179
82277
|
}
|
|
82180
82278
|
return { deletedConfig: basename14(targetConfigPath), deletedDbFile };
|
|
@@ -82208,7 +82306,7 @@ async function handleDatabasesRoutes(req, res, ctx, deps) {
|
|
|
82208
82306
|
return true;
|
|
82209
82307
|
}
|
|
82210
82308
|
const newPath = resolve15(body.path);
|
|
82211
|
-
if (!
|
|
82309
|
+
if (!existsSync31(newPath)) {
|
|
82212
82310
|
sendJson(res, { error: `Config not found: ${newPath}` }, 400);
|
|
82213
82311
|
return true;
|
|
82214
82312
|
}
|
|
@@ -82314,8 +82412,8 @@ async function handleDatabasesRoutes(req, res, ctx, deps) {
|
|
|
82314
82412
|
// src/gui/server.ts
|
|
82315
82413
|
init_user_config();
|
|
82316
82414
|
function resolveDefaultGuiAssetsDir() {
|
|
82317
|
-
const bundleSibling = process.argv[1] ? resolve16(
|
|
82318
|
-
if (bundleSibling &&
|
|
82415
|
+
const bundleSibling = process.argv[1] ? resolve16(dirname17(process.argv[1]), "gui-assets") : null;
|
|
82416
|
+
if (bundleSibling && existsSync32(bundleSibling)) return bundleSibling;
|
|
82319
82417
|
return resolve16(process.cwd(), "dist", "gui-assets");
|
|
82320
82418
|
}
|
|
82321
82419
|
function sendText(res, body, status = 200, contentType = "text/plain; charset=utf-8") {
|
|
@@ -82372,7 +82470,7 @@ async function startGuiServer(options) {
|
|
|
82372
82470
|
const sessionId = crypto.randomUUID();
|
|
82373
82471
|
let updateService = null;
|
|
82374
82472
|
let activeRef = bootConfigPath && bootOutputDir ? await openConfig(bootConfigPath, bootOutputDir, autoRender, options.realtimeWatchdogMs) : null;
|
|
82375
|
-
const latticeRoot = (bootConfigPath ? findLatticeRoot(
|
|
82473
|
+
const latticeRoot = (bootConfigPath ? findLatticeRoot(dirname17(bootConfigPath)) : null) ?? (options.latticeRoot ? resolve16(options.latticeRoot) : null);
|
|
82376
82474
|
let currentWorkspaceId = null;
|
|
82377
82475
|
if (latticeRoot && bootConfigPath) {
|
|
82378
82476
|
const launched = listWorkspaces(latticeRoot).find(
|
|
@@ -82726,7 +82824,7 @@ async function startGuiServer(options) {
|
|
|
82726
82824
|
createJunction: (otherTable) => createFileJunction(active, otherTable, sessionId),
|
|
82727
82825
|
createEntity: (entity, columns) => createUserEntity(active, entity, columns, sessionId),
|
|
82728
82826
|
aggressiveness: getAggressiveness(),
|
|
82729
|
-
latticeRoot:
|
|
82827
|
+
latticeRoot: dirname17(active.configPath),
|
|
82730
82828
|
configPath: active.configPath,
|
|
82731
82829
|
outputDir: active.outputDir,
|
|
82732
82830
|
sessionId,
|
|
@@ -82751,7 +82849,7 @@ async function startGuiServer(options) {
|
|
|
82751
82849
|
createJunction: (otherTable) => createFileJunction(active, otherTable, sessionId),
|
|
82752
82850
|
createEntity: (entity, columns) => createUserEntity(active, entity, columns, sessionId),
|
|
82753
82851
|
aggressiveness: getAggressiveness(),
|
|
82754
|
-
latticeRoot:
|
|
82852
|
+
latticeRoot: dirname17(active.configPath),
|
|
82755
82853
|
configPath: active.configPath,
|
|
82756
82854
|
outputDir: active.outputDir,
|
|
82757
82855
|
sessionId,
|
|
@@ -82762,6 +82860,7 @@ async function startGuiServer(options) {
|
|
|
82762
82860
|
return await dispatchSourcesRoute(req2, res2, {
|
|
82763
82861
|
db: active.db,
|
|
82764
82862
|
ingestFile: (p3) => ingestLocalFile(ingestCtx, mctx, p3, false),
|
|
82863
|
+
configPath: active.configPath,
|
|
82765
82864
|
pathname,
|
|
82766
82865
|
method
|
|
82767
82866
|
});
|
|
@@ -82777,7 +82876,7 @@ async function startGuiServer(options) {
|
|
|
82777
82876
|
return await dispatchImportRoute(req2, res2, {
|
|
82778
82877
|
db: active.db,
|
|
82779
82878
|
configPath: active.configPath,
|
|
82780
|
-
latticeRoot:
|
|
82879
|
+
latticeRoot: dirname17(active.configPath),
|
|
82781
82880
|
validTables: active.validTables,
|
|
82782
82881
|
softDeletable: active.softDeletable
|
|
82783
82882
|
});
|
|
@@ -82806,7 +82905,7 @@ async function startGuiServer(options) {
|
|
|
82806
82905
|
if (!pathname.startsWith("/api/files/")) return false;
|
|
82807
82906
|
return await dispatchFilesRoute(req2, res2, {
|
|
82808
82907
|
db: active.db,
|
|
82809
|
-
latticeRoot:
|
|
82908
|
+
latticeRoot: dirname17(active.configPath),
|
|
82810
82909
|
configPath: active.configPath,
|
|
82811
82910
|
pathname,
|
|
82812
82911
|
method
|
|
@@ -83017,8 +83116,8 @@ ${e6.stack ?? ""}`
|
|
|
83017
83116
|
}
|
|
83018
83117
|
|
|
83019
83118
|
// src/cloud/file-source-key-store.ts
|
|
83020
|
-
import { readFileSync as readFileSync27, writeFileSync as writeFileSync11, existsSync as
|
|
83021
|
-
import { dirname as
|
|
83119
|
+
import { readFileSync as readFileSync27, writeFileSync as writeFileSync11, existsSync as existsSync33, mkdirSync as mkdirSync13, renameSync as renameSync5, chmodSync as chmodSync3 } from "fs";
|
|
83120
|
+
import { dirname as dirname18, resolve as resolve17 } from "path";
|
|
83022
83121
|
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes9, scryptSync as scryptSync3 } from "crypto";
|
|
83023
83122
|
var ENC_HEADER = "LATTICE-KMS-v1\n";
|
|
83024
83123
|
var SCRYPT_N = 1 << 15;
|
|
@@ -83069,9 +83168,9 @@ var FileSourceKeyStore = class {
|
|
|
83069
83168
|
// ── internals ────────────────────────────────────────────────────────
|
|
83070
83169
|
load() {
|
|
83071
83170
|
const out = /* @__PURE__ */ new Map();
|
|
83072
|
-
if (!
|
|
83073
|
-
const dir =
|
|
83074
|
-
if (!
|
|
83171
|
+
if (!existsSync33(this.path)) {
|
|
83172
|
+
const dir = dirname18(this.path);
|
|
83173
|
+
if (!existsSync33(dir)) mkdirSync13(dir, { recursive: true, mode: 448 });
|
|
83075
83174
|
return out;
|
|
83076
83175
|
}
|
|
83077
83176
|
const raw = readFileSync27(this.path);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "latticesql",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.2",
|
|
4
4
|
"description": "Persistent structured memory for AI agent systems — pluggable SQLite or Postgres backend, LLM context bridge",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"test:deno": "deno test --no-check -A tests/deno/",
|
|
49
49
|
"desktop:dev": "npm run build && node scripts/sync-desktop-version.mjs && deno desktop --no-check --allow-all desktop/main.ts",
|
|
50
50
|
"desktop:build:mac": "npm run build && node scripts/sync-desktop-version.mjs && deno desktop --no-check --allow-env --allow-read --allow-write --allow-net --allow-run --allow-sys --allow-ffi --include dist/gui-assets --output dist-desktop/Lattice.dmg desktop/main.ts",
|
|
51
|
+
"desktop:build:mac:pkg": "npm run build && node scripts/sync-desktop-version.mjs && deno desktop --no-check --allow-env --allow-read --allow-write --allow-net --allow-run --allow-sys --allow-ffi --include dist/gui-assets --output dist-desktop/Lattice.app desktop/main.ts && sh scripts/build-mac-pkg.sh",
|
|
51
52
|
"desktop:build:win": "npm run build && node scripts/sync-desktop-version.mjs && deno desktop --no-check --allow-env --allow-read --allow-write --allow-net --allow-run --allow-sys --allow-ffi --include dist/gui-assets --output dist-desktop/Lattice.msi desktop/main.ts",
|
|
52
53
|
"prepublishOnly": "npm run check:generic && npm run build && npm run typecheck && npm test"
|
|
53
54
|
},
|