@fastagent-sh/fastagent 0.12.0 → 0.13.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 (82) hide show
  1. package/README.md +42 -36
  2. package/dist/channels/feishu/bootstrap-token.d.ts +42 -0
  3. package/dist/channels/feishu/bootstrap-token.js +94 -0
  4. package/dist/channels/feishu/card.d.ts +32 -0
  5. package/dist/channels/feishu/card.js +66 -0
  6. package/dist/channels/feishu/cloud.d.ts +17 -0
  7. package/dist/channels/feishu/cloud.js +19 -0
  8. package/dist/channels/feishu/crypto.d.ts +13 -0
  9. package/dist/channels/feishu/crypto.js +41 -0
  10. package/dist/channels/feishu/feishu-api.d.ts +108 -0
  11. package/dist/channels/feishu/feishu-api.js +325 -0
  12. package/dist/channels/feishu/feishu.d.ts +36 -0
  13. package/dist/channels/feishu/feishu.js +359 -0
  14. package/dist/channels/feishu/invoke-turn.d.ts +59 -0
  15. package/dist/channels/feishu/invoke-turn.js +106 -0
  16. package/dist/channels/feishu/parse.d.ts +125 -0
  17. package/dist/channels/feishu/parse.js +175 -0
  18. package/dist/channels/feishu/preview.d.ts +36 -0
  19. package/dist/channels/feishu/preview.js +387 -0
  20. package/dist/channels/feishu/register-app.d.ts +70 -0
  21. package/dist/channels/feishu/register-app.js +141 -0
  22. package/dist/channels/feishu/register-webhook.d.ts +22 -0
  23. package/dist/channels/feishu/register-webhook.js +106 -0
  24. package/dist/channels/feishu/scaffold/channel.ts +34 -0
  25. package/dist/channels/feishu/scaffold/feishu-send.ts +87 -0
  26. package/dist/channels/feishu/seen.d.ts +5 -0
  27. package/dist/channels/feishu/seen.js +47 -0
  28. package/dist/channels/feishu/text.d.ts +13 -0
  29. package/dist/channels/feishu/text.js +63 -0
  30. package/dist/channels/lark/lark.d.ts +15 -0
  31. package/dist/channels/lark/lark.js +10 -0
  32. package/dist/channels/lark/onboard.d.ts +39 -0
  33. package/dist/channels/lark/onboard.js +58 -0
  34. package/dist/channels/lark/scaffold/channel.ts +32 -0
  35. package/dist/channels/lark/scaffold/lark-send.ts +87 -0
  36. package/dist/channels/registration.d.ts +15 -0
  37. package/dist/channels/registration.js +1 -0
  38. package/dist/channels/{telegram/state.js → state.js} +6 -4
  39. package/dist/channels/telegram/context-buffer.js +1 -1
  40. package/dist/channels/telegram/register-webhook.d.ts +4 -1
  41. package/dist/channels/telegram/register-webhook.js +17 -26
  42. package/dist/channels/telegram/telegram.js +2 -2
  43. package/dist/channels/telegram/turn-store.d.ts +8 -21
  44. package/dist/channels/telegram/turn-store.js +11 -130
  45. package/dist/channels/{telegram/turn-queue.js → turn-queue.js} +3 -3
  46. package/dist/channels/turn-store.d.ts +42 -0
  47. package/dist/channels/turn-store.js +139 -0
  48. package/dist/channels/wait-health.d.ts +6 -0
  49. package/dist/channels/wait-health.js +27 -0
  50. package/dist/cli-add-feishu.d.ts +8 -0
  51. package/dist/cli-add-feishu.js +223 -0
  52. package/dist/cli.js +68 -23
  53. package/dist/deploy/container.js +10 -6
  54. package/dist/deploy/fly/plan.d.ts +1 -1
  55. package/dist/deploy/fly/plan.js +15 -4
  56. package/dist/deploy/fly/run.d.ts +7 -4
  57. package/dist/deploy/fly/run.js +26 -5
  58. package/dist/deploy/railway/plan.d.ts +1 -1
  59. package/dist/deploy/railway/plan.js +17 -5
  60. package/dist/deploy/railway/run.d.ts +6 -3
  61. package/dist/deploy/railway/run.js +26 -4
  62. package/dist/deploy/registration-gate.d.ts +20 -0
  63. package/dist/deploy/registration-gate.js +20 -0
  64. package/dist/deploy/secrets.d.ts +10 -9
  65. package/dist/deploy/secrets.js +15 -14
  66. package/dist/dev-supervisor.js +2 -1
  67. package/dist/engines/pi/chat.js +3 -3
  68. package/dist/engines/pi/create.d.ts +0 -1
  69. package/dist/engines/pi/create.js +8 -7
  70. package/dist/feishu.d.ts +2 -0
  71. package/dist/feishu.js +2 -0
  72. package/dist/lark.d.ts +3 -0
  73. package/dist/lark.js +3 -0
  74. package/dist/open-url.d.ts +2 -0
  75. package/dist/open-url.js +6 -0
  76. package/dist/scaffold/add-channel.d.ts +9 -5
  77. package/dist/scaffold/add-channel.js +73 -7
  78. package/dist/tunnel.d.ts +9 -6
  79. package/dist/tunnel.js +48 -31
  80. package/package.json +19 -8
  81. /package/dist/channels/{telegram/state.d.ts → state.d.ts} +0 -0
  82. /package/dist/channels/{telegram/turn-queue.d.ts → turn-queue.d.ts} +0 -0
@@ -17,6 +17,7 @@ const CHANNEL_SCAFFOLDS = {
17
17
  {
18
18
  name: "GITHUB_WEBHOOK_SECRET",
19
19
  hint: "any random string; set the same value in the GitHub webhook",
20
+ required: true,
20
21
  generate: true,
21
22
  },
22
23
  ],
@@ -29,14 +30,75 @@ const CHANNEL_SCAFFOLDS = {
29
30
  },
30
31
  telegram: {
31
32
  env: [
32
- { name: "TELEGRAM_BOT_TOKEN", hint: "from @BotFather → /newbot" },
33
- { name: "TELEGRAM_SECRET_TOKEN", hint: "any random string; verifies inbound updates", generate: true },
33
+ { name: "TELEGRAM_BOT_TOKEN", hint: "from @BotFather → /newbot", required: true },
34
+ {
35
+ name: "TELEGRAM_SECRET_TOKEN",
36
+ hint: "any random string; verifies inbound updates",
37
+ required: true,
38
+ generate: true,
39
+ },
34
40
  ],
35
41
  steps: [
36
42
  "edit {channel} — customise routing with route() (optional; the defaults already work)",
37
43
  "the agent can send messages or files back by calling the scaffolded {tools}/telegram-send.ts tool",
38
44
  ],
39
45
  },
46
+ // Feishu is the canonical engine/cloud; Lark international reuses its protocol through a degraded
47
+ // compatibility profile. Each remains its own channel KIND: route, env, state, console, onboarding.
48
+ // No `generate` in either: every value comes FROM the platform (a locally generated Encrypt Key
49
+ // would break inbound events until mirrored in the console). `add feishu` scan-creates the app;
50
+ // Lark lacks that control-plane capability, so `add lark` guides console credential collection.
51
+ feishu: {
52
+ env: [
53
+ {
54
+ name: "FEISHU_APP_ID",
55
+ hint: "created + written automatically by `add feishu` (console → Credentials & Basic Info)",
56
+ required: true,
57
+ },
58
+ {
59
+ name: "FEISHU_APP_SECRET",
60
+ hint: "created + written automatically by `add feishu` (console → Credentials & Basic Info)",
61
+ required: true,
62
+ },
63
+ {
64
+ name: "FEISHU_VERIFICATION_TOKEN",
65
+ hint: "captured automatically (console → Events & Callbacks)",
66
+ required: true,
67
+ },
68
+ {
69
+ name: "FEISHU_ENCRYPT_KEY",
70
+ hint: "optional but recommended — set one in the console and copy it here",
71
+ required: false,
72
+ },
73
+ ],
74
+ steps: [
75
+ "PUBLISH the app version on the page the CLI opened — the switch to webhook mode takes effect on publish (one click, once ever; no API for it)",
76
+ "edit {channel} — routing policy (the header walks through the console setup, for hand-made apps)",
77
+ "the event Request URL is auto-registered by `dev --tunnel` / `deploy --run`",
78
+ "the agent can push messages from scheduled turns via the scaffolded {tools}/feishu-send.ts tool",
79
+ ],
80
+ },
81
+ lark: {
82
+ env: [
83
+ { name: "LARK_APP_ID", hint: "developer console → Credentials & Basic Info", required: true },
84
+ { name: "LARK_APP_SECRET", hint: "developer console → Credentials & Basic Info", required: true },
85
+ {
86
+ name: "LARK_VERIFICATION_TOKEN",
87
+ hint: "console → Events & Callbacks; authenticates inbound events",
88
+ required: true,
89
+ },
90
+ {
91
+ name: "LARK_ENCRYPT_KEY",
92
+ hint: "optional but recommended — set one in the console and copy it here",
93
+ required: false,
94
+ },
95
+ ],
96
+ steps: [
97
+ "finish the console setup: enable Bot and add the permissions + im.message.receive_v1 event listed in {channel} (do not publish yet)",
98
+ "run `fastagent dev --tunnel` and keep it running; if auto-registration reports a config-API 404, manually switch Subscription mode to webhook, set its printed https://…/lark Request URL, save, then create + publish a version",
99
+ "the agent can push messages from scheduled turns via the scaffolded {tools}/lark-send.ts tool",
100
+ ],
101
+ },
40
102
  };
41
103
  /** The channel kinds `fastagent add <kind>` can scaffold. */
42
104
  export const CHANNEL_KINDS = Object.keys(CHANNEL_SCAFFOLDS);
@@ -83,11 +145,13 @@ function mentionsEnvName(content, name) {
83
145
  }
84
146
  /**
85
147
  * Append generated channel secrets to the run-root `.env` (never `.env.example`) after the CLI has
86
- * verified that `.env` is gitignored. Existing non-empty values are kept. Manual values (e.g.
87
- * TELEGRAM_BOT_TOKEN from BotFather) are added only as commented placeholders, so the file is ready to
88
- * edit while no fake secret is committed to the user's mental model.
148
+ * verified that `.env` is gitignored. Existing non-empty values are kept EXCEPT the names listed in
149
+ * `overwrite`: those are authoritative (e.g. the credentials of an app `add feishu` JUST minted —
150
+ * skipping them for a stale value would silently discard a fresh, unrecoverable secret). Manual values
151
+ * (e.g. TELEGRAM_BOT_TOKEN from BotFather) are added only as commented placeholders, so the file is
152
+ * ready to edit while no fake secret is committed to the user's mental model.
89
153
  */
90
- export async function appendChannelDotEnv(dir, kind, generated) {
154
+ export async function appendChannelDotEnv(dir, kind, generated, overwrite = []) {
91
155
  const file = join(dir, ".env");
92
156
  let current = "";
93
157
  try {
@@ -97,7 +161,9 @@ export async function appendChannelDotEnv(dir, kind, generated) {
97
161
  if (e.code !== "ENOENT")
98
162
  throw e;
99
163
  }
100
- const alreadySet = CHANNEL_SCAFFOLDS[kind].env.filter((e) => hasActiveEnvValue(current, e.name)).map((e) => e.name);
164
+ const alreadySet = CHANNEL_SCAFFOLDS[kind].env
165
+ .filter((e) => !overwrite.includes(e.name) && hasActiveEnvValue(current, e.name))
166
+ .map((e) => e.name);
101
167
  const lines = [];
102
168
  const written = [];
103
169
  const contentLines = current.split("\n");
package/dist/tunnel.d.ts CHANGED
@@ -1,7 +1,8 @@
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; github prints the
4
- * URL to paste into repo settings). This closes the "local dev → public URL" gap webhooks need.
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
5
+ * "local dev → public URL" gap webhooks need.
5
6
  *
6
7
  * Process orchestration, not assembly — lives outside the engine, beside dev-supervisor.ts.
7
8
  */
@@ -22,10 +23,12 @@ type SpawnCloudflared = (port: number) => ChildProcess;
22
23
  * (Edge warmup AFTER the URL appears is handled downstream: the telegram registrar polls /health before
23
24
  * it calls setWebhook, so a not-yet-routable tunnel just delays registration rather than failing it.)
24
25
  */
25
- export declare function startCloudflareTunnel(port: number, spawnFn?: SpawnCloudflared): Promise<Tunnel | undefined>;
26
+ export declare function startCloudflareTunnel(port: number, spawnFn?: SpawnCloudflared, attemptTimeoutMs?: number): Promise<Tunnel | undefined>;
26
27
  /**
27
- * Print the public URL and wire up the first-party webhook channels found under `dir`: telegram is
28
- * auto-registered via setWebhook (using .env tokens); github prints the URL to add in repo settings.
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.
29
30
  */
30
- export declare function announceWebhooks(dir: string, baseUrl: string): Promise<void>;
31
+ export declare function announceWebhooks(dir: string, baseUrl: string, opts?: {
32
+ openUrl?: (url: string) => void;
33
+ }): Promise<void>;
31
34
  export {};
package/dist/tunnel.js CHANGED
@@ -1,14 +1,15 @@
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; github prints the
4
- * URL to paste into repo settings). This closes the "local dev → public URL" gap webhooks need.
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
5
+ * "local dev → public URL" gap webhooks need.
5
6
  *
6
7
  * Process orchestration, not assembly — lives outside the engine, beside dev-supervisor.ts.
7
8
  */
8
9
  import { spawn } from "node:child_process";
9
10
  import { readdirSync } from "node:fs";
10
11
  import { join } from "node:path";
11
- import { setTimeout as sleep } from "node:timers/promises";
12
+ import { registerFeishuWebhook } from "./channels/feishu/register-webhook.js";
12
13
  import { registerTelegramWebhook } from "./channels/telegram/register-webhook.js";
13
14
  import { loadDotEnv } from "./env.js";
14
15
  import { log } from "./log.js";
@@ -21,8 +22,12 @@ const TUNNEL_URL_RE = /https:\/\/(?!api\.)[a-z0-9-]+\.trycloudflare\.com/i;
21
22
  export function parseTunnelUrl(chunk) {
22
23
  return chunk.match(TUNNEL_URL_RE)?.[0];
23
24
  }
25
+ /** Global timer (rather than timers/promises) so timeout/retry behavior is deterministic under fake timers. */
26
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
24
27
  const TUNNEL_ATTEMPTS = 3;
25
28
  const TUNNEL_RETRY_MS = 2000;
29
+ /** cloudflared can stay alive without ever receiving/printing an assigned quick-tunnel URL. */
30
+ const TUNNEL_START_TIMEOUT_MS = 30_000;
26
31
  const spawnCloudflared = (port) => spawn("cloudflared", ["tunnel", "--url", `http://localhost:${port}`], { stdio: ["ignore", "pipe", "pipe"] });
27
32
  /**
28
33
  * Start a Cloudflare quick tunnel to localhost:`port`, resolving once its public URL appears.
@@ -32,9 +37,9 @@ const spawnCloudflared = (port) => spawn("cloudflared", ["tunnel", "--url", `htt
32
37
  * (Edge warmup AFTER the URL appears is handled downstream: the telegram registrar polls /health before
33
38
  * it calls setWebhook, so a not-yet-routable tunnel just delays registration rather than failing it.)
34
39
  */
35
- export async function startCloudflareTunnel(port, spawnFn = spawnCloudflared) {
40
+ export async function startCloudflareTunnel(port, spawnFn = spawnCloudflared, attemptTimeoutMs = TUNNEL_START_TIMEOUT_MS) {
36
41
  for (let attempt = 1; attempt <= TUNNEL_ATTEMPTS; attempt++) {
37
- const r = await spawnTunnelOnce(port, spawnFn);
42
+ const r = await spawnTunnelOnce(port, spawnFn, attemptTimeoutMs);
38
43
  if (r.tunnel)
39
44
  return r.tunnel;
40
45
  if (r.fatal) {
@@ -50,43 +55,45 @@ export async function startCloudflareTunnel(port, spawnFn = spawnCloudflared) {
50
55
  return undefined;
51
56
  }
52
57
  /** One cloudflared launch: a Tunnel on the first URL, or a failure (missing binary / exit before a URL). */
53
- function spawnTunnelOnce(port, spawnFn) {
58
+ function spawnTunnelOnce(port, spawnFn, timeoutMs) {
54
59
  return new Promise((resolve) => {
55
60
  const child = spawnFn(port);
56
61
  let settled = false;
62
+ let timer;
57
63
  let tail = ""; // recent output, surfaced as the failure reason
58
- const onChunk = (buf) => {
59
- tail = (tail + String(buf)).slice(-600);
64
+ const finish = (result) => {
60
65
  if (settled)
61
66
  return;
67
+ settled = true;
68
+ if (timer)
69
+ clearTimeout(timer);
70
+ resolve(result);
71
+ };
72
+ const onChunk = (buf) => {
73
+ tail = (tail + String(buf)).slice(-600);
62
74
  const url = parseTunnelUrl(String(buf));
63
- if (url) {
64
- settled = true;
65
- resolve({ tunnel: { url, close: () => child.kill("SIGTERM") } });
66
- }
75
+ if (url)
76
+ finish({ tunnel: { url, close: () => child.kill("SIGTERM") } });
67
77
  };
68
78
  child.stdout?.on("data", onChunk);
69
79
  child.stderr?.on("data", onChunk); // cloudflared prints the URL (and its errors) on stderr
70
80
  child.on("error", (e) => {
71
- if (settled)
72
- return;
73
- settled = true;
74
81
  if (e.code === "ENOENT") {
75
- resolve({
82
+ finish({
76
83
  fatal: true,
77
84
  message: "[fastagent] --tunnel needs cloudflared — install it (e.g. `brew install cloudflared`), then re-run. Serving without a tunnel.",
78
85
  });
79
86
  }
80
87
  else {
81
- resolve({ fatal: false, detail: e.message });
88
+ finish({ fatal: false, detail: e.message });
82
89
  }
83
90
  });
84
- child.on("exit", () => {
85
- if (settled)
86
- return;
87
- settled = true;
88
- resolve({ fatal: false, detail: lastErrorLine(tail) });
89
- });
91
+ child.on("exit", () => finish({ fatal: false, detail: lastErrorLine(tail) }));
92
+ timer = setTimeout(() => {
93
+ child.kill("SIGTERM");
94
+ finish({ fatal: false, detail: `timed out after ${Math.round(timeoutMs / 1000)}s waiting for a public URL` });
95
+ }, timeoutMs);
96
+ timer.unref();
90
97
  });
91
98
  }
92
99
  /** The most informative line of cloudflared's output tail (prefer an error line) for a failure log. */
@@ -109,31 +116,41 @@ function channelBasenames(dir) {
109
116
  }
110
117
  }
111
118
  /**
112
- * Print the public URL and wire up the first-party webhook channels found under `dir`: telegram is
113
- * auto-registered via setWebhook (using .env tokens); github prints the URL to add in repo settings.
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.
114
121
  */
115
- export async function announceWebhooks(dir, baseUrl) {
122
+ export async function announceWebhooks(dir, baseUrl, opts = {}) {
116
123
  log.info(`[fastagent] public URL: ${baseUrl}`);
117
124
  try {
118
- loadDotEnv(dir); // telegram registration reads tokens from .env
125
+ loadDotEnv(dir); // webhook registrars read channel credentials from .env
119
126
  }
120
127
  catch (error) {
121
128
  // best-effort boundary: a MISSING .env is already tolerated by loadDotEnv; an unreadable one (EACCES,
122
129
  // or .env is a directory) must NOT crash the long-running dev/start server — announceWebhooks is
123
130
  // void-called with no unhandledRejection handler, so a throw here would terminate the process. Warn
124
- // (surface it, rule 8) and continue best-effort; telegram registration then degrades to its manual
125
- // instruction if the token is absent. loadDotEnv keeps throwing for the synchronous command callers.
131
+ // (surface it, rule 8) and continue best-effort; each registrar then surfaces its own
132
+ // missing-credential guidance. loadDotEnv keeps throwing for the synchronous command callers.
126
133
  log.warn(`[fastagent] could not read ${join(dir, ".env")}: ${error.message} — continuing without it`);
127
134
  }
128
135
  const channels = channelBasenames(dir);
129
136
  if (channels.length === 0)
130
137
  return;
131
138
  // Readiness is the registrar's job now: a fresh quick tunnel returns Cloudflare 530 for ~20-30s before
132
- // its origin connects, and registerTelegramWebhook polls /health until it serves before setWebhook (the
133
- // same wait the deploy runners rely on). github needs no wait — the operator adds that webhook by hand.
139
+ // its origin connects, and the automatic registrars poll /health before configuring the platform (the
140
+ // same wait the deploy runners rely on). GitHub needs no wait — the operator adds that webhook by hand.
134
141
  if (channels.includes("telegram"))
135
142
  await registerTelegramWebhook(baseUrl);
136
143
  if (channels.includes("github")) {
137
144
  log.info(`[fastagent] github: add a webhook in your repo (Settings → Webhooks): Payload URL = ${baseUrl}/webhook, content type application/json, secret = GITHUB_WEBHOOK_SECRET`);
138
145
  }
146
+ // feishu/lark register programmatically too (application-v7 config PATCH — telegram-setWebhook
147
+ // parity), once per mounted kind (each kind is its own app with its own credentials); the registrar
148
+ // owns its own health wait and degrades to the manual console instruction.
149
+ const feishuOptions = {
150
+ onManualRegistration: ({ consoleUrl }) => opts.openUrl?.(consoleUrl),
151
+ };
152
+ if (channels.includes("feishu"))
153
+ await registerFeishuWebhook(baseUrl, "feishu", feishuOptions);
154
+ if (channels.includes("lark"))
155
+ await registerFeishuWebhook(baseUrl, "lark", feishuOptions);
139
156
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fastagent-sh/fastagent",
3
- "version": "0.12.0",
4
- "description": "Vibe first. Then FastAgent: turn a local agent directory into a running service in your app, on GitHub, in Telegram, or behind any channel.",
3
+ "version": "0.13.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.",
5
5
  "keywords": [
6
6
  "agent",
7
7
  "ai-agent",
@@ -9,13 +9,16 @@
9
9
  "agents.md",
10
10
  "agent-skills",
11
11
  "agent-serving",
12
+ "telegram",
13
+ "github",
14
+ "webhook",
12
15
  "sse",
13
16
  "pi",
14
17
  "fastagent"
15
18
  ],
16
19
  "license": "MIT",
17
20
  "author": "the fastagent authors (https://github.com/fastagent-sh/fastagent)",
18
- "homepage": "https://github.com/fastagent-sh/fastagent#readme",
21
+ "homepage": "https://fastagent.sh",
19
22
  "repository": {
20
23
  "type": "git",
21
24
  "url": "git+https://github.com/fastagent-sh/fastagent.git"
@@ -51,6 +54,14 @@
51
54
  "types": "./dist/telegram.d.ts",
52
55
  "default": "./dist/telegram.js"
53
56
  },
57
+ "./feishu": {
58
+ "types": "./dist/feishu.d.ts",
59
+ "default": "./dist/feishu.js"
60
+ },
61
+ "./lark": {
62
+ "types": "./dist/lark.d.ts",
63
+ "default": "./dist/lark.js"
64
+ },
54
65
  "./package.json": "./package.json"
55
66
  },
56
67
  "bin": {
@@ -77,13 +88,13 @@
77
88
  },
78
89
  "dependencies": {
79
90
  "@clack/prompts": "^1.6.0",
80
- "@earendil-works/pi-agent-core": "^0.80.3",
81
- "@earendil-works/pi-ai": "^0.80.3",
82
- "@earendil-works/pi-coding-agent": "^0.80.3",
91
+ "@earendil-works/pi-agent-core": "^0.80.7",
92
+ "@earendil-works/pi-ai": "^0.80.7",
93
+ "@earendil-works/pi-coding-agent": "^0.80.7",
83
94
  "@octokit/webhooks-methods": "^6.0.0",
84
95
  "@octokit/webhooks-types": "^7.6.1",
85
96
  "chokidar": "^5.0.0",
86
- "croner": "^9.1.0",
97
+ "croner": "^10.0.1",
87
98
  "giget": "^3.3.0",
88
99
  "ignore": "^7.0.5",
89
100
  "undici": "^8.6.0",
@@ -91,7 +102,7 @@
91
102
  },
92
103
  "devDependencies": {
93
104
  "@biomejs/biome": "^2.5.2",
94
- "typescript": "^6.0.3",
105
+ "typescript": "^7.0.2",
95
106
  "vitest": "^4.1.9"
96
107
  }
97
108
  }