botmux 2.44.0 → 2.45.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.
- package/README.en.md +1 -2
- package/README.md +1 -2
- package/dist/cli/bots-list-output.d.ts +8 -0
- package/dist/cli/bots-list-output.d.ts.map +1 -1
- package/dist/cli/bots-list-output.js +9 -0
- package/dist/cli/bots-list-output.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -0
- package/dist/cli.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +132 -50
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts +2 -0
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +56 -0
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/role-resolver.d.ts +17 -1
- package/dist/core/role-resolver.d.ts.map +1 -1
- package/dist/core/role-resolver.js +64 -10
- package/dist/core/role-resolver.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +14 -9
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/trigger-session.d.ts +9 -0
- package/dist/core/trigger-session.d.ts.map +1 -0
- package/dist/core/trigger-session.js +158 -0
- package/dist/core/trigger-session.js.map +1 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +73 -44
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/connector-api.d.ts +3 -0
- package/dist/dashboard/connector-api.d.ts.map +1 -0
- package/dist/dashboard/connector-api.js +351 -0
- package/dist/dashboard/connector-api.js.map +1 -0
- package/dist/dashboard/federated-group-core.d.ts +54 -0
- package/dist/dashboard/federated-group-core.d.ts.map +1 -0
- package/dist/dashboard/federated-group-core.js +165 -0
- package/dist/dashboard/federated-group-core.js.map +1 -0
- package/dist/dashboard/federation-api.d.ts +42 -0
- package/dist/dashboard/federation-api.d.ts.map +1 -0
- package/dist/dashboard/federation-api.js +408 -0
- package/dist/dashboard/federation-api.js.map +1 -0
- package/dist/dashboard/federation-spoke-api.d.ts +76 -0
- package/dist/dashboard/federation-spoke-api.d.ts.map +1 -0
- package/dist/dashboard/federation-spoke-api.js +618 -0
- package/dist/dashboard/federation-spoke-api.js.map +1 -0
- package/dist/dashboard/team-group.d.ts +18 -0
- package/dist/dashboard/team-group.d.ts.map +1 -0
- package/dist/dashboard/team-group.js +7 -0
- package/dist/dashboard/team-group.js.map +1 -0
- package/dist/dashboard/trigger-api.d.ts +13 -0
- package/dist/dashboard/trigger-api.d.ts.map +1 -0
- package/dist/dashboard/trigger-api.js +77 -0
- package/dist/dashboard/trigger-api.js.map +1 -0
- package/dist/dashboard/web/app.js +8 -0
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/connectors.d.ts +2 -0
- package/dist/dashboard/web/connectors.d.ts.map +1 -0
- package/dist/dashboard/web/connectors.js +187 -0
- package/dist/dashboard/web/connectors.js.map +1 -0
- package/dist/dashboard/web/team-federation.d.ts +3 -0
- package/dist/dashboard/web/team-federation.d.ts.map +1 -0
- package/dist/dashboard/web/team-federation.js +472 -0
- package/dist/dashboard/web/team-federation.js.map +1 -0
- package/dist/dashboard/webhook-routes.d.ts +19 -0
- package/dist/dashboard/webhook-routes.d.ts.map +1 -0
- package/dist/dashboard/webhook-routes.js +321 -0
- package/dist/dashboard/webhook-routes.js.map +1 -0
- package/dist/dashboard-web/app.js +509 -386
- package/dist/dashboard-web/index.html +2 -0
- package/dist/dashboard.js +152 -1
- package/dist/dashboard.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +24 -8
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +24 -8
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/client.d.ts +21 -0
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +86 -18
- package/dist/im/lark/client.js.map +1 -1
- package/dist/services/bot-owner-store.d.ts +28 -0
- package/dist/services/bot-owner-store.d.ts.map +1 -0
- package/dist/services/bot-owner-store.js +82 -0
- package/dist/services/bot-owner-store.js.map +1 -0
- package/dist/services/bot-profile-store.d.ts +16 -0
- package/dist/services/bot-profile-store.d.ts.map +1 -0
- package/dist/services/bot-profile-store.js +98 -0
- package/dist/services/bot-profile-store.js.map +1 -0
- package/dist/services/connector-store.d.ts +58 -0
- package/dist/services/connector-store.d.ts.map +1 -0
- package/dist/services/connector-store.js +79 -0
- package/dist/services/connector-store.js.map +1 -0
- package/dist/services/deployment-identity.d.ts +22 -0
- package/dist/services/deployment-identity.d.ts.map +1 -0
- package/dist/services/deployment-identity.js +67 -0
- package/dist/services/deployment-identity.js.map +1 -0
- package/dist/services/federation-membership-store.d.ts +23 -0
- package/dist/services/federation-membership-store.d.ts.map +1 -0
- package/dist/services/federation-membership-store.js +66 -0
- package/dist/services/federation-membership-store.js.map +1 -0
- package/dist/services/federation-roster.d.ts +54 -0
- package/dist/services/federation-roster.d.ts.map +1 -0
- package/dist/services/federation-roster.js +51 -0
- package/dist/services/federation-roster.js.map +1 -0
- package/dist/services/federation-store.d.ts +76 -0
- package/dist/services/federation-store.d.ts.map +1 -0
- package/dist/services/federation-store.js +133 -0
- package/dist/services/federation-store.js.map +1 -0
- package/dist/services/group-creator.d.ts +6 -0
- package/dist/services/group-creator.d.ts.map +1 -1
- package/dist/services/group-creator.js +10 -1
- package/dist/services/group-creator.js.map +1 -1
- package/dist/services/groups-store.d.ts +11 -0
- package/dist/services/groups-store.d.ts.map +1 -1
- package/dist/services/groups-store.js +42 -0
- package/dist/services/groups-store.js.map +1 -1
- package/dist/services/invite-store.d.ts +28 -0
- package/dist/services/invite-store.d.ts.map +1 -0
- package/dist/services/invite-store.js +85 -0
- package/dist/services/invite-store.js.map +1 -0
- package/dist/services/pairing-store.d.ts +47 -0
- package/dist/services/pairing-store.d.ts.map +1 -0
- package/dist/services/pairing-store.js +132 -0
- package/dist/services/pairing-store.js.map +1 -0
- package/dist/services/team-roster.d.ts +38 -0
- package/dist/services/team-roster.d.ts.map +1 -0
- package/dist/services/team-roster.js +82 -0
- package/dist/services/team-roster.js.map +1 -0
- package/dist/services/team-store.d.ts +54 -0
- package/dist/services/team-store.d.ts.map +1 -0
- package/dist/services/team-store.js +156 -0
- package/dist/services/team-store.js.map +1 -0
- package/dist/services/trigger-log-store.d.ts +46 -0
- package/dist/services/trigger-log-store.d.ts.map +1 -0
- package/dist/services/trigger-log-store.js +132 -0
- package/dist/services/trigger-log-store.js.map +1 -0
- package/dist/services/trigger-types.d.ts +57 -0
- package/dist/services/trigger-types.d.ts.map +1 -0
- package/dist/services/trigger-types.js +28 -0
- package/dist/services/trigger-types.js.map +1 -0
- package/dist/services/webhook-key.d.ts +16 -0
- package/dist/services/webhook-key.d.ts.map +1 -0
- package/dist/services/webhook-key.js +123 -0
- package/dist/services/webhook-key.js.map +1 -0
- package/dist/services/webhook-lifecycle-extractors.d.ts +15 -0
- package/dist/services/webhook-lifecycle-extractors.d.ts.map +1 -0
- package/dist/services/webhook-lifecycle-extractors.js +59 -0
- package/dist/services/webhook-lifecycle-extractors.js.map +1 -0
- package/dist/services/webhook-lifecycle-store.d.ts +45 -0
- package/dist/services/webhook-lifecycle-store.d.ts.map +1 -0
- package/dist/services/webhook-lifecycle-store.js +159 -0
- package/dist/services/webhook-lifecycle-store.js.map +1 -0
- package/dist/setup/verify-permissions.d.ts.map +1 -1
- package/dist/setup/verify-permissions.js +4 -0
- package/dist/setup/verify-permissions.js.map +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +64 -10
- package/dist/skills/definitions.js.map +1 -1
- package/dist/workflows/events/payloads.d.ts +2 -2
- package/dist/workflows/events/schema.d.ts +8 -8
- package/dist/workflows/trigger-from-envelope.d.ts +13 -0
- package/dist/workflows/trigger-from-envelope.d.ts.map +1 -0
- package/dist/workflows/trigger-from-envelope.js +67 -0
- package/dist/workflows/trigger-from-envelope.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team-level collaboration roster for the platform UI: every bot the deployment
|
|
3
|
+
* runs (from bots-info.json) enriched with its team capability label and whether
|
|
4
|
+
* it has a team-level role, plus the team's member count.
|
|
5
|
+
*
|
|
6
|
+
* This is the TEAM view (who's on the team), distinct from the per-chat roster
|
|
7
|
+
* in listChatBotMembers (who's in a given group + reliably @-mentionable).
|
|
8
|
+
* Pure read from `{dataDir}` files — no Lark API, no config coupling — so it is
|
|
9
|
+
* trivially testable and cheap for the UI to poll.
|
|
10
|
+
*/
|
|
11
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import { getBotCapability } from './bot-profile-store.js';
|
|
14
|
+
import { getBotOwner } from './bot-owner-store.js';
|
|
15
|
+
import { getTeam, getDefaultTeam, DEFAULT_TEAM_ID } from './team-store.js';
|
|
16
|
+
function readBotsInfo(dataDir) {
|
|
17
|
+
const fp = join(dataDir, 'bots-info.json');
|
|
18
|
+
if (!existsSync(fp))
|
|
19
|
+
return [];
|
|
20
|
+
try {
|
|
21
|
+
const parsed = JSON.parse(readFileSync(fp, 'utf-8'));
|
|
22
|
+
if (Array.isArray(parsed))
|
|
23
|
+
return parsed;
|
|
24
|
+
}
|
|
25
|
+
catch { /* corrupt — empty roster */ }
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
function hasTeamRoleFile(dataDir, larkAppId) {
|
|
29
|
+
return existsSync(join(dataDir, 'team-roles', `${larkAppId}.md`));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* @param configOrder optional list of larkAppIds in bots.json (config) order;
|
|
33
|
+
* when given, the roster is sorted to match it (and the personal dashboard).
|
|
34
|
+
* @param liveBots optional live daemon-registry bots. When given, the roster's
|
|
35
|
+
* bot set is THESE (authoritative — fixes an empty/stale bots-info.json
|
|
36
|
+
* showing no bots even though daemons are running), enriched with cliId from
|
|
37
|
+
* bots-info.json by larkAppId. When omitted, falls back to bots-info.json.
|
|
38
|
+
*/
|
|
39
|
+
export function buildTeamRoster(dataDir, teamId = DEFAULT_TEAM_ID, configOrder, liveBots) {
|
|
40
|
+
const team = getTeam(dataDir, teamId) ?? getDefaultTeam(dataDir);
|
|
41
|
+
const info = readBotsInfo(dataDir);
|
|
42
|
+
let entries;
|
|
43
|
+
if (liveBots !== undefined) {
|
|
44
|
+
// Live registry is the source of truth WHEN PROVIDED — including an empty
|
|
45
|
+
// array (no daemons running ⇒ empty roster). Never fall back to a stale
|
|
46
|
+
// bots-info.json here, or removed/offline bots would linger. Enrich
|
|
47
|
+
// cliId/openId/name from bots-info.json (which carries cliId — the registry
|
|
48
|
+
// doesn't) by larkAppId.
|
|
49
|
+
const byId = new Map(info.map(e => [e.larkAppId, e]));
|
|
50
|
+
entries = liveBots.map(lb => {
|
|
51
|
+
const ex = byId.get(lb.larkAppId);
|
|
52
|
+
return {
|
|
53
|
+
larkAppId: lb.larkAppId,
|
|
54
|
+
botOpenId: ex?.botOpenId ?? null,
|
|
55
|
+
botName: lb.botName ?? ex?.botName ?? null,
|
|
56
|
+
cliId: lb.cliId ?? ex?.cliId ?? '',
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
entries = info;
|
|
62
|
+
}
|
|
63
|
+
if (configOrder && configOrder.length) {
|
|
64
|
+
const rank = new Map(configOrder.map((id, i) => [id, i]));
|
|
65
|
+
const at = (id) => rank.has(id) ? rank.get(id) : Number.MAX_SAFE_INTEGER;
|
|
66
|
+
// stable sort by config index; unknown bots fall to the end keeping their order
|
|
67
|
+
entries = entries.map((b, i) => ({ b, i })).sort((x, y) => (at(x.b.larkAppId) - at(y.b.larkAppId)) || (x.i - y.i)).map(x => x.b);
|
|
68
|
+
}
|
|
69
|
+
const bots = entries.map((b) => {
|
|
70
|
+
const o = getBotOwner(dataDir, b.larkAppId);
|
|
71
|
+
return {
|
|
72
|
+
larkAppId: b.larkAppId,
|
|
73
|
+
name: b.botName ?? b.cliId,
|
|
74
|
+
cliId: b.cliId,
|
|
75
|
+
capability: getBotCapability(dataDir, b.larkAppId),
|
|
76
|
+
hasTeamRole: hasTeamRoleFile(dataDir, b.larkAppId),
|
|
77
|
+
owner: o ? { unionId: o.unionId, openId: o.openId, name: o.name } : null,
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
return { team: { id: team.id, name: team.name, memberCount: team.members.length }, bots };
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=team-roster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-roster.js","sourceRoot":"","sources":["../../src/services/team-roster.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export declare const DEFAULT_TEAM_ID = "default";
|
|
2
|
+
export interface TeamMember {
|
|
3
|
+
unionId?: string;
|
|
4
|
+
openId?: string;
|
|
5
|
+
email?: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
addedAt: number;
|
|
8
|
+
addedBy?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface Team {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
members: TeamMember[];
|
|
14
|
+
createdAt: number;
|
|
15
|
+
updatedAt: number;
|
|
16
|
+
}
|
|
17
|
+
/** Identifiers a membership check can match on. Match succeeds on ANY non-empty hit. */
|
|
18
|
+
export interface MemberIdentity {
|
|
19
|
+
unionId?: string;
|
|
20
|
+
openId?: string;
|
|
21
|
+
email?: string;
|
|
22
|
+
}
|
|
23
|
+
/** All teams (empty array if none materialized yet). */
|
|
24
|
+
export declare function listTeams(dataDir: string): Team[];
|
|
25
|
+
/** A team by id, or null. */
|
|
26
|
+
export declare function getTeam(dataDir: string, teamId: string): Team | null;
|
|
27
|
+
/** All teams the given identity belongs to (matches any identifier). */
|
|
28
|
+
export declare function listTeamsForMember(dataDir: string, id: MemberIdentity): Team[];
|
|
29
|
+
/**
|
|
30
|
+
* The default (implicit single-deployment) team. Read-only: returns the first
|
|
31
|
+
* persisted team, else a synthesized empty default that is NOT written. Use
|
|
32
|
+
* `ensureDefaultTeam` when you intend to persist.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getDefaultTeam(dataDir: string): Team;
|
|
35
|
+
/** Materialize (persist) the default team if no team exists yet; returns it. */
|
|
36
|
+
export declare function ensureDefaultTeam(dataDir: string, now?: number): Team;
|
|
37
|
+
/** Delete a team entirely (members + the team entry). Returns true if removed.
|
|
38
|
+
* Bots/connectors live at the deployment level (not per-team), so they are
|
|
39
|
+
* unaffected — only the membership/trust boundary is dropped. */
|
|
40
|
+
export declare function deleteTeam(dataDir: string, teamId: string): boolean;
|
|
41
|
+
/** Create a new explicit team. */
|
|
42
|
+
export declare function createTeam(dataDir: string, name: string, now?: number): Team;
|
|
43
|
+
/**
|
|
44
|
+
* Add (or merge) a member into a team. Dedupes by any matching identifier and
|
|
45
|
+
* fills in newly-known fields. Returns the updated team, or null if no such team.
|
|
46
|
+
*/
|
|
47
|
+
export declare function addMember(dataDir: string, teamId: string, member: Omit<TeamMember, 'addedAt'> & {
|
|
48
|
+
addedAt?: number;
|
|
49
|
+
}, now?: number): Team | null;
|
|
50
|
+
/** Remove a member matching any identifier. Returns true if removed. */
|
|
51
|
+
export declare function removeMember(dataDir: string, teamId: string, id: MemberIdentity, now?: number): boolean;
|
|
52
|
+
/** Whether the given identity is a member of the team (matches any identifier). */
|
|
53
|
+
export declare function isMember(dataDir: string, teamId: string, id: MemberIdentity): boolean;
|
|
54
|
+
//# sourceMappingURL=team-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-store.d.ts","sourceRoot":"","sources":["../../src/services/team-store.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,eAAe,YAAY,CAAC;AAEzC,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAOD,wFAAwF;AACxF,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAwBD,wDAAwD;AACxD,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,CAEjD;AAED,6BAA6B;AAC7B,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEpE;AAED,wEAAwE;AACxE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,cAAc,GAAG,IAAI,EAAE,CAG9E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAMpD;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,IAAI,CAOjF;AAED;;kEAEkE;AAClE,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAOnE;AAED,kCAAkC;AAClC,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,IAAI,CAMxF;AAQD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,GAAE,MAAmB,GAAG,IAAI,GAAG,IAAI,CAgB5J;AAED,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,cAAc,EAAE,GAAG,GAAE,MAAmB,GAAG,OAAO,CAUnH;AAED,mFAAmF;AACnF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,cAAc,GAAG,OAAO,CAKrF"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team store: the trust boundary for multi-bot collaboration.
|
|
3
|
+
*
|
|
4
|
+
* A "team" is a set of people (members) who trust each other; within a team,
|
|
5
|
+
* bots collaborate freely (discover, team up, hand off) without per-action
|
|
6
|
+
* authorization. Team membership is what the platform login (pairing flow) and
|
|
7
|
+
* the team Web UI gate on.
|
|
8
|
+
*
|
|
9
|
+
* Identity: members are keyed canonically by **union_id** (stable across apps
|
|
10
|
+
* under the same Feishu developer/tenant — see docs/platform-design.md). We also
|
|
11
|
+
* keep open_id / email / name when known so membership checks can match on any
|
|
12
|
+
* identifier the caller has on hand.
|
|
13
|
+
*
|
|
14
|
+
* Deployment model: "one deployment = one implicit team" is the simplest case,
|
|
15
|
+
* so a single default team is auto-materialized on first write. Explicit
|
|
16
|
+
* multi-team support is the same shape, just more than one entry.
|
|
17
|
+
*
|
|
18
|
+
* Storage: `{dataDir}/teams.json`, atomic writes (unique tmp + rename).
|
|
19
|
+
*/
|
|
20
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, renameSync } from 'node:fs';
|
|
21
|
+
import { join } from 'node:path';
|
|
22
|
+
import { randomUUID } from 'node:crypto';
|
|
23
|
+
export const DEFAULT_TEAM_ID = 'default';
|
|
24
|
+
function filePath(dataDir) {
|
|
25
|
+
return join(dataDir, 'teams.json');
|
|
26
|
+
}
|
|
27
|
+
function readFile(dataDir) {
|
|
28
|
+
const fp = filePath(dataDir);
|
|
29
|
+
if (!existsSync(fp))
|
|
30
|
+
return { version: 1, teams: [] };
|
|
31
|
+
try {
|
|
32
|
+
const parsed = JSON.parse(readFileSync(fp, 'utf-8'));
|
|
33
|
+
if (parsed && Array.isArray(parsed.teams))
|
|
34
|
+
return { version: 1, teams: parsed.teams };
|
|
35
|
+
}
|
|
36
|
+
catch { /* corrupt — fall through */ }
|
|
37
|
+
return { version: 1, teams: [] };
|
|
38
|
+
}
|
|
39
|
+
function writeFileAtomic(dataDir, data) {
|
|
40
|
+
if (!existsSync(dataDir))
|
|
41
|
+
mkdirSync(dataDir, { recursive: true });
|
|
42
|
+
const fp = filePath(dataDir);
|
|
43
|
+
const tmp = `${fp}.${process.pid}.${randomUUID()}.tmp`;
|
|
44
|
+
writeFileSync(tmp, JSON.stringify(data, null, 2) + '\n', 'utf-8');
|
|
45
|
+
renameSync(tmp, fp);
|
|
46
|
+
}
|
|
47
|
+
/** All teams (empty array if none materialized yet). */
|
|
48
|
+
export function listTeams(dataDir) {
|
|
49
|
+
return readFile(dataDir).teams;
|
|
50
|
+
}
|
|
51
|
+
/** A team by id, or null. */
|
|
52
|
+
export function getTeam(dataDir, teamId) {
|
|
53
|
+
return readFile(dataDir).teams.find(t => t.id === teamId) ?? null;
|
|
54
|
+
}
|
|
55
|
+
/** All teams the given identity belongs to (matches any identifier). */
|
|
56
|
+
export function listTeamsForMember(dataDir, id) {
|
|
57
|
+
if (!id.unionId && !id.openId && !id.email)
|
|
58
|
+
return [];
|
|
59
|
+
return readFile(dataDir).teams.filter(t => t.members.some(m => sameMember(m, id)));
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The default (implicit single-deployment) team. Read-only: returns the first
|
|
63
|
+
* persisted team, else a synthesized empty default that is NOT written. Use
|
|
64
|
+
* `ensureDefaultTeam` when you intend to persist.
|
|
65
|
+
*/
|
|
66
|
+
export function getDefaultTeam(dataDir) {
|
|
67
|
+
const teams = readFile(dataDir).teams;
|
|
68
|
+
const existing = teams.find(t => t.id === DEFAULT_TEAM_ID) ?? teams[0];
|
|
69
|
+
if (existing)
|
|
70
|
+
return existing;
|
|
71
|
+
const now = Date.now();
|
|
72
|
+
return { id: DEFAULT_TEAM_ID, name: '默认团队', members: [], createdAt: now, updatedAt: now };
|
|
73
|
+
}
|
|
74
|
+
/** Materialize (persist) the default team if no team exists yet; returns it. */
|
|
75
|
+
export function ensureDefaultTeam(dataDir, now = Date.now()) {
|
|
76
|
+
const data = readFile(dataDir);
|
|
77
|
+
if (data.teams.length > 0)
|
|
78
|
+
return data.teams.find(t => t.id === DEFAULT_TEAM_ID) ?? data.teams[0];
|
|
79
|
+
const team = { id: DEFAULT_TEAM_ID, name: '默认团队', members: [], createdAt: now, updatedAt: now };
|
|
80
|
+
data.teams.push(team);
|
|
81
|
+
writeFileAtomic(dataDir, data);
|
|
82
|
+
return team;
|
|
83
|
+
}
|
|
84
|
+
/** Delete a team entirely (members + the team entry). Returns true if removed.
|
|
85
|
+
* Bots/connectors live at the deployment level (not per-team), so they are
|
|
86
|
+
* unaffected — only the membership/trust boundary is dropped. */
|
|
87
|
+
export function deleteTeam(dataDir, teamId) {
|
|
88
|
+
const data = readFile(dataDir);
|
|
89
|
+
const before = data.teams.length;
|
|
90
|
+
data.teams = data.teams.filter(t => t.id !== teamId);
|
|
91
|
+
if (data.teams.length === before)
|
|
92
|
+
return false;
|
|
93
|
+
writeFileAtomic(dataDir, data);
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
/** Create a new explicit team. */
|
|
97
|
+
export function createTeam(dataDir, name, now = Date.now()) {
|
|
98
|
+
const data = readFile(dataDir);
|
|
99
|
+
const team = { id: `team_${randomUUID().slice(0, 8)}`, name: name.trim() || '未命名团队', members: [], createdAt: now, updatedAt: now };
|
|
100
|
+
data.teams.push(team);
|
|
101
|
+
writeFileAtomic(dataDir, data);
|
|
102
|
+
return team;
|
|
103
|
+
}
|
|
104
|
+
function sameMember(m, id) {
|
|
105
|
+
return (!!id.unionId && m.unionId === id.unionId)
|
|
106
|
+
|| (!!id.openId && m.openId === id.openId)
|
|
107
|
+
|| (!!id.email && m.email === id.email);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Add (or merge) a member into a team. Dedupes by any matching identifier and
|
|
111
|
+
* fills in newly-known fields. Returns the updated team, or null if no such team.
|
|
112
|
+
*/
|
|
113
|
+
export function addMember(dataDir, teamId, member, now = Date.now()) {
|
|
114
|
+
const data = readFile(dataDir);
|
|
115
|
+
const team = data.teams.find(t => t.id === teamId);
|
|
116
|
+
if (!team)
|
|
117
|
+
return null;
|
|
118
|
+
const existing = team.members.find(m => sameMember(m, member));
|
|
119
|
+
if (existing) {
|
|
120
|
+
existing.unionId ??= member.unionId;
|
|
121
|
+
existing.openId ??= member.openId;
|
|
122
|
+
existing.email ??= member.email;
|
|
123
|
+
if (member.name)
|
|
124
|
+
existing.name = member.name;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
team.members.push({ ...member, addedAt: member.addedAt ?? now });
|
|
128
|
+
}
|
|
129
|
+
team.updatedAt = now;
|
|
130
|
+
writeFileAtomic(dataDir, data);
|
|
131
|
+
return team;
|
|
132
|
+
}
|
|
133
|
+
/** Remove a member matching any identifier. Returns true if removed. */
|
|
134
|
+
export function removeMember(dataDir, teamId, id, now = Date.now()) {
|
|
135
|
+
const data = readFile(dataDir);
|
|
136
|
+
const team = data.teams.find(t => t.id === teamId);
|
|
137
|
+
if (!team)
|
|
138
|
+
return false;
|
|
139
|
+
const before = team.members.length;
|
|
140
|
+
team.members = team.members.filter(m => !sameMember(m, id));
|
|
141
|
+
if (team.members.length === before)
|
|
142
|
+
return false;
|
|
143
|
+
team.updatedAt = now;
|
|
144
|
+
writeFileAtomic(dataDir, data);
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
/** Whether the given identity is a member of the team (matches any identifier). */
|
|
148
|
+
export function isMember(dataDir, teamId, id) {
|
|
149
|
+
if (!id.unionId && !id.openId && !id.email)
|
|
150
|
+
return false;
|
|
151
|
+
const team = getTeam(dataDir, teamId);
|
|
152
|
+
if (!team)
|
|
153
|
+
return false;
|
|
154
|
+
return team.members.some(m => sameMember(m, id));
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=team-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-store.js","sourceRoot":"","sources":["../../src/services/team-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { TriggerAction, TriggerErrorCode } from './trigger-types.js';
|
|
2
|
+
export interface TriggerLogEntry {
|
|
3
|
+
triggerId: string;
|
|
4
|
+
connectorId?: string;
|
|
5
|
+
action: TriggerAction | 'failed';
|
|
6
|
+
status: 'ok' | 'error';
|
|
7
|
+
error?: string;
|
|
8
|
+
errorCode?: TriggerErrorCode;
|
|
9
|
+
createdAt: string;
|
|
10
|
+
}
|
|
11
|
+
export interface TriggerLogListOptions {
|
|
12
|
+
limit?: number;
|
|
13
|
+
connectorId?: string;
|
|
14
|
+
status?: TriggerLogEntry['status'];
|
|
15
|
+
errorCode?: TriggerErrorCode;
|
|
16
|
+
since?: string | Date;
|
|
17
|
+
}
|
|
18
|
+
export interface TriggerLogStats {
|
|
19
|
+
connectorId?: string;
|
|
20
|
+
total: number;
|
|
21
|
+
ok: number;
|
|
22
|
+
error: number;
|
|
23
|
+
actions: Partial<Record<TriggerLogEntry['action'], number>>;
|
|
24
|
+
errorCodes: Partial<Record<TriggerErrorCode, number>>;
|
|
25
|
+
lastTriggeredAt?: string;
|
|
26
|
+
lastOkAt?: string;
|
|
27
|
+
lastErrorAt?: string;
|
|
28
|
+
lastError?: string;
|
|
29
|
+
lastErrorCode?: TriggerErrorCode;
|
|
30
|
+
}
|
|
31
|
+
export interface TriggerLogPruneResult {
|
|
32
|
+
before: number;
|
|
33
|
+
after: number;
|
|
34
|
+
deleted: number;
|
|
35
|
+
}
|
|
36
|
+
export declare function appendTriggerLog(entry: Omit<TriggerLogEntry, 'createdAt'> & {
|
|
37
|
+
createdAt?: string;
|
|
38
|
+
}, dataDir?: string): TriggerLogEntry;
|
|
39
|
+
export declare function listTriggerLogs(opts?: TriggerLogListOptions, dataDir?: string): TriggerLogEntry[];
|
|
40
|
+
export declare function summarizeTriggerLogs(opts?: Pick<TriggerLogListOptions, 'connectorId' | 'since'>, dataDir?: string): TriggerLogStats[];
|
|
41
|
+
export declare function pruneTriggerLogs(opts?: {
|
|
42
|
+
retentionDays?: number;
|
|
43
|
+
maxEntries?: number;
|
|
44
|
+
now?: Date | string | number;
|
|
45
|
+
}, dataDir?: string): TriggerLogPruneResult;
|
|
46
|
+
//# sourceMappingURL=trigger-log-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trigger-log-store.d.ts","sourceRoot":"","sources":["../../src/services/trigger-log-store.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,aAAa,GAAG,QAAQ,CAAC;IACjC,MAAM,EAAE,IAAI,GAAG,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5D,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,gBAAgB,CAAC;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AA2CD,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,WAAW,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,EAClE,OAAO,GAAE,MAA+B,GACvC,eAAe,CAMjB;AAED,wBAAgB,eAAe,CAC7B,IAAI,GAAE,qBAA0B,EAChC,OAAO,GAAE,MAA+B,GACvC,eAAe,EAAE,CAQnB;AAED,wBAAgB,oBAAoB,CAClC,IAAI,GAAE,IAAI,CAAC,qBAAqB,EAAE,aAAa,GAAG,OAAO,CAAM,EAC/D,OAAO,GAAE,MAA+B,GACvC,eAAe,EAAE,CAgCnB;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAA;CAAO,EACxF,OAAO,GAAE,MAA+B,GACvC,qBAAqB,CAiCvB"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { config } from '../config.js';
|
|
5
|
+
function logPath(dataDir = config.session.dataDir) {
|
|
6
|
+
return join(dataDir, 'trigger-logs.jsonl');
|
|
7
|
+
}
|
|
8
|
+
function normalizeLimit(limit, fallback = 100, max = 1000) {
|
|
9
|
+
const n = typeof limit === 'number' ? limit : Number(limit);
|
|
10
|
+
if (!Number.isFinite(n))
|
|
11
|
+
return fallback;
|
|
12
|
+
return Math.max(1, Math.min(Math.floor(n), max));
|
|
13
|
+
}
|
|
14
|
+
function sinceMs(since) {
|
|
15
|
+
if (!since)
|
|
16
|
+
return undefined;
|
|
17
|
+
const ms = since instanceof Date ? since.getTime() : Date.parse(since);
|
|
18
|
+
return Number.isFinite(ms) ? ms : undefined;
|
|
19
|
+
}
|
|
20
|
+
function readTriggerLogEntries(dataDir = config.session.dataDir) {
|
|
21
|
+
const fp = logPath(dataDir);
|
|
22
|
+
if (!existsSync(fp))
|
|
23
|
+
return [];
|
|
24
|
+
const out = [];
|
|
25
|
+
const lines = readFileSync(fp, 'utf-8').split(/\r?\n/).filter(Boolean);
|
|
26
|
+
for (const line of lines) {
|
|
27
|
+
try {
|
|
28
|
+
out.push(JSON.parse(line));
|
|
29
|
+
}
|
|
30
|
+
catch { /* ignore corrupt line */ }
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
function matchesFilter(entry, opts) {
|
|
35
|
+
if (opts.connectorId && entry.connectorId !== opts.connectorId)
|
|
36
|
+
return false;
|
|
37
|
+
if (opts.status && entry.status !== opts.status)
|
|
38
|
+
return false;
|
|
39
|
+
if (opts.errorCode && entry.errorCode !== opts.errorCode)
|
|
40
|
+
return false;
|
|
41
|
+
const minMs = sinceMs(opts.since);
|
|
42
|
+
if (minMs !== undefined) {
|
|
43
|
+
const createdMs = Date.parse(entry.createdAt);
|
|
44
|
+
if (!Number.isFinite(createdMs) || createdMs < minMs)
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
export function appendTriggerLog(entry, dataDir = config.session.dataDir) {
|
|
50
|
+
const full = { ...entry, createdAt: entry.createdAt ?? new Date().toISOString() };
|
|
51
|
+
const fp = logPath(dataDir);
|
|
52
|
+
mkdirSync(dirname(fp), { recursive: true });
|
|
53
|
+
appendFileSync(fp, JSON.stringify(full) + '\n', 'utf-8');
|
|
54
|
+
return full;
|
|
55
|
+
}
|
|
56
|
+
export function listTriggerLogs(opts = {}, dataDir = config.session.dataDir) {
|
|
57
|
+
const limit = normalizeLimit(opts.limit);
|
|
58
|
+
const out = [];
|
|
59
|
+
const entries = readTriggerLogEntries(dataDir);
|
|
60
|
+
for (let i = entries.length - 1; i >= 0 && out.length < limit; i--) {
|
|
61
|
+
if (matchesFilter(entries[i], opts))
|
|
62
|
+
out.push(entries[i]);
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
export function summarizeTriggerLogs(opts = {}, dataDir = config.session.dataDir) {
|
|
67
|
+
const groups = new Map();
|
|
68
|
+
for (const entry of readTriggerLogEntries(dataDir)) {
|
|
69
|
+
if (!matchesFilter(entry, opts))
|
|
70
|
+
continue;
|
|
71
|
+
const key = entry.connectorId ?? '';
|
|
72
|
+
let stat = groups.get(key);
|
|
73
|
+
if (!stat) {
|
|
74
|
+
stat = {
|
|
75
|
+
...(entry.connectorId ? { connectorId: entry.connectorId } : {}),
|
|
76
|
+
total: 0,
|
|
77
|
+
ok: 0,
|
|
78
|
+
error: 0,
|
|
79
|
+
actions: {},
|
|
80
|
+
errorCodes: {},
|
|
81
|
+
};
|
|
82
|
+
groups.set(key, stat);
|
|
83
|
+
}
|
|
84
|
+
stat.total += 1;
|
|
85
|
+
stat[entry.status] += 1;
|
|
86
|
+
stat.actions[entry.action] = (stat.actions[entry.action] ?? 0) + 1;
|
|
87
|
+
stat.lastTriggeredAt = entry.createdAt;
|
|
88
|
+
if (entry.status === 'ok')
|
|
89
|
+
stat.lastOkAt = entry.createdAt;
|
|
90
|
+
if (entry.status === 'error') {
|
|
91
|
+
stat.lastErrorAt = entry.createdAt;
|
|
92
|
+
stat.lastError = entry.error;
|
|
93
|
+
if (entry.errorCode) {
|
|
94
|
+
stat.lastErrorCode = entry.errorCode;
|
|
95
|
+
stat.errorCodes[entry.errorCode] = (stat.errorCodes[entry.errorCode] ?? 0) + 1;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return [...groups.values()];
|
|
100
|
+
}
|
|
101
|
+
export function pruneTriggerLogs(opts = {}, dataDir = config.session.dataDir) {
|
|
102
|
+
const entries = readTriggerLogEntries(dataDir);
|
|
103
|
+
const before = entries.length;
|
|
104
|
+
const retentionDays = opts.retentionDays === undefined ? undefined : normalizeLimit(opts.retentionDays, 1, 3650);
|
|
105
|
+
const maxEntries = opts.maxEntries === undefined ? undefined : normalizeLimit(opts.maxEntries, before || 1, 1_000_000);
|
|
106
|
+
const nowMs = opts.now instanceof Date ? opts.now.getTime()
|
|
107
|
+
: typeof opts.now === 'string' ? Date.parse(opts.now)
|
|
108
|
+
: typeof opts.now === 'number' ? opts.now
|
|
109
|
+
: Date.now();
|
|
110
|
+
const cutoffMs = retentionDays === undefined || !Number.isFinite(nowMs)
|
|
111
|
+
? undefined
|
|
112
|
+
: nowMs - retentionDays * 24 * 60 * 60 * 1000;
|
|
113
|
+
let kept = cutoffMs === undefined
|
|
114
|
+
? entries
|
|
115
|
+
: entries.filter(entry => {
|
|
116
|
+
const createdMs = Date.parse(entry.createdAt);
|
|
117
|
+
return !Number.isFinite(createdMs) || createdMs >= cutoffMs;
|
|
118
|
+
});
|
|
119
|
+
if (maxEntries !== undefined && kept.length > maxEntries) {
|
|
120
|
+
kept = kept.slice(kept.length - maxEntries);
|
|
121
|
+
}
|
|
122
|
+
const fp = logPath(dataDir);
|
|
123
|
+
mkdirSync(dirname(fp), { recursive: true });
|
|
124
|
+
const tmp = `${fp}.${process.pid}.${randomUUID()}.tmp`;
|
|
125
|
+
writeFileSync(tmp, kept.map(entry => JSON.stringify(entry)).join('\n') + (kept.length ? '\n' : ''), {
|
|
126
|
+
encoding: 'utf-8',
|
|
127
|
+
mode: 0o600,
|
|
128
|
+
});
|
|
129
|
+
renameSync(tmp, fp);
|
|
130
|
+
return { before, after: kept.length, deleted: before - kept.length };
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=trigger-log-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trigger-log-store.js","sourceRoot":"","sources":["../../src/services/trigger-log-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export type TriggerSourceType = 'webhook' | 'ui' | 'workflow' | 'schedule';
|
|
2
|
+
export type TriggerTargetKind = 'turn' | 'workflow';
|
|
3
|
+
export type TriggerAction = 'queued' | 'delivered' | 'dry_run' | 'ignored';
|
|
4
|
+
export interface TriggerRequest {
|
|
5
|
+
source: {
|
|
6
|
+
type: TriggerSourceType;
|
|
7
|
+
connectorId?: string;
|
|
8
|
+
requestId?: string;
|
|
9
|
+
receivedAt?: string;
|
|
10
|
+
};
|
|
11
|
+
target: {
|
|
12
|
+
kind: TriggerTargetKind;
|
|
13
|
+
botId?: string;
|
|
14
|
+
chatId?: string;
|
|
15
|
+
sessionId?: string;
|
|
16
|
+
workflowId?: string;
|
|
17
|
+
};
|
|
18
|
+
envelope: {
|
|
19
|
+
format: string;
|
|
20
|
+
sourceName: string;
|
|
21
|
+
trusted: false;
|
|
22
|
+
headers?: Record<string, unknown>;
|
|
23
|
+
payload?: unknown;
|
|
24
|
+
rawText?: string;
|
|
25
|
+
};
|
|
26
|
+
options?: {
|
|
27
|
+
dryRun?: boolean;
|
|
28
|
+
dedupKey?: string;
|
|
29
|
+
status?: 'firing' | 'resolved' | string;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export type TriggerErrorCode = 'bad_json' | 'bad_request' | 'bot_not_found' | 'bot_not_in_chat' | 'daemon_offline' | 'dry_run' | 'invalid_signature' | 'chat_not_allowed' | 'group_create_failed' | 'lifecycle_extract_failed' | 'rate_limited' | 'replay' | 'session_not_found' | 'target_required' | 'trigger_failed' | 'workflow_trigger_not_implemented';
|
|
33
|
+
export interface TriggerResponse {
|
|
34
|
+
ok: boolean;
|
|
35
|
+
triggerId?: string;
|
|
36
|
+
action?: TriggerAction;
|
|
37
|
+
target?: {
|
|
38
|
+
kind: TriggerTargetKind;
|
|
39
|
+
sessionId?: string;
|
|
40
|
+
workflowRunId?: string;
|
|
41
|
+
chatId?: string;
|
|
42
|
+
};
|
|
43
|
+
message?: string;
|
|
44
|
+
errorCode?: TriggerErrorCode;
|
|
45
|
+
error?: string;
|
|
46
|
+
promptPreview?: string;
|
|
47
|
+
}
|
|
48
|
+
export declare function isRecord(v: unknown): v is Record<string, unknown>;
|
|
49
|
+
export declare function validateTriggerRequest(raw: unknown): {
|
|
50
|
+
ok: true;
|
|
51
|
+
request: TriggerRequest;
|
|
52
|
+
} | {
|
|
53
|
+
ok: false;
|
|
54
|
+
status: number;
|
|
55
|
+
body: TriggerResponse;
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=trigger-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trigger-types.d.ts","sourceRoot":"","sources":["../../src/services/trigger-types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,IAAI,GAAG,UAAU,GAAG,UAAU,CAAC;AAC3E,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,UAAU,CAAC;AACpD,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;AAE3E,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE;QACN,IAAI,EAAE,iBAAiB,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,MAAM,EAAE;QACN,IAAI,EAAE,iBAAiB,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,KAAK,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAClC,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;KACzC,CAAC;CACH;AAED,MAAM,MAAM,gBAAgB,GACxB,UAAU,GACV,aAAa,GACb,eAAe,GACf,iBAAiB,GACjB,gBAAgB,GAChB,SAAS,GACT,mBAAmB,GACnB,kBAAkB,GAClB,qBAAqB,GACrB,0BAA0B,GAC1B,cAAc,GACd,QAAQ,GACR,mBAAmB,GACnB,iBAAiB,GACjB,gBAAgB,GAChB,kCAAkC,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,iBAAiB,CAAC;QACxB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEjE;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,CAuBjJ"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function isRecord(v) {
|
|
2
|
+
return !!v && typeof v === 'object' && !Array.isArray(v);
|
|
3
|
+
}
|
|
4
|
+
export function validateTriggerRequest(raw) {
|
|
5
|
+
if (!isRecord(raw)) {
|
|
6
|
+
return { ok: false, status: 400, body: { ok: false, errorCode: 'bad_request', error: 'request body must be an object' } };
|
|
7
|
+
}
|
|
8
|
+
const source = raw.source;
|
|
9
|
+
const target = raw.target;
|
|
10
|
+
const envelope = raw.envelope;
|
|
11
|
+
if (!isRecord(source) || !isRecord(target) || !isRecord(envelope)) {
|
|
12
|
+
return { ok: false, status: 400, body: { ok: false, errorCode: 'bad_request', error: 'source, target, and envelope are required objects' } };
|
|
13
|
+
}
|
|
14
|
+
if (target.kind !== 'turn' && target.kind !== 'workflow') {
|
|
15
|
+
return { ok: false, status: 400, body: { ok: false, errorCode: 'target_required', error: 'target.kind must be turn or workflow' } };
|
|
16
|
+
}
|
|
17
|
+
if (target.kind === 'turn' && typeof target.chatId !== 'string' && typeof target.sessionId !== 'string') {
|
|
18
|
+
return { ok: false, status: 400, body: { ok: false, errorCode: 'target_required', error: 'turn target requires chatId or sessionId' } };
|
|
19
|
+
}
|
|
20
|
+
if (target.kind === 'workflow' && typeof target.workflowId !== 'string') {
|
|
21
|
+
return { ok: false, status: 400, body: { ok: false, errorCode: 'target_required', error: 'workflow target requires workflowId' } };
|
|
22
|
+
}
|
|
23
|
+
if (typeof envelope.sourceName !== 'string' || envelope.trusted !== false) {
|
|
24
|
+
return { ok: false, status: 400, body: { ok: false, errorCode: 'bad_request', error: 'envelope.sourceName is required and envelope.trusted must be false' } };
|
|
25
|
+
}
|
|
26
|
+
return { ok: true, request: raw };
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=trigger-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trigger-types.js","sourceRoot":"","sources":["../../src/services/trigger-types.ts"],"names":[],"mappings":"AAmEA,MAAM,UAAU,QAAQ,CAAC,CAAU;IACjC,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,GAAY;IACjD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACnB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,gCAAgC,EAAE,EAAE,CAAC;IAC5H,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC1B,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC1B,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC9B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,mDAAmD,EAAE,EAAE,CAAC;IAC/I,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACzD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,KAAK,EAAE,sCAAsC,EAAE,EAAE,CAAC;IACtI,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;QACxG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,KAAK,EAAE,0CAA0C,EAAE,EAAE,CAAC;IAC1I,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACxE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,KAAK,EAAE,qCAAqC,EAAE,EAAE,CAAC;IACrI,CAAC;IACD,IAAI,OAAO,QAAQ,CAAC,UAAU,KAAK,QAAQ,IAAI,QAAQ,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;QAC1E,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,oEAAoE,EAAE,EAAE,CAAC;IAChK,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,GAAgC,EAAE,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface WebhookSecretRecord {
|
|
2
|
+
ref: string;
|
|
3
|
+
alg: 'aes-256-gcm';
|
|
4
|
+
iv: string;
|
|
5
|
+
tag: string;
|
|
6
|
+
ciphertext: string;
|
|
7
|
+
createdAt: string;
|
|
8
|
+
updatedAt: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function createWebhookSecret(plaintext: string, dataDir?: string): WebhookSecretRecord;
|
|
11
|
+
export declare function generateWebhookSecretPlaintext(): string;
|
|
12
|
+
export declare function setWebhookSecret(ref: string, plaintext: string, dataDir?: string): WebhookSecretRecord;
|
|
13
|
+
export declare function getWebhookSecret(ref: string, dataDir?: string): string | null;
|
|
14
|
+
export declare function deleteWebhookSecret(ref: string, dataDir?: string): boolean;
|
|
15
|
+
export declare function listWebhookSecretRefs(dataDir?: string): Array<Omit<WebhookSecretRecord, 'iv' | 'tag' | 'ciphertext'>>;
|
|
16
|
+
//# sourceMappingURL=webhook-key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-key.d.ts","sourceRoot":"","sources":["../../src/services/webhook-key.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,aAAa,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAiFD,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,MAA+B,GACvC,mBAAmB,CAGrB;AAED,wBAAgB,8BAA8B,IAAI,MAAM,CAEvD;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,MAA+B,GACvC,mBAAmB,CAgBrB;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAA+B,GACvC,MAAM,GAAG,IAAI,CAKf;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,MAA+B,GAAG,OAAO,CAMlG;AAED,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,MAA+B,GAAG,KAAK,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,GAAG,KAAK,GAAG,YAAY,CAAC,CAAC,CAG7I"}
|