@withone/cli 1.38.0 → 1.39.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 +2 -0
- package/dist/index.js +37 -16
- package/package.json +1 -1
- package/skills/one/SKILL.md +2 -0
package/README.md
CHANGED
|
@@ -330,6 +330,8 @@ one sync init stripe balanceTransactions --config '{"onInsert":"one flow execute
|
|
|
330
330
|
one sync run stripe --full-refresh
|
|
331
331
|
```
|
|
332
332
|
|
|
333
|
+
> **Sync uses passthrough actions only.** Profiles referencing a custom/composer action are rejected at runtime. `sync models` already filters to passthrough-only; if a model has no passthrough list endpoint, compose a flow instead of syncing.
|
|
334
|
+
|
|
333
335
|
| Subcommand | What it does |
|
|
334
336
|
|------------|-------------|
|
|
335
337
|
| `install` / `doctor` | Install + verify the SQLite engine |
|
package/dist/index.js
CHANGED
|
@@ -4666,6 +4666,9 @@ function parseActionType(actionKey) {
|
|
|
4666
4666
|
if (parts.length < 5) return null;
|
|
4667
4667
|
return parts[4];
|
|
4668
4668
|
}
|
|
4669
|
+
function isCustomAction(tags) {
|
|
4670
|
+
return !!tags && tags.includes("custom");
|
|
4671
|
+
}
|
|
4669
4672
|
async function discoverModels(api, platform) {
|
|
4670
4673
|
const actions2 = await api.listAvailableActions(platform);
|
|
4671
4674
|
const listActionTypes = /* @__PURE__ */ new Set(["get_many", "list", "get_all"]);
|
|
@@ -4674,6 +4677,7 @@ async function discoverModels(api, platform) {
|
|
|
4674
4677
|
const actionType = parseActionType(action.key);
|
|
4675
4678
|
if (!actionType) continue;
|
|
4676
4679
|
if (!listActionTypes.has(actionType)) continue;
|
|
4680
|
+
if (isCustomAction(action.tags)) continue;
|
|
4677
4681
|
const modelName = action.modelName;
|
|
4678
4682
|
if (!modelName) continue;
|
|
4679
4683
|
if (modelMap.has(modelName)) {
|
|
@@ -4697,7 +4701,7 @@ async function discoverModels(api, platform) {
|
|
|
4697
4701
|
try {
|
|
4698
4702
|
const searchResults = await api.searchActions(platform, model.displayName, "execute");
|
|
4699
4703
|
const resolved = searchResults.find(
|
|
4700
|
-
(a) => a.path === model.listAction.path && a.method === model.listAction.method
|
|
4704
|
+
(a) => a.path === model.listAction.path && a.method === model.listAction.method && !isCustomAction(a.tags)
|
|
4701
4705
|
);
|
|
4702
4706
|
if (resolved?.systemId) {
|
|
4703
4707
|
model.listAction.actionId = resolved.systemId;
|
|
@@ -4706,7 +4710,8 @@ async function discoverModels(api, platform) {
|
|
|
4706
4710
|
}
|
|
4707
4711
|
})
|
|
4708
4712
|
);
|
|
4709
|
-
|
|
4713
|
+
const syncable = models.filter((m) => m.listAction.actionId.startsWith("conn_mod_def::"));
|
|
4714
|
+
return syncable.sort((a, b) => a.name.localeCompare(b.name));
|
|
4710
4715
|
}
|
|
4711
4716
|
|
|
4712
4717
|
// src/lib/sync/profile.ts
|
|
@@ -5524,6 +5529,11 @@ async function enrichPhase(api, db, config2, model, idField, connectionKey, plat
|
|
|
5524
5529
|
`Enrich: could not load action ${config2.actionId}: ${err instanceof Error ? err.message : String(err)}`
|
|
5525
5530
|
);
|
|
5526
5531
|
}
|
|
5532
|
+
if (detailAction.tags?.includes("custom")) {
|
|
5533
|
+
throw new Error(
|
|
5534
|
+
`Enrich does not support custom actions. Action ${config2.actionId} is tagged "custom". Use a passthrough detail endpoint \u2014 run 'one actions search ${platform} "<model> get"' to find one.`
|
|
5535
|
+
);
|
|
5536
|
+
}
|
|
5527
5537
|
let concurrency = config2.concurrency ?? DEFAULT_CONCURRENCY;
|
|
5528
5538
|
let enriched = 0;
|
|
5529
5539
|
let skipped = 0;
|
|
@@ -5913,6 +5923,11 @@ async function syncModel(api, profile, options) {
|
|
|
5913
5923
|
}
|
|
5914
5924
|
}
|
|
5915
5925
|
const actionDetails = await api.getActionDetails(profile.actionId);
|
|
5926
|
+
if (actionDetails.tags?.includes("custom")) {
|
|
5927
|
+
throw new Error(
|
|
5928
|
+
`Sync does not support custom actions. Action ${profile.actionId} is tagged "custom". Use a passthrough action \u2014 run 'one actions search ${platform} "${model}"' to find one, or compose a flow that chains passthrough calls if the logic is complex.`
|
|
5929
|
+
);
|
|
5930
|
+
}
|
|
5916
5931
|
const maxPages = options.maxPages ?? Infinity;
|
|
5917
5932
|
let tableCreated = tableExists(db, model);
|
|
5918
5933
|
let currentPageQueryParams = { ...queryParams };
|
|
@@ -8582,23 +8597,29 @@ one --agent sync profiles stripe # filter by platform
|
|
|
8582
8597
|
|
|
8583
8598
|
When a built-in exists, \`sync init\` uses it automatically \u2014 no inference needed, no manual config. The agent just needs to match the user's intent to a profile description.
|
|
8584
8599
|
|
|
8585
|
-
## Action Resolution
|
|
8600
|
+
## Action Resolution \u2014 custom actions are hard-blocked
|
|
8586
8601
|
|
|
8587
|
-
Sync
|
|
8588
|
-
|
|
8589
|
-
|
|
8590
|
-
|
|
8591
|
-
of that creates problems, not value.
|
|
8602
|
+
Sync refuses to run against custom/composer actions (tag \`custom\`). Both
|
|
8603
|
+
the list action and any enrich detail action in a profile MUST be passthrough.
|
|
8604
|
+
\`sync run\` loads the action's knowledge, checks for the \`custom\` tag, and
|
|
8605
|
+
aborts with a clear error pointing at the passthrough alternative.
|
|
8592
8606
|
|
|
8593
|
-
|
|
8594
|
-
|
|
8595
|
-
|
|
8596
|
-
|
|
8597
|
-
|
|
8598
|
-
|
|
8599
|
-
4. Only fall back to custom actions when no passthrough equivalent exists
|
|
8607
|
+
Why the block:
|
|
8608
|
+
- Custom actions run on a small shared fleet that collapses under sync-scale load
|
|
8609
|
+
- Custom list endpoints often expect filters in the body and silently return
|
|
8610
|
+
unfiltered or empty results (sync sends params as query/path only by design)
|
|
8611
|
+
- The sync engine already handles pagination, retry, rate limiting, and per-record
|
|
8612
|
+
enrichment locally \u2014 server-side fan-out on top of that creates 5xx, not value
|
|
8600
8613
|
|
|
8601
|
-
|
|
8614
|
+
How to build a profile:
|
|
8615
|
+
1. \`one actions search <platform> "<model>"\` surfaces passthrough actions.
|
|
8616
|
+
\`sync init\`'s auto-infer also drops customs before offering choices.
|
|
8617
|
+
2. Prefer GET passthrough endpoints (e.g. /gmail/v1/users/{userId}/threads)
|
|
8618
|
+
over POST custom endpoints (e.g. /gmail/get-threads).
|
|
8619
|
+
3. If no passthrough list action exists for a model, that model can't be
|
|
8620
|
+
synced. Compose a flow that chains passthrough calls instead. Custom
|
|
8621
|
+
actions are for one-off agent use only \u2014 never sync, never flow.
|
|
8622
|
+
4. The enrich \`actionId\` is held to the same rule: must be passthrough.
|
|
8602
8623
|
|
|
8603
8624
|
## Workflow: init \u2192 run \u2192 query
|
|
8604
8625
|
|
package/package.json
CHANGED
package/skills/one/SKILL.md
CHANGED
|
@@ -173,6 +173,8 @@ one --agent sync list stripe # progress + freshness
|
|
|
173
173
|
one sync schedule add stripe --every 1h
|
|
174
174
|
```
|
|
175
175
|
|
|
176
|
+
**Sync rejects custom actions** — profiles must use passthrough. `sync init` only surfaces passthrough models; `sync run` aborts if the list or enrich action is tagged `custom`. If no passthrough exists, compose a flow instead.
|
|
177
|
+
|
|
176
178
|
**Advanced features** (enrich, transform, exclude, identityKey, hooks, --full-refresh, --where-sql delete, cursor resume): run `one guide sync` for the full reference.
|
|
177
179
|
|
|
178
180
|
## Beyond Single Actions
|