@withone/cli 1.50.0 → 1.52.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/README.md +16 -3
- package/dist/{chunk-D6W756DN.js → chunk-K56Z5BTM.js} +38 -3
- package/dist/{chunk-4WWK3GO5.js → chunk-UV4YYDF3.js} +1 -1
- package/dist/{chunk-7RV7T5PX.js → chunk-Z4KAQGIG.js} +139 -15
- package/dist/{chunk-GXOIR3GF.js → chunk-ZOJW6IMU.js} +278 -13
- package/dist/{flow-runner-YDKAYGZW.js → flow-runner-WZIYXW47.js} +1 -1
- package/dist/index.js +416 -256
- package/dist/{migrate-TRUZVAT5.js → migrate-LXDIZMXH.js} +2 -2
- package/dist/{runtime-2PRVL2NO.js → runtime-HDZCBTWH.js} +1 -1
- package/dist/{schema-LCRWSFD5.js → schema-SYMG6SRC.js} +1 -1
- package/dist/{sql-HG7R2JML.js → sql-AZDCMY7G.js} +2 -2
- package/package.json +2 -1
- package/profiles/fathom/meetings.json +4 -0
- package/profiles/gmail/gmailThreads.json +5 -0
- package/profiles/google-calendar/events.json +5 -1
- package/skills/one/SKILL.md +48 -5
- package/skills/one/references/flows.md +5 -3
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
dotPathToJsonbExpr,
|
|
4
4
|
memMigrateCommand,
|
|
5
5
|
reviveStringifiedJson
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ZOJW6IMU.js";
|
|
7
7
|
import "./chunk-44CV5IMX.js";
|
|
8
8
|
import "./chunk-CLJFSFFM.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-Z4KAQGIG.js";
|
|
10
10
|
import "./chunk-C7DWZ7B5.js";
|
|
11
11
|
import "./chunk-SO323PZP.js";
|
|
12
12
|
export {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
memSqlCommand,
|
|
3
3
|
syncSqlCommand
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-UV4YYDF3.js";
|
|
5
5
|
import "./chunk-CLJFSFFM.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-Z4KAQGIG.js";
|
|
7
7
|
import "./chunk-C7DWZ7B5.js";
|
|
8
8
|
import "./chunk-SO323PZP.js";
|
|
9
9
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@withone/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.52.0",
|
|
4
4
|
"description": "CLI for managing One",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"@types/node": "^22.13.1",
|
|
45
45
|
"@types/pg": "^8.20.0",
|
|
46
46
|
"tsup": "^8.3.6",
|
|
47
|
+
"tsx": "^4.23.1",
|
|
47
48
|
"typescript": "^5.7.3"
|
|
48
49
|
},
|
|
49
50
|
"repository": {
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
"queryParams": {
|
|
18
18
|
"include_action_items": "true"
|
|
19
19
|
},
|
|
20
|
+
"identityKeys": [
|
|
21
|
+
{ "prefix": "email", "path": "recorded_by.email" },
|
|
22
|
+
{ "prefix": "email", "path": "calendar_invitees[].email" }
|
|
23
|
+
],
|
|
20
24
|
"enrich": {
|
|
21
25
|
"actionId": "conn_mod_def::GIpBYFV5Mog::G6aag6ykQ-uD6XCeUUnq7Q",
|
|
22
26
|
"pathVars": {
|
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
"defaultLimit": 100,
|
|
16
16
|
"pathVars": { "userId": "me" },
|
|
17
17
|
"queryParams": { "q": "category:primary" },
|
|
18
|
+
"identityKeys": [
|
|
19
|
+
{ "prefix": "email", "path": "messages[].payload.headers[name=From].value" },
|
|
20
|
+
{ "prefix": "email", "path": "messages[].payload.headers[name=To].value" },
|
|
21
|
+
{ "prefix": "email", "path": "messages[].payload.headers[name=Cc].value" }
|
|
22
|
+
],
|
|
18
23
|
"enrich": {
|
|
19
24
|
"actionId": "conn_mod_def::GJ3ok0Eq0R8::AAzgZVLqTg2iBuITKpJLZg",
|
|
20
25
|
"pathVars": { "userId": "me", "id": "{id}" },
|
|
@@ -13,5 +13,9 @@
|
|
|
13
13
|
},
|
|
14
14
|
"pathVars": { "calendarId": "primary" },
|
|
15
15
|
"defaultLimit": 250,
|
|
16
|
-
"limitParam": "maxResults"
|
|
16
|
+
"limitParam": "maxResults",
|
|
17
|
+
"identityKeys": [
|
|
18
|
+
{ "prefix": "email", "path": "organizer.email" },
|
|
19
|
+
{ "prefix": "email", "path": "attendees[].email" }
|
|
20
|
+
]
|
|
17
21
|
}
|
package/skills/one/SKILL.md
CHANGED
|
@@ -189,10 +189,17 @@ one --agent mem search "deadline" # hybrid if key set, els
|
|
|
189
189
|
one --agent mem list note --limit 20
|
|
190
190
|
one --agent mem link <from-id> <to-id> relates_to --bi
|
|
191
191
|
|
|
192
|
-
#
|
|
193
|
-
# archiving a record frees its keys. `mem update '{"keys":[...]}'` is rejected.
|
|
194
|
-
one --agent mem key <id> --add email:x@y.com # add/--remove/--set
|
|
195
|
-
one --agent mem find-by-source
|
|
192
|
+
# Merge keys — the `keys[]` column (first-class, NOT data). Unique across ACTIVE
|
|
193
|
+
# records; archiving a record frees its keys. `mem update '{"keys":[...]}'` is rejected.
|
|
194
|
+
one --agent mem key <id> --add email:x@y.com # add/--remove/--set — EDITS keys[]
|
|
195
|
+
one --agent mem find-by-source attio/attioPeople:abc-1 # ONE record (prefers the active owner)
|
|
196
|
+
|
|
197
|
+
# Identity keys — cross-platform lookup. READ-ONLY query, does not edit anything.
|
|
198
|
+
# Spans BOTH `keys[]` (record IS the entity) and `identity_keys[]` (record INVOLVES
|
|
199
|
+
# the entity: Gmail thread From/To/Cc, calendar attendees — never merges).
|
|
200
|
+
one --agent mem find-by-key email:jane@acme.com # every record involving this person
|
|
201
|
+
one --agent mem find-by-key email:jane@acme.com --type gmail/gmailThreads
|
|
202
|
+
one --agent mem find-by-key email:a@x.com email:b@y.com # intersection — records with BOTH
|
|
196
203
|
|
|
197
204
|
# Backfill searchable_text (no embedding provider needed) — fixes NULL/noisy text
|
|
198
205
|
one --agent mem reindex --searchable --type attio/attioPeople
|
|
@@ -202,6 +209,33 @@ one --agent mem status # backend, provider, _up
|
|
|
202
209
|
one --agent mem doctor # full health report
|
|
203
210
|
```
|
|
204
211
|
|
|
212
|
+
**Don't confuse `mem key` with `mem find-by-key`.** `mem key` WRITES the merge column (`keys[]`) on one record — adding a key another active record already owns is an error, and `--set` replaces the whole array. `mem find-by-key` only READS, across both key columns. If you want "show me everything about this person", you always want `find-by-key`.
|
|
213
|
+
|
|
214
|
+
`find-by-key` agent output is grouped by record type:
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
{
|
|
218
|
+
"keys": ["email:jane@acme.com"],
|
|
219
|
+
"total": 13,
|
|
220
|
+
"truncated": false,
|
|
221
|
+
"fetchCap": 2000,
|
|
222
|
+
"perTypeLimit": 10,
|
|
223
|
+
"byType": {
|
|
224
|
+
"attio/attioPeople": { "count": 1, "items": [ {"id": "...", "type": "...", "data": {}, "keys": ["attio/attioPeople:J1", "email:jane@acme.com"], "updated_at": "..."} ] },
|
|
225
|
+
"gmail/gmailThreads": { "count": 12, "items": [] }
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
`items` are whole mem records. `keys` and `identity_keys` are OMITTED, not `[]`, when the record has none — the contact above matched on `keys[]` and so carries no `identity_keys` field at all. Always read them as `(item.identity_keys ?? [])`.
|
|
231
|
+
|
|
232
|
+
Read it in this order:
|
|
233
|
+
|
|
234
|
+
1. **`truncated`** — if `true`, more than `fetchCap` (2000) records matched. `total` and every `count` are then floors, and because rows come back ordered by type, whole types sorting after the cut are MISSING from `byType` entirely. Re-run with `--type <type>` to get an accurate answer; do not report the counts as-is.
|
|
235
|
+
2. **`total` / `count`** — ungrouped and per-type match counts (accurate when `truncated` is `false`).
|
|
236
|
+
3. **`items`** — whole mem records, same fields as `mem get`, capped at `perTypeLimit` (`--limit`, default 10). `count > items.length` just means display truncation — raise `--limit`.
|
|
237
|
+
4. **`keys`** — the key form that actually matched. Lookups are lowercased/trimmed first (matching how sync writes them), with a one-shot verbatim retry for hand-written mixed-case keys, so `email:Jane@Acme.com` finds `email:jane@acme.com`.
|
|
238
|
+
|
|
205
239
|
### Adding OpenAI for semantic search
|
|
206
240
|
|
|
207
241
|
Stored at the top level of `~/.one/config.json` as `openaiApiKey`, same precedence as `ONE_SECRET` (env > `.onerc OPENAI_API_KEY=...` > project > global). Three equivalent ways to set:
|
|
@@ -277,7 +311,16 @@ Without declared paths, the default walker concatenates every string in the reco
|
|
|
277
311
|
|
|
278
312
|
**Connections are late-bound** — profiles use `"connection": { "platform": "<name>" }`, not literal `connectionKey` strings. The key is resolved at sync time, so `one add <platform>` (re-auth) doesn't break the profile. For multi-account platforms, add `"tag": "<connection-tag>"` to disambiguate, and create the tagged connection with `one add <platform> --tag <name>`. Don't hardcode connection keys in profiles.
|
|
279
313
|
|
|
280
|
-
**
|
|
314
|
+
**Cross-platform identity on a profile.** Two separate fields, and picking the wrong one silently mangles data:
|
|
315
|
+
|
|
316
|
+
- `"identityKey": "properties.email"` — singular. "This record IS this entity." One dot-path; the value lands in `keys[]` and MERGES records for the same entity across platforms (HubSpot + Attio for one person collapse into a single record).
|
|
317
|
+
- `"identityKeys": [{"prefix": "email", "path": "attendees[].email"}]` — plural. "This record INVOLVES these people." Paths support `[]` wildcards and a `[name=From]` equality filter (Gmail headers). Values land in the separate `identity_keys[]` column, which does NOT merge — a 20-attendee event stays one event, not 20 contacts. Use this for anything with N participants.
|
|
318
|
+
|
|
319
|
+
Both are queryable with `one --agent mem find-by-key <prefix>:<value>`.
|
|
320
|
+
|
|
321
|
+
**Enriching profiles** (`gmail/gmailThreads`, `fathom/meetings`) sync in two phases: a list pass, then a detail pass that fetches full bodies/transcripts. Two things follow. Enrichment happens **once per record** — phase 2 only visits rows it has never enriched, and `--full-refresh` does *not* reset that, so re-running a sync will not refresh detail content (delete `.one/sync/data/<platform>.db` to force it). And the list pass never overwrites an enriched record: `data` merges rather than replaces, and `searchable_text` / `identity_keys[]` are left alone. `sync run` reports these as `memPreserved`. So on an enriching profile, a record whose upstream *detail* changed will look stale until the mirror is cleared — that is expected, not a sync failure.
|
|
322
|
+
|
|
323
|
+
**Advanced features** (enrich, transform, exclude, hooks, --full-refresh, alternative backends, embedding tuning): run `one guide memory` or `one guide sync` for the full reference.
|
|
281
324
|
|
|
282
325
|
## Beyond Single Actions
|
|
283
326
|
|
|
@@ -478,10 +478,12 @@ e.g. if sub-flow `enrich-customer` has a step `load` that returns `{ TEAM: "acme
|
|
|
478
478
|
{
|
|
479
479
|
"id": "analyze",
|
|
480
480
|
"type": "bash",
|
|
481
|
-
"bash": { "command": "cat /tmp/data.json | claude --print 'Analyze this' --output-format json", "timeout": 180000, "
|
|
481
|
+
"bash": { "command": "cat /tmp/data.json | claude --print 'Analyze this' --output-format json", "timeout": 180000, "parseEnvelope": true }
|
|
482
482
|
}
|
|
483
483
|
```
|
|
484
484
|
|
|
485
|
+
**Parsing output.** `parseJson: true` parses stdout as JSON (and strips outer code fences). For **`claude --print --output-format json`** steps use **`parseEnvelope: true`** instead — `claude` wraps the model's answer in a CLI envelope `{ "type": "result", "result": "```json\n{...}\n```" }`, and `parseEnvelope` unwraps `.result`, strips the inner code fences, drops any preamble/trailer text, and parses the inner JSON as `$.steps.<id>.output`. If the unwrapped payload isn't valid JSON the step fails (no silently-broken data). No more hand-rolled `unwrap()` helpers in code steps.
|
|
486
|
+
|
|
485
487
|
**Safe interpolation.** Plain `{{$.input.x}}` does string substitution and is **unsafe** for bash — values containing quotes, `$`, backticks, `&`, etc. will break the command (or worse). Use the `q` helper to POSIX-shell-quote the value:
|
|
486
488
|
|
|
487
489
|
```json
|
|
@@ -665,8 +667,8 @@ Each substep inside `parallel.steps` must have the full step schema: `id`, `name
|
|
|
665
667
|
|
|
666
668
|
When raw data needs analysis, use this pattern:
|
|
667
669
|
1. `file-write` — save data to temp file (API responses are too large to inline)
|
|
668
|
-
2. `bash` — call `claude --print` to analyze (set timeout to 180000+, use `--output-format json`)
|
|
669
|
-
3. `code` —
|
|
670
|
+
2. `bash` — call `claude --print` to analyze (set timeout to 180000+, use `--output-format json` and `"parseEnvelope": true` so `$.steps.<id>.output` is the clean parsed JSON)
|
|
671
|
+
3. `code` — structure the AI output for downstream steps (no manual envelope unwrap needed — `parseEnvelope` already did it)
|
|
670
672
|
|
|
671
673
|
## CLI Commands
|
|
672
674
|
|