@holon-run/agentinbox 0.6.0 → 0.7.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/dist/src/adapters.js +6 -6
- package/dist/src/cli.js +18 -5
- package/dist/src/daemon.js +36 -2
- package/dist/src/http.js +1 -0
- package/dist/src/logging.js +112 -0
- package/dist/src/paths.js +1 -0
- package/dist/src/runtime_gate.js +360 -37
- package/dist/src/service.js +60 -3
- package/dist/src/source_resolution.js +20 -20
- package/dist/src/source_schema.js +2 -2
- package/dist/src/sources/remote.js +23 -23
- package/dist/src/sources/remote_modules.js +418 -0
- package/dist/src/sources/remote_profiles.js +9 -414
- package/package.json +1 -1
- package/scripts/iterm2_cursor_probe.py +8 -3
|
@@ -1,418 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.RemoteSourceProfileRegistry = void 0;
|
|
7
|
-
|
|
8
|
-
exports.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
const github_ci_1 = require("./github_ci");
|
|
14
|
-
const feishu_1 = require("./feishu");
|
|
15
|
-
const REMOTE_USER_PROFILE_ROOT_DIR = "source-profiles";
|
|
16
|
-
const BUILTIN_PROFILE_IDS = new Set(["builtin.github_repo", "builtin.github_repo_ci", "builtin.feishu_bot"]);
|
|
17
|
-
class RemoteSourceProfileRegistry {
|
|
18
|
-
profileCache = new Map();
|
|
19
|
-
resolve(source, homeDir) {
|
|
20
|
-
if (source.sourceType === "github_repo") {
|
|
21
|
-
return Promise.resolve(GITHUB_REPO_PROFILE);
|
|
22
|
-
}
|
|
23
|
-
if (source.sourceType === "github_repo_ci") {
|
|
24
|
-
return Promise.resolve(GITHUB_REPO_CI_PROFILE);
|
|
25
|
-
}
|
|
26
|
-
if (source.sourceType === "feishu_bot") {
|
|
27
|
-
return Promise.resolve(FEISHU_BOT_PROFILE);
|
|
28
|
-
}
|
|
29
|
-
if (source.sourceType !== "remote_source") {
|
|
30
|
-
throw new Error(`unsupported source type for remote profile: ${source.sourceType}`);
|
|
31
|
-
}
|
|
32
|
-
return this.loadUserProfile(source, homeDir);
|
|
33
|
-
}
|
|
34
|
-
async loadUserProfile(source, homeDir) {
|
|
35
|
-
const config = source.config ?? {};
|
|
36
|
-
const profilePath = asNonEmptyString(config.profilePath);
|
|
37
|
-
if (!profilePath) {
|
|
38
|
-
throw new Error("remote_source requires config.profilePath");
|
|
39
|
-
}
|
|
40
|
-
const profileRoot = node_path_1.default.resolve(homeDir, REMOTE_USER_PROFILE_ROOT_DIR);
|
|
41
|
-
const resolvedPath = resolveAndValidateProfilePath(profileRoot, profilePath);
|
|
42
|
-
const cacheKey = `${resolvedPath}:${source.sourceKey}`;
|
|
43
|
-
const cached = this.profileCache.get(cacheKey);
|
|
44
|
-
if (cached) {
|
|
45
|
-
return cached;
|
|
46
|
-
}
|
|
47
|
-
if (!node_fs_1.default.existsSync(resolvedPath)) {
|
|
48
|
-
throw new Error(`remote_source profile not found: ${resolvedPath}`);
|
|
49
|
-
}
|
|
50
|
-
const imported = await dynamicImportModule((0, node_url_1.pathToFileURL)(resolvedPath).href);
|
|
51
|
-
const profile = (imported.default ?? imported);
|
|
52
|
-
if (!profile || typeof profile !== "object") {
|
|
53
|
-
throw new Error(`remote_source profile must export default object: ${resolvedPath}`);
|
|
54
|
-
}
|
|
55
|
-
validateProfileContract(profile, resolvedPath);
|
|
56
|
-
this.profileCache.set(cacheKey, profile);
|
|
57
|
-
return profile;
|
|
58
|
-
}
|
|
3
|
+
exports.profileConfigForSource = exports.builtInProfileIdForSourceType = exports.RemoteSourceProfileRegistry = exports.moduleConfigForSource = exports.builtInModuleIdForSourceType = exports.RemoteSourceModuleRegistry = void 0;
|
|
4
|
+
var remote_modules_1 = require("./remote_modules");
|
|
5
|
+
Object.defineProperty(exports, "RemoteSourceModuleRegistry", { enumerable: true, get: function () { return remote_modules_1.RemoteSourceModuleRegistry; } });
|
|
6
|
+
Object.defineProperty(exports, "builtInModuleIdForSourceType", { enumerable: true, get: function () { return remote_modules_1.builtInModuleIdForSourceType; } });
|
|
7
|
+
Object.defineProperty(exports, "moduleConfigForSource", { enumerable: true, get: function () { return remote_modules_1.moduleConfigForSource; } });
|
|
8
|
+
const remote_modules_2 = require("./remote_modules");
|
|
9
|
+
class RemoteSourceProfileRegistry extends remote_modules_2.RemoteSourceModuleRegistry {
|
|
59
10
|
}
|
|
60
11
|
exports.RemoteSourceProfileRegistry = RemoteSourceProfileRegistry;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return importer(moduleUrl);
|
|
64
|
-
}
|
|
65
|
-
function builtInProfileIdForSourceType(sourceType) {
|
|
66
|
-
if (sourceType === "github_repo") {
|
|
67
|
-
return "builtin.github_repo";
|
|
68
|
-
}
|
|
69
|
-
if (sourceType === "github_repo_ci") {
|
|
70
|
-
return "builtin.github_repo_ci";
|
|
71
|
-
}
|
|
72
|
-
if (sourceType === "feishu_bot") {
|
|
73
|
-
return "builtin.feishu_bot";
|
|
74
|
-
}
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
77
|
-
function validateProfileContract(profile, sourcePath) {
|
|
78
|
-
if (!profile.id || typeof profile.id !== "string") {
|
|
79
|
-
throw new Error(`remote_source profile id must be a non-empty string: ${sourcePath}`);
|
|
80
|
-
}
|
|
81
|
-
if (BUILTIN_PROFILE_IDS.has(profile.id)) {
|
|
82
|
-
throw new Error(`remote_source profile id is reserved: ${profile.id}`);
|
|
83
|
-
}
|
|
84
|
-
if (typeof profile.validateConfig !== "function") {
|
|
85
|
-
throw new Error(`remote_source profile missing validateConfig(): ${sourcePath}`);
|
|
86
|
-
}
|
|
87
|
-
if (typeof profile.buildManagedSourceSpec !== "function") {
|
|
88
|
-
throw new Error(`remote_source profile missing buildManagedSourceSpec(): ${sourcePath}`);
|
|
89
|
-
}
|
|
90
|
-
if (typeof profile.mapRawEvent !== "function") {
|
|
91
|
-
throw new Error(`remote_source profile missing mapRawEvent(): ${sourcePath}`);
|
|
92
|
-
}
|
|
93
|
-
validateOptionalHook(profile.describeCapabilities, "describeCapabilities", sourcePath);
|
|
94
|
-
validateOptionalHook(profile.listSubscriptionShortcuts, "listSubscriptionShortcuts", sourcePath);
|
|
95
|
-
validateOptionalHook(profile.expandSubscriptionShortcut, "expandSubscriptionShortcut", sourcePath);
|
|
96
|
-
validateOptionalHook(profile.deriveTrackedResource, "deriveTrackedResource", sourcePath);
|
|
97
|
-
validateOptionalHook(profile.projectLifecycleSignal, "projectLifecycleSignal", sourcePath);
|
|
98
|
-
validateOptionalHook(profile.deriveInlinePreview, "deriveInlinePreview", sourcePath);
|
|
99
|
-
}
|
|
100
|
-
function validateOptionalHook(value, name, sourcePath) {
|
|
101
|
-
if (value !== undefined && typeof value !== "function") {
|
|
102
|
-
throw new Error(`remote_source profile ${name} must be a function when provided: ${sourcePath}`);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
function resolveAndValidateProfilePath(profileRoot, profilePath) {
|
|
106
|
-
const resolved = node_path_1.default.isAbsolute(profilePath)
|
|
107
|
-
? node_path_1.default.resolve(profilePath)
|
|
108
|
-
: node_path_1.default.resolve(profileRoot, profilePath);
|
|
109
|
-
const normalizedRoot = ensureTrailingSep(node_path_1.default.resolve(profileRoot));
|
|
110
|
-
const normalizedResolved = node_path_1.default.resolve(resolved);
|
|
111
|
-
if (!normalizedResolved.startsWith(normalizedRoot) && normalizedResolved !== node_path_1.default.resolve(profileRoot)) {
|
|
112
|
-
throw new Error(`remote_source profilePath must stay under ${profileRoot}`);
|
|
113
|
-
}
|
|
114
|
-
return normalizedResolved;
|
|
115
|
-
}
|
|
116
|
-
function ensureTrailingSep(input) {
|
|
117
|
-
return input.endsWith(node_path_1.default.sep) ? input : `${input}${node_path_1.default.sep}`;
|
|
118
|
-
}
|
|
119
|
-
function asRecord(value) {
|
|
120
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
121
|
-
return {};
|
|
122
|
-
}
|
|
123
|
-
return value;
|
|
124
|
-
}
|
|
125
|
-
function asNonEmptyString(value) {
|
|
126
|
-
if (typeof value !== "string") {
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
|
-
const trimmed = value.trim();
|
|
130
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
131
|
-
}
|
|
132
|
-
const GITHUB_REPO_PROFILE = {
|
|
133
|
-
id: "builtin.github_repo",
|
|
134
|
-
describeCapabilities(source) {
|
|
135
|
-
const config = (0, github_1.parseGithubSourceConfig)(source);
|
|
136
|
-
return {
|
|
137
|
-
sourceKind: "github_repo",
|
|
138
|
-
aliases: ["github_repo"],
|
|
139
|
-
configSchema: [
|
|
140
|
-
{ name: "owner", type: "string", required: true, description: "GitHub repository owner." },
|
|
141
|
-
{ name: "repo", type: "string", required: true, description: "GitHub repository name." },
|
|
142
|
-
{ name: "uxcAuth", type: "string", required: false, description: "Optional uxc auth profile." },
|
|
143
|
-
{ name: "eventTypes", type: "string[]", required: false, description: "Optional GitHub event type allowlist." },
|
|
144
|
-
{ name: "perPage", type: "number", required: false, description: `Repository events requested per poll. Default ${config.perPage ?? 10}.` },
|
|
145
|
-
{ name: "pollIntervalSecs", type: "number", required: false, description: `Polling interval in seconds. Default ${config.pollIntervalSecs ?? 30}.` },
|
|
146
|
-
],
|
|
147
|
-
metadataFields: [
|
|
148
|
-
{ name: "eventType", type: "string", description: "GitHub event type such as IssueCommentEvent." },
|
|
149
|
-
{ name: "action", type: "string", description: "GitHub event action suffix such as created." },
|
|
150
|
-
{ name: "author", type: "string|null", description: "Actor login for the event." },
|
|
151
|
-
{ name: "isPullRequest", type: "boolean", description: "Whether the event targets a pull request surface." },
|
|
152
|
-
{ name: "reviewState", type: "string|null", description: "Review decision state for PullRequestReviewEvent such as approved or changes_requested." },
|
|
153
|
-
{ name: "labels", type: "string[]", description: "Labels extracted from the issue or pull request." },
|
|
154
|
-
{ name: "mentions", type: "string[]", description: "Mention handles extracted from title/body/comment text." },
|
|
155
|
-
{ name: "number", type: "number|null", description: "Issue or pull request number when present." },
|
|
156
|
-
{ name: "repoFullName", type: "string", description: "Repository full name in owner/repo form." },
|
|
157
|
-
{ name: "title", type: "string|null", description: "Issue, pull request, or comment title." },
|
|
158
|
-
{ name: "body", type: "string|null", description: "Issue, pull request, or comment body text." },
|
|
159
|
-
{ name: "url", type: "string|null", description: "Primary GitHub HTML URL for the event target." },
|
|
160
|
-
],
|
|
161
|
-
payloadExamples: [
|
|
162
|
-
{
|
|
163
|
-
id: "1234567891",
|
|
164
|
-
type: "PullRequestReviewEvent",
|
|
165
|
-
action: "created",
|
|
166
|
-
actor: "Copilot",
|
|
167
|
-
pull_request: { number: 67, title: "feat: add remote module capability hooks" },
|
|
168
|
-
review: { state: "commented", body: "review summary" },
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
id: "1234567892",
|
|
172
|
-
type: "PullRequestEvent",
|
|
173
|
-
action: "closed",
|
|
174
|
-
actor: "jolestar",
|
|
175
|
-
pull_request: { number: 72, title: "feat: add cleanup policy lifecycle engine", merged: true },
|
|
176
|
-
},
|
|
177
|
-
],
|
|
178
|
-
eventVariantExamples: [
|
|
179
|
-
"IssueCommentEvent.created",
|
|
180
|
-
"PullRequestEvent.opened",
|
|
181
|
-
"PullRequestEvent.closed",
|
|
182
|
-
"PullRequestReviewEvent.created",
|
|
183
|
-
"PullRequestReviewCommentEvent.created",
|
|
184
|
-
],
|
|
185
|
-
};
|
|
186
|
-
},
|
|
187
|
-
listSubscriptionShortcuts() {
|
|
188
|
-
return (0, github_1.githubSubscriptionShortcutSpec)();
|
|
189
|
-
},
|
|
190
|
-
expandSubscriptionShortcut(input) {
|
|
191
|
-
return (0, github_1.expandGithubSubscriptionShortcut)(input);
|
|
192
|
-
},
|
|
193
|
-
deriveTrackedResource(filter) {
|
|
194
|
-
return (0, github_1.deriveGithubTrackedResource)(filter);
|
|
195
|
-
},
|
|
196
|
-
projectLifecycleSignal(rawPayload) {
|
|
197
|
-
return (0, github_1.projectGithubLifecycleSignal)(rawPayload);
|
|
198
|
-
},
|
|
199
|
-
validateConfig(source) {
|
|
200
|
-
(0, github_1.parseGithubSourceConfig)(source);
|
|
201
|
-
},
|
|
202
|
-
buildManagedSourceSpec(source) {
|
|
203
|
-
const config = (0, github_1.parseGithubSourceConfig)(source);
|
|
204
|
-
return {
|
|
205
|
-
endpoint: github_1.GITHUB_ENDPOINT,
|
|
206
|
-
operation_id: "get:/repos/{owner}/{repo}/events",
|
|
207
|
-
args: {
|
|
208
|
-
owner: config.owner,
|
|
209
|
-
repo: config.repo,
|
|
210
|
-
per_page: config.perPage ?? 10,
|
|
211
|
-
},
|
|
212
|
-
mode: "poll",
|
|
213
|
-
poll_config: {
|
|
214
|
-
interval_secs: config.pollIntervalSecs ?? 30,
|
|
215
|
-
extract_items_pointer: "",
|
|
216
|
-
checkpoint_strategy: {
|
|
217
|
-
type: "item_key",
|
|
218
|
-
item_key_pointer: "/id",
|
|
219
|
-
seen_window: 1024,
|
|
220
|
-
},
|
|
221
|
-
},
|
|
222
|
-
options: { auth: config.uxcAuth },
|
|
223
|
-
};
|
|
224
|
-
},
|
|
225
|
-
mapRawEvent(rawPayload, source) {
|
|
226
|
-
const config = (0, github_1.parseGithubSourceConfig)(source);
|
|
227
|
-
const normalized = (0, github_1.normalizeGithubRepoEvent)(source, config, rawPayload);
|
|
228
|
-
if (!normalized) {
|
|
229
|
-
return null;
|
|
230
|
-
}
|
|
231
|
-
return {
|
|
232
|
-
sourceNativeId: normalized.sourceNativeId,
|
|
233
|
-
eventVariant: normalized.eventVariant,
|
|
234
|
-
metadata: normalized.metadata ?? {},
|
|
235
|
-
rawPayload: normalized.rawPayload ?? rawPayload,
|
|
236
|
-
occurredAt: normalized.occurredAt,
|
|
237
|
-
deliveryHandle: normalized.deliveryHandle,
|
|
238
|
-
};
|
|
239
|
-
},
|
|
240
|
-
};
|
|
241
|
-
const GITHUB_REPO_CI_PROFILE = {
|
|
242
|
-
id: "builtin.github_repo_ci",
|
|
243
|
-
describeCapabilities() {
|
|
244
|
-
return {
|
|
245
|
-
sourceKind: "github_repo_ci",
|
|
246
|
-
aliases: ["github_repo_ci"],
|
|
247
|
-
configSchema: [
|
|
248
|
-
{ name: "owner", type: "string", required: true, description: "GitHub repository owner." },
|
|
249
|
-
{ name: "repo", type: "string", required: true, description: "GitHub repository name." },
|
|
250
|
-
{ name: "uxcAuth", type: "string", required: false, description: "Optional uxc auth profile." },
|
|
251
|
-
{ name: "pollIntervalSecs", type: "number", required: false, description: "Polling interval in seconds." },
|
|
252
|
-
{ name: "perPage", type: "number", required: false, description: "Workflow runs requested per poll." },
|
|
253
|
-
{ name: "eventFilter", type: "string", required: false, description: "Optional GitHub workflow event filter." },
|
|
254
|
-
{ name: "branch", type: "string", required: false, description: "Optional branch filter for workflow runs." },
|
|
255
|
-
{ name: "statusFilter", type: "string", required: false, description: "Optional workflow status filter." },
|
|
256
|
-
],
|
|
257
|
-
metadataFields: [
|
|
258
|
-
{ name: "name", type: "string|null", description: "Workflow run name." },
|
|
259
|
-
{ name: "status", type: "string", description: "Normalized workflow run status." },
|
|
260
|
-
{ name: "conclusion", type: "string|null", description: "Workflow run conclusion when completed." },
|
|
261
|
-
{ name: "event", type: "string|null", description: "GitHub trigger event for the workflow run." },
|
|
262
|
-
{ name: "headBranch", type: "string|null", description: "Head branch for the workflow run." },
|
|
263
|
-
{ name: "headSha", type: "string|null", description: "Head commit SHA for the workflow run." },
|
|
264
|
-
{ name: "actor", type: "string|null", description: "Actor login for the workflow run." },
|
|
265
|
-
{ name: "commitMessage", type: "string|null", description: "Head commit message when present." },
|
|
266
|
-
{ name: "htmlUrl", type: "string|null", description: "GitHub Actions run URL." },
|
|
267
|
-
],
|
|
268
|
-
eventVariantExamples: ["workflow_run.ci.completed.failure", "workflow_run.nightly_checks.observed"],
|
|
269
|
-
};
|
|
270
|
-
},
|
|
271
|
-
deriveInlinePreview(item) {
|
|
272
|
-
const repoFullName = asNonEmptyString(item.metadata.repoFullName);
|
|
273
|
-
const workflowName = asNonEmptyString(item.metadata.name)
|
|
274
|
-
?? asNonEmptyString(item.metadata.displayTitle)
|
|
275
|
-
?? asNonEmptyString(item.rawPayload.name)
|
|
276
|
-
?? asNonEmptyString(item.rawPayload.display_title);
|
|
277
|
-
const headBranch = asNonEmptyString(item.metadata.headBranch) ?? asNonEmptyString(item.rawPayload.head_branch);
|
|
278
|
-
const conclusion = asNonEmptyString(item.metadata.conclusion) ?? asNonEmptyString(item.rawPayload.conclusion);
|
|
279
|
-
const status = asNonEmptyString(item.metadata.status) ?? asNonEmptyString(item.rawPayload.status);
|
|
280
|
-
const parts = [];
|
|
281
|
-
if (workflowName) {
|
|
282
|
-
parts.push(workflowName);
|
|
283
|
-
}
|
|
284
|
-
else {
|
|
285
|
-
parts.push("Workflow run");
|
|
286
|
-
}
|
|
287
|
-
if (conclusion) {
|
|
288
|
-
parts.push(`completed ${conclusion}`);
|
|
289
|
-
}
|
|
290
|
-
else if (status) {
|
|
291
|
-
parts.push(status);
|
|
292
|
-
}
|
|
293
|
-
if (repoFullName) {
|
|
294
|
-
parts.push(`for ${repoFullName}`);
|
|
295
|
-
}
|
|
296
|
-
if (headBranch) {
|
|
297
|
-
parts.push(`on ${headBranch}`);
|
|
298
|
-
}
|
|
299
|
-
return parts.join(" ");
|
|
300
|
-
},
|
|
301
|
-
validateConfig(source) {
|
|
302
|
-
(0, github_ci_1.parseGithubCiSourceConfig)(source);
|
|
303
|
-
},
|
|
304
|
-
buildManagedSourceSpec(source) {
|
|
305
|
-
const config = (0, github_ci_1.parseGithubCiSourceConfig)(source);
|
|
306
|
-
const args = {
|
|
307
|
-
owner: config.owner,
|
|
308
|
-
repo: config.repo,
|
|
309
|
-
per_page: config.perPage ?? github_ci_1.DEFAULT_GITHUB_CI_PER_PAGE,
|
|
310
|
-
};
|
|
311
|
-
if (config.eventFilter) {
|
|
312
|
-
args.event = config.eventFilter;
|
|
313
|
-
}
|
|
314
|
-
if (config.branch) {
|
|
315
|
-
args.branch = config.branch;
|
|
316
|
-
}
|
|
317
|
-
if (config.statusFilter) {
|
|
318
|
-
args.status = config.statusFilter;
|
|
319
|
-
}
|
|
320
|
-
return {
|
|
321
|
-
endpoint: github_ci_1.GITHUB_CI_ENDPOINT,
|
|
322
|
-
operation_id: "get:/repos/{owner}/{repo}/actions/runs",
|
|
323
|
-
args,
|
|
324
|
-
mode: "poll",
|
|
325
|
-
poll_config: {
|
|
326
|
-
interval_secs: config.pollIntervalSecs ?? github_ci_1.DEFAULT_GITHUB_CI_POLL_INTERVAL_SECS,
|
|
327
|
-
extract_items_pointer: "/workflow_runs",
|
|
328
|
-
checkpoint_strategy: {
|
|
329
|
-
type: "content_hash",
|
|
330
|
-
seen_window: 1024,
|
|
331
|
-
},
|
|
332
|
-
},
|
|
333
|
-
options: { auth: config.uxcAuth },
|
|
334
|
-
};
|
|
335
|
-
},
|
|
336
|
-
mapRawEvent(rawPayload, source) {
|
|
337
|
-
const config = (0, github_ci_1.parseGithubCiSourceConfig)(source);
|
|
338
|
-
const normalized = (0, github_ci_1.normalizeGithubWorkflowRunEvent)(source, config, rawPayload);
|
|
339
|
-
if (!normalized) {
|
|
340
|
-
return null;
|
|
341
|
-
}
|
|
342
|
-
return {
|
|
343
|
-
sourceNativeId: normalized.sourceNativeId,
|
|
344
|
-
eventVariant: normalized.eventVariant,
|
|
345
|
-
metadata: normalized.metadata ?? {},
|
|
346
|
-
rawPayload: normalized.rawPayload ?? rawPayload,
|
|
347
|
-
occurredAt: normalized.occurredAt,
|
|
348
|
-
deliveryHandle: normalized.deliveryHandle,
|
|
349
|
-
};
|
|
350
|
-
},
|
|
351
|
-
};
|
|
352
|
-
const FEISHU_BOT_PROFILE = {
|
|
353
|
-
id: "builtin.feishu_bot",
|
|
354
|
-
describeCapabilities() {
|
|
355
|
-
return {
|
|
356
|
-
sourceKind: "feishu_bot",
|
|
357
|
-
aliases: ["feishu_bot"],
|
|
358
|
-
configSchema: [
|
|
359
|
-
{ name: "appId", type: "string", required: true, description: "Feishu app ID." },
|
|
360
|
-
{ name: "appSecret", type: "string", required: true, description: "Feishu app secret." },
|
|
361
|
-
{ name: "eventTypes", type: "string[]", required: false, description: "Optional Feishu event type allowlist." },
|
|
362
|
-
{ name: "chatIds", type: "string[]", required: false, description: "Optional Feishu chat allowlist." },
|
|
363
|
-
{ name: "schemaUrl", type: "string", required: false, description: "Optional Feishu OpenAPI schema URL." },
|
|
364
|
-
{ name: "replyInThread", type: "boolean", required: false, description: "Reply in thread when sending outbound messages." },
|
|
365
|
-
{ name: "uxcAuth", type: "string", required: false, description: "Optional uxc auth profile." },
|
|
366
|
-
],
|
|
367
|
-
metadataFields: [
|
|
368
|
-
{ name: "eventType", type: "string", description: "Feishu event type." },
|
|
369
|
-
{ name: "chatId", type: "string", description: "Target chat ID." },
|
|
370
|
-
{ name: "chatType", type: "string|null", description: "Feishu chat type." },
|
|
371
|
-
{ name: "messageId", type: "string", description: "Feishu message ID." },
|
|
372
|
-
{ name: "messageType", type: "string", description: "Feishu message type such as text." },
|
|
373
|
-
{ name: "senderOpenId", type: "string|null", description: "Sender open_id when present." },
|
|
374
|
-
{ name: "senderType", type: "string|null", description: "Sender type." },
|
|
375
|
-
{ name: "mentions", type: "string[]", description: "Mention names extracted from the message." },
|
|
376
|
-
{ name: "mentionOpenIds", type: "string[]", description: "Mention open_ids extracted from the message." },
|
|
377
|
-
{ name: "content", type: "string|null", description: "Normalized message content string." },
|
|
378
|
-
{ name: "threadId", type: "string|null", description: "Thread or root message ID when present." },
|
|
379
|
-
{ name: "parentId", type: "string|null", description: "Parent message ID when present." },
|
|
380
|
-
],
|
|
381
|
-
eventVariantExamples: ["im.message.receive_v1.text"],
|
|
382
|
-
};
|
|
383
|
-
},
|
|
384
|
-
validateConfig(source) {
|
|
385
|
-
(0, feishu_1.parseFeishuSourceConfig)(source);
|
|
386
|
-
},
|
|
387
|
-
buildManagedSourceSpec(source) {
|
|
388
|
-
const config = (0, feishu_1.parseFeishuSourceConfig)(source);
|
|
389
|
-
return {
|
|
390
|
-
endpoint: config.endpoint ?? feishu_1.FEISHU_OPENAPI_ENDPOINT,
|
|
391
|
-
mode: "stream",
|
|
392
|
-
transport_hint: "feishu_long_connection",
|
|
393
|
-
options: { auth: config.uxcAuth },
|
|
394
|
-
};
|
|
395
|
-
},
|
|
396
|
-
mapRawEvent(rawPayload, source) {
|
|
397
|
-
const config = (0, feishu_1.parseFeishuSourceConfig)(source);
|
|
398
|
-
const normalized = (0, feishu_1.normalizeFeishuBotEvent)(source, config, rawPayload);
|
|
399
|
-
if (!normalized) {
|
|
400
|
-
return null;
|
|
401
|
-
}
|
|
402
|
-
return {
|
|
403
|
-
sourceNativeId: normalized.sourceNativeId,
|
|
404
|
-
eventVariant: normalized.eventVariant,
|
|
405
|
-
metadata: normalized.metadata ?? {},
|
|
406
|
-
rawPayload: normalized.rawPayload ?? rawPayload,
|
|
407
|
-
occurredAt: normalized.occurredAt,
|
|
408
|
-
deliveryHandle: normalized.deliveryHandle,
|
|
409
|
-
};
|
|
410
|
-
},
|
|
411
|
-
};
|
|
412
|
-
function profileConfigForSource(source) {
|
|
413
|
-
const config = asRecord(source.config);
|
|
414
|
-
if (source.sourceType === "remote_source") {
|
|
415
|
-
return asRecord(config.profileConfig);
|
|
416
|
-
}
|
|
417
|
-
return config;
|
|
418
|
-
}
|
|
12
|
+
exports.builtInProfileIdForSourceType = remote_modules_2.builtInModuleIdForSourceType;
|
|
13
|
+
exports.profileConfigForSource = remote_modules_2.moduleConfigForSource;
|
package/package.json
CHANGED
|
@@ -8,6 +8,11 @@ import sys
|
|
|
8
8
|
import json
|
|
9
9
|
import asyncio
|
|
10
10
|
|
|
11
|
+
# Keep this value in sync with the TypeScript probe normalization constant
|
|
12
|
+
# `NORMALIZED_BUFFER_TAIL_LINES`, since both are intended to mirror the same
|
|
13
|
+
# CLI/probe tail window.
|
|
14
|
+
CAPTURE_TAIL_LINES = 20
|
|
15
|
+
|
|
11
16
|
|
|
12
17
|
def probe_session(connection, session_id):
|
|
13
18
|
"""Probe iTerm2 session state and return cursor position with buffer contents."""
|
|
@@ -25,9 +30,9 @@ def probe_session(connection, session_id):
|
|
|
25
30
|
screen = await session.async_get_screen_contents()
|
|
26
31
|
cursor = screen.cursor_coord
|
|
27
32
|
|
|
28
|
-
#
|
|
33
|
+
# Capture a tail comparable to the CLI probe window.
|
|
29
34
|
lines = []
|
|
30
|
-
start_line = max(0, screen.number_of_lines -
|
|
35
|
+
start_line = max(0, screen.number_of_lines - CAPTURE_TAIL_LINES)
|
|
31
36
|
for i in range(start_line, screen.number_of_lines):
|
|
32
37
|
try:
|
|
33
38
|
line = screen.line(i)
|
|
@@ -83,4 +88,4 @@ def main():
|
|
|
83
88
|
|
|
84
89
|
|
|
85
90
|
if __name__ == "__main__":
|
|
86
|
-
main()
|
|
91
|
+
main()
|