managed-deepagents 0.9.6-dev.19 → 0.9.6-dev.20
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.md +1075 -37
- package/dist/agent-auth.d.ts +1 -1
- package/dist/agent-auth.d.ts.map +1 -1
- package/dist/agent-auth.js +36 -12
- package/dist/agent-auth.js.map +1 -1
- package/dist/browser.d.ts +37 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +31 -0
- package/dist/browser.js.map +1 -0
- package/dist/channels/actor.d.ts +57 -0
- package/dist/channels/actor.d.ts.map +1 -0
- package/dist/channels/actor.js +24 -0
- package/dist/channels/actor.js.map +1 -0
- package/dist/channels/assistant-text.d.ts +29 -0
- package/dist/channels/assistant-text.d.ts.map +1 -1
- package/dist/channels/assistant-text.js +72 -1
- package/dist/channels/assistant-text.js.map +1 -1
- package/dist/channels/binding.d.ts +20 -1
- package/dist/channels/binding.d.ts.map +1 -1
- package/dist/channels/binding.js +44 -11
- package/dist/channels/binding.js.map +1 -1
- package/dist/channels/delivery.d.ts +51 -0
- package/dist/channels/delivery.d.ts.map +1 -0
- package/dist/channels/delivery.js +424 -0
- package/dist/channels/delivery.js.map +1 -0
- package/dist/channels/github/app-setup.d.ts +32 -0
- package/dist/channels/github/app-setup.d.ts.map +1 -0
- package/dist/channels/github/app-setup.js +146 -0
- package/dist/channels/github/app-setup.js.map +1 -0
- package/dist/channels/github/connections.d.ts +11 -0
- package/dist/channels/github/connections.d.ts.map +1 -0
- package/dist/channels/github/connections.js +14 -0
- package/dist/channels/github/connections.js.map +1 -0
- package/dist/channels/github/index.d.ts +12 -0
- package/dist/channels/github/index.d.ts.map +1 -0
- package/dist/channels/github/index.js +266 -0
- package/dist/channels/github/index.js.map +1 -0
- package/dist/channels/github/mentions.d.ts +12 -0
- package/dist/channels/github/mentions.d.ts.map +1 -0
- package/dist/channels/github/mentions.js +185 -0
- package/dist/channels/github/mentions.js.map +1 -0
- package/dist/channels/github/schema.d.ts +4165 -0
- package/dist/channels/github/schema.d.ts.map +1 -0
- package/dist/channels/github/schema.js +221 -0
- package/dist/channels/github/schema.js.map +1 -0
- package/dist/channels/github/types.d.ts +170 -0
- package/dist/channels/github/types.d.ts.map +1 -0
- package/dist/channels/github/types.js +2 -0
- package/dist/channels/github/types.js.map +1 -0
- package/dist/channels/http/endpoint.d.ts +137 -0
- package/dist/channels/http/endpoint.d.ts.map +1 -0
- package/dist/channels/http/endpoint.js +286 -0
- package/dist/channels/http/endpoint.js.map +1 -0
- package/dist/channels/http/http.d.ts.map +1 -1
- package/dist/channels/http/http.js +439 -65
- package/dist/channels/http/http.js.map +1 -1
- package/dist/channels/http/index.d.ts +8 -1
- package/dist/channels/http/index.d.ts.map +1 -1
- package/dist/channels/http/index.js +35 -16
- package/dist/channels/http/index.js.map +1 -1
- package/dist/channels/http/ingress.d.ts +67 -5
- package/dist/channels/http/ingress.d.ts.map +1 -1
- package/dist/channels/http/ingress.js +155 -43
- package/dist/channels/http/ingress.js.map +1 -1
- package/dist/channels/http/provider.d.ts +125 -0
- package/dist/channels/http/provider.d.ts.map +1 -0
- package/dist/channels/http/provider.js +227 -0
- package/dist/channels/http/provider.js.map +1 -0
- package/dist/channels/http/studio.d.ts +24 -0
- package/dist/channels/http/studio.d.ts.map +1 -0
- package/dist/channels/http/studio.js +95 -0
- package/dist/channels/http/studio.js.map +1 -0
- package/dist/channels/http/threads.d.ts +7 -0
- package/dist/channels/http/threads.d.ts.map +1 -0
- package/dist/channels/http/threads.js +10 -0
- package/dist/channels/http/threads.js.map +1 -0
- package/dist/channels/http/types.d.ts +166 -2
- package/dist/channels/http/types.d.ts.map +1 -1
- package/dist/channels/linear/app-setup.d.ts +29 -0
- package/dist/channels/linear/app-setup.d.ts.map +1 -0
- package/dist/channels/linear/app-setup.js +102 -0
- package/dist/channels/linear/app-setup.js.map +1 -0
- package/dist/channels/linear/connections.d.ts +11 -0
- package/dist/channels/linear/connections.d.ts.map +1 -0
- package/dist/channels/linear/connections.js +14 -0
- package/dist/channels/linear/connections.js.map +1 -0
- package/dist/channels/linear/graphql.d.ts +57 -0
- package/dist/channels/linear/graphql.d.ts.map +1 -0
- package/dist/channels/linear/graphql.js +167 -0
- package/dist/channels/linear/graphql.js.map +1 -0
- package/dist/channels/linear/index.d.ts +13 -0
- package/dist/channels/linear/index.d.ts.map +1 -0
- package/dist/channels/linear/index.js +457 -0
- package/dist/channels/linear/index.js.map +1 -0
- package/dist/channels/linear/schema.d.ts +1050 -0
- package/dist/channels/linear/schema.d.ts.map +1 -0
- package/dist/channels/linear/schema.js +255 -0
- package/dist/channels/linear/schema.js.map +1 -0
- package/dist/channels/linear/types.d.ts +169 -0
- package/dist/channels/linear/types.d.ts.map +1 -0
- package/dist/channels/linear/types.js +2 -0
- package/dist/channels/linear/types.js.map +1 -0
- package/dist/channels/message-schema.d.ts +2 -0
- package/dist/channels/message-schema.d.ts.map +1 -1
- package/dist/channels/message-schema.js +4 -0
- package/dist/channels/message-schema.js.map +1 -1
- package/dist/channels/messaging-registry.d.ts +16 -0
- package/dist/channels/messaging-registry.d.ts.map +1 -1
- package/dist/channels/messaging-registry.js +29 -0
- package/dist/channels/messaging-registry.js.map +1 -1
- package/dist/channels/reserved-connections.d.ts +12 -0
- package/dist/channels/reserved-connections.d.ts.map +1 -0
- package/dist/channels/reserved-connections.js +55 -0
- package/dist/channels/reserved-connections.js.map +1 -0
- package/dist/channels/resolve-user-endpoint.d.ts +34 -0
- package/dist/channels/resolve-user-endpoint.d.ts.map +1 -0
- package/dist/channels/resolve-user-endpoint.js +51 -0
- package/dist/channels/resolve-user-endpoint.js.map +1 -0
- package/dist/channels/resolve-user.d.ts +95 -0
- package/dist/channels/resolve-user.d.ts.map +1 -0
- package/dist/channels/resolve-user.js +143 -0
- package/dist/channels/resolve-user.js.map +1 -0
- package/dist/channels/run-input.d.ts +88 -0
- package/dist/channels/run-input.d.ts.map +1 -0
- package/dist/channels/run-input.js +177 -0
- package/dist/channels/run-input.js.map +1 -0
- package/dist/channels/runtime.d.ts +5 -2
- package/dist/channels/runtime.d.ts.map +1 -1
- package/dist/channels/runtime.js +19 -10
- package/dist/channels/runtime.js.map +1 -1
- package/dist/channels/schedule-delivery.d.ts +2 -13
- package/dist/channels/schedule-delivery.d.ts.map +1 -1
- package/dist/channels/schedule-delivery.js +6 -73
- package/dist/channels/schedule-delivery.js.map +1 -1
- package/dist/channels/slack/api.d.ts +2 -0
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +6 -0
- package/dist/channels/slack/api.js.map +1 -1
- package/dist/channels/slack/connections.d.ts +6 -0
- package/dist/channels/slack/connections.d.ts.map +1 -0
- package/dist/channels/slack/connections.js +6 -0
- package/dist/channels/slack/connections.js.map +1 -0
- package/dist/channels/slack/events.d.ts +278 -0
- package/dist/channels/slack/events.d.ts.map +1 -0
- package/dist/channels/slack/events.js +235 -0
- package/dist/channels/slack/events.js.map +1 -0
- package/dist/channels/slack/files.d.ts.map +1 -1
- package/dist/channels/slack/files.js +2 -3
- package/dist/channels/slack/files.js.map +1 -1
- package/dist/channels/slack/index.d.ts +90 -2
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +188 -6
- package/dist/channels/slack/index.js.map +1 -1
- package/dist/channels/slack/message-content.d.ts.map +1 -1
- package/dist/channels/slack/message-content.js +23 -28
- package/dist/channels/slack/message-content.js.map +1 -1
- package/dist/channels/slack/status.d.ts +76 -0
- package/dist/channels/slack/status.d.ts.map +1 -0
- package/dist/channels/slack/status.js +427 -0
- package/dist/channels/slack/status.js.map +1 -0
- package/dist/channels/source-providers.js +1 -1
- package/dist/channels/source-providers.js.map +1 -1
- package/dist/channels/trigger/client.d.ts.map +1 -1
- package/dist/channels/trigger/client.js +6 -9
- package/dist/channels/trigger/client.js.map +1 -1
- package/dist/channels/trigger/conversation.d.ts +11 -0
- package/dist/channels/trigger/conversation.d.ts.map +1 -0
- package/dist/channels/trigger/conversation.js +72 -0
- package/dist/channels/trigger/conversation.js.map +1 -0
- package/dist/channels/trigger/http.d.ts +130 -4
- package/dist/channels/trigger/http.d.ts.map +1 -1
- package/dist/channels/trigger/http.js +408 -78
- package/dist/channels/trigger/http.js.map +1 -1
- package/dist/channels/trigger/ingress.d.ts +70 -1
- package/dist/channels/trigger/ingress.d.ts.map +1 -1
- package/dist/channels/trigger/ingress.js +130 -19
- package/dist/channels/trigger/ingress.js.map +1 -1
- package/dist/channels/trigger/transport.d.ts +10 -0
- package/dist/channels/trigger/transport.d.ts.map +1 -1
- package/dist/channels/trigger/transport.js +25 -9
- package/dist/channels/trigger/transport.js.map +1 -1
- package/dist/channels/trigger/types.d.ts +92 -3
- package/dist/channels/trigger/types.d.ts.map +1 -1
- package/dist/channels/trigger/types.js +37 -0
- package/dist/channels/trigger/types.js.map +1 -1
- package/dist/channels/types.d.ts +53 -4
- package/dist/channels/types.d.ts.map +1 -1
- package/dist/channels/types.js +2 -0
- package/dist/channels/types.js.map +1 -1
- package/dist/connections.d.ts +35 -1
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +121 -10
- package/dist/connections.js.map +1 -1
- package/dist/credential-gate.d.ts +2 -0
- package/dist/credential-gate.d.ts.map +1 -1
- package/dist/credential-gate.js +37 -3
- package/dist/credential-gate.js.map +1 -1
- package/dist/define-deep-agent.d.ts +2 -2
- package/dist/define-deep-agent.d.ts.map +1 -1
- package/dist/define-deep-agent.js +53 -2
- package/dist/define-deep-agent.js.map +1 -1
- package/dist/identity/index.d.ts.map +1 -1
- package/dist/identity/index.js +3 -1
- package/dist/identity/index.js.map +1 -1
- package/dist/identity/options.d.ts +9 -0
- package/dist/identity/options.d.ts.map +1 -1
- package/dist/identity/options.js +1 -1
- package/dist/identity/options.js.map +1 -1
- package/dist/identity/types.d.ts +3 -0
- package/dist/identity/types.d.ts.map +1 -1
- package/dist/index.d.ts +19 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/ingress/loopback.d.ts +1 -0
- package/dist/ingress/loopback.d.ts.map +1 -1
- package/dist/ingress/loopback.js +4 -1
- package/dist/ingress/loopback.js.map +1 -1
- package/dist/ingress/runs.d.ts +74 -1
- package/dist/ingress/runs.d.ts.map +1 -1
- package/dist/ingress/runs.js +184 -9
- package/dist/ingress/runs.js.map +1 -1
- package/dist/managed-composition.d.ts +3 -0
- package/dist/managed-composition.d.ts.map +1 -1
- package/dist/managed-composition.js +29 -13
- package/dist/managed-composition.js.map +1 -1
- package/dist/namespaces.d.ts +25 -21
- package/dist/namespaces.d.ts.map +1 -1
- package/dist/namespaces.js +4 -29
- package/dist/namespaces.js.map +1 -1
- package/dist/runtime/async-subagents.d.ts +27 -0
- package/dist/runtime/async-subagents.d.ts.map +1 -0
- package/dist/runtime/async-subagents.js +139 -0
- package/dist/runtime/async-subagents.js.map +1 -0
- package/dist/runtime/auth.d.ts.map +1 -1
- package/dist/runtime/auth.js +177 -8
- package/dist/runtime/auth.js.map +1 -1
- package/dist/runtime/backend.d.ts +7 -0
- package/dist/runtime/backend.d.ts.map +1 -1
- package/dist/runtime/backend.js +32 -7
- package/dist/runtime/backend.js.map +1 -1
- package/dist/runtime/browser-facade.d.ts +10 -0
- package/dist/runtime/browser-facade.d.ts.map +1 -0
- package/dist/runtime/browser-facade.js +23 -0
- package/dist/runtime/browser-facade.js.map +1 -0
- package/dist/runtime/browser-langsmith.d.ts +143 -0
- package/dist/runtime/browser-langsmith.d.ts.map +1 -0
- package/dist/runtime/browser-langsmith.js +508 -0
- package/dist/runtime/browser-langsmith.js.map +1 -0
- package/dist/runtime/browser-recorder.py +831 -0
- package/dist/runtime/browser-selection.d.ts +10 -0
- package/dist/runtime/browser-selection.d.ts.map +1 -0
- package/dist/runtime/browser-selection.js +21 -0
- package/dist/runtime/browser-selection.js.map +1 -0
- package/dist/runtime/browser.d.ts +128 -0
- package/dist/runtime/browser.d.ts.map +1 -0
- package/dist/runtime/browser.js +795 -0
- package/dist/runtime/browser.js.map +1 -0
- package/dist/runtime/channel-icon.d.ts +22 -0
- package/dist/runtime/channel-icon.d.ts.map +1 -0
- package/dist/runtime/channel-icon.js +81 -0
- package/dist/runtime/channel-icon.js.map +1 -0
- package/dist/runtime/channel.d.ts +11 -0
- package/dist/runtime/channel.d.ts.map +1 -1
- package/dist/runtime/channel.js.map +1 -1
- package/dist/runtime/identity-http.d.ts +2 -0
- package/dist/runtime/identity-http.d.ts.map +1 -1
- package/dist/runtime/identity-http.js +38 -2
- package/dist/runtime/identity-http.js.map +1 -1
- package/dist/runtime/identity-runtime.d.ts +10 -0
- package/dist/runtime/identity-runtime.d.ts.map +1 -1
- package/dist/runtime/identity-runtime.js +22 -0
- package/dist/runtime/identity-runtime.js.map +1 -1
- package/dist/runtime/index.d.ts +38 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +76 -34
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/managed-thread.d.ts +61 -0
- package/dist/runtime/managed-thread.d.ts.map +1 -0
- package/dist/runtime/managed-thread.js +76 -0
- package/dist/runtime/managed-thread.js.map +1 -0
- package/dist/runtime/managed-tools.d.ts +10 -2
- package/dist/runtime/managed-tools.d.ts.map +1 -1
- package/dist/runtime/managed-tools.js +10 -8
- package/dist/runtime/managed-tools.js.map +1 -1
- package/dist/runtime/memory/policy.d.ts.map +1 -1
- package/dist/runtime/memory/policy.js +1 -3
- package/dist/runtime/memory/policy.js.map +1 -1
- package/dist/runtime/parent-run.d.ts +33 -0
- package/dist/runtime/parent-run.d.ts.map +1 -0
- package/dist/runtime/parent-run.js +114 -0
- package/dist/runtime/parent-run.js.map +1 -0
- package/dist/runtime/run-input.d.ts +14 -1
- package/dist/runtime/run-input.d.ts.map +1 -1
- package/dist/runtime/run-input.js +100 -7
- package/dist/runtime/run-input.js.map +1 -1
- package/dist/runtime/sandbox-manager.d.ts +15 -2
- package/dist/runtime/sandbox-manager.d.ts.map +1 -1
- package/dist/runtime/sandbox-manager.js +37 -12
- package/dist/runtime/sandbox-manager.js.map +1 -1
- package/dist/runtime/schedule-auth.d.ts +79 -0
- package/dist/runtime/schedule-auth.d.ts.map +1 -1
- package/dist/runtime/schedule-auth.js +163 -6
- package/dist/runtime/schedule-auth.js.map +1 -1
- package/dist/runtime/static-entry.d.ts.map +1 -1
- package/dist/runtime/static-entry.js +1 -0
- package/dist/runtime/static-entry.js.map +1 -1
- package/dist/runtime/thread-record.d.ts +88 -0
- package/dist/runtime/thread-record.d.ts.map +1 -0
- package/dist/runtime/thread-record.js +213 -0
- package/dist/runtime/thread-record.js.map +1 -0
- package/dist/runtime/types.d.ts +12 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime-schedules.d.ts +15 -0
- package/dist/runtime-schedules.d.ts.map +1 -1
- package/dist/runtime-schedules.js +83 -20
- package/dist/runtime-schedules.js.map +1 -1
- package/dist/sandbox.d.ts +0 -6
- package/dist/sandbox.d.ts.map +1 -1
- package/dist/sandbox.js +3 -7
- package/dist/sandbox.js.map +1 -1
- package/dist/schedule-channel.d.ts +5 -2
- package/dist/schedule-channel.d.ts.map +1 -1
- package/dist/schedule-channel.js +13 -12
- package/dist/schedule-channel.js.map +1 -1
- package/dist/types.d.ts +19 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/values.d.ts +15 -0
- package/dist/values.d.ts.map +1 -0
- package/dist/values.js +31 -0
- package/dist/values.js.map +1 -0
- package/package.json +23 -9
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { validateChannelIconPath } from "../../runtime/channel-icon.js";
|
|
2
|
+
import { definedFields, handledEventKeys } from "../http/provider.js";
|
|
3
|
+
/** The webhook resource type that delivers each event. */
|
|
4
|
+
const EVENT_RESOURCE_TYPES = {
|
|
5
|
+
"Issue.create": "Issue",
|
|
6
|
+
"Issue.update": "Issue",
|
|
7
|
+
"Comment.create": "Comment",
|
|
8
|
+
"AgentSessionEvent.created": "AgentSessionEvent",
|
|
9
|
+
"AgentSessionEvent.prompted": "AgentSessionEvent",
|
|
10
|
+
};
|
|
11
|
+
const SESSION_EVENTS = [
|
|
12
|
+
"AgentSessionEvent.created",
|
|
13
|
+
"AgentSessionEvent.prompted",
|
|
14
|
+
];
|
|
15
|
+
/** A revoked install, so the runtime can say why events stopped. */
|
|
16
|
+
const ALWAYS_SUBSCRIBED = ["OAuthAuthorization"];
|
|
17
|
+
/** Reading the workspace, and writing comments and agent activities. */
|
|
18
|
+
const BASE_SCOPES = ["read", "write"];
|
|
19
|
+
/** Mentioning the app and delegating issues to it, which open agent sessions. */
|
|
20
|
+
const SESSION_SCOPES = ["app:mentionable", "app:assignable"];
|
|
21
|
+
/**
|
|
22
|
+
* Scopes Linear can grant along with `write` without being asked. Agent Auth
|
|
23
|
+
* refuses a grant beyond the allowed scopes, so they are allowed.
|
|
24
|
+
*/
|
|
25
|
+
const IMPLIED_SCOPES = [
|
|
26
|
+
"customer:read",
|
|
27
|
+
"customer:write",
|
|
28
|
+
"initiative:read",
|
|
29
|
+
"initiative:write",
|
|
30
|
+
];
|
|
31
|
+
const APP_OPTIONS = ["name", "description", "icon", "teams"];
|
|
32
|
+
const MAX_TEAMS = 100;
|
|
33
|
+
const TEAM_KEY = /^[A-Za-z0-9]{1,16}$/;
|
|
34
|
+
/**
|
|
35
|
+
* The app the channel's handlers and options need. The CLI reads it from the
|
|
36
|
+
* channel's manifest instead of working it out; the Python runtime mirrors
|
|
37
|
+
* these rules in `linear_app_setup.py`.
|
|
38
|
+
*/
|
|
39
|
+
export function linearAppSetup(handlers, app, options) {
|
|
40
|
+
checkAppOptions(app);
|
|
41
|
+
const events = [
|
|
42
|
+
...new Set([
|
|
43
|
+
...handledEventKeys(handlers),
|
|
44
|
+
...(options.sessions ? SESSION_EVENTS : []),
|
|
45
|
+
]),
|
|
46
|
+
]
|
|
47
|
+
.filter(isLinearEventKey)
|
|
48
|
+
.sort();
|
|
49
|
+
// A session event handler answers sessions even with `sessions: false`.
|
|
50
|
+
const sessions = events.some((key) => SESSION_EVENTS.includes(key));
|
|
51
|
+
const scopes = sessions ? [...BASE_SCOPES, ...SESSION_SCOPES] : BASE_SCOPES;
|
|
52
|
+
return {
|
|
53
|
+
events,
|
|
54
|
+
sessions,
|
|
55
|
+
webhookResourceTypes: [
|
|
56
|
+
...new Set([
|
|
57
|
+
...ALWAYS_SUBSCRIBED,
|
|
58
|
+
...events.map((key) => EVENT_RESOURCE_TYPES[key]),
|
|
59
|
+
// A change to the app's team access changes which sessions reach it.
|
|
60
|
+
...(sessions ? ["PermissionChange"] : []),
|
|
61
|
+
]),
|
|
62
|
+
].sort(),
|
|
63
|
+
scopes,
|
|
64
|
+
allowedScopes: [...scopes, ...IMPLIED_SCOPES],
|
|
65
|
+
...(app && {
|
|
66
|
+
app: definedFields({
|
|
67
|
+
name: app.name?.trim(),
|
|
68
|
+
description: app.description?.trim(),
|
|
69
|
+
icon: app.icon && validateChannelIconPath(app.icon, "Linear app.icon"),
|
|
70
|
+
}),
|
|
71
|
+
}),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function isLinearEventKey(key) {
|
|
75
|
+
return Object.hasOwn(EVENT_RESOURCE_TYPES, key);
|
|
76
|
+
}
|
|
77
|
+
/** Check the app options against Linear's rules before deploy sends them. */
|
|
78
|
+
function checkAppOptions(app) {
|
|
79
|
+
if (!app)
|
|
80
|
+
return;
|
|
81
|
+
// A misspelled option would silently widen what starts runs.
|
|
82
|
+
const unknown = Object.keys(app).filter((key) => !APP_OPTIONS.includes(key));
|
|
83
|
+
if (unknown.length)
|
|
84
|
+
throw new TypeError(`unknown Linear app option ${unknown.join(", ")}; use ${APP_OPTIONS.join(", ")}`);
|
|
85
|
+
const name = app.name?.trim();
|
|
86
|
+
if (name !== undefined &&
|
|
87
|
+
(name.length < 2 || name.length > 80 || /linear|https?:\/\//i.test(name)))
|
|
88
|
+
throw new TypeError('Linear app.name must be 2-80 characters, without "Linear" or a URL');
|
|
89
|
+
const description = app.description?.trim();
|
|
90
|
+
if (description !== undefined && (!description || description.length > 1000))
|
|
91
|
+
throw new TypeError("Linear app.description must be 1-1000 characters");
|
|
92
|
+
if (app.teams === undefined)
|
|
93
|
+
return;
|
|
94
|
+
if (app.teams.length === 0)
|
|
95
|
+
throw new TypeError("Linear app.teams must list team keys; omit it to allow every team");
|
|
96
|
+
if (app.teams.length > MAX_TEAMS)
|
|
97
|
+
throw new TypeError(`Linear app.teams must list at most ${MAX_TEAMS} teams`);
|
|
98
|
+
for (const team of app.teams)
|
|
99
|
+
if (!TEAM_KEY.test(team.trim()))
|
|
100
|
+
throw new TypeError(`Linear app.teams has an invalid team key '${team.trim()}'; use keys such as ENG`);
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=app-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-setup.js","sourceRoot":"","sources":["../../../src/channels/linear/app-setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reserved agent connection for the deployment's Linear app: reading it
|
|
3
|
+
* returns the app's access token, which Agent Auth renews.
|
|
4
|
+
*/
|
|
5
|
+
export declare const LINEAR_TOKEN_SLUG = "mda/linear-token";
|
|
6
|
+
/**
|
|
7
|
+
* The deployment's Linear app connection, or one of the app values stored
|
|
8
|
+
* beside it (`webhook-secret`) when `suffix` is given.
|
|
9
|
+
*/
|
|
10
|
+
export declare function linearAppConnectionSlug(deploymentId: string, suffix?: string): string;
|
|
11
|
+
//# sourceMappingURL=connections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connections.d.ts","sourceRoot":"","sources":["../../../src/channels/linear/connections.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AAEpD;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CAER"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { appConnectionSlug } from "../http/provider.js";
|
|
2
|
+
/**
|
|
3
|
+
* Reserved agent connection for the deployment's Linear app: reading it
|
|
4
|
+
* returns the app's access token, which Agent Auth renews.
|
|
5
|
+
*/
|
|
6
|
+
export const LINEAR_TOKEN_SLUG = "mda/linear-token";
|
|
7
|
+
/**
|
|
8
|
+
* The deployment's Linear app connection, or one of the app values stored
|
|
9
|
+
* beside it (`webhook-secret`) when `suffix` is given.
|
|
10
|
+
*/
|
|
11
|
+
export function linearAppConnectionSlug(deploymentId, suffix) {
|
|
12
|
+
return appConnectionSlug("linear", deploymentId, suffix);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=connections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connections.js","sourceRoot":"","sources":["../../../src/channels/linear/connections.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AAEpD;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,YAAoB,EACpB,MAAe;IAEf,OAAO,iBAAiB,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Linear refused a request for exceeding its rate limit. */
|
|
3
|
+
export declare class LinearRateLimitError extends Error {
|
|
4
|
+
constructor();
|
|
5
|
+
}
|
|
6
|
+
/** Forget the cached app token; for tests. */
|
|
7
|
+
export declare function resetLinearToken(): void;
|
|
8
|
+
/**
|
|
9
|
+
* Run a GraphQL operation as the app. `query` is a constant; everything that
|
|
10
|
+
* varies goes in `variables`. A rejected token is read again once. Returns
|
|
11
|
+
* the response's `data`, checked against `schema`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function linearRequest<T>(query: string, variables: Record<string, unknown>, schema: z.ZodType<T>): Promise<T>;
|
|
14
|
+
/** The Linear user the app acts as. */
|
|
15
|
+
export type LinearAppUser = {
|
|
16
|
+
id: string;
|
|
17
|
+
displayName: string;
|
|
18
|
+
};
|
|
19
|
+
export declare function linearAppUser(): Promise<LinearAppUser>;
|
|
20
|
+
/** Forget the cached app user; for tests. */
|
|
21
|
+
export declare function resetLinearAppUser(): void;
|
|
22
|
+
/**
|
|
23
|
+
* Comment on an issue as the app, threaded under `parentId` when given.
|
|
24
|
+
* Returns the comment's id and URL.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createLinearComment(input: {
|
|
27
|
+
issueId: string;
|
|
28
|
+
body: string;
|
|
29
|
+
parentId?: string;
|
|
30
|
+
}): Promise<{
|
|
31
|
+
id: string;
|
|
32
|
+
url?: string;
|
|
33
|
+
}>;
|
|
34
|
+
/** Whether a comment belongs to an agent session's thread. */
|
|
35
|
+
export declare function commentInAgentSession(commentId: string): Promise<boolean>;
|
|
36
|
+
/** What the app says in an agent session. */
|
|
37
|
+
export type LinearActivityContent = {
|
|
38
|
+
type: "thought" | "response" | "error" | "elicitation";
|
|
39
|
+
body: string;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Post an activity to an agent session as the app. An `ephemeral` thought is
|
|
43
|
+
* replaced by the next activity.
|
|
44
|
+
*/
|
|
45
|
+
export declare function createLinearActivity(input: {
|
|
46
|
+
agentSessionId: string;
|
|
47
|
+
content: LinearActivityContent;
|
|
48
|
+
ephemeral?: boolean;
|
|
49
|
+
}): Promise<{
|
|
50
|
+
id: string;
|
|
51
|
+
}>;
|
|
52
|
+
/** Link an agent session to a page about it, such as its Studio thread. */
|
|
53
|
+
export declare function addLinearSessionUrl(agentSessionId: string, link: {
|
|
54
|
+
label: string;
|
|
55
|
+
url: string;
|
|
56
|
+
}): Promise<void>;
|
|
57
|
+
//# sourceMappingURL=graphql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql.d.ts","sourceRoot":"","sources":["../../../src/channels/linear/graphql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiCxB,6DAA6D;AAC7D,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,cAGC;CACF;AAQD,8CAA8C;AAC9C,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAWD;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CA4BZ;AAoBD,uCAAuC;AACvC,MAAM,MAAM,aAAa,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAahE,wBAAgB,aAAa,IAAI,OAAO,CAAC,aAAa,CAAC,CAEtD;AAED,6CAA6C;AAC7C,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAYD;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAKxC;AAWD,8DAA8D;AAC9D,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED,6CAA6C;AAC7C,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,aAAa,CAAC;IACvD,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAYF;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE;IAChD,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAS1B;AASD,2EAA2E;AAC3E,wBAAsB,mBAAmB,CACvC,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACnC,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { connections } from "../../connections.js";
|
|
3
|
+
import { CachedRead } from "../http/provider.js";
|
|
4
|
+
import { nonblankStringSchema } from "../message-schema.js";
|
|
5
|
+
import { LINEAR_TOKEN_SLUG } from "./connections.js";
|
|
6
|
+
const LINEAR_GRAPHQL_URL = "https://api.linear.app/graphql";
|
|
7
|
+
const LINEAR_API_TIMEOUT_MS = 10_000;
|
|
8
|
+
/** The largest Linear response body read. */
|
|
9
|
+
const LINEAR_RESPONSE_MAX_CHARS = 1_000_000;
|
|
10
|
+
/** How long the app token read from Agent Auth is reused. */
|
|
11
|
+
const TOKEN_TTL_MS = 5 * 60_000;
|
|
12
|
+
/**
|
|
13
|
+
* How long the app's user is reused. It changes only when the app is
|
|
14
|
+
* installed anew, which a long-lived process should notice too.
|
|
15
|
+
*/
|
|
16
|
+
const APP_USER_TTL_MS = 60 * 60_000;
|
|
17
|
+
/**
|
|
18
|
+
* Where GraphQL requests go: Linear's API, or under `mda dev`
|
|
19
|
+
* (`MDA_LOCAL_DEV=1`) the stand-in `MDA_LINEAR_API_URL` names, so local
|
|
20
|
+
* tests never reach Linear. A deployment always uses Linear's API.
|
|
21
|
+
*/
|
|
22
|
+
function graphqlUrl(env = process.env) {
|
|
23
|
+
const override = env.MDA_LINEAR_API_URL?.trim();
|
|
24
|
+
if (env.MDA_LOCAL_DEV !== "1" || !override)
|
|
25
|
+
return LINEAR_GRAPHQL_URL;
|
|
26
|
+
const url = new URL(override);
|
|
27
|
+
if (url.protocol !== "http:" && url.protocol !== "https:")
|
|
28
|
+
throw new TypeError("MDA_LINEAR_API_URL must be an http(s) URL");
|
|
29
|
+
return url.toString();
|
|
30
|
+
}
|
|
31
|
+
/** Linear refused a request for exceeding its rate limit. */
|
|
32
|
+
export class LinearRateLimitError extends Error {
|
|
33
|
+
constructor() {
|
|
34
|
+
super("Linear rate limit exceeded");
|
|
35
|
+
this.name = "LinearRateLimitError";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** The app's access token, read from Agent Auth at most every few minutes. */
|
|
39
|
+
const appToken = new CachedRead(() => connections.resolveDeploymentSecret(LINEAR_TOKEN_SLUG), () => TOKEN_TTL_MS);
|
|
40
|
+
/** Forget the cached app token; for tests. */
|
|
41
|
+
export function resetLinearToken() {
|
|
42
|
+
appToken.reset();
|
|
43
|
+
}
|
|
44
|
+
function errorCodes(body) {
|
|
45
|
+
return (body.errors ?? []).flatMap((error) => typeof error.extensions?.code === "string" ? [error.extensions.code] : []);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Run a GraphQL operation as the app. `query` is a constant; everything that
|
|
49
|
+
* varies goes in `variables`. A rejected token is read again once. Returns
|
|
50
|
+
* the response's `data`, checked against `schema`.
|
|
51
|
+
*/
|
|
52
|
+
export async function linearRequest(query, variables, schema) {
|
|
53
|
+
const send = async () => fetch(graphqlUrl(), {
|
|
54
|
+
method: "POST",
|
|
55
|
+
headers: {
|
|
56
|
+
Authorization: `Bearer ${await appToken.get()}`,
|
|
57
|
+
"Content-Type": "application/json",
|
|
58
|
+
},
|
|
59
|
+
body: JSON.stringify({ query, variables }),
|
|
60
|
+
signal: AbortSignal.timeout(LINEAR_API_TIMEOUT_MS),
|
|
61
|
+
});
|
|
62
|
+
let response = await send();
|
|
63
|
+
let body = await readBody(response);
|
|
64
|
+
if (response.status === 401 ||
|
|
65
|
+
errorCodes(body).includes("AUTHENTICATION_ERROR")) {
|
|
66
|
+
appToken.reset();
|
|
67
|
+
response = await send();
|
|
68
|
+
body = await readBody(response);
|
|
69
|
+
}
|
|
70
|
+
if (errorCodes(body).includes("RATELIMITED"))
|
|
71
|
+
throw new LinearRateLimitError();
|
|
72
|
+
if (!response.ok || body.errors?.length || body.data === undefined)
|
|
73
|
+
throw new Error(`Linear refused the request (HTTP ${response.status})`);
|
|
74
|
+
const data = schema.safeParse(body.data);
|
|
75
|
+
if (!data.success)
|
|
76
|
+
throw new Error("Linear answered in an unexpected shape");
|
|
77
|
+
return data.data;
|
|
78
|
+
}
|
|
79
|
+
async function readBody(response) {
|
|
80
|
+
const text = await response.text();
|
|
81
|
+
if (text.length > LINEAR_RESPONSE_MAX_CHARS)
|
|
82
|
+
return {};
|
|
83
|
+
try {
|
|
84
|
+
const parsed = JSON.parse(text);
|
|
85
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
86
|
+
? parsed
|
|
87
|
+
: {};
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return {};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const VIEWER_QUERY = "query MdaLinearViewer { viewer { id displayName } }";
|
|
94
|
+
const viewerSchema = z.object({
|
|
95
|
+
viewer: z.object({ id: nonblankStringSchema, displayName: z.string() }),
|
|
96
|
+
});
|
|
97
|
+
/**
|
|
98
|
+
* The Linear user the app acts as, read at most hourly: its own comments and
|
|
99
|
+
* changes are ignored, and a comment mentioning its `displayName` starts an
|
|
100
|
+
* agent session.
|
|
101
|
+
*/
|
|
102
|
+
const appUser = new CachedRead(async () => (await linearRequest(VIEWER_QUERY, {}, viewerSchema)).viewer, () => APP_USER_TTL_MS);
|
|
103
|
+
export function linearAppUser() {
|
|
104
|
+
return appUser.get();
|
|
105
|
+
}
|
|
106
|
+
/** Forget the cached app user; for tests. */
|
|
107
|
+
export function resetLinearAppUser() {
|
|
108
|
+
appUser.reset();
|
|
109
|
+
}
|
|
110
|
+
const COMMENT_CREATE_MUTATION = `mutation MdaLinearCommentCreate($input: CommentCreateInput!) {
|
|
111
|
+
commentCreate(input: $input) { success comment { id url } }
|
|
112
|
+
}`;
|
|
113
|
+
const commentCreateSchema = z.object({
|
|
114
|
+
commentCreate: z.object({
|
|
115
|
+
success: z.literal(true),
|
|
116
|
+
comment: z.object({ id: nonblankStringSchema, url: z.string().nullish() }),
|
|
117
|
+
}),
|
|
118
|
+
});
|
|
119
|
+
/**
|
|
120
|
+
* Comment on an issue as the app, threaded under `parentId` when given.
|
|
121
|
+
* Returns the comment's id and URL.
|
|
122
|
+
*/
|
|
123
|
+
export async function createLinearComment(input) {
|
|
124
|
+
const { comment } = (await linearRequest(COMMENT_CREATE_MUTATION, { input }, commentCreateSchema)).commentCreate;
|
|
125
|
+
return { id: comment.id, ...(comment.url && { url: comment.url }) };
|
|
126
|
+
}
|
|
127
|
+
const COMMENT_SESSION_QUERY = `query MdaLinearCommentSession($id: String!) {
|
|
128
|
+
comment(id: $id) { agentSession { id } }
|
|
129
|
+
}`;
|
|
130
|
+
const commentSessionSchema = z.object({
|
|
131
|
+
comment: z
|
|
132
|
+
.object({ agentSession: z.object({ id: nonblankStringSchema }).nullable() })
|
|
133
|
+
.nullable(),
|
|
134
|
+
});
|
|
135
|
+
/** Whether a comment belongs to an agent session's thread. */
|
|
136
|
+
export async function commentInAgentSession(commentId) {
|
|
137
|
+
const { comment } = await linearRequest(COMMENT_SESSION_QUERY, { id: commentId }, commentSessionSchema);
|
|
138
|
+
return Boolean(comment?.agentSession);
|
|
139
|
+
}
|
|
140
|
+
const ACTIVITY_CREATE_MUTATION = `mutation MdaLinearActivityCreate($input: AgentActivityCreateInput!) {
|
|
141
|
+
agentActivityCreate(input: $input) { success agentActivity { id } }
|
|
142
|
+
}`;
|
|
143
|
+
const activityCreateSchema = z.object({
|
|
144
|
+
agentActivityCreate: z.object({
|
|
145
|
+
success: z.literal(true),
|
|
146
|
+
agentActivity: z.object({ id: nonblankStringSchema }),
|
|
147
|
+
}),
|
|
148
|
+
});
|
|
149
|
+
/**
|
|
150
|
+
* Post an activity to an agent session as the app. An `ephemeral` thought is
|
|
151
|
+
* replaced by the next activity.
|
|
152
|
+
*/
|
|
153
|
+
export async function createLinearActivity(input) {
|
|
154
|
+
const { agentActivity } = (await linearRequest(ACTIVITY_CREATE_MUTATION, { input }, activityCreateSchema)).agentActivityCreate;
|
|
155
|
+
return { id: agentActivity.id };
|
|
156
|
+
}
|
|
157
|
+
const SESSION_UPDATE_MUTATION = `mutation MdaLinearSessionUpdate($id: String!, $input: AgentSessionUpdateInput!) {
|
|
158
|
+
agentSessionUpdate(id: $id, input: $input) { success }
|
|
159
|
+
}`;
|
|
160
|
+
const sessionUpdateSchema = z.object({
|
|
161
|
+
agentSessionUpdate: z.object({ success: z.literal(true) }),
|
|
162
|
+
});
|
|
163
|
+
/** Link an agent session to a page about it, such as its Studio thread. */
|
|
164
|
+
export async function addLinearSessionUrl(agentSessionId, link) {
|
|
165
|
+
await linearRequest(SESSION_UPDATE_MUTATION, { id: agentSessionId, input: { addedExternalUrls: [link] } }, sessionUpdateSchema);
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=graphql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../../src/channels/linear/graphql.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type HttpChannel } from "../http/index.js";
|
|
2
|
+
import type { LinearChannelOptions } from "./types.js";
|
|
3
|
+
export type { LinearAppOptions, LinearChannelOptions, LinearChannelThread, LinearEvent, LinearEventCallback, LinearEventKey, LinearEventResult, LinearPayloadFor, } from "./types.js";
|
|
4
|
+
export { LinearRateLimitError } from "./graphql.js";
|
|
5
|
+
/**
|
|
6
|
+
* Adapt verified Linear webhooks into HTTP channel messages or skips.
|
|
7
|
+
*
|
|
8
|
+
* @experimental The Linear channel may change in a minor release.
|
|
9
|
+
*/
|
|
10
|
+
export declare function linearChannel(options?: LinearChannelOptions): HttpChannel;
|
|
11
|
+
/** Forget the cached webhook secret; for tests. */
|
|
12
|
+
export declare function resetLinearWebhookSecret(): void;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/channels/linear/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,WAAW,EAOjB,MAAM,kBAAkB,CAAC;AA2C1B,OAAO,KAAK,EACV,oBAAoB,EAIrB,MAAM,YAAY,CAAC;AAIpB,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAwBpD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,WAAW,CAuD7E;AAgBD,mDAAmD;AACnD,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C"}
|