[object Object]

← back to Dw Pairs Well

auto-save: 2026-07-13T10:54:28 (1 files) — scripts/pipe-title-backfill/fm-cli.mjs

fbc4abae01dfbbdea7eb81f9a17261f09a9af4cc · 2026-07-13 10:54:33 -0700 · Steve Abrams

Files touched

Diff

commit fbc4abae01dfbbdea7eb81f9a17261f09a9af4cc
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Jul 13 10:54:33 2026 -0700

    auto-save: 2026-07-13T10:54:28 (1 files) — scripts/pipe-title-backfill/fm-cli.mjs
---
 scripts/pipe-title-backfill/fm-cli.mjs | 55 ++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/scripts/pipe-title-backfill/fm-cli.mjs b/scripts/pipe-title-backfill/fm-cli.mjs
new file mode 100644
index 0000000..a8a81cb
--- /dev/null
+++ b/scripts/pipe-title-backfill/fm-cli.mjs
@@ -0,0 +1,55 @@
+#!/usr/bin/env node
+// Thin CLI over the filemaker-mcp client library so we can drive fm_find / fm_layouts /
+// fm_field_metadata / fm_get_record from bash (the MCP tools aren't exposed in-session).
+// READ-ONLY usage here (find/layouts/fields/get). Env comes from the MCP `env` block in ~/.claude.json.
+// Author: steve@designerwallcoverings.com
+import fs from 'node:fs';
+
+// Load FM creds from ~/.claude.json filemaker MCP env block (same source the MCP server uses).
+const cj = JSON.parse(fs.readFileSync(process.env.HOME + '/.claude.json', 'utf8'));
+function findEnv(o) {
+  if (o && typeof o === 'object') {
+    if (o.filemaker?.env) return o.filemaker.env;
+    for (const k in o) { const r = findEnv(o[k]); if (r) return r; }
+  }
+  return null;
+}
+const env = findEnv(cj);
+if (!env) { console.error('no filemaker MCP env found'); process.exit(1); }
+for (const [k, v] of Object.entries(env)) if (!process.env[k]) process.env[k] = v;
+
+const fm = await import('/Users/macstudio3/Projects/filemaker-mcp/src/fm-client.js');
+
+const [cmd, ...rest] = process.argv.slice(2);
+try {
+  if (cmd === 'ping') {
+    console.log(JSON.stringify(await fm.ping(), null, 2));
+  } else if (cmd === 'databases') {
+    console.log(JSON.stringify(fm.listDatabases(), null, 2));
+  } else if (cmd === 'layouts') {
+    const [db] = rest;
+    console.log(JSON.stringify(await fm.layouts(db), null, 2));
+  } else if (cmd === 'fields') {
+    const [db, layout] = rest;
+    const r = await fm.fieldMetadata(db, layout);
+    const names = (r.fieldMetaData || []).map(f => f.name);
+    console.log(JSON.stringify(names, null, 2));
+  } else if (cmd === 'find') {
+    // args: <db> <layout|-> <queryJSON> [limit]
+    const [db, layoutArg, queryJSON, limit] = rest;
+    const layout = layoutArg === '-' ? undefined : layoutArg;
+    const query = JSON.parse(queryJSON);
+    const r = await fm.findRecords(db, layout, query, { limit: limit ? Number(limit) : 5 });
+    console.log(JSON.stringify(r, null, 2));
+  } else if (cmd === 'get') {
+    const [db, layoutArg, recordId] = rest;
+    const layout = layoutArg === '-' ? undefined : layoutArg;
+    console.log(JSON.stringify(await fm.getRecord(db, layout, recordId), null, 2));
+  } else {
+    console.error('usage: ping | databases | layouts <db> | fields <db> [layout] | find <db> <layout|-> <queryJSON> [limit] | get <db> <layout|-> <recordId>');
+    process.exit(2);
+  }
+} catch (e) {
+  console.error('FM_ERR', e.message);
+  process.exit(1);
+}

← 1f6151b fix: OSP Kamatera sync survives prevent_dw_prefix_mfr_sku gu  ·  back to Dw Pairs Well  ·  add reload-visual-search.sh: resolve :9914 owner by listenin f89ae0b →