latticesql 1.13.1 → 1.13.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/README.md CHANGED
@@ -2082,6 +2082,10 @@ npx lattice gui --config ./lattice.config.yml --output ./context --port 4317
2082
2082
 
2083
2083
  The convergence means you don't need to duplicate entity-context definitions in YAML for the GUI to find rendered files.
2084
2084
 
2085
+ **Database wizard form (v1.13.2+).** The Postgres connection form (used by Migrate to cloud + Connect to existing cloud) disables browser autocapitalize, autocorrect, and spellcheck on every text input, and trims whitespace on every read. This avoids silent failure modes where macOS Safari / iOS turned a Supabase tenant user `postgres.<ref>` into `Postgres.<ref>` on submit, and where pasted credentials carrying a trailing newline produced opaque "zero-length delimiter identifier" or SCRAM-mismatch errors. `probeCloud` also folds SQLSTATE + `routine` into `result.error` so the GUI's "Unreachable: …" surface is actionable.
2086
+
2087
+ **Switch vs. migrate (v1.13.2+ wording).** "Connect to existing cloud" _switches_ the project's `db:` line to point at the cloud; the local SQLite file stays on disk and you can switch back by editing the YAML or via the Databases catalog under User Config. Use "Migrate to cloud" only when you want to _push_ the local data into a fresh empty target.
2088
+
2085
2089
  **Views**
2086
2090
 
2087
2091
  - **Dashboard** (`#/`) — one card per first-class entity with live row counts.
package/dist/cli.js CHANGED
@@ -7999,27 +7999,39 @@ var guiAppHtml = `<!doctype html>
7999
7999
 
8000
8000
  function postgresFormHtml(prefill) {
8001
8001
  prefill = prefill || {};
8002
+ // autocapitalize="off" + autocorrect="off" + spellcheck="false" keep
8003
+ // mobile / macOS keyboards from "helpfully" capitalizing the first
8004
+ // letter of usernames + host fragments. Supabase tenant users
8005
+ // (postgres.<ref>) are case-sensitive and silently failed
8006
+ // authentication when iOS Safari turned the leading "p" into "P".
8007
+ var attrs = ' autocapitalize="off" autocorrect="off" spellcheck="false"';
8002
8008
  return (
8003
8009
  '<div class="grid" style="display:grid;grid-template-columns:repeat(2,1fr);gap:8px">' +
8004
- '<div><label class="field-label">Label</label><input type="text" id="w-label" placeholder="atlas" value="' + escapeHtml(prefill.label || '') + '" style="width:100%"></div>' +
8005
- '<div><label class="field-label">Host</label><input type="text" id="w-host" placeholder="db.example.com" value="' + escapeHtml(prefill.host || '') + '" style="width:100%"></div>' +
8010
+ '<div><label class="field-label">Label</label><input type="text" id="w-label" placeholder="atlas" value="' + escapeHtml(prefill.label || '') + '" style="width:100%"' + attrs + '></div>' +
8011
+ '<div><label class="field-label">Host</label><input type="text" id="w-host" placeholder="db.example.com" value="' + escapeHtml(prefill.host || '') + '" style="width:100%"' + attrs + '></div>' +
8006
8012
  '<div><label class="field-label">Port</label><input type="number" id="w-port" placeholder="5432" value="' + escapeHtml(String(prefill.port || 5432)) + '" style="width:100%"></div>' +
8007
- '<div><label class="field-label">Database name</label><input type="text" id="w-dbname" placeholder="app" value="' + escapeHtml(prefill.dbname || '') + '" style="width:100%"></div>' +
8008
- '<div><label class="field-label">User</label><input type="text" id="w-user" placeholder="lattice_user" value="' + escapeHtml(prefill.user || '') + '" style="width:100%"></div>' +
8009
- '<div><label class="field-label">Password</label><input type="password" id="w-password" placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" style="width:100%"></div>' +
8013
+ '<div><label class="field-label">Database name</label><input type="text" id="w-dbname" placeholder="app" value="' + escapeHtml(prefill.dbname || '') + '" style="width:100%"' + attrs + '></div>' +
8014
+ '<div><label class="field-label">User</label><input type="text" id="w-user" placeholder="lattice_user" value="' + escapeHtml(prefill.user || '') + '" style="width:100%"' + attrs + '></div>' +
8015
+ '<div><label class="field-label">Password</label><input type="password" id="w-password" placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" style="width:100%"' + attrs + '></div>' +
8010
8016
  '</div>'
8011
8017
  );
8012
8018
  }
8013
8019
 
8014
8020
  function readPostgresWizardForm() {
8021
+ // Every text field is trimmed \u2014 pasted credentials frequently carry a
8022
+ // trailing newline or leading space that breaks URL construction
8023
+ // (zero-length identifier errors from the Postgres parser) or SCRAM
8024
+ // auth (silent password mismatch). Trim once, here, so every caller
8025
+ // benefits.
8026
+ var get = function (id) { return (document.getElementById(id).value || '').trim(); };
8015
8027
  return {
8016
8028
  type: 'postgres',
8017
- label: (document.getElementById('w-label').value || '').trim(),
8018
- host: (document.getElementById('w-host').value || '').trim(),
8029
+ label: get('w-label'),
8030
+ host: get('w-host'),
8019
8031
  port: Number(document.getElementById('w-port').value || 5432),
8020
- dbname: (document.getElementById('w-dbname').value || '').trim(),
8021
- user: document.getElementById('w-user').value || '',
8022
- password: document.getElementById('w-password').value || '',
8032
+ dbname: get('w-dbname'),
8033
+ user: get('w-user'),
8034
+ password: get('w-password'),
8023
8035
  };
8024
8036
  }
8025
8037
 
@@ -8054,10 +8066,14 @@ var guiAppHtml = `<!doctype html>
8054
8066
  function showConnectExistingModal(onClose) {
8055
8067
  var bodyHtml =
8056
8068
  '<p style="margin:0 0 12px;font-size:13px;color:var(--text-muted)">' +
8057
- 'Connect this project to an <strong>existing</strong> cloud Postgres. ' +
8058
- 'Your local SQLite data will be ignored \u2014 use Migrate to cloud instead ' +
8059
- 'if you want to push it. If the target is a teams DB you\\'ll be asked ' +
8060
- 'for an invite token after the probe.' +
8069
+ 'Switch this project to an <strong>existing</strong> cloud Postgres. ' +
8070
+ 'Your local SQLite file is preserved \u2014 only this project\\'s active ' +
8071
+ 'connection changes. Switch back any time by editing ' +
8072
+ '<code>lattice.config.yml</code>\\'s <code>db:</code> line or via the ' +
8073
+ 'Databases catalog under User Config. If you want to <em>push</em> ' +
8074
+ 'your local rows into the target instead, use Migrate to cloud. If ' +
8075
+ 'the target is a teams DB you\\'ll be asked for an invite token ' +
8076
+ 'after the probe.' +
8061
8077
  '</p>' +
8062
8078
  postgresFormHtml({}) +
8063
8079
  '<div id="w-team-zone" style="margin-top:10px"></div>' +
@@ -9748,11 +9764,18 @@ async function probeCloud(targetUrl) {
9748
9764
  }
9749
9765
  return teamName !== void 0 ? { reachable: true, dialect, teamEnabled, teamName } : { reachable: true, dialect, teamEnabled };
9750
9766
  } catch (e) {
9767
+ const err = e;
9768
+ const parts = [];
9769
+ if (err.code) parts.push(`[${err.code}]`);
9770
+ if (err.message) parts.push(err.message);
9771
+ if (err.routine && !err.message.includes(err.routine)) {
9772
+ parts.push(`(routine: ${err.routine})`);
9773
+ }
9751
9774
  return {
9752
9775
  reachable: false,
9753
9776
  dialect,
9754
9777
  teamEnabled: false,
9755
- error: e.message
9778
+ error: parts.join(" ") || "unknown"
9756
9779
  };
9757
9780
  } finally {
9758
9781
  if (probe) {
package/dist/index.cjs CHANGED
@@ -5730,11 +5730,18 @@ async function probeCloud(targetUrl) {
5730
5730
  }
5731
5731
  return teamName !== void 0 ? { reachable: true, dialect, teamEnabled, teamName } : { reachable: true, dialect, teamEnabled };
5732
5732
  } catch (e) {
5733
+ const err = e;
5734
+ const parts = [];
5735
+ if (err.code) parts.push(`[${err.code}]`);
5736
+ if (err.message) parts.push(err.message);
5737
+ if (err.routine && !err.message.includes(err.routine)) {
5738
+ parts.push(`(routine: ${err.routine})`);
5739
+ }
5733
5740
  return {
5734
5741
  reachable: false,
5735
5742
  dialect,
5736
5743
  teamEnabled: false,
5737
- error: e.message
5744
+ error: parts.join(" ") || "unknown"
5738
5745
  };
5739
5746
  } finally {
5740
5747
  if (probe) {
package/dist/index.js CHANGED
@@ -5658,11 +5658,18 @@ async function probeCloud(targetUrl) {
5658
5658
  }
5659
5659
  return teamName !== void 0 ? { reachable: true, dialect, teamEnabled, teamName } : { reachable: true, dialect, teamEnabled };
5660
5660
  } catch (e) {
5661
+ const err = e;
5662
+ const parts = [];
5663
+ if (err.code) parts.push(`[${err.code}]`);
5664
+ if (err.message) parts.push(err.message);
5665
+ if (err.routine && !err.message.includes(err.routine)) {
5666
+ parts.push(`(routine: ${err.routine})`);
5667
+ }
5661
5668
  return {
5662
5669
  reachable: false,
5663
5670
  dialect,
5664
5671
  teamEnabled: false,
5665
- error: e.message
5672
+ error: parts.join(" ") || "unknown"
5666
5673
  };
5667
5674
  } finally {
5668
5675
  if (probe) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "latticesql",
3
- "version": "1.13.1",
3
+ "version": "1.13.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",