Skip to content

Releases: withoneai/cli

v1.43.4

04 May 16:06
096a331

Choose a tag to compare

Fixes

  • one connection list --limit N now honors --limit in human mode (previously it was applied only with --agent).
  • one list --limit N (top-level shortcut) now forwards --limit and --search to the handler. Fixes one --agent list --limit 25.

Closes #134

v1.43.3

04 May 03:36
265392e

Choose a tag to compare

Fix: one --agent mem search exits in ~300ms instead of hanging for ~10s after the JSON response prints.

Root cause: node-pg Pool's default idleTimeoutMillis: 10000 kept the still-idle pooled connection alive after the query completed, so the event loop sat for the full 10 seconds before the process could exit. The mem_hybrid_search SQL itself was 37ms; the OpenAI embed call was 200ms; the actual work always finished in ~700ms — the rest was just the idle-timeout drain.

Fix: closeBackendIfCached() helper in runtime.ts, called from the program's postAction hook. Awaits the cached backend promise (if any) and calls backend.close() so every command that touched memory drains its pool before exit. No-op when no mem/sync command instantiated a backend; errors are swallowed (we're shutting down). Idle-timeout stays at the node-pg default during a command so sequential queries reuse one pool connection.

Verified against ~/CEO with 14,543 records:

  • Before: ~10.4s per mem search invocation
  • After: 300–420ms warm, ~2s cold

98/98 tests pass.

v1.43.2

04 May 02:11
d9f40e9

Choose a tag to compare

Folds the standalone @withone/mem package into the One CLI as a pluggable memory subsystem, makes it the primary target for sync, and introduces a real-Postgres-by-default story for new users.

Default backend: embedded-postgres

New installs get a real local Postgres process via pgserve (Postgres 18, cluster bootstrapped at ~/.one/pg/cluster/). PGlite repeatedly corrupted during real syncs against ~250M of Gmail data, so it's been retired from the product surface — unregistered from the plugin registry, removed from mem init, mem config, and the help/doctor diagnostics. The plugin source remains in tree as a dev-only unit-test fixture; not bundled, not selectable.

  • First boot downloads ~52MB of Postgres binaries; later boots are ~2s.
  • The daemon survives across CLI invocations via a .pgserve.json PID/port file. Multiple One CLI processes share one cluster.
  • pgserve auto-provisions databases on first connect.
  • Long-term convergence: same cluster will host one-run's tables once it adopts pgserve too.

Runtime pgvector detection

The plugin probes CREATE EXTENSION IF NOT EXISTS vector once at first connect. Available → vectorSearch: true, schema applies the vector block (extension, embedding columns, HNSW index, hybrid_search function), and the vector-aware mem_upsert_by_keys overrides the no-vector variant. Not available → vectorSearch: false, FTS-only, with a structured _upgrade hint on mem doctor, mem search, and mem status pointing at brew install pgvector. Reversible — install pgvector later and the next ensureSchema picks it up via IF NOT EXISTS ALTERs.

What's new in the unification

  • Zero-config memory — auto-initializes the configured backend on first call. No mem init prerequisite.
  • Top-level OpenAI key — stored as config.openaiApiKey, same precedence chain as ONE_SECRET.
  • Upgrade hintsmem status / mem search / mem doctor carry a structured _upgrade block when semantic search is available but off. Three variants: no OpenAI key, key but provider=none, and now: backend without pgvector.
  • Agent-declared memory.searchable — profiles carry dot-paths that drive embedded + FTS text. Supports numeric indexes and [] wildcards.
  • Memory-primary sync — every sync run writes into mem_records. SQLite dual-write retained only for enrich profiles.
  • one mem sync alias — full alias of one sync, single command tree.
  • Sync state moves to mem_sync_state table — legacy .one/sync/state/*.json auto-migrated on first access.
  • sync query --where supports dotted paths (values.job_title[0].value like %Engineering%).
  • Replace-semantics upsert — synced rows replace data, tags, searchable_text, content_hash wholesale so fields removed upstream actually disappear from memory.
  • Deterministic mergeORDER BY r.updated_at DESC NULLS LAST, r.id ASC LIMIT 1 so multi-row key overlap doesn't pick a random winner.
  • Schema race fixensureSchema runs inside client.transaction(...) with a pg_advisory_xact_lock, pinned to a single connection so concurrent CLI processes can't race on CREATE EXTENSION / CREATE OR REPLACE FUNCTION.

Migration

one mem migrate reads legacy .one/sync/data/*.db files into the unified store. Self-heals stale installed-profile idField against the in-tree built-in (with --no-heal opt-out and full transparency in agent JSON: originalIdField, healedTo, builtinNewerThanInstalled, plus a tailored note). Read-only on the user's SQLite — no journal_mode rewrite, no -wal/-shm siblings, no destructive corruption-recovery rename. --cleanup --dry-run previews the file list before touching anything.

Verified end-to-end against 14,543 rows of real production data

Total Inserted MergedByIdentity Skipped
14,543 24 3,474 0

Idempotency: re-running migrate produces 0 new inserts; all updates. Concurrency: 3 parallel mem doctor runs all green. mem migrate dry-run does not create -wal/-shm siblings.

Deprecations (non-breaking)

  • --to-memory flag on sync run — silent no-op (memory always written). Use --no-memory to opt out.
  • sync sql — errors with a pointer to mem search / mem list.
  • PGlite — retired from the product surface.

Schema version 2.1.0.

v1.42.0

22 Apr 17:02
582cce1

Choose a tag to compare

New one relay platforms command — discover which platforms support webhook relay and how many event types each exposes, without having to guess-and-check with relay event-types <platform>.

$ one relay platforms
  Platform         Event types
  ───────────────  ───────────
  airtable         3
  attio            27
  stripe           224
  ...

$ one --agent relay platforms
{"platforms":[{"platform":"airtable","eventTypeCount":3}, ...]}

Also fixes a bug where sync always hit prod because OneApi was constructed without apiBase. #124

v1.41.0

21 Apr 01:18
da14a0e

Choose a tag to compare

Late-bound connection refs in flow action steps. Re-auth no longer breaks flows.

```json
"connection": { "platform": "gmail" } // single account
"connection": { "platform": "gmail", "tag": "work@example.com" } // multi-account
```

Resolution runs at flow-execute time. The connection list is fetched once per flow run and cached on the flow context — a many-step flow does ONE `listConnections` round-trip regardless of step count. Selectors work inside the ref's `tag` field for multi-tenant flows.

Backwards compatible: literal `connectionKey` still works.

Companion to v1.40.0 (sync). #121

v1.40.0

21 Apr 00:56
619eb64

Choose a tag to compare

Late-bound connection refs in sync profiles. Re-auth no longer breaks profiles.

```json
"connection": { "platform": "gmail" } // single account
"connection": { "platform": "gmail", "tag": "work@example.com" } // multi-account
```

Resolution runs at sync test/run time. After `one add gmail` (re-auth), the next sync picks up the fresh key automatically — no manual edits across profiles.

Backwards compatible: literal `connectionKey` still works. Built-in profiles migrated.

Closes #114. Partial fix for #113 (closed). Flow engine support to follow.

#120

v1.39.1

21 Apr 00:19
3891b93

Choose a tag to compare

Hard-block custom actions in sync test (and sync init auto-validation).

Follow-up to #118: the previous fix added the guard in sync run and enrich, but sync test was missing it — so a profile pointing at a custom action would pass test and only fail later at run time. The check now lives in testSyncProfile so every entry point rejects custom actions consistently.

#119

v1.39.0

20 Apr 23:46
3bc1935

Choose a tag to compare

fix: hard-block custom actions in sync

Sync refuses profiles referencing custom/composer actions (tag custom). Both the list action and any enrich action must be passthrough — custom actions run on a small shared fleet that collapses under sync-scale load and often expect filters in the request body that sync doesn't send.

Changes

  • discoverModels filters customs at resolution and drops models with no passthrough variant — sync models <platform> only returns syncable models
  • sync run aborts with a clear error pointing at one actions search and the flow alternative when the list or enrich action is tagged custom
  • Docs updated: guide, skill, README

Why

The symptoms were empty results (withoneai/knowledge#65) and a feature request for body-param support (#116). Neither is the right fix — sync should never use custom actions. Custom actions are for one-off agent use only.

Closes #116, closes withoneai/knowledge#65. Shipped in #118.

v1.38.0

19 Apr 23:12
68b9a98

Choose a tag to compare

What's new

  • Root-array response support for sync. Profiles can now set resultsPath to "" / "$" / "." when the API returns a bare array at the root (e.g. Hacker News /v0/topstories.json[9129911, 9129199, ...]).
  • Primitive-array auto-wrapping. Arrays of numbers/strings/bools are wrapped as { [idField]: String(value) } so they flow through the existing schema-inference and upsert pipeline with no downstream special-casing.
  • Built-in profile: hacker-news/topStoriesone sync init hacker-news topStories now works out of the box.
  • Clearer extraction errors. When resultsPath doesn't resolve to an array, the error now names the profile (platform/model), the path, and the actual top-level type of the response.

Profile validation no longer rejects an empty resultsPath (only undefined). Existing object-rooted profiles (Attio, Gmail, Fathom, Calendar, Notion, Stripe) are unchanged.

PR: #117

v1.37.3

19 Apr 22:33
ef557cc

Choose a tag to compare

Fix: eliminate cross-platform sync state race. Concurrent syncs (cron firing all platforms at once) were racing on the shared .one/sync/sync_state.json — failed renames wedged models in status=syncing, and the read-modify-write could silently lose an update. State is now stored per-platform/per-model at .one/sync/state/<platform>/<model>.json so each writer owns its own file. Legacy file is migrated on first read.

Closes #111 (PR #112)