@fargowealth/fargo-ai-cli 1.5.0 → 1.5.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.5.1 — 2026-10-17
4
+
5
+ - Remove the local `fargo yida` command family, personal YiDA OAuth and seven local `yida_*` MCP tools from the distributed CLI. The MCP bridge and one-shot commands use the hosted Fargo Pass catalog. Local YiDA source and maintenance tests are archived outside the npm package.
6
+
7
+ - Request explicit default-mailbox read/write scopes for desktop Fargo Pass connections. Reauthorize an existing connection to enable the four mail tools.
8
+
3
9
  ## 1.5.0 — 2026-10-15
4
10
 
5
11
  - Align the Portal and Fargo Pass displayed CLI version with this package.
package/README.md CHANGED
@@ -37,8 +37,7 @@ reused by both MCP and local CLI operations.
37
37
  deploy composition, and migration-file ordering.
38
38
  - CLI has no generic R2 or Cloudflare administration commands.
39
39
  - `fargo mcp serve` is the local stdio bridge for WorkBuddy, Claude Code,
40
- Codex, and Cursor. It executes the reserved `yida_*` tools locally and
41
- forwards other tools to hosted Fargo Pass.
40
+ Codex, and Cursor. It forwards tool discovery and calls to hosted Fargo Pass.
42
41
  - `fargo mcp tools` and `fargo mcp call` support scripts and one-shot
43
42
  diagnostics without starting an MCP host.
44
43
 
@@ -48,140 +47,6 @@ fargo mcp call lego_app_read --args '{"action":"get","appId":"app_xxx"}'
48
47
  fargo mcp call lego_app_read --args-file ./arguments.json
49
48
  ```
50
49
 
51
- ## Personal YiDA connection
52
-
53
- YiDA runs in the local CLI for client Agents. Sign in to Fargo first, then
54
- authorize your own DingTalk/YiDA account:
55
-
56
- ```sh
57
- fargo yida auth login --endpoint https://xdlonl.aliwork.com --corp-id ding376dac86ffe9d2dbf2c783f7214b6d69
58
- fargo yida auth status
59
- fargo yida schema APP_GITLRTH76PM6J4M29F5D FORM-0AE7D3E4C01D45AC97D8C68DF7FF6B6CH3LQ
60
- ```
61
-
62
- Login uses the OpenYida-compatible public client, `openid corpid`, an ephemeral
63
- IPv4 loopback callback at `/oauth/callback`, and the YiDA service's token
64
- exchange. It requires that the target YiDA environment accept this client
65
- and callback. The OAuth screen identifies the provider as YiDA. This is
66
- YiDA's personal Bearer-token channel, distinct from the DingTalk server API
67
- `x-acs-dingtalk-access-token` / `systemToken` channel.
68
-
69
- Each operation verifies the current Fargo identity with `ping_who_am_i`.
70
- YiDA credentials stay in owner-restricted local files under `~/.fargo/yida`
71
- (`%APPDATA%/Fargo AI/yida` on Windows), isolated by Fargo issuer, account and
72
- organization, then by YiDA enterprise and member. They are not sent to Fargo
73
- servers or printed in CLI/MCP output. State checks, a refresh lock, and identity
74
- checks protect callback handling and rotating tokens. These are restricted
75
- files, not an OS keychain or encrypted credential vault.
76
-
77
- `auth status` and `auth profiles` report local metadata only. If multiple
78
- profiles exist, select the exact returned `profile` ID with `--profile` for
79
- schema reads and logout. Logout attempts provider revocation and always removes
80
- the selected local credentials; `remoteRevoked` reports whether the provider
81
- confirmed success. `fargo auth logout` alone does not revoke YiDA credentials.
82
-
83
- The client MCP connection adds five read-only tools and two workflow write tools:
84
-
85
- | Tool | Result |
86
- | --- | --- |
87
- | `yida_connection_status` | Current Fargo account's local YiDA profiles; no tokens |
88
- | `yida_describe_form` | Field IDs, labels, aliases, parent fields, static options, detected source/association references and event bindings |
89
- | `yida_resolve_field` | Live options or linked defaults from a reviewed read-only expression and its originating form |
90
- | `yida_business_list` | Admitted business packages matching the selected local enterprise |
91
- | `yida_business_bundle` | Versioned Schema and Handbook, cached as one package and checked against the live YiDA schema |
92
- | `yida_cancel_request` | Preview, then terminate the current member's own running process; requires a declared business capability and final YiDA permission |
93
- | `yida_submit_expense` | Preview, then submit the current member's own ordinary non-project expense using one reviewed form adapter, live HR/bank/default/rate lookups, a registered PDF upload receipt and invoice/order duplicate checks |
94
-
95
- ```sh
96
- fargo mcp call yida_describe_form --args '{"appType":"APP_GITLRTH76PM6J4M29F5D","formUuid":"FORM-0AE7D3E4C01D45AC97D8C68DF7FF6B6CH3LQ"}'
97
- fargo yida auth logout --profile <profileId>
98
- ```
99
-
100
- The LEGO publisher is App `app_5c7114fa1a53`; the App is published
101
- for company-account access without a marketplace listing. These commands require
102
- CLI 1.5.0 or later:
103
-
104
- ```sh
105
- fargo yida business list
106
- fargo yida business get external_payment
107
- ```
108
-
109
- `business list` returns catalog summaries (Chinese name, business ID, version
110
- and capability flags), not all Schema/Handbook bodies. Agents should match the
111
- user's request against this directory, ask the user to choose when ambiguous,
112
- and fetch only the selected business. There is no keyword/search flag yet.
113
- The YiDA publisher selects 14 homepage business entries, grouped as finance,
114
- business, assets and other applications, with Chinese display names and aliases.
115
- Enterprise matching does not prove personal permission to submit, and catalog
116
- presence does not enable an unimplemented submission adapter. Department,
117
- currency, exchange-rate, accounting, company and supplier sources are business
118
- dependencies, not standalone employee entries. Query only a selected business's
119
- configured fields with `yida_resolve_field`; adapters resolve the applicant and
120
- department through that form's reviewed personal connector. Copied/test forms
121
- and retired HR workflows do not appear in the employee directory.
122
-
123
- Each fetch checks App access online, validates the enterprise, package hash and
124
- minimum CLI version, then caches the pair atomically under `~/.fargo/yida-business`
125
- (`%APPDATA%/Fargo AI/yida-business` on Windows). Cache keys include the verified
126
- Fargo account/organization, publisher App and YiDA profile. Cache hits still
127
- check authorization; network and permission errors have no offline fallback.
128
- The returned `pin` contains `businessId`, `revision` and `bundleHash`; pass all
129
- three to `yida_business_bundle` for subsequent calls within the same workflow.
130
- The CLI equivalent is `business get <businessId> --revision <n> --bundle-hash <hash>`.
131
- An unpinned lookup checks the latest release; a pinned lookup retains its exact
132
- version. Published revisions are immutable and latest-version downgrades fail.
133
-
134
- Every package lookup also reads the live YiDA schema. `status=schema_changed`
135
- requires model and handbook review before a new business revision is published.
136
- No package currently enables generic submission. Dynamic dictionary values are
137
- queried at runtime, rather than cached in the handbook. All admitted
138
- App users use one default role; YiDA data access still follows personal grants.
139
- See [publisher maintenance](../../apps/yida-connector/README.md) for release steps.
140
-
141
- All 45 captured process businesses declare the same cancellation capability;
142
- 42 receipt tables do not. `yida_cancel_request` defaults to a read-only preview.
143
- Pass its `pin.revision`, `pin.bundleHash` and `previewHash` back with `dryRun:false`
144
- only when the user requests cancellation. Execution verifies live schema and
145
- form/process binding, enterprise/member and originator, current state and unchanged
146
- preview; YiDA still decides whether the member can terminate. This retains the
147
- record and does not reverse completed downstream business effects. Already
148
- terminated/canceled returns `already_cancelled`; completed requests are blocked.
149
- Active termination has mock coverage, but has not yet been tested on a live active
150
- instance. A preview and no-op read of the user's manually terminated test do not
151
- prove active-write permission. Accepted or ambiguous writes are never resent;
152
- only proven pre-dispatch failures and authorization rejections permit a later
153
- explicit attempt after a fresh preview. Journals live under `~/.fargo/yida-operations`
154
- (Windows: `%APPDATA%/Fargo AI/yida-operations`). These tools require this updated
155
- CLI 1.5.0 or later.
156
-
157
- The expense adapter supports only ordinary expense form
158
- `FORM-6EB2E57A94CF4445BB28508DC45262E3MDDX` at its reviewed live schema hash.
159
- It does not accept raw form payloads, an alternative originator, projects or other
160
- forms. Its payment company follows the member's configured default and its payment
161
- currency/rates follow live definitions; `amount` and `currency` are the original
162
- expense. Bank fields come only from the member's own HR record. Pass a local JSON
163
- receipt from the registered YiDA PDF upload as `attachmentReceiptPath`. Preview
164
- first, then pass `dryRun:false`, `previewHash`, `revision` and `bundleHash` to execute.
165
- One invoice gets one durable operation record; an ambiguous write must be reconciled
166
- instead of retried. This local reviewed adapter is separate from the still-disabled
167
- generic submission capability in business packages.
168
-
169
- Schema reads use the user's permission to read YiDA design schemas. Dynamic
170
- options and effective employee permissions need runtime verification; formula
171
- and event detection does not reconstruct all business logic. Model output omits
172
- default values and executable source, reports traversal/option truncation, and
173
- does not submit or modify any business record. Only public-cloud HTTPS
174
- `aliwork.com` / `yidaapps.com` origins are supported in this first version.
175
-
176
- Restart the client MCP process after updating the CLI to discover the new tools.
177
- Hosted-only MCP connections do not expose these local tools. For an unpublished
178
- checkout, use `node packages/fargo-cli/bin/fargo.mjs` in place of `fargo`.
179
-
180
- Implementation references and the upstream MIT notice are included in
181
- [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
182
-
183
- Run the local connector and CLI tests with `npm test` from this package.
184
-
185
50
  ## Large-file transfer
186
51
 
187
52
  `fargo upload` transfers a local file using an upload descriptor supplied by
@@ -386,69 +251,6 @@ serialized across CLI processes.
386
251
  Never copy, upload, commit, or print the credential file. Use
387
252
  `fargo auth logout` when a device is no longer trusted.
388
253
 
389
- ## YiDA runtime rules
390
-
391
- The local `yida_describe_form` response now includes `runtime.rules` with the
392
- configured calculation expressions, dependent fields, lookup source fields,
393
- conditions and triggers. Page JavaScript is not executed. Distributed business
394
- packages carry configuration-read and runtime-verification states separately.
395
-
396
- Use the local MCP tool `yida_resolve_field` with `appType`, `formUuid`, `fieldId`,
397
- `kind` (`options` or `linked_value`), the dependent field `values`, and an exact
398
- `profile` when needed. The tool re-reads the actual schema and uses its configured
399
- read-only lookup expression with the originating form context. It rejects raw
400
- expressions, unsupported functions and cross-app queries. No arbitrary POST or
401
- general submission tool is exposed. A related-option response reaching 100 items
402
- is possibly truncated and must not be treated as a complete dictionary.
403
-
404
- The reviewed payment initialization adapter queries only the token member's HR
405
- record, filters the returned fields, validates department membership, and resolves
406
- the first department manager according to the page implementation. It does not
407
- return unrelated HR fields or accept another user's identity.
408
-
409
- `docs/yida/process-center/README.md` indexes every captured page and its paired
410
- Schema/Handbook; the LEGO App distributes the 87 process/receipt business packages.
411
- The local source implements these capabilities; this CLI update is not yet
412
- published to npm. The specifically authorized 0.06 HKD payment smoke test is
413
- recorded separately and does not enable general submission.
414
-
415
- The reviewed expense execution contract lives in `schema.execution` of the ordinary
416
- expense business package. It records semantic inputs, source rules and dependencies,
417
- rounding, currencies, upload/read-back representation, and recovery states. Its
418
- 13 lookups run by dependency with at most four concurrent queries; a single own-HR
419
- response supplies applicant and bank fields within each preparation. No live values
420
- are cached between preview and execution. Currency multiplication uses decimal
421
- half-up cents; the API read-back checks rates, accounting categories and file metadata.
422
-
423
- Update the contract source in `src/yida-expense-contract.mjs`, materialize it with
424
- `node scripts/yida-update-expense-contract.mjs` from the repository root, then freeze
425
- a new immutable Schema/Handbook revision. The capture script reapplies this contract
426
- only for the exact reviewed schema hash. Publishing a business package does not
427
- update the local CLI executable. See `docs/yida/expense-workflow-review.md` for the
428
- measured request count, remaining upload/recovery gaps and validation limits.
429
-
430
- Expense identity checks now share an internal task context for one MCP invocation
431
- (preparation or execution), not the lifetime of a chat or the MCP process. It is
432
- never an externally supplied identity or persistent permission cache. Reads share
433
- one online result while local credential changes invalidate the task; execution
434
- performs an additional online check immediately before writing. Contexts expire
435
- within five minutes and are closed on success or failure. Credential rotation
436
- requires a fresh task, including same-account token refresh during the task.
437
-
438
- A matching prior expense may be excluded from duplicate blocking only after its
439
- details confirm the same owner/form/process and TERMINATED/CANCELED state. A fresh
440
- application has no business linkage to the terminated one. The local replay guard
441
- uses the verified terminal history to distinguish a new attempt without deleting
442
- or bypassing the earlier operation journal. Active/completed/uncertain records
443
- continue to block duplicates; no mutation is automatically retried.
444
-
445
- ### User confirmation before expense submission
446
-
447
- The three main business Handbooks contain their own overall-parameter and detail-row
448
- Markdown tables. `yida_submit_expense` returns the rendered table in
449
- `confirmation.markdown`; show both parts to the user and wait for an explicit
450
- Confirm of that exact preview. Only then pass `userConfirmed: true` with
451
- `dryRun: false`, `revision`, `bundleHash`, and `previewHash`. A change to data,
452
- attachments or the preview requires a fresh user confirmation. This Boolean is
453
- caller attestation, not independent proof of a human signature. Travel and external
454
- payment display templates do not enable new submission adapters.
254
+ ## Default Mate mailbox
255
+
256
+ Fargo Pass exposes `mail_list`, `mail_get`, `mail_get_attachment` and `mail_update` for your single default Agent mailbox. Upgrade to CLI 1.5.1 and sign in again to grant `fargo:mail:read` and `fargo:mail:write`. The mailbox address comes from the default Agent, not your login username. If no default Agent is active, the tools return `mailbox_not_provisioned` with a link to Fargo Mate. `ping_who_am_i.account.defaultAgent` exposes its current name and email, or `null`.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fargowealth/fargo-ai-cli",
3
- "version": "1.5.0",
4
- "description": "Fargo Pass CLI and local MCP with personal YiDA authorization, business definitions and confirmed expense requests",
3
+ "version": "1.5.2",
4
+ "description": "Fargo Pass CLI for desktop agents, hosted MCP, default Agent mailboxes, uploads and LEGO deployment",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "fargo": "bin/fargo.mjs",
@@ -11,7 +11,6 @@
11
11
  "bin",
12
12
  "src",
13
13
  "CHANGELOG.md",
14
- "THIRD_PARTY_NOTICES.md",
15
14
  "README.md"
16
15
  ],
17
16
  "engines": {
package/src/cli.mjs CHANGED
@@ -10,17 +10,12 @@ import { callMcpTool, listMcpTools } from "./mcp-client.mjs";
10
10
  import { runMcpProxy } from "./mcp-proxy.mjs";
11
11
  import { installAgentMcp } from "./agent-install.mjs";
12
12
  import { transferUpload } from "./upload-transfer.mjs";
13
- import { runYidaCli } from "./yida-cli.mjs";
14
13
 
15
14
  export async function runCli(args, options = {}) {
16
15
  const stdout = options.stdout ?? process.stdout;
17
16
  const stderr = options.stderr ?? process.stderr;
18
17
  const store = options.store ?? createCredentialStore(options.storeOptions);
19
18
  try {
20
- if (args[0] === "yida") {
21
- await runYidaCli(args.slice(1), store, { ...options, stdout, stderr });
22
- return;
23
- }
24
19
  if (isHelpOption(args) && args[0] === "lego" && args[1] === "deploy") {
25
20
  stdout.write(LEGO_DEPLOY_HELP);
26
21
  return;
@@ -155,7 +150,7 @@ export async function runCli(args, options = {}) {
155
150
  await installAgentConnection(args, "workbuddy", stdout, store, options);
156
151
  return;
157
152
  }
158
- throw new Error("Usage: fargo auth login|device|status|logout | fargo yida auth|schema|business | fargo agent install --agent <agent> | fargo mcp serve|tools|call | fargo upload | fargo lego snapshot upload|list|download | fargo lego deploy | fargo lego d1 migrate plan|apply | fargo workbuddy install | fargo version");
153
+ throw new Error("Usage: fargo auth login|device|status|logout | fargo agent install --agent <agent> | fargo mcp serve|tools|call | fargo upload | fargo lego snapshot upload|list|download | fargo lego deploy | fargo lego d1 migrate plan|apply | fargo workbuddy install | fargo version");
159
154
  } catch (error) {
160
155
  stderr.write(`fargo: ${error instanceof Error ? error.message : "unknown error"}\n`);
161
156
  if (options.throwOnError) throw error;
@@ -167,7 +162,6 @@ const ROOT_HELP = `Usage: fargo <command> [options]
167
162
 
168
163
  Commands:
169
164
  auth login|device|status|logout
170
- yida auth login|status|profiles|logout | schema <appType> <formUuid>
171
165
  agent install --agent <codex|claude-code|cursor|workbuddy>
172
166
  mcp serve|tools|call
173
167
  upload --file <path> --request-file <path>
package/src/constants.mjs CHANGED
@@ -1,8 +1,8 @@
1
- export const CLI_VERSION = "1.5.0";
1
+ export const CLI_VERSION = "1.5.2";
2
2
  export const DEVICE_CODE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
3
3
  export const DEFAULT_AUTH_URL = "https://auth.fargowealth.app";
4
4
  export const DEFAULT_API_URL = "https://mcp.fargowealth.app";
5
5
  export const DEFAULT_MCP_URL = "https://mcp.fargowealth.app/mcp";
6
6
  export const OAUTH_CLIENT_ID = "fargo-cli-workbuddy";
7
- export const OAUTH_SCOPE = "fargo:forum:read fargo:forum:write fargo:hub:read fargo:lego:read fargo:lego:write fargo:knowledge:read fargo:knowledge:write fargo:knowledge:share";
7
+ export const OAUTH_SCOPE = "fargo:mail:read fargo:mail:write fargo:mail:send fargo:forum:read fargo:forum:write fargo:hub:read fargo:lego:read fargo:lego:write fargo:knowledge:read fargo:knowledge:write fargo:knowledge:share";
8
8
  export const SUPPORTED_AGENT_TYPES = ["codex", "claude-code", "cursor", "workbuddy"];
@@ -1,14 +1,13 @@
1
1
  import { DEFAULT_MCP_URL } from "./constants.mjs";
2
2
  import { authenticatedRequest, responsePayload } from "./api-client.mjs";
3
- import { callLocalYidaTool, isLocalYidaTool, localYidaTools } from "./yida-tools.mjs";
3
+ import { requireCurrentTool } from "./retired-tools.mjs";
4
4
 
5
5
  export async function listMcpTools(store, options = {}) {
6
- const result = await mcpRequest(store, "tools/list", {}, options);
7
- return { ...result, tools: [...(result.tools ?? []).filter(tool => !isLocalYidaTool(tool.name)), ...localYidaTools()] };
6
+ return mcpRequest(store, "tools/list", {}, options);
8
7
  }
9
8
 
10
9
  export async function callMcpTool(store, name, args, options = {}) {
11
- if (isLocalYidaTool(name)) return callLocalYidaTool(store, name, args, options);
10
+ requireCurrentTool(name);
12
11
  return mcpRequest(store, "tools/call", { name, arguments: args }, options);
13
12
  }
14
13
 
package/src/mcp-proxy.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createInterface } from "node:readline";
2
2
  import { CLI_VERSION, DEFAULT_MCP_URL } from "./constants.mjs";
3
3
  import { currentCredential, refreshCurrentCredential } from "./auth.mjs";
4
- import { callLocalYidaTool, isLocalYidaTool, localYidaTools } from "./yida-tools.mjs";
4
+ import { requireCurrentTool } from "./retired-tools.mjs";
5
5
 
6
6
  export async function runMcpProxy(store, options = {}) {
7
7
  const input = options.input ?? process.stdin;
@@ -18,19 +18,9 @@ export async function runMcpProxy(store, options = {}) {
18
18
  try { message = JSON.parse(line); }
19
19
  catch { return; }
20
20
  try {
21
- if (message.method === "tools/call" && isLocalYidaTool(message.params?.name)) {
22
- if (message.id === undefined) return;
23
- let result;
24
- try { result = await callLocalYidaTool(store, message.params.name, message.params.arguments, options); }
25
- catch (error) { result = { isError: true, content: [{ type: "text", text: error instanceof Error ? error.message : "Local YiDA tool failed" }] }; }
26
- output.write(`${JSON.stringify({ jsonrpc: "2.0", id: message.id, result })}\n`);
27
- return;
28
- }
21
+ if (message.method === "tools/call") requireCurrentTool(message.params?.name);
29
22
  const responses = await forward(message, false);
30
23
  for (const response of responses) {
31
- if (message.method === "tools/list" && !message.params?.cursor && response.id === message.id && Array.isArray(response.result?.tools)) {
32
- response.result.tools = [...response.result.tools.filter(tool => !isLocalYidaTool(tool.name)), ...localYidaTools()];
33
- }
34
24
  output.write(`${JSON.stringify(response)}\n`);
35
25
  }
36
26
  } catch (error) {
@@ -0,0 +1,6 @@
1
+ /** Old local tool calls must not send their private arguments to the hosted MCP. */
2
+ export function requireCurrentTool(name) {
3
+ if (typeof name === "string" && name.startsWith("yida_")) {
4
+ throw new Error("Local YiDA tools were removed in Fargo CLI 1.5.1. Restart the MCP client to refresh its tool catalog.");
5
+ }
6
+ }
@@ -1,28 +0,0 @@
1
- # OpenYida
2
-
3
- The YiDA OAuth/token protocol, schema conventions and endpoint usage in
4
- `src/yida-auth.mjs` and `src/yida-schema.mjs` are adapted from OpenYida:
5
- https://github.com/openyida/openyida
6
- Revision: bdd45f54605cc7239ff8db116b2ef1b506179c70
7
-
8
- MIT License
9
-
10
- Copyright (c) 2026 Alibaba Group Holding Limited
11
-
12
- Permission is hereby granted, free of charge, to any person obtaining a copy
13
- of this software and associated documentation files (the "Software"), to deal
14
- in the Software without restriction, including without limitation the rights
15
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
- copies of the Software, and to permit persons to whom the Software is
17
- furnished to do so, subject to the following conditions:
18
-
19
- The above copyright notice and this permission notice shall be included in all
20
- copies or substantial portions of the Software.
21
-
22
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
- SOFTWARE.