@everruns/channelkit 0.0.0-stage → 0.1.0-alpha.1
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/LICENSE +21 -0
- package/README.md +79 -2
- package/THIRD_PARTY_NOTICES.txt +27664 -0
- package/channelkit.darwin-arm64.node +0 -0
- package/channelkit.darwin-x64.node +0 -0
- package/channelkit.linux-x64-gnu.node +0 -0
- package/channelkit.win32-x64-msvc.node +0 -0
- package/index.cjs +71 -0
- package/index.d.ts +34 -0
- package/package.json +37 -4
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/index.cjs
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const {join} = require('node:path');
|
|
3
|
+
const {platform, arch} = process;
|
|
4
|
+
const target = platform === 'linux' && arch === 'x64' && process.report.getReport().header.glibcVersionRuntime
|
|
5
|
+
? 'linux-x64-gnu' : platform === 'darwin' && ['arm64', 'x64'].includes(arch)
|
|
6
|
+
? `darwin-${arch}` : platform === 'win32' && arch === 'x64' ? 'win32-x64-msvc' : null;
|
|
7
|
+
if (!target) throw new Error('Channelkit supports Linux x64 glibc, macOS arm64/x64, and Windows x64. No platform fallback is used.');
|
|
8
|
+
const native = require(join(__dirname, `channelkit.${target}.node`));
|
|
9
|
+
|
|
10
|
+
class ChannelkitError extends Error {
|
|
11
|
+
constructor(details) {
|
|
12
|
+
super(details.message);
|
|
13
|
+
this.name = 'ChannelkitError';
|
|
14
|
+
this.code = details.code;
|
|
15
|
+
this.details = details;
|
|
16
|
+
this.confirmed = details.confirmed || [];
|
|
17
|
+
this.retryAfterMs = details.retry_after_ms;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function unwrap(result) {
|
|
21
|
+
const value = JSON.parse(result);
|
|
22
|
+
if (!value.ok) throw new ChannelkitError(value.error);
|
|
23
|
+
return value.value;
|
|
24
|
+
}
|
|
25
|
+
function utility(name, value) { return unwrap(native.utility(name, JSON.stringify(value))); }
|
|
26
|
+
function conversation(provider, installation, channel, thread = null) {
|
|
27
|
+
return utility('conversation', {provider, installation, channel, thread});
|
|
28
|
+
}
|
|
29
|
+
function text(value) { return utility('content', {Text: value}); }
|
|
30
|
+
function markdown(value) { return utility('content', {Markdown: value}); }
|
|
31
|
+
function card(title, body, actions) { return utility('content', {Card: {title, body, actions}}); }
|
|
32
|
+
function splitText(value, maxChars) { return utility('split_text', {text: value, max_chars: maxChars}); }
|
|
33
|
+
class Adapter {
|
|
34
|
+
#adapter;
|
|
35
|
+
#metadata;
|
|
36
|
+
constructor(config) {
|
|
37
|
+
try { this.#adapter = new native.NativeAdapter(JSON.stringify(config)); }
|
|
38
|
+
catch (error) { throw new ChannelkitError(JSON.parse(error.message)); }
|
|
39
|
+
this.#metadata = unwrap(this.#adapter.metadata());
|
|
40
|
+
}
|
|
41
|
+
get providerCapabilities() { return {...this.#metadata.capabilities}; }
|
|
42
|
+
conversation(channel, thread = null) {
|
|
43
|
+
return conversation(this.#metadata.provider, this.#metadata.installation, channel, thread);
|
|
44
|
+
}
|
|
45
|
+
receive(body, headers = {}, {method = 'POST', query = {}} = {}) {
|
|
46
|
+
if (!Buffer.isBuffer(body)) throw new TypeError('webhook body must be the original Buffer');
|
|
47
|
+
const result = unwrap(this.#adapter.receive(body, JSON.stringify({method, headers, query})));
|
|
48
|
+
result.response.body = Buffer.from(result.response.body);
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
async _call(operation, args) { return unwrap(await this.#adapter.call(JSON.stringify({operation, ...args}))); }
|
|
52
|
+
async post(target, content) { return this._call('post', {target, content: typeof content === 'string' ? text(content) : content}); }
|
|
53
|
+
async reply(source, content) { return this._call('reply', {source, content: typeof content === 'string' ? text(content) : content}); }
|
|
54
|
+
react(target, emoji = null) { return this._call('react', {target, emoji}); }
|
|
55
|
+
async edit(target, content) { return this._call('edit', {target, content: typeof content === 'string' ? text(content) : content}); }
|
|
56
|
+
delete(target) { return this._call('delete', {target}); }
|
|
57
|
+
history(target, {cursor = null, limit = 100} = {}) { return this._call('history', {target, cursor, limit}); }
|
|
58
|
+
typing(target) { return this._call('typing', {target}); }
|
|
59
|
+
}
|
|
60
|
+
class Slack extends Adapter {
|
|
61
|
+
constructor({installation, teamId, token, signingSecret, apiOrigin = null}) {
|
|
62
|
+
super({provider: 'slack', installation, team_id: teamId, token, signing_secret: signingSecret, api_origin: apiOrigin});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
class WhatsApp extends Adapter {
|
|
66
|
+
constructor({installation, phoneNumberId, token, appSecret, verifyToken, apiOrigin = null}) {
|
|
67
|
+
super({provider: 'whatsapp', installation, phone_number_id: phoneNumberId, token, app_secret: appSecret, verify_token: verifyToken, api_origin: apiOrigin});
|
|
68
|
+
}
|
|
69
|
+
sendTemplate(target, name, language, components = []) { return this._call('template', {target, name, language, components}); }
|
|
70
|
+
}
|
|
71
|
+
module.exports = {Slack, WhatsApp, ChannelkitError, conversation, text, markdown, card, splitText, version: native.version()};
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/// Native direct-adapter bindings. HTTP acceptance, authorization and agents remain host-owned.
|
|
2
|
+
import type {Buffer} from 'node:buffer';
|
|
3
|
+
export type Provider = 'slack' | 'whatsapp';
|
|
4
|
+
export interface Conversation { provider: Provider; installation: string; channel: string; thread: string | null }
|
|
5
|
+
export interface MessageRef { conversation: Conversation; id: string }
|
|
6
|
+
export interface User { id: string; display_name: string | null; is_bot: boolean }
|
|
7
|
+
export interface Message { reference: MessageRef; author: User; text: string; attachments: Array<{id: string; name: string | null; media_type: string | null; size: number | null}>; direct: boolean; mentioned: boolean; reply_to: string | null; timestamp: number | null }
|
|
8
|
+
export type Content = {Text: string} | {Markdown: string} | {Card: {title: string; body: string; actions: Array<{id: string; label: string}>}};
|
|
9
|
+
export interface Receipt { messages: MessageRef[]; status: 'accepted' | 'sent' | 'delivered' | 'read' | 'failed' }
|
|
10
|
+
export interface Ingress { response: {status: number; content_type: string; body: Buffer}; events: Array<{id: string; kind: Record<string, unknown>}> }
|
|
11
|
+
export class ChannelkitError extends Error { code: string; details: Record<string, unknown>; confirmed: MessageRef[]; retryAfterMs?: number }
|
|
12
|
+
declare class Adapter {
|
|
13
|
+
readonly providerCapabilities: Record<string, 'Native' | 'Emulated' | 'Conditional' | 'Unsupported'>;
|
|
14
|
+
conversation(channel: string, thread?: string | null): Conversation;
|
|
15
|
+
receive(body: Buffer, headers?: Record<string, string>, options?: {method?: string; query?: Record<string, string>}): Ingress;
|
|
16
|
+
post(target: Conversation, content: string | Content): Promise<Receipt>;
|
|
17
|
+
reply(source: Message, content: string | Content): Promise<Receipt>;
|
|
18
|
+
react(target: MessageRef, emoji?: string | null): Promise<null>;
|
|
19
|
+
edit(target: MessageRef, content: string | Content): Promise<null>;
|
|
20
|
+
delete(target: MessageRef): Promise<null>;
|
|
21
|
+
history(target: Conversation, options?: {cursor?: string | null; limit?: number}): Promise<{messages: Message[]; next_cursor: string | null; complete: boolean; native: boolean}>;
|
|
22
|
+
typing(target: MessageRef): Promise<null>;
|
|
23
|
+
}
|
|
24
|
+
export class Slack extends Adapter { constructor(config: {installation: string; teamId: string; token: string; signingSecret: string; apiOrigin?: string | null}) }
|
|
25
|
+
export class WhatsApp extends Adapter {
|
|
26
|
+
constructor(config: {installation: string; phoneNumberId: string; token: string; appSecret: string; verifyToken: string; apiOrigin?: string | null});
|
|
27
|
+
sendTemplate(target: Conversation, name: string, language: string, components?: unknown[]): Promise<Receipt>;
|
|
28
|
+
}
|
|
29
|
+
export function conversation(provider: Provider, installation: string, channel: string, thread?: string | null): Conversation;
|
|
30
|
+
export function text(value: string): Content;
|
|
31
|
+
export function markdown(value: string): Content;
|
|
32
|
+
export function card(title: string, body: string, actions: Array<{id: string; label: string}>): Content;
|
|
33
|
+
export function splitText(value: string, maxChars: number): string[];
|
|
34
|
+
export const version: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@everruns/channelkit",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"description": "Rust-backed Slack and WhatsApp messaging adapters for application-owned agents",
|
|
5
|
+
"main": "index.cjs",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"index.cjs",
|
|
9
|
+
"index.d.ts",
|
|
10
|
+
"channelkit.*.node",
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE",
|
|
13
|
+
"THIRD_PARTY_NOTICES.txt"
|
|
14
|
+
],
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"author": "Mykhailo Chalyi <mike@chaliy.name>",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/everruns/channelkit.git",
|
|
20
|
+
"directory": "bindings/node"
|
|
21
|
+
},
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=20"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"agents",
|
|
27
|
+
"slack",
|
|
28
|
+
"whatsapp",
|
|
29
|
+
"messaging",
|
|
30
|
+
"rust"
|
|
31
|
+
],
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public",
|
|
34
|
+
"tag": "alpha"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"test": "node --test tests/*.test.cjs"
|
|
38
|
+
}
|
|
39
|
+
}
|