@withone/cli 1.47.7 → 1.47.8
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/index.js +6 -0
- package/dist/schema-DXHEU47V.js +109 -0
- package/package.json +1 -1
- package/skills/one/SKILL.md +1 -0
package/dist/index.js
CHANGED
|
@@ -8300,6 +8300,10 @@ function registerSyncSubcommands(sync) {
|
|
|
8300
8300
|
sync.command("sql <platform/model> <sql>").description("Run a read-only SELECT / WITH / EXPLAIN against the memory store (type-scoped helper)").action(async (platformModel, sql) => {
|
|
8301
8301
|
await syncSqlCommand(platformModel, sql);
|
|
8302
8302
|
});
|
|
8303
|
+
sync.command("schema <platform/model>").description("Inspect the JSON structure of synced records (field paths, types, examples) \u2014 useful before writing `sync sql` queries").action(async (platformModel) => {
|
|
8304
|
+
const { syncSchemaCommand } = await import("./schema-DXHEU47V.js");
|
|
8305
|
+
await syncSchemaCommand(platformModel);
|
|
8306
|
+
});
|
|
8303
8307
|
sync.command("delete <platform/model>").description('Delete records from local sync data (e.g. one sync delete notion/pages --id "abc-123")').option("--id <value>", "Delete record by ID").option("--where <conditions>", 'Delete records matching conditions (e.g. "status=archived")').option("--where-sql <predicate>", `Delete using a raw SQL WHERE clause (e.g. "json_extract(data, '$.type') = 'promotion'")`).option("--yes", "Skip confirmation prompt").action(async (platformModel, options) => {
|
|
8304
8308
|
await syncDeleteCommand(platformModel, options);
|
|
8305
8309
|
});
|
|
@@ -10019,6 +10023,7 @@ one --agent sync run stripe
|
|
|
10019
10023
|
one --agent mem sync run stripe # identical (alias)
|
|
10020
10024
|
|
|
10021
10025
|
# 5. Query + search (read from memory)
|
|
10026
|
+
one --agent sync schema stripe/customers # inspect field paths/types first
|
|
10022
10027
|
one --agent sync query stripe/balanceTransactions --where "status=available" --limit 20
|
|
10023
10028
|
one --agent sync query stripe/customers --where 'address.city=SF' # dotted --where paths
|
|
10024
10029
|
one --agent sync search "refund" --platform stripe # hybrid FTS + semantic
|
|
@@ -10259,6 +10264,7 @@ Every \`sync X\` command is also exposed as \`mem sync X\` \u2014 same handlers,
|
|
|
10259
10264
|
| \`sync suggest-searchable <plat>/<model>\` | Rank candidate \`memory.searchable\` paths by signal density; emits paste-ready config |
|
|
10260
10265
|
| \`sync run <platform>\` | Sync data (\`--full-refresh\`, \`--since\`, \`--dry-run\`, \`--no-memory\`) |
|
|
10261
10266
|
| \`sync query <plat>/<model>\` | Query memory with \`--where\` (dotted paths), \`--after/before\` |
|
|
10267
|
+
| \`sync schema <plat>/<model>\` | Inspect the JSON structure of synced records (field paths, types, examples) \u2014 run before writing \`--where\` / query paths |
|
|
10262
10268
|
| \`sync search "<query>"\` | Hybrid FTS + semantic across all synced data |
|
|
10263
10269
|
| \`sync list [platform]\` | Show profiles, record counts, freshness |
|
|
10264
10270
|
| \`sync schedule add/list/status/remove/repair\` | Manage cron schedules |
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isAgentMode,
|
|
3
|
+
note,
|
|
4
|
+
okJson,
|
|
5
|
+
requireMemoryInit
|
|
6
|
+
} from "./chunk-HS5AHQ4V.js";
|
|
7
|
+
import {
|
|
8
|
+
getBackend
|
|
9
|
+
} from "./chunk-OADHUAEU.js";
|
|
10
|
+
import "./chunk-TXTRXV74.js";
|
|
11
|
+
import "./chunk-K6MWE2ZH.js";
|
|
12
|
+
|
|
13
|
+
// src/lib/memory/sync/schema.ts
|
|
14
|
+
import pc from "picocolors";
|
|
15
|
+
var SAMPLE_SIZE = 100;
|
|
16
|
+
function typeOf(v) {
|
|
17
|
+
if (v === null) return "null";
|
|
18
|
+
if (Array.isArray(v)) return "array";
|
|
19
|
+
return typeof v;
|
|
20
|
+
}
|
|
21
|
+
function exampleOf(v) {
|
|
22
|
+
if (typeof v === "string") return v.length > 60 ? `${v.slice(0, 57)}\u2026` : v;
|
|
23
|
+
return v;
|
|
24
|
+
}
|
|
25
|
+
function addPath(path, value, acc) {
|
|
26
|
+
const t = typeOf(value);
|
|
27
|
+
let typeLabel;
|
|
28
|
+
if (t === "array") {
|
|
29
|
+
const arr = value;
|
|
30
|
+
const elemType = arr.length ? typeOf(arr[0]) : "unknown";
|
|
31
|
+
typeLabel = `array[${elemType}]`;
|
|
32
|
+
} else {
|
|
33
|
+
typeLabel = t;
|
|
34
|
+
}
|
|
35
|
+
const entry = acc.get(path) ?? { types: /* @__PURE__ */ new Set(), hasExample: false, presence: 0 };
|
|
36
|
+
entry.types.add(typeLabel);
|
|
37
|
+
entry.presence += 1;
|
|
38
|
+
if (!entry.hasExample && t !== "object" && t !== "array" && value !== null && value !== void 0) {
|
|
39
|
+
entry.example = exampleOf(value);
|
|
40
|
+
entry.hasExample = true;
|
|
41
|
+
}
|
|
42
|
+
acc.set(path, entry);
|
|
43
|
+
if (t === "object") {
|
|
44
|
+
for (const [k, v] of Object.entries(value)) {
|
|
45
|
+
addPath(path ? `${path}.${k}` : k, v, acc);
|
|
46
|
+
}
|
|
47
|
+
} else if (t === "array") {
|
|
48
|
+
const arr = value;
|
|
49
|
+
if (arr.length && typeOf(arr[0]) === "object") {
|
|
50
|
+
for (const [k, v] of Object.entries(arr[0])) {
|
|
51
|
+
addPath(`${path}[].${k}`, v, acc);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function inferSyncSchema(dataRecords) {
|
|
57
|
+
const acc = /* @__PURE__ */ new Map();
|
|
58
|
+
for (const data of dataRecords) {
|
|
59
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) continue;
|
|
60
|
+
for (const [k, v] of Object.entries(data)) addPath(k, v, acc);
|
|
61
|
+
}
|
|
62
|
+
return [...acc.entries()].map(([path, e]) => ({
|
|
63
|
+
path,
|
|
64
|
+
types: [...e.types].sort(),
|
|
65
|
+
...e.hasExample ? { example: e.example } : {},
|
|
66
|
+
presence: e.presence
|
|
67
|
+
})).sort((a, b) => a.path.localeCompare(b.path));
|
|
68
|
+
}
|
|
69
|
+
async function syncSchemaCommand(platformModel, _options = {}) {
|
|
70
|
+
requireMemoryInit();
|
|
71
|
+
const type = platformModel;
|
|
72
|
+
const backend = await getBackend();
|
|
73
|
+
let recordCount = 0;
|
|
74
|
+
try {
|
|
75
|
+
recordCount = await backend.count(type, { status: "active" });
|
|
76
|
+
} catch {
|
|
77
|
+
}
|
|
78
|
+
const records = await backend.list(type, { limit: SAMPLE_SIZE, status: "active" });
|
|
79
|
+
if (records.length === 0) {
|
|
80
|
+
if (isAgentMode()) {
|
|
81
|
+
okJson({ type, recordCount: 0, sampled: 0, fields: [] });
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
note(`No records found for "${type}". Run \`one sync run <platform>\` first, or check \`one --agent sync status\`.`, "Schema");
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const fields = inferSyncSchema(records.map((r) => r.data));
|
|
88
|
+
if (isAgentMode()) {
|
|
89
|
+
okJson({ type, recordCount, sampled: records.length, fields });
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
console.log();
|
|
93
|
+
console.log(`${pc.bold(type)} ${pc.dim(`(${recordCount.toLocaleString()} record${recordCount === 1 ? "" : "s"}, sampled ${records.length})`)}`);
|
|
94
|
+
console.log();
|
|
95
|
+
const pathWidth = Math.min(Math.max(...fields.map((f) => f.path.length), 4) + 2, 50);
|
|
96
|
+
const typeWidth = Math.max(...fields.map((f) => f.types.join("|").length), 4) + 2;
|
|
97
|
+
for (const f of fields) {
|
|
98
|
+
const optional = f.presence < records.length ? pc.yellow(" ?") : "";
|
|
99
|
+
const ex = f.example !== void 0 ? pc.dim(JSON.stringify(f.example)) : "";
|
|
100
|
+
console.log(` ${f.path.padEnd(pathWidth)}${pc.cyan(f.types.join("|").padEnd(typeWidth))}${ex}${optional}`);
|
|
101
|
+
}
|
|
102
|
+
console.log();
|
|
103
|
+
console.log(pc.dim(` ? = present in only some sampled records (optional/sparse field)`));
|
|
104
|
+
console.log();
|
|
105
|
+
}
|
|
106
|
+
export {
|
|
107
|
+
inferSyncSchema,
|
|
108
|
+
syncSchemaCommand
|
|
109
|
+
};
|
package/package.json
CHANGED
package/skills/one/SKILL.md
CHANGED
|
@@ -229,6 +229,7 @@ one --agent sync test attio/attioPeople --show-searchable
|
|
|
229
229
|
|
|
230
230
|
# Run — memory is always written; pass --no-memory to skip (rare)
|
|
231
231
|
one --agent sync run stripe
|
|
232
|
+
one --agent sync schema stripe/customers # inspect field paths/types before querying
|
|
232
233
|
one --agent sync query stripe/balanceTransactions --where "status=available" --limit 20
|
|
233
234
|
one --agent sync search "refund" # hybrid across all synced platforms
|
|
234
235
|
one --agent sync list stripe # progress + freshness
|