blink 1.1.16 → 1.1.17

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.
@@ -1,50 +1,4 @@
1
- const e={scratch:{"agent.ts":`import { convertToModelMessages, streamText, tool } from "ai";
2
- import * as blink from "blink";
3
- import { z } from "zod";
4
-
5
- const agent = blink.agent();
6
-
7
- agent.on("chat", async ({ messages }) => {
8
- return streamText({
9
- model: blink.model("anthropic/claude-sonnet-4.5"),
10
- system: \`You are a basic agent the user will customize.
11
-
12
- Suggest the user enters edit mode with Ctrl+T or /edit to customize the agent.
13
- Demonstrate your capabilities with the IP tool.\`,
14
- messages: convertToModelMessages(messages),
15
- tools: {
16
- get_ip_info: tool({
17
- description: "Get IP address information of the computer.",
18
- inputSchema: z.object({}),
19
- execute: async () => {
20
- const response = await fetch("https://ipinfo.io/json");
21
- return response.json();
22
- },
23
- }),
24
- },
25
- });
26
- });
27
-
28
- agent.serve();
29
- `,"package.json":`{
30
- "name": "{{name}}",
31
- "main": "agent.ts",
32
- "type": "module",
33
- "private": true,
34
- "scripts": {
35
- "dev": "blink dev",
36
- "deploy": "blink deploy"
37
- },
38
- "devDependencies": {
39
- "zod": "latest",
40
- "ai": "latest",
41
- "blink": "latest",
42
- "esbuild": "latest",
43
- "@types/node": "latest",
44
- "typescript": "latest"
45
- }
46
- }
47
- `,".gitignore":`# dependencies
1
+ const e={scratch:{".gitignore":`# dependencies
48
2
  node_modules
49
3
 
50
4
  # config and build
@@ -524,106 +478,53 @@ The agent process can restart at any time, so all important state must be extern
524
478
  # Store local environment variables here.
525
479
  # They will be used by blink dev for development.
526
480
  # EXTERNAL_SERVICE_API_KEY=
527
- `,".env.production":`
528
- # Store production environment variables here.
481
+ `,".env.production":`# Store production environment variables here.
529
482
  # They will be upserted as secrets on blink deploy.
530
483
  # EXTERNAL_SERVICE_API_KEY=
531
- `},"slack-bot":{"agent.ts":`import { convertToModelMessages, streamText } from "ai";
484
+ `,"agent.ts.hbs":`import { convertToModelMessages, streamText, tool } from "ai";
532
485
  import * as blink from "blink";
533
- import * as slack from "@blink-sdk/slack";
534
- import { App } from "@slack/bolt";
535
-
536
- const receiver = new slack.Receiver();
537
- const app = new App({
538
- token: process.env.SLACK_BOT_TOKEN,
539
- signingSecret: process.env.SLACK_SIGNING_SECRET,
540
- receiver,
541
- });
542
-
543
- // Handle messages in channels (only when @mentioned)
544
- app.event("app_mention", async ({ event }) => {
545
- const chat = await agent.chat.upsert([
546
- "slack",
547
- event.channel,
548
- event.thread_ts ?? event.ts,
549
- ]);
550
- const { message } = await slack.createMessageFromEvent({
551
- client: app.client,
552
- event,
553
- });
554
- await agent.chat.sendMessages(chat.id, [message]);
555
- await app.client.assistant.threads.setStatus({
556
- channel_id: event.channel,
557
- status: "is typing...",
558
- thread_ts: event.thread_ts ?? event.ts,
559
- });
560
- });
486
+ import { z } from "zod";
487
+ {{#if (eq aiProvider "anthropic")}}
488
+ import { anthropic } from "@ai-sdk/anthropic";
489
+ {{else if (eq aiProvider "openai")}}
490
+ import { openai } from "@ai-sdk/openai";
491
+ {{/if}}
561
492
 
562
- // Handle direct messages (always respond)
563
- app.event("message", async ({ event }) => {
564
- // Ignore bot messages and message changes
565
- if (event.subtype || event.bot_id) {
566
- return;
567
- }
568
- // Only handle DMs (channel type is 'im')
569
- const channelInfo = await app.client.conversations.info({
570
- channel: event.channel,
571
- });
572
- if (!channelInfo.channel?.is_im) {
573
- return;
574
- }
575
- const chat = await agent.chat.upsert(["slack", event.channel]);
576
- const { message } = await slack.createMessageFromEvent({
577
- client: app.client,
578
- event,
579
- });
580
- await agent.chat.sendMessages(chat.id, [message]);
581
- await app.client.assistant.threads.setStatus({
582
- channel_id: event.channel,
583
- status: "is typing...",
584
- thread_ts: event.thread_ts ?? event.ts,
585
- });
586
- });
587
493
  const agent = new blink.Agent();
588
494
 
589
- agent.on("request", async (request) => {
590
- return receiver.handle(app, request);
591
- });
592
-
593
495
  agent.on("chat", async ({ messages }) => {
594
- const tools = slack.createTools({ client: app.client });
595
- const lastMessage = messages[messages.length - 1];
596
- const threadInfo = lastMessage?.metadata as
597
- | { channel?: string; thread_ts?: string }
598
- | undefined;
599
-
600
- // Add instruction to clear status after completion
601
- if (threadInfo?.channel && threadInfo?.thread_ts) {
602
- const clonedMessages = structuredClone(messages);
603
- const lastClonedMessage = clonedMessages[clonedMessages.length - 1];
604
- if (lastClonedMessage) {
605
- lastClonedMessage.parts.push({
606
- type: "text",
607
- text: \`*INTERNAL INSTRUCTION*: Clear the status of this thread after you finish: channel=\${threadInfo.channel} thread_ts=\${threadInfo.thread_ts}\`,
608
- });
609
- }
610
- messages = clonedMessages;
611
- }
612
-
613
496
  return streamText({
614
- model: blink.model("anthropic/claude-sonnet-4.5"),
615
- system: "You are a helpful Slack bot assistant.",
616
- messages: convertToModelMessages(messages, {
617
- ignoreIncompleteToolCalls: true,
618
- tools,
619
- }),
620
- tools,
497
+ {{#if (eq aiProvider "anthropic")}}
498
+ model: anthropic("claude-sonnet-4-5"),
499
+ {{else if (eq aiProvider "openai")}}
500
+ model: openai("gpt-5-chat-latest"),
501
+ {{else if (eq aiProvider "vercel")}}
502
+ model: "anthropic/claude-sonnet-4.5",
503
+ {{else}}
504
+ // Unknown provider: {{aiProvider}}. Defaulting to Vercel AI Gateway syntax.
505
+ model: "anthropic/claude-sonnet-4.5",
506
+ {{/if}}
507
+ system: \`You are a basic agent the user will customize.
508
+
509
+ Suggest the user enters edit mode with Ctrl+T or /edit to customize the agent.
510
+ Demonstrate your capabilities with the IP tool.\`,
511
+ messages: convertToModelMessages(messages),
512
+ tools: {
513
+ get_ip_info: tool({
514
+ description: "Get IP address information of the computer.",
515
+ inputSchema: z.object({}),
516
+ execute: async () => {
517
+ const response = await fetch("https://ipinfo.io/json");
518
+ return response.json();
519
+ },
520
+ }),
521
+ },
621
522
  });
622
523
  });
623
524
 
624
525
  agent.serve();
625
- `,"package.json":`{
626
- "name": "{{name}}",
526
+ `,"package.json.hbs":`{
527
+ "name": "{{packageName}}",
627
528
  "main": "agent.ts",
628
529
  "type": "module",
629
530
  "private": true,
@@ -634,15 +535,18 @@ agent.serve();
634
535
  "devDependencies": {
635
536
  "zod": "latest",
636
537
  "ai": "latest",
538
+ {{#if (eq aiProvider "anthropic")}}
539
+ "@ai-sdk/anthropic": "latest",
540
+ {{else if (eq aiProvider "openai")}}
541
+ "@ai-sdk/openai": "latest",
542
+ {{/if}}
637
543
  "blink": "latest",
638
544
  "esbuild": "latest",
639
545
  "@types/node": "latest",
640
- "typescript": "latest",
641
- "@slack/bolt": "latest",
642
- "@blink-sdk/slack": "latest"
546
+ "typescript": "latest"
643
547
  }
644
548
  }
645
- `,".gitignore":`# dependencies
549
+ `},"slack-bot":{".gitignore":`# dependencies
646
550
  node_modules
647
551
 
648
552
  # config and build
@@ -1123,9 +1027,140 @@ The agent process can restart at any time, so all important state must be extern
1123
1027
  # They will be used by blink dev for development.
1124
1028
  SLACK_BOT_TOKEN=xoxb-your-token-here
1125
1029
  SLACK_SIGNING_SECRET=your-signing-secret-here
1126
- `,".env.production":`
1127
- # Store production environment variables here.
1030
+ `,".env.production":`# Store production environment variables here.
1128
1031
  # They will be upserted as secrets on blink deploy.
1129
- SLACK_BOT_TOKEN=
1130
- SLACK_SIGNING_SECRET=
1032
+ # EXTERNAL_SERVICE_API_KEY=
1033
+ `,"agent.ts.hbs":`import { convertToModelMessages, streamText } from "ai";
1034
+ import * as blink from "blink";
1035
+ import * as slack from "@blink-sdk/slack";
1036
+ import { App } from "@slack/bolt";
1037
+ {{#if (eq aiProvider "anthropic")}}
1038
+ import { anthropic } from "@ai-sdk/anthropic";
1039
+ {{else if (eq aiProvider "openai")}}
1040
+ import { openai } from "@ai-sdk/openai";
1041
+ {{/if}}
1042
+
1043
+ const receiver = new slack.Receiver();
1044
+ const app = new App({
1045
+ token: process.env.SLACK_BOT_TOKEN,
1046
+ signingSecret: process.env.SLACK_SIGNING_SECRET,
1047
+ receiver,
1048
+ });
1049
+
1050
+ // Handle messages in channels (only when @mentioned)
1051
+ app.event("app_mention", async ({ event }) => {
1052
+ const chat = await agent.chat.upsert([
1053
+ "slack",
1054
+ event.channel,
1055
+ event.thread_ts ?? event.ts,
1056
+ ]);
1057
+ const { message } = await slack.createMessageFromEvent({
1058
+ client: app.client,
1059
+ event,
1060
+ });
1061
+ await agent.chat.sendMessages(chat.id, [message]);
1062
+ await app.client.assistant.threads.setStatus({
1063
+ channel_id: event.channel,
1064
+ status: "is typing...",
1065
+ thread_ts: event.thread_ts ?? event.ts,
1066
+ });
1067
+ });
1068
+
1069
+ // Handle direct messages (always respond)
1070
+ app.event("message", async ({ event }) => {
1071
+ // Ignore bot messages and message changes
1072
+ if (event.subtype || event.bot_id) {
1073
+ return;
1074
+ }
1075
+ // Only handle DMs (channel type is 'im')
1076
+ const channelInfo = await app.client.conversations.info({
1077
+ channel: event.channel,
1078
+ });
1079
+ if (!channelInfo.channel?.is_im) {
1080
+ return;
1081
+ }
1082
+ const chat = await agent.chat.upsert(["slack", event.channel]);
1083
+ const { message } = await slack.createMessageFromEvent({
1084
+ client: app.client,
1085
+ event,
1086
+ });
1087
+ await agent.chat.sendMessages(chat.id, [message]);
1088
+ await app.client.assistant.threads.setStatus({
1089
+ channel_id: event.channel,
1090
+ status: "is typing...",
1091
+ thread_ts: event.thread_ts ?? event.ts,
1092
+ });
1093
+ });
1094
+
1095
+ const agent = new blink.Agent();
1096
+
1097
+ agent.on("request", async (request) => {
1098
+ return receiver.handle(app, request);
1099
+ });
1100
+
1101
+ agent.on("chat", async ({ messages }) => {
1102
+ const tools = slack.createTools({ client: app.client });
1103
+ const lastMessage = messages[messages.length - 1];
1104
+ const threadInfo = lastMessage?.metadata as
1105
+ | { channel?: string; thread_ts?: string }
1106
+ | undefined;
1107
+
1108
+ // Add instruction to clear status after completion
1109
+ if (threadInfo?.channel && threadInfo?.thread_ts) {
1110
+ const clonedMessages = structuredClone(messages);
1111
+ const lastClonedMessage = clonedMessages[clonedMessages.length - 1];
1112
+ if (lastClonedMessage) {
1113
+ lastClonedMessage.parts.push({
1114
+ type: "text",
1115
+ text: \`*INTERNAL INSTRUCTION*: Clear the status of this thread after you finish: channel=\${threadInfo.channel} thread_ts=\${threadInfo.thread_ts}\`,
1116
+ });
1117
+ }
1118
+ messages = clonedMessages;
1119
+ }
1120
+
1121
+ return streamText({
1122
+ {{#if (eq aiProvider "anthropic")}}
1123
+ model: anthropic("claude-sonnet-4-5"),
1124
+ {{else if (eq aiProvider "openai")}}
1125
+ model: openai("gpt-5-chat-latest"),
1126
+ {{else if (eq aiProvider "vercel")}}
1127
+ model: "anthropic/claude-sonnet-4.5",
1128
+ {{else}}
1129
+ // Unknown provider: {{aiProvider}}. Defaulting to Vercel AI Gateway syntax.
1130
+ model: "anthropic/claude-sonnet-4.5",
1131
+ {{/if}}
1132
+ system: "You are a helpful Slack bot assistant.",
1133
+ messages: convertToModelMessages(messages, {
1134
+ ignoreIncompleteToolCalls: true,
1135
+ tools,
1136
+ }),
1137
+ tools,
1138
+ });
1139
+ });
1140
+
1141
+ agent.serve();`,"package.json.hbs":`{
1142
+ "name": "{{packageName}}",
1143
+ "main": "agent.ts",
1144
+ "type": "module",
1145
+ "private": true,
1146
+ "scripts": {
1147
+ "dev": "blink dev",
1148
+ "deploy": "blink deploy"
1149
+ },
1150
+ "devDependencies": {
1151
+ "zod": "latest",
1152
+ "ai": "latest",
1153
+ {{#if (eq aiProvider "anthropic")}}
1154
+ "@ai-sdk/anthropic": "latest",
1155
+ {{else if (eq aiProvider "openai")}}
1156
+ "@ai-sdk/openai": "latest",
1157
+ {{/if}}
1158
+ "blink": "latest",
1159
+ "esbuild": "latest",
1160
+ "@types/node": "latest",
1161
+ "typescript": "latest",
1162
+ "@slack/bolt": "latest",
1163
+ "@blink-sdk/slack": "latest"
1164
+ }
1165
+ }
1131
1166
  `}};export{e as templates};
@@ -0,0 +1 @@
1
+ import"./dist-DxkSGwUH.js";import{login as e}from"./auth-Db3lxkv2.js";import"./open-S_jcQ0nw.js";async function t(){await e()}export{t as default};
@@ -1 +1 @@
1
- import{__toESM as e}from"./chunk-D9KrCrVq.js";import{findNearestEntry as t,migrateBlinkToData as n,require_main as r,resolveConfig as i}from"./util-DBfnc6lD.js";import"./dist-AXHevRdg.js";import{getAuthToken as a}from"./auth-DCUw-BJE.js";import"./open-DCYivxgo.js";import{ChatManager as o,Client as s}from"./chat-manager-BtRfjylv.js";import{spawn as c}from"node:child_process";import{join as l,resolve as u}from"node:path";import{existsSync as d}from"node:fs";import{readFile as f}from"node:fs/promises";import{createServer as p}from"node:net";async function m(e){let t=e.env?.PORT??await h(),n=e.env?.HOST??`127.0.0.1`,r=`http://${n}:${t}`,i={...e.env??process.env,PORT:t.toString(),HOST:n},a=c(e.command,e.args,{stdio:`pipe`,env:i});e.signal?.addEventListener(`abort`,()=>{try{a.kill()}catch{}},{once:!0});let o=new AbortController,l=[o.signal];e.signal&&l.push(e.signal);let u=AbortSignal.any(l);a.stdout.on(`data`,t=>{e.onStdout?.(Buffer.from(t).toString(`utf-8`))});let d=``;a.stderr.on(`data`,t=>{o.signal.aborted||(d+=Buffer.from(t).toString(`utf-8`)),e.onStderr?.(Buffer.from(t).toString(`utf-8`))}),a.on(`error`,e=>{o.abort(e)}),a.on(`exit`,(t,n)=>{o.signal.aborted?e.onExit?.(t,n):o.abort()});let f=new s({baseUrl:r}),p=0;for(;!u.aborted;){try{await f.health();break}catch{}if(await new Promise(e=>setTimeout(e,p*5)),p++,p>100)throw Error(`Health endpoint timed out`)}if(u.aborted)throw u.reason;return o.abort(),{client:f,dispose:()=>{a.kill()}}}async function h(){let e=p();return new Promise((t,n)=>{e.listen(0,()=>{let n=e.address().port;t(n)}).on(`error`,e=>{n(e)})}).finally(()=>{e.close()})}var g=e(r(),1);async function _(e,r={}){if(!r.directory){let e=process.cwd();try{i(e),r.directory=e}catch{let n=await t(e,`.blink`);n&&d(l(n,`build`))&&(n=void 0),n?r.directory=n:r.directory=e}}await n(r.directory);let s=i(r.directory),c={};try{c=(0,g.parse)(await f(l(r.directory,`.env.local`),`utf-8`))}catch{}let p=await a(),h=await m({command:`node`,args:[`--experimental-strip-types`,`--no-deprecation`,s.entry],env:{...process.env,...c,BLINK_TOKEN:p}});console.log(`Agent spawned`);let _=u(r?.directory??process.cwd(),`data`,`chats`),v=new o({chatId:r?.chat,chatsDirectory:_});v.setAgent(h.client);try{let t=new Promise(e=>{let t=v.subscribe(n=>{(n.status===`idle`||n.status===`error`)&&(t(),e())})});await v.sendMessages([{id:crypto.randomUUID(),created_at:new Date().toISOString(),metadata:void 0,parts:[{type:`text`,text:e.join(` `)}],role:`user`,mode:`run`}]),await t;let n=v.getState();n.error&&console.error(`Error:`,n.error),console.log(`Final state:`,n.messages.pop())}finally{v.dispose(),h.dispose()}}export{_ as default};
1
+ import{__toESM as e}from"./chunk-D9KrCrVq.js";import{findNearestEntry as t,migrateBlinkToData as n,require_main as r,resolveConfig as i}from"./util-x4GqZFrj.js";import"./dist-DxkSGwUH.js";import{getAuthToken as a}from"./auth-Db3lxkv2.js";import"./open-S_jcQ0nw.js";import{ChatManager as o,Client as s}from"./chat-manager-BtRfjylv.js";import{spawn as c}from"node:child_process";import{join as l,resolve as u}from"node:path";import{existsSync as d}from"node:fs";import{readFile as f}from"node:fs/promises";import{createServer as p}from"node:net";async function m(e){let t=e.env?.PORT??await h(),n=e.env?.HOST??`127.0.0.1`,r=`http://${n}:${t}`,i={...e.env??process.env,PORT:t.toString(),HOST:n},a=c(e.command,e.args,{stdio:`pipe`,env:i});e.signal?.addEventListener(`abort`,()=>{try{a.kill()}catch{}},{once:!0});let o=new AbortController,l=[o.signal];e.signal&&l.push(e.signal);let u=AbortSignal.any(l);a.stdout.on(`data`,t=>{e.onStdout?.(Buffer.from(t).toString(`utf-8`))});let d=``;a.stderr.on(`data`,t=>{o.signal.aborted||(d+=Buffer.from(t).toString(`utf-8`)),e.onStderr?.(Buffer.from(t).toString(`utf-8`))}),a.on(`error`,e=>{o.abort(e)}),a.on(`exit`,(t,n)=>{o.signal.aborted?e.onExit?.(t,n):o.abort()});let f=new s({baseUrl:r}),p=0;for(;!u.aborted;){try{await f.health();break}catch{}if(await new Promise(e=>setTimeout(e,p*5)),p++,p>100)throw Error(`Health endpoint timed out`)}if(u.aborted)throw u.reason;return o.abort(),{client:f,dispose:()=>{a.kill()}}}async function h(){let e=p();return new Promise((t,n)=>{e.listen(0,()=>{let n=e.address().port;t(n)}).on(`error`,e=>{n(e)})}).finally(()=>{e.close()})}var g=e(r(),1);async function _(e,r={}){if(!r.directory){let e=process.cwd();try{i(e),r.directory=e}catch{let n=await t(e,`.blink`);n&&d(l(n,`build`))&&(n=void 0),n?r.directory=n:r.directory=e}}await n(r.directory);let s=i(r.directory),c={};try{c=(0,g.parse)(await f(l(r.directory,`.env.local`),`utf-8`))}catch{}let p=await a(),h=await m({command:`node`,args:[`--experimental-strip-types`,`--no-deprecation`,s.entry],env:{...process.env,...c,BLINK_TOKEN:p}});console.log(`Agent spawned`);let _=u(r?.directory??process.cwd(),`data`,`chats`),v=new o({chatId:r?.chat,chatsDirectory:_});v.setAgent(h.client);try{let t=new Promise(e=>{let t=v.subscribe(n=>{(n.status===`idle`||n.status===`error`)&&(t(),e())})});await v.sendMessages([{id:crypto.randomUUID(),created_at:new Date().toISOString(),metadata:void 0,parts:[{type:`text`,text:e.join(` `)}],role:`user`,mode:`run`}]),await t;let n=v.getState();n.error&&console.error(`Error:`,n.error),console.log(`Final state:`,n.messages.pop())}finally{v.dispose(),h.dispose()}}export{_ as default};
@@ -1 +1 @@
1
- import{__toESM as e}from"./chunk-D9KrCrVq.js";import{Client as t,Ie as n,M as r,Se as i,Y as a,ge as o,he as s,pD as c,require_source as l,ye as u}from"./dist-AXHevRdg.js";import{open_default as d}from"./open-DCYivxgo.js";import{createDevhookID as f,createSlackApp as p,getDevhookID as m,hasDevhook as h}from"./create-slack-app-CNDXDwfs.js";import g from"crypto";import{basename as _,join as v}from"path";import{access as y,readFile as b,readdir as x,writeFile as S}from"fs/promises";import C from"node:util";function w(){var e=typeof SuppressedError==`function`?SuppressedError:function(e,t){var n=Error();return n.name=`SuppressedError`,n.error=e,n.suppressed=t,n},t={},n=[];function r(e,t){if(t!=null){if(Object(t)!==t)throw TypeError(`using declarations can only be used with objects, functions, null, or undefined.`);if(e)var r=t[Symbol.asyncDispose||Symbol.for(`Symbol.asyncDispose`)];if(r===void 0&&(r=t[Symbol.dispose||Symbol.for(`Symbol.dispose`)],e))var i=r;if(typeof r!=`function`)throw TypeError(`Object is not disposable.`);i&&(r=function(){try{i.call(t)}catch(e){return Promise.reject(e)}}),n.push({v:t,d:r,a:e})}else e&&n.push({d:t,a:e});return t}return{e:t,u:r.bind(null,!1),a:r.bind(null,!0),d:function(){var r,i=this.e,a=0;function o(){for(;r=n.pop();)try{if(!r.a&&a===1)return a=0,n.push(r),Promise.resolve().then(o);if(r.d){var e=r.d.call(r.v);if(r.a)return a|=2,Promise.resolve(e).then(o,s)}else a|=1}catch(e){return s(e)}if(a===1)return i===t?Promise.resolve():Promise.reject(i);if(i!==t)throw i}function s(n){return i=i===t?n:new e(n,i),o()}return o()}}}var T=e(l(),1);async function E(e){try{let t=await(await fetch(`https://slack.com/api/auth.test`,{method:`POST`,headers:{Authorization:`Bearer ${e}`,"Content-Type":`application/json`}})).json();return t.ok?{valid:!0,botName:t.user}:{valid:!1,error:t.error||`Invalid bot token`}}catch(e){return{valid:!1,error:`Failed to verify credentials: ${e}`}}}function D(e,t,n,r){let i=Math.floor(Date.now()/1e3),a=parseInt(t,10);if(Math.abs(i-a)>300)return!1;let o=g.createHmac(`sha256`,e),s=`v0:${t}:${n}`;o.update(s);let c=`v0=${o.digest(`hex`)}`;return g.timingSafeEqual(Buffer.from(c),Buffer.from(r))}const O=e=>{if(!(typeof e==`object`&&e))throw Error(`Unable to make value disposable, it's not an object`);if(Symbol.dispose in e)return e;if(`dispose`in e&&typeof e.dispose==`function`)return e[Symbol.dispose]=()=>e.dispose(),e;throw Error(`Unable to make value disposable`)};async function k(e,t,n){let r=await b(e,`utf-8`);t&&(r=r.replace(/SLACK_BOT_TOKEN=.*/,`SLACK_BOT_TOKEN=${t}`)),n&&(r=r.replace(/SLACK_SIGNING_SECRET=.*/,`SLACK_SIGNING_SECRET=${n}`)),await S(e,r)}async function A(e){let t=await x(e);for(let[e,n]of[[`bun`,`bun.lock`],[`npm`,`package-lock.json`],[`pnpm`,`pnpm-lock.yaml`],[`yarn`,`yarn.lock`]])for(let r of t)if(r.includes(n))return e;return`npm`}async function j(e,n){try{var l=w();let g=n?.name||_(e).replace(/[^a-zA-Z0-9]/g,`-`),b=n?.packageManager||await A(e),x=v(e,`.env.local`);try{await y(x)}catch{r.error(`No .env.local file found in this directory. Please run this command from a Blink agent directory.`),i(`Slack app setup cancelled`);return}let S=await s({message:`What should your Slack app be called? This will be the name displayed in Slack. You can change it later.`,placeholder:g,defaultValue:g,validate:e=>{if(!e||e.trim().length===0)return`App name cannot be empty`}});if(c(S))return;let j=h(e)?m(e):f(e),M=`https://${j}.blink.host`;if(!j)throw Error(`Failed to obtain devhook ID`);r.info(`Starting webhook listener...`);let N=``,P=``,F=!1,I=``,L=``,R=!1,z,B=new t({baseURL:`https://blink.so`}),V=()=>{},H=e=>{},U=new Promise((e,t)=>{V=e,H=t}),W=B.devhook.listen({id:j,onRequest:async e=>{let t=await e.text(),n;try{n=JSON.parse(t)}catch{return new Response(`Invalid JSON`,{status:400})}if(n.type===`url_verification`)return r.info(`✓ Webhook challenge received`),new Response(JSON.stringify({challenge:n.challenge}),{headers:{"Content-Type":`application/json`}});if(N){let r=e.headers.get(`x-slack-signature`),i=e.headers.get(`x-slack-request-timestamp`);if(!r||!i)return new Response(`Missing signature`,{status:401});if(!D(N,i,t,r))return R=!0,n.event?.type===`message`&&n.event.channel_type===`im`&&!n.event.bot_id&&(z=n.event.channel),new Response(`Invalid signature`,{status:401})}return n.event?.type===`message`&&n.event.channel_type===`im`&&!n.event.bot_id&&(F=!0,I=n.event.channel,L=n.event.ts),new Response(`OK`)},onConnect:()=>{V()},onDisconnect:()=>{},onError:e=>{H(e)}});l.u(O(W));let G={display_information:{name:S.toString(),description:`A Blink agent for Slack`,background_color:`#4A154B`},features:{bot_user:{display_name:S.toString(),always_online:!0},app_home:{home_tab_enabled:!1,messages_tab_enabled:!0,messages_tab_read_only_enabled:!1},assistant_view:{assistant_description:`A helpful assistant powered by Blink`}},oauth_config:{scopes:{bot:[`app_mentions:read`,`assistant:write`,`reactions:write`,`reactions:read`,`channels:history`,`chat:write`,`groups:history`,`groups:read`,`files:read`,`im:history`,`im:read`,`im:write`,`mpim:history`,`mpim:read`,`users:read`,`links:read`,`commands`]}},settings:{event_subscriptions:{request_url:M,bot_events:[`app_mention`,`message.channels`,`message.groups`,`message.im`,`reaction_added`,`reaction_removed`,`assistant_thread_started`,`member_joined_channel`]},interactivity:{is_enabled:!0,request_url:M},token_rotation_enabled:!1,org_deploy_enabled:!1,socket_mode_enabled:!1}},K=p(G);r.info(`Please visit this URL to create your Slack app and return here after finishing:\n\n${T.default.gray(K)}\n`);let q=await u({message:`Open this URL in your browser automatically?`,initialValue:!0});if(c(q)){r.warn(`Skipping Slack app setup`);return}if(q)try{await d(K)}catch{r.warn(`Could not automatically open browser. Please visit the URL manually.`)}let J=await s({message:`After creating the app, paste the App ID from the "Basic Information" page:`,placeholder:`A01234567AB`,validate:e=>{if(!e||e.trim().length===0)return`App ID is required`}});if(c(J)){r.warn(`Skipping Slack app setup`);return}if(N=await o({message:`Paste your Signing Secret from the same page:`,validate:e=>{if(!e||e.trim().length===0)return`Signing secret is required`}}),c(N)){r.warn(`Skipping Slack app setup`);return}let Y=!1;for(;!Y;){if(P=await o({message:`Install your app and paste your Bot Token from ${T.default.cyan(`https://api.slack.com/apps/${J}/install-on-team`)}:`,validate:e=>{if(!e||e.trim().length===0)return`Bot token is required`}}),c(P)){r.warn(`Skipping Slack app setup`);return}let e=a();e.start(`Verifying bot token...`);let t=await E(P);if(t.valid)e.stop(`✓ Bot token verified!`),Y=!0;else{e.stop(`✗ Failed to verify bot token: ${t.error}`);let n=await u({message:`Would you like to try again?`,initialValue:!0});if(c(n)||!n){r.warn(`Skipping Slack app setup`);return}}}await k(x,P,N),r.success(`Credentials saved to .env.local`),await U;let X=a();X.start(`Try sending a DM to the bot on Slack - it's ${T.default.bold(T.default.cyan(S))} in the search bar.`);let Z={bun:`bun run dev`,npm:`npm run dev`,pnpm:`pnpm run dev`,yarn:`yarn dev`}[b];for(;!F;){if(R){if(X.stop(`✗ Invalid signing secret detected`),z&&P)try{await fetch(`https://slack.com/api/chat.postMessage`,{method:`POST`,headers:{Authorization:`Bearer ${P}`,"Content-Type":`application/json`},body:JSON.stringify({channel:z,text:`⚠️ There seems to be a problem with the signing secret. Please check the CLI for instructions on how to fix it.`})})}catch{}let e=await o({message:`The signing secret appears to be incorrect. Please paste the correct Signing Secret from ${T.default.cyan(`https://api.slack.com/apps/${J}/general`)}:`,validate:e=>{if(!e||e.trim().length===0)return`Signing secret is required`}});if(c(e)){r.warn(`Skipping Slack app setup`);return}N=e,R=!1,z=void 0,await k(x,void 0,N),X.start(`Please try sending a DM to the bot again on Slack...`)}await new Promise(e=>setTimeout(e,500))}X.stop(T.default.green(`✓ DM received!`));try{await fetch(`https://slack.com/api/chat.postMessage`,{method:`POST`,headers:{Authorization:`Bearer ${P}`,"Content-Type":`application/json`},body:JSON.stringify({channel:I,thread_ts:L,text:`Congrats, your app is now installed and ready to use! Run \`${Z}\` to use your agent.`})})}catch(e){r.warn(`Could not send message to Slack: ${C.inspect(e)}`)}r.success(`Slack app setup complete!`)}catch(e){l.e=e}finally{l.d()}}async function M(e){e||=process.cwd(),n(`Setting up Slack app`),await j(e),process.exit(0)}export{j as setupSlackApp,M as setupSlackAppCommand};
1
+ import{__toESM as e}from"./chunk-D9KrCrVq.js";import{Client as t,Ie as n,M as r,Se as i,Y as a,ge as o,he as s,pD as c,require_source as l,ye as u}from"./dist-DxkSGwUH.js";import{open_default as d}from"./open-S_jcQ0nw.js";import{createDevhookID as f,createSlackApp as p,getDevhookID as m,hasDevhook as h}from"./create-slack-app-CNDXDwfs.js";import g from"crypto";import{basename as _,join as v}from"path";import{access as y,readFile as b,readdir as x,writeFile as S}from"fs/promises";import C from"node:util";function w(){var e=typeof SuppressedError==`function`?SuppressedError:function(e,t){var n=Error();return n.name=`SuppressedError`,n.error=e,n.suppressed=t,n},t={},n=[];function r(e,t){if(t!=null){if(Object(t)!==t)throw TypeError(`using declarations can only be used with objects, functions, null, or undefined.`);if(e)var r=t[Symbol.asyncDispose||Symbol.for(`Symbol.asyncDispose`)];if(r===void 0&&(r=t[Symbol.dispose||Symbol.for(`Symbol.dispose`)],e))var i=r;if(typeof r!=`function`)throw TypeError(`Object is not disposable.`);i&&(r=function(){try{i.call(t)}catch(e){return Promise.reject(e)}}),n.push({v:t,d:r,a:e})}else e&&n.push({d:t,a:e});return t}return{e:t,u:r.bind(null,!1),a:r.bind(null,!0),d:function(){var r,i=this.e,a=0;function o(){for(;r=n.pop();)try{if(!r.a&&a===1)return a=0,n.push(r),Promise.resolve().then(o);if(r.d){var e=r.d.call(r.v);if(r.a)return a|=2,Promise.resolve(e).then(o,s)}else a|=1}catch(e){return s(e)}if(a===1)return i===t?Promise.resolve():Promise.reject(i);if(i!==t)throw i}function s(n){return i=i===t?n:new e(n,i),o()}return o()}}}var T=e(l(),1);async function E(e){try{let t=await(await fetch(`https://slack.com/api/auth.test`,{method:`POST`,headers:{Authorization:`Bearer ${e}`,"Content-Type":`application/json`}})).json();return t.ok?{valid:!0,botName:t.user}:{valid:!1,error:t.error||`Invalid bot token`}}catch(e){return{valid:!1,error:`Failed to verify credentials: ${e}`}}}function D(e,t,n,r){let i=Math.floor(Date.now()/1e3),a=parseInt(t,10);if(Math.abs(i-a)>300)return!1;let o=g.createHmac(`sha256`,e),s=`v0:${t}:${n}`;o.update(s);let c=`v0=${o.digest(`hex`)}`;return g.timingSafeEqual(Buffer.from(c),Buffer.from(r))}const O=e=>{if(!(typeof e==`object`&&e))throw Error(`Unable to make value disposable, it's not an object`);if(Symbol.dispose in e)return e;if(`dispose`in e&&typeof e.dispose==`function`)return e[Symbol.dispose]=()=>e.dispose(),e;throw Error(`Unable to make value disposable`)};async function k(e,t,n){let r=await b(e,`utf-8`);t&&(r=r.replace(/SLACK_BOT_TOKEN=.*/,`SLACK_BOT_TOKEN=${t}`)),n&&(r=r.replace(/SLACK_SIGNING_SECRET=.*/,`SLACK_SIGNING_SECRET=${n}`)),await S(e,r)}async function A(e){let t=await x(e);for(let[e,n]of[[`bun`,`bun.lock`],[`npm`,`package-lock.json`],[`pnpm`,`pnpm-lock.yaml`],[`yarn`,`yarn.lock`]])for(let r of t)if(r.includes(n))return e;return`npm`}async function j(e,n){try{var l=w();let g=n?.name||_(e).replace(/[^a-zA-Z0-9]/g,`-`),b=n?.packageManager||await A(e),x=v(e,`.env.local`);try{await y(x)}catch{r.error(`No .env.local file found in this directory. Please run this command from a Blink agent directory.`),i(`Slack app setup cancelled`);return}let S=await s({message:`What should your Slack app be called? This will be the name displayed in Slack. You can change it later.`,placeholder:g,defaultValue:g,validate:e=>{if(!e||e.trim().length===0)return`App name cannot be empty`}});if(c(S))return;let j=h(e)?m(e):f(e),M=`https://${j}.blink.host`;if(!j)throw Error(`Failed to obtain devhook ID`);r.info(`Starting webhook listener...`);let N=``,P=``,F=!1,I=``,L=``,R=!1,z,B=new t({baseURL:`https://blink.so`}),V=()=>{},H=e=>{},U=new Promise((e,t)=>{V=e,H=t}),W=B.devhook.listen({id:j,onRequest:async e=>{let t=await e.text(),n;try{n=JSON.parse(t)}catch{return new Response(`Invalid JSON`,{status:400})}if(n.type===`url_verification`)return r.info(`✓ Webhook challenge received`),new Response(JSON.stringify({challenge:n.challenge}),{headers:{"Content-Type":`application/json`}});if(N){let r=e.headers.get(`x-slack-signature`),i=e.headers.get(`x-slack-request-timestamp`);if(!r||!i)return new Response(`Missing signature`,{status:401});if(!D(N,i,t,r))return R=!0,n.event?.type===`message`&&n.event.channel_type===`im`&&!n.event.bot_id&&(z=n.event.channel),new Response(`Invalid signature`,{status:401})}return n.event?.type===`message`&&n.event.channel_type===`im`&&!n.event.bot_id&&(F=!0,I=n.event.channel,L=n.event.ts),new Response(`OK`)},onConnect:()=>{V()},onDisconnect:()=>{},onError:e=>{H(e)}});l.u(O(W));let G={display_information:{name:S.toString(),description:`A Blink agent for Slack`,background_color:`#4A154B`},features:{bot_user:{display_name:S.toString(),always_online:!0},app_home:{home_tab_enabled:!1,messages_tab_enabled:!0,messages_tab_read_only_enabled:!1},assistant_view:{assistant_description:`A helpful assistant powered by Blink`}},oauth_config:{scopes:{bot:[`app_mentions:read`,`assistant:write`,`reactions:write`,`reactions:read`,`channels:history`,`chat:write`,`groups:history`,`groups:read`,`files:read`,`im:history`,`im:read`,`im:write`,`mpim:history`,`mpim:read`,`users:read`,`links:read`,`commands`]}},settings:{event_subscriptions:{request_url:M,bot_events:[`app_mention`,`message.channels`,`message.groups`,`message.im`,`reaction_added`,`reaction_removed`,`assistant_thread_started`,`member_joined_channel`]},interactivity:{is_enabled:!0,request_url:M},token_rotation_enabled:!1,org_deploy_enabled:!1,socket_mode_enabled:!1}},K=p(G);r.info(`Please visit this URL to create your Slack app and return here after finishing:\n\n${T.default.gray(K)}\n`);let q=await u({message:`Open this URL in your browser automatically?`,initialValue:!0});if(c(q)){r.warn(`Skipping Slack app setup`);return}if(q)try{await d(K)}catch{r.warn(`Could not automatically open browser. Please visit the URL manually.`)}let J=await s({message:`After creating the app, paste the App ID from the "Basic Information" page:`,placeholder:`A01234567AB`,validate:e=>{if(!e||e.trim().length===0)return`App ID is required`}});if(c(J)){r.warn(`Skipping Slack app setup`);return}if(N=await o({message:`Paste your Signing Secret from the same page:`,validate:e=>{if(!e||e.trim().length===0)return`Signing secret is required`}}),c(N)){r.warn(`Skipping Slack app setup`);return}let Y=!1;for(;!Y;){if(P=await o({message:`Install your app and paste your Bot Token from ${T.default.cyan(`https://api.slack.com/apps/${J}/install-on-team`)}`,validate:e=>{if(!e||e.trim().length===0)return`Bot token is required`}}),c(P)){r.warn(`Skipping Slack app setup`);return}let e=a();e.start(`Verifying bot token...`);let t=await E(P);if(t.valid)e.stop(`✓ Bot token verified!`),Y=!0;else{e.stop(`✗ Failed to verify bot token: ${t.error}`);let n=await u({message:`Would you like to try again?`,initialValue:!0});if(c(n)||!n){r.warn(`Skipping Slack app setup`);return}}}await k(x,P,N),r.success(`Credentials saved to .env.local`),await U;let X=a();X.start(`Try sending a DM to the bot on Slack - it's ${T.default.bold(T.default.cyan(S))} in the search bar.`);let Z={bun:`bun run dev`,npm:`npm run dev`,pnpm:`pnpm run dev`,yarn:`yarn dev`}[b];for(;!F;){if(R){if(X.stop(`✗ Invalid signing secret detected`),z&&P)try{await fetch(`https://slack.com/api/chat.postMessage`,{method:`POST`,headers:{Authorization:`Bearer ${P}`,"Content-Type":`application/json`},body:JSON.stringify({channel:z,text:`⚠️ There seems to be a problem with the signing secret. Please check the CLI for instructions on how to fix it.`})})}catch{}let e=await o({message:`The signing secret appears to be incorrect. Please paste the correct Signing Secret from ${T.default.cyan(`https://api.slack.com/apps/${J}/general`)}`,validate:e=>{if(!e||e.trim().length===0)return`Signing secret is required`}});if(c(e)){r.warn(`Skipping Slack app setup`);return}N=e,R=!1,z=void 0,await k(x,void 0,N),X.start(`Please try sending a DM to the bot again on Slack...`)}await new Promise(e=>setTimeout(e,500))}X.stop(T.default.green(`✓ DM received!`));try{await fetch(`https://slack.com/api/chat.postMessage`,{method:`POST`,headers:{Authorization:`Bearer ${P}`,"Content-Type":`application/json`},body:JSON.stringify({channel:I,thread_ts:L,text:`Congrats, your app is now installed and ready to use! Run \`${Z}\` to use your agent.`})})}catch(e){r.warn(`Could not send message to Slack: ${C.inspect(e)}`)}r.success(`Slack app setup complete!`)}catch(e){l.e=e}finally{l.d()}}async function M(e){e||=process.cwd(),n(`Setting up Slack app`),await j(e),process.exit(0)}export{j as setupSlackApp,M as setupSlackAppCommand};
@@ -1,4 +1,4 @@
1
- import{__commonJSMin as e,__require as t,__toESM as n}from"./chunk-D9KrCrVq.js";import{require_source as r}from"./dist-AXHevRdg.js";import i,{dirname as a,join as o}from"path";import{existsSync as s,readFileSync as c,readdirSync as l,writeFileSync as u}from"fs";import{builtinModules as d}from"module";import{mkdir as f,rename as p,rm as m,stat as h,writeFile as g}from"fs/promises";const _=`ai-telemetry-wrapper`;function v(e={}){let{functions:t=[`streamText`,`generateText`,`generateObject`,`streamObject`,`embed`,`embedMany`],telemetryConfig:n={isEnabled:!0}}=e;return{name:`ai-telemetry`,setup(e){e.onResolve({filter:/^ai$/},e=>{if(e.namespace!==_)return{path:`ai`,namespace:_,pluginData:{resolveDir:e.resolveDir}}}),e.onLoad({filter:/^ai$/,namespace:_},e=>{let r=JSON.stringify(n),i=e.pluginData;return{contents:`
1
+ import{__commonJSMin as e,__require as t,__toESM as n}from"./chunk-D9KrCrVq.js";import{require_source as r}from"./dist-DxkSGwUH.js";import i,{dirname as a,join as o}from"path";import{existsSync as s,readFileSync as c,readdirSync as l,writeFileSync as u}from"fs";import{builtinModules as d}from"module";import{mkdir as f,rename as p,rm as m,stat as h,writeFile as g}from"fs/promises";const _=`ai-telemetry-wrapper`;function v(e={}){let{functions:t=[`streamText`,`generateText`,`generateObject`,`streamObject`,`embed`,`embedMany`],telemetryConfig:n={isEnabled:!0}}=e;return{name:`ai-telemetry`,setup(e){e.onResolve({filter:/^ai$/},e=>{if(e.namespace!==_)return{path:`ai`,namespace:_,pluginData:{resolveDir:e.resolveDir}}}),e.onLoad({filter:/^ai$/,namespace:_},e=>{let r=JSON.stringify(n),i=e.pluginData;return{contents:`
2
2
  // Import everything from the original 'ai' package
3
3
  import * as aiOriginal from 'ai';
4
4
 
@@ -1 +1 @@
1
- const e=require(`../chunk-iXuH7AlR.cjs`),t=require(`../index.node-sb6fILn2.cjs`);require(`../token-error-BoNG8ooW.cjs`),require(`../esm-0UNjvroT.cjs`),exports.Agent=t.Agent,exports.StreamResponseFormatHeader=t.StreamResponseFormatHeader,exports.agent=t.agent,exports.api=t.api,exports.isToolApprovalOutput=t.isToolApprovalOutput,exports.lastUIOptions=t.lastUIOptions,exports.model=t.model,exports.toolWithApproval=t.toolWithApproval,exports.tools=t.tools,exports.waitUntil=t.waitUntil,exports.withResponseFormat=t.withResponseFormat;
1
+ const e=require(`../chunk-iXuH7AlR.cjs`),t=require(`../index.node-CijG75ex.cjs`);require(`../token-error-BoNG8ooW.cjs`),require(`../esm-0UNjvroT.cjs`),exports.Agent=t.Agent,exports.StreamResponseFormatHeader=t.StreamResponseFormatHeader,exports.agent=t.agent,exports.api=t.api,exports.isToolApprovalOutput=t.isToolApprovalOutput,exports.lastUIOptions=t.lastUIOptions,exports.model=t.model,exports.toolWithApproval=t.toolWithApproval,exports.tools=t.tools,exports.waitUntil=t.waitUntil,exports.withResponseFormat=t.withResponseFormat;
@@ -1 +1 @@
1
- import{Agent as e,StreamResponseFormatHeader as t,agent as n,api as r,isToolApprovalOutput as i,lastUIOptions as a,model as o,toolWithApproval as s,tools as c,waitUntil as l,withResponseFormat as u}from"../index.node-CERnwYbK.js";import"../token-error-488npYdU.js";import"../esm-CbZfjZBn.js";export{e as Agent,t as StreamResponseFormatHeader,n as agent,r as api,i as isToolApprovalOutput,a as lastUIOptions,o as model,s as toolWithApproval,c as tools,l as waitUntil,u as withResponseFormat};
1
+ import{Agent as e,StreamResponseFormatHeader as t,agent as n,api as r,isToolApprovalOutput as i,lastUIOptions as a,model as o,toolWithApproval as s,tools as c,waitUntil as l,withResponseFormat as u}from"../index.node-CvZqlsJo.js";import"../token-error-488npYdU.js";import"../esm-CbZfjZBn.js";export{e as Agent,t as StreamResponseFormatHeader,n as agent,r as api,i as isToolApprovalOutput,a as lastUIOptions,o as model,s as toolWithApproval,c as tools,l as waitUntil,u as withResponseFormat};