@fastagent-sh/fastagent 0.14.0 → 0.15.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.
Files changed (209) hide show
  1. package/README.md +3 -3
  2. package/dist/agent.d.ts +20 -0
  3. package/dist/agent.js +9 -0
  4. package/dist/channels/context-buffer.d.ts +30 -0
  5. package/dist/channels/context-buffer.js +98 -0
  6. package/dist/channels/control.d.ts +28 -0
  7. package/dist/channels/control.js +214 -0
  8. package/dist/channels/feishu/card.js +1 -1
  9. package/dist/channels/feishu/context-buffer.d.ts +8 -11
  10. package/dist/channels/feishu/context-buffer.js +6 -67
  11. package/dist/channels/feishu/feishu-api.d.ts +11 -3
  12. package/dist/channels/feishu/feishu-api.js +20 -2
  13. package/dist/channels/feishu/feishu.d.ts +28 -16
  14. package/dist/channels/feishu/feishu.js +210 -188
  15. package/dist/channels/feishu/invoke-turn.d.ts +7 -20
  16. package/dist/channels/feishu/invoke-turn.js +10 -62
  17. package/dist/channels/feishu/model.d.ts +2 -1
  18. package/dist/channels/feishu/normalize.d.ts +2 -1
  19. package/dist/channels/feishu/owned-threads.d.ts +2 -6
  20. package/dist/channels/feishu/parse.d.ts +1 -1
  21. package/dist/channels/feishu/preview.d.ts +4 -7
  22. package/dist/channels/feishu/preview.js +24 -140
  23. package/dist/channels/feishu/register-app.d.ts +2 -1
  24. package/dist/channels/feishu/register-webhook.d.ts +2 -1
  25. package/dist/channels/feishu/setup-mode.d.ts +8 -0
  26. package/dist/channels/feishu/setup-mode.js +2 -0
  27. package/dist/channels/feishu/ws-ingress.d.ts +28 -0
  28. package/dist/channels/feishu/ws-ingress.js +136 -0
  29. package/dist/channels/github/github.js +8 -6
  30. package/dist/channels/http.d.ts +14 -0
  31. package/dist/channels/http.js +35 -2
  32. package/dist/channels/invoke-turn-kit.d.ts +65 -0
  33. package/dist/channels/invoke-turn-kit.js +87 -0
  34. package/dist/channels/lark/lark.d.ts +4 -2
  35. package/dist/channels/lark/lark.js +4 -1
  36. package/dist/channels/lark/onboard.d.ts +8 -4
  37. package/dist/channels/lark/onboard.js +8 -0
  38. package/dist/channels/preview-kit.d.ts +109 -0
  39. package/dist/channels/preview-kit.js +183 -0
  40. package/dist/channels/seen.d.ts +5 -0
  41. package/dist/channels/seen.js +35 -0
  42. package/dist/channels/slack/bot-auth.d.ts +15 -0
  43. package/dist/channels/slack/bot-auth.js +146 -0
  44. package/dist/channels/slack/config-api.d.ts +60 -0
  45. package/dist/channels/slack/config-api.js +149 -0
  46. package/dist/channels/slack/context-buffer.d.ts +24 -0
  47. package/dist/channels/slack/context-buffer.js +37 -0
  48. package/dist/channels/slack/invoke-turn.d.ts +19 -0
  49. package/dist/channels/slack/invoke-turn.js +63 -0
  50. package/dist/channels/slack/manifest.d.ts +49 -0
  51. package/dist/channels/slack/manifest.js +69 -0
  52. package/dist/channels/slack/model.d.ts +67 -0
  53. package/dist/channels/slack/model.js +2 -0
  54. package/dist/channels/slack/onboard.d.ts +41 -0
  55. package/dist/channels/slack/onboard.js +120 -0
  56. package/dist/channels/slack/onboarding-state.d.ts +31 -0
  57. package/dist/channels/slack/onboarding-state.js +69 -0
  58. package/dist/channels/slack/owned-threads.d.ts +6 -0
  59. package/dist/channels/slack/owned-threads.js +43 -0
  60. package/dist/channels/slack/parse.d.ts +23 -0
  61. package/dist/channels/slack/parse.js +81 -0
  62. package/dist/channels/slack/preview.d.ts +24 -0
  63. package/dist/channels/slack/preview.js +359 -0
  64. package/dist/channels/slack/reaction.d.ts +24 -0
  65. package/dist/channels/slack/reaction.js +62 -0
  66. package/dist/channels/slack/register-webhook.d.ts +10 -0
  67. package/dist/channels/slack/register-webhook.js +49 -0
  68. package/dist/channels/slack/scaffold/channel.ts +33 -0
  69. package/dist/channels/slack/scaffold/slack-send.ts +171 -0
  70. package/dist/channels/slack/setup-server.d.ts +17 -0
  71. package/dist/channels/slack/setup-server.js +103 -0
  72. package/dist/channels/slack/slack-api.d.ts +77 -0
  73. package/dist/channels/slack/slack-api.js +415 -0
  74. package/dist/channels/slack/slack.d.ts +58 -0
  75. package/dist/channels/slack/slack.js +451 -0
  76. package/dist/channels/slack/welcomed.d.ts +5 -0
  77. package/dist/channels/slack/welcomed.js +32 -0
  78. package/dist/channels/state.js +3 -3
  79. package/dist/channels/stop-command.d.ts +6 -0
  80. package/dist/channels/stop-command.js +36 -0
  81. package/dist/channels/tasks.d.ts +13 -0
  82. package/dist/channels/tasks.js +10 -0
  83. package/dist/channels/telegram/context-buffer.d.ts +8 -17
  84. package/dist/channels/telegram/context-buffer.js +6 -85
  85. package/dist/channels/telegram/invoke-turn.d.ts +5 -22
  86. package/dist/channels/telegram/invoke-turn.js +11 -58
  87. package/dist/channels/telegram/preview.d.ts +4 -7
  88. package/dist/channels/telegram/preview.js +24 -142
  89. package/dist/channels/telegram/telegram.js +23 -9
  90. package/dist/channels/{feishu/text.d.ts → text.d.ts} +1 -1
  91. package/dist/channels/{feishu/text.js → text.js} +1 -1
  92. package/dist/channels/turn-queue.js +1 -1
  93. package/dist/channels/turn-store.d.ts +1 -1
  94. package/dist/channels/turn-store.js +2 -3
  95. package/dist/cli/add-feishu.d.ts +27 -0
  96. package/dist/{cli-add-feishu.js → cli/add-feishu.js} +167 -44
  97. package/dist/cli/add-slack.d.ts +10 -0
  98. package/dist/cli/add-slack.js +204 -0
  99. package/dist/{cli-auth.d.ts → cli/auth-view.d.ts} +1 -1
  100. package/dist/{cli-auth.js → cli/auth-view.js} +1 -1
  101. package/dist/cli/commands/add.d.ts +4 -0
  102. package/dist/cli/commands/add.js +152 -20
  103. package/dist/cli/commands/attach.d.ts +82 -0
  104. package/dist/cli/commands/attach.js +559 -0
  105. package/dist/cli/commands/chat.d.ts +1 -0
  106. package/dist/cli/commands/chat.js +6 -1
  107. package/dist/cli/commands/deploy.d.ts +2 -0
  108. package/dist/cli/commands/deploy.js +78 -22
  109. package/dist/cli/commands/dev.js +11 -5
  110. package/dist/cli/commands/fire.js +3 -3
  111. package/dist/cli/commands/info.js +2 -2
  112. package/dist/cli/commands/invoke.js +2 -3
  113. package/dist/cli/commands/login.js +14 -25
  114. package/dist/cli/commands/models.js +1 -1
  115. package/dist/cli/commands/start.js +15 -8
  116. package/dist/cli/commands/tool.js +2 -1
  117. package/dist/cli/fail.d.ts +0 -2
  118. package/dist/cli/fail.js +1 -1
  119. package/dist/{invoke-stream.d.ts → cli/invoke-stream.d.ts} +1 -1
  120. package/dist/{invoke-stream.js → cli/invoke-stream.js} +4 -0
  121. package/dist/cli/kernel.d.ts +3 -2
  122. package/dist/cli/models-view.d.ts +21 -0
  123. package/dist/cli/models-view.js +66 -0
  124. package/dist/cli/program.js +79 -21
  125. package/dist/cli/serve.d.ts +38 -18
  126. package/dist/cli/serve.js +197 -39
  127. package/dist/cli/shared.d.ts +26 -6
  128. package/dist/cli/shared.js +163 -33
  129. package/dist/collect.d.ts +14 -3
  130. package/dist/collect.js +24 -0
  131. package/dist/core.d.ts +3 -1
  132. package/dist/core.js +2 -0
  133. package/dist/deploy/docker/plan.d.ts +2 -2
  134. package/dist/deploy/docker/plan.js +8 -6
  135. package/dist/deploy/fly/plan.d.ts +3 -1
  136. package/dist/deploy/fly/plan.js +12 -7
  137. package/dist/deploy/fly/run.d.ts +5 -4
  138. package/dist/deploy/fly/run.js +16 -5
  139. package/dist/deploy/preflight.d.ts +10 -4
  140. package/dist/deploy/preflight.js +53 -9
  141. package/dist/deploy/railway/plan.d.ts +3 -1
  142. package/dist/deploy/railway/plan.js +12 -4
  143. package/dist/deploy/railway/run.d.ts +5 -4
  144. package/dist/deploy/railway/run.js +15 -5
  145. package/dist/deploy/runner.d.ts +2 -1
  146. package/dist/deploy/secrets.d.ts +2 -1
  147. package/dist/deploy/secrets.js +23 -3
  148. package/dist/dev-supervisor.d.ts +0 -2
  149. package/dist/dev-supervisor.js +7 -3
  150. package/dist/engines/pi/channel.d.ts +22 -16
  151. package/dist/engines/pi/channel.js +90 -60
  152. package/dist/engines/pi/chat.d.ts +4 -16
  153. package/dist/engines/pi/chat.js +8 -261
  154. package/dist/engines/pi/config.d.ts +14 -9
  155. package/dist/engines/pi/config.js +33 -18
  156. package/dist/engines/pi/create.d.ts +22 -2
  157. package/dist/engines/pi/create.js +20 -14
  158. package/dist/engines/pi/harness.d.ts +49 -0
  159. package/dist/engines/pi/harness.js +90 -2
  160. package/dist/engines/pi/invoke.d.ts +55 -2
  161. package/dist/engines/pi/invoke.js +304 -19
  162. package/dist/engines/pi/login.d.ts +11 -0
  163. package/dist/engines/pi/login.js +16 -4
  164. package/dist/engines/pi/models.d.ts +56 -10
  165. package/dist/engines/pi/models.js +61 -23
  166. package/dist/engines/pi/session-builder.d.ts +16 -0
  167. package/dist/engines/pi/session-builder.js +308 -0
  168. package/dist/engines/pi/session-control.d.ts +50 -0
  169. package/dist/engines/pi/session-control.js +604 -0
  170. package/dist/engines/pi/sessions.d.ts +17 -2
  171. package/dist/engines/pi/sessions.js +9 -0
  172. package/dist/engines/pi/tool-context.d.ts +18 -11
  173. package/dist/engines/pi/tool-context.js +3 -9
  174. package/dist/engines/pi/tool.d.ts +6 -8
  175. package/dist/engines/pi/tool.js +6 -1
  176. package/dist/engines/pi/wake-tool.d.ts +0 -3
  177. package/dist/engines/pi/wake-tool.js +9 -7
  178. package/dist/engines/pi/workspace.d.ts +52 -0
  179. package/dist/engines/pi/workspace.js +72 -15
  180. package/dist/feishu.d.ts +1 -1
  181. package/dist/feishu.js +1 -1
  182. package/dist/host/node.d.ts +23 -6
  183. package/dist/host/node.js +5 -4
  184. package/dist/index.d.ts +1 -0
  185. package/dist/index.js +1 -0
  186. package/dist/lark.d.ts +1 -1
  187. package/dist/lark.js +1 -1
  188. package/dist/observe.js +3 -0
  189. package/dist/pi.d.ts +5 -4
  190. package/dist/pi.js +2 -1
  191. package/dist/scaffold/add-channel.d.ts +19 -6
  192. package/dist/scaffold/add-channel.js +126 -17
  193. package/dist/scaffold/templates/fastagent.config.mjs +4 -3
  194. package/dist/schedule/wakeups.d.ts +0 -3
  195. package/dist/schedule/wakeups.js +1 -1
  196. package/dist/session-remote.d.ts +53 -0
  197. package/dist/session-remote.js +336 -0
  198. package/dist/session.d.ts +265 -0
  199. package/dist/session.js +37 -0
  200. package/dist/slack.d.ts +2 -0
  201. package/dist/slack.js +2 -0
  202. package/dist/tunnel.d.ts +7 -4
  203. package/dist/tunnel.js +21 -10
  204. package/package.json +19 -7
  205. package/dist/channels/feishu/seen.d.ts +0 -5
  206. package/dist/channels/feishu/seen.js +0 -47
  207. package/dist/cli-add-feishu.d.ts +0 -8
  208. package/dist/cli-models.d.ts +0 -11
  209. package/dist/cli-models.js +0 -20
package/dist/tunnel.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * `--tunnel`: expose the local dev server on a public HTTPS URL via a Cloudflare quick tunnel, then
3
- * auto-register the first-party webhook channels against it (Telegram setWebhook; Feishu/Lark
4
- * application-config PATCH; GitHub prints the URL to paste into repo settings). This closes the
3
+ * auto-register the first-party webhook channels against it (Telegram setWebhook; onboarded Slack
4
+ * App Manifest update; Feishu/Lark application-config PATCH; GitHub/manual Slack print URLs). This closes the
5
5
  * "local dev → public URL" gap webhooks need.
6
6
  *
7
7
  * Process orchestration, not assembly — lives outside the engine, beside dev-supervisor.ts.
@@ -25,10 +25,13 @@ type SpawnCloudflared = (port: number) => ChildProcess;
25
25
  */
26
26
  export declare function startCloudflareTunnel(port: number, spawnFn?: SpawnCloudflared, attemptTimeoutMs?: number): Promise<Tunnel | undefined>;
27
27
  /**
28
- * Print the public URL and wire up the first-party webhook channels found under `dir`: Telegram and
29
- * Feishu/Lark auto-register using credentials from .env; GitHub prints the URL to add in repo settings.
28
+ * Print the public URL and wire up first-party webhook channels found under `dir`: Telegram and
29
+ * Feishu/Lark use runtime credentials; onboarded Slack uses its owner-local config token; GitHub and a
30
+ * manually scaffolded Slack app receive explicit console URLs.
30
31
  */
31
32
  export declare function announceWebhooks(dir: string, baseUrl: string, opts?: {
32
33
  openUrl?: (url: string) => void;
34
+ routeChannels?: string[];
35
+ stateRoot?: string;
33
36
  }): Promise<void>;
34
37
  export {};
package/dist/tunnel.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * `--tunnel`: expose the local dev server on a public HTTPS URL via a Cloudflare quick tunnel, then
3
- * auto-register the first-party webhook channels against it (Telegram setWebhook; Feishu/Lark
4
- * application-config PATCH; GitHub prints the URL to paste into repo settings). This closes the
3
+ * auto-register the first-party webhook channels against it (Telegram setWebhook; onboarded Slack
4
+ * App Manifest update; Feishu/Lark application-config PATCH; GitHub/manual Slack print URLs). This closes the
5
5
  * "local dev → public URL" gap webhooks need.
6
6
  *
7
7
  * Process orchestration, not assembly — lives outside the engine, beside dev-supervisor.ts.
@@ -10,8 +10,10 @@ import { spawn } from "node:child_process";
10
10
  import { readdirSync } from "node:fs";
11
11
  import { join } from "node:path";
12
12
  import { registerFeishuWebhook } from "./channels/feishu/register-webhook.js";
13
+ import { registerSlackWebhook } from "./channels/slack/register-webhook.js";
13
14
  import { registerTelegramWebhook } from "./channels/telegram/register-webhook.js";
14
15
  import { loadDotEnv } from "./env.js";
16
+ import { resolveStateRoot } from "./engines/pi/config.js";
15
17
  import { log } from "./log.js";
16
18
  // `(?!api\.)`: cloudflared's ERROR lines mention its request endpoint (`https://api.trycloudflare.com/tunnel`,
17
19
  // e.g. "failed to request quick Tunnel: Post ... timeout" under a flaky proxy) — without the exclusion a
@@ -116,8 +118,9 @@ function channelBasenames(dir) {
116
118
  }
117
119
  }
118
120
  /**
119
- * Print the public URL and wire up the first-party webhook channels found under `dir`: Telegram and
120
- * Feishu/Lark auto-register using credentials from .env; GitHub prints the URL to add in repo settings.
121
+ * Print the public URL and wire up first-party webhook channels found under `dir`: Telegram and
122
+ * Feishu/Lark use runtime credentials; onboarded Slack uses its owner-local config token; GitHub and a
123
+ * manually scaffolded Slack app receive explicit console URLs.
121
124
  */
122
125
  export async function announceWebhooks(dir, baseUrl, opts = {}) {
123
126
  log.info(`[fastagent] public URL: ${baseUrl}`);
@@ -132,25 +135,33 @@ export async function announceWebhooks(dir, baseUrl, opts = {}) {
132
135
  // missing-credential guidance. loadDotEnv keeps throwing for the synchronous command callers.
133
136
  log.warn(`[fastagent] could not read ${join(dir, ".env")}: ${error.message} — continuing without it`);
134
137
  }
135
- const channels = channelBasenames(dir);
136
- if (channels.length === 0)
138
+ // Serving passes the validated route-channel subset. The basename fallback preserves the public
139
+ // helper's standalone behavior for callers that did not assemble channels first.
140
+ const routeChannels = opts.routeChannels ?? channelBasenames(dir);
141
+ if (routeChannels.length === 0)
137
142
  return;
138
143
  // Readiness is the registrar's job now: a fresh quick tunnel returns Cloudflare 530 for ~20-30s before
139
144
  // its origin connects, and the automatic registrars poll /health before configuring the platform (the
140
145
  // same wait the deploy runners rely on). GitHub needs no wait — the operator adds that webhook by hand.
141
- if (channels.includes("telegram"))
146
+ if (routeChannels.includes("telegram"))
142
147
  await registerTelegramWebhook(baseUrl);
143
- if (channels.includes("github")) {
148
+ if (routeChannels.includes("github")) {
144
149
  log.info(`[fastagent] github: add a webhook in your repo (Settings → Webhooks): Payload URL = ${baseUrl}/webhook, content type application/json, secret = GITHUB_WEBHOOK_SECRET`);
145
150
  }
151
+ if (routeChannels.includes("slack")) {
152
+ await registerSlackWebhook(baseUrl, {
153
+ stateRoot: opts.stateRoot ?? resolveStateRoot(dir),
154
+ log: (message) => log.info(message),
155
+ });
156
+ }
146
157
  // feishu/lark register programmatically too (application-v7 config PATCH — telegram-setWebhook
147
158
  // parity), once per mounted kind (each kind is its own app with its own credentials); the registrar
148
159
  // owns its own health wait and degrades to the manual console instruction.
149
160
  const feishuOptions = {
150
161
  onManualRegistration: ({ consoleUrl }) => opts.openUrl?.(consoleUrl),
151
162
  };
152
- if (channels.includes("feishu"))
163
+ if (routeChannels.includes("feishu"))
153
164
  await registerFeishuWebhook(baseUrl, "feishu", feishuOptions);
154
- if (channels.includes("lark"))
165
+ if (routeChannels.includes("lark"))
155
166
  await registerFeishuWebhook(baseUrl, "lark", feishuOptions);
156
167
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fastagent-sh/fastagent",
3
- "version": "0.14.0",
4
- "description": "Vibe first. Then FastAgent: turn a local agent directory into a live service in your app, on GitHub, in Telegram, or behind any channel.",
3
+ "version": "0.15.0",
4
+ "description": "Vibe first. Then FastAgent: turn a local agent directory into a live service in your app, on GitHub, Telegram, Slack, or behind any channel.",
5
5
  "keywords": [
6
6
  "agent",
7
7
  "ai-agent",
@@ -10,6 +10,7 @@
10
10
  "agent-skills",
11
11
  "agent-serving",
12
12
  "telegram",
13
+ "slack",
13
14
  "github",
14
15
  "webhook",
15
16
  "sse",
@@ -42,6 +43,10 @@
42
43
  "types": "./dist/core.d.ts",
43
44
  "default": "./dist/core.js"
44
45
  },
46
+ "./session": {
47
+ "types": "./dist/session.d.ts",
48
+ "default": "./dist/session.js"
49
+ },
45
50
  "./pi": {
46
51
  "types": "./dist/pi.d.ts",
47
52
  "default": "./dist/pi.js"
@@ -54,6 +59,10 @@
54
59
  "types": "./dist/telegram.d.ts",
55
60
  "default": "./dist/telegram.js"
56
61
  },
62
+ "./slack": {
63
+ "types": "./dist/slack.d.ts",
64
+ "default": "./dist/slack.js"
65
+ },
57
66
  "./feishu": {
58
67
  "types": "./dist/feishu.d.ts",
59
68
  "default": "./dist/feishu.js"
@@ -82,15 +91,17 @@
82
91
  "prepack": "npm run build",
83
92
  "test": "vitest --run",
84
93
  "typecheck": "tsc --noEmit",
85
- "lint": "biome check src test && node scripts/check-doc-links.mjs",
94
+ "lint": "biome check src test && node scripts/check-doc-links.mjs && knip",
86
95
  "format": "biome check --write src test",
87
- "postbuild": "node scripts/copy-scaffold-assets.mjs"
96
+ "postbuild": "node scripts/copy-scaffold-assets.mjs",
97
+ "knip": "knip"
88
98
  },
89
99
  "dependencies": {
90
100
  "@clack/prompts": "^1.6.0",
91
- "@earendil-works/pi-agent-core": "^0.80.10",
92
- "@earendil-works/pi-ai": "^0.80.10",
93
- "@earendil-works/pi-coding-agent": "^0.80.10",
101
+ "@earendil-works/pi-agent-core": "^0.81.1",
102
+ "@earendil-works/pi-ai": "^0.81.1",
103
+ "@earendil-works/pi-coding-agent": "^0.81.1",
104
+ "@larksuiteoapi/node-sdk": "^1.71.1",
94
105
  "@octokit/webhooks-methods": "^6.0.0",
95
106
  "@octokit/webhooks-types": "^7.6.1",
96
107
  "chokidar": "^5.0.0",
@@ -105,6 +116,7 @@
105
116
  "devDependencies": {
106
117
  "@biomejs/biome": "^2.5.2",
107
118
  "@types/proper-lockfile": "^4.1.4",
119
+ "knip": "^6.29.0",
108
120
  "typescript": "^7.0.2",
109
121
  "vitest": "^4.1.9"
110
122
  }
@@ -1,5 +0,0 @@
1
- export interface SeenRing {
2
- has(id: string): boolean;
3
- add(id: string): void;
4
- }
5
- export declare function createSeenRing(path: string, label?: string, cap?: number): SeenRing;
@@ -1,47 +0,0 @@
1
- /**
2
- * Bounded delivery dedup for message_ids whose webhook handling produced a durable side effect: either
3
- * an accepted turn intent or a buffered group-context entry. Feishu/Lark document duplicate pushes even
4
- * after a successful 200 and recommend idempotency on message_id (not event_id). The unfinished-turn
5
- * store cannot cover a duplicate after completion, and a duplicated background event would otherwise be
6
- * folded twice.
7
- *
8
- * Record only AFTER the pre-ACK side effect is durable: recording first could turn a later state-write
9
- * failure into silent loss when the platform redelivers. The ring write is best-effort post-persist
10
- * insurance. A crash between the two writes, a ring-write failure, or an id older than the bounded cap
11
- * retains L1's at-least-once tail; this is dedup, not exactly-once execution.
12
- */
13
- import { log } from "../../log.js";
14
- import { loadStateFile, saveStateFile } from "../state.js";
15
- export function createSeenRing(path, label = "[feishu]", cap = 2000) {
16
- const load = () => {
17
- const raw = loadStateFile(path);
18
- if (raw === undefined)
19
- return [];
20
- if (Array.isArray(raw) && raw.every((id) => typeof id === "string"))
21
- return raw.slice(-cap);
22
- log.warn(`${label} unexpected shape in ${path} — starting with no seen ids`);
23
- return [];
24
- };
25
- const order = load();
26
- const ids = new Set(order);
27
- return {
28
- has: (id) => ids.has(id),
29
- add(id) {
30
- if (ids.has(id))
31
- return;
32
- ids.add(id);
33
- order.push(id);
34
- while (order.length > cap) {
35
- const evicted = order.shift();
36
- if (evicted !== undefined)
37
- ids.delete(evicted);
38
- }
39
- try {
40
- saveStateFile(path, order);
41
- }
42
- catch (error) {
43
- log.warn(`${label} seen-ring write failed (delivery dedup is in-memory until restart): ${String(error)}`);
44
- }
45
- },
46
- };
47
- }
@@ -1,8 +0,0 @@
1
- /**
2
- * Create or resume the platform app behind `add feishu` / `add lark`. Returns credentials for the
3
- * caller's generic .env write (the guided Lark path), or undefined when nothing remains to write —
4
- * the feishu path persists its own two credential stages internally (the App ID/Secret boundary is
5
- * irreversible and must not wait for the caller). Throws on refusal (a committable .env, a
6
- * non-interactive lark run); the caller surfaces that as a startup failure.
7
- */
8
- export declare function onboardFeishuCloudApp(target: string, kind: "feishu" | "lark", envIgnored: boolean): Promise<Record<string, string> | undefined>;
@@ -1,11 +0,0 @@
1
- /**
2
- * CLI presenter for `fastagent models [search]`: the stdout/stderr output DECISION, kept out of the
3
- * engine config layer (config.ts owns model resolution / listModels) so this process-boundary behavior
4
- * is unit-testable without spawning the CLI.
5
- */
6
- /** The output of `fastagent models [search]`: the spec `lines` to print to stdout (a case-insensitive
7
- * substring filter; no search → all), and an stderr `error` diagnostic when a search matches nothing. */
8
- export declare function formatModelsCommand(specs: string[], search?: string): {
9
- lines: string[];
10
- error?: string;
11
- };
@@ -1,20 +0,0 @@
1
- /**
2
- * CLI presenter for `fastagent models [search]`: the stdout/stderr output DECISION, kept out of the
3
- * engine config layer (config.ts owns model resolution / listModels) so this process-boundary behavior
4
- * is unit-testable without spawning the CLI.
5
- */
6
- /** The output of `fastagent models [search]`: the spec `lines` to print to stdout (a case-insensitive
7
- * substring filter; no search → all), and an stderr `error` diagnostic when a search matches nothing. */
8
- export function formatModelsCommand(specs, search) {
9
- if (!search)
10
- return { lines: specs };
11
- const q = search.toLowerCase();
12
- const matches = specs.filter((spec) => spec.toLowerCase().includes(q));
13
- if (matches.length === 0)
14
- return { lines: matches, error: `no model matches "${search}"` };
15
- // Rank a PROVIDER-name match (query in the part before "/") above an incidental model-id match, so
16
- // `models anthropic` leads with anthropic/* rather than burying it under amazon-bedrock/anthropic.*
17
- // and google-vertex/…-anthropic-… (which only match in the model id). Order within each group is kept.
18
- const providerMatch = (spec) => spec.slice(0, spec.indexOf("/")).toLowerCase().includes(q);
19
- return { lines: [...matches.filter(providerMatch), ...matches.filter((s) => !providerMatch(s))] };
20
- }