@vess-id/ai-identity 0.17.0 → 0.19.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/index.d.mts +8740 -106
- package/dist/index.js +2129 -477
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2129 -477
- package/dist/index.mjs.map +1 -1
- package/dist/registry/action-registry-json.d.ts +8710 -106
- package/dist/registry/action-registry-json.d.ts.map +1 -1
- package/dist/registry/action-registry.d.ts.map +1 -1
- package/dist/registry/action-summary.d.ts +2 -0
- package/dist/registry/action-summary.d.ts.map +1 -1
- package/dist/types/connector-plugin.d.ts +15 -0
- package/dist/types/connector-plugin.d.ts.map +1 -1
- package/dist/types/permission-vc.d.ts +13 -0
- package/dist/types/permission-vc.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4184,7 +4184,7 @@ function validateRegistryObject(registry) {
|
|
|
4184
4184
|
for (const a of typed.actions) {
|
|
4185
4185
|
if (a.input_schema) {
|
|
4186
4186
|
try {
|
|
4187
|
-
const local = new import_ajv.default({ strict: true, allErrors: true });
|
|
4187
|
+
const local = new import_ajv.default({ strict: true, allErrors: true, allowUnionTypes: true });
|
|
4188
4188
|
(0, import_ajv_formats.default)(local);
|
|
4189
4189
|
const compiled = local.compile(a.input_schema);
|
|
4190
4190
|
if (compiled.errors?.length) {
|
|
@@ -7750,472 +7750,1513 @@ var ACTION_REGISTRY = {
|
|
|
7750
7750
|
target_bindings: { resource_id: { source: "param", param: "portalId" } },
|
|
7751
7751
|
version: "1.0.0"
|
|
7752
7752
|
},
|
|
7753
|
-
// ───
|
|
7754
|
-
// Inbox actions back the Agent Inbox MCP tools (task delegation between
|
|
7755
|
-
// agents/people). They are internal (no external OAuth provider), so they
|
|
7756
|
-
// carry a single nominal base scope `inbox` to satisfy the registry
|
|
7757
|
-
// meta-schema's `minItems: 1` (same pattern as hubspot.account.link.get).
|
|
7753
|
+
// ─── Linear Actions ───
|
|
7758
7754
|
{
|
|
7759
|
-
action: "
|
|
7760
|
-
resource_type: "
|
|
7761
|
-
required_relations: ["editor", "
|
|
7762
|
-
required_scopes: ["
|
|
7763
|
-
capability: "
|
|
7755
|
+
action: "linear.issue.list",
|
|
7756
|
+
resource_type: "linear:issue",
|
|
7757
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
7758
|
+
required_scopes: ["read"],
|
|
7759
|
+
capability: "linear.read.basic",
|
|
7764
7760
|
input_schema: {
|
|
7765
7761
|
type: "object",
|
|
7766
7762
|
properties: {
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7763
|
+
teamId: { type: "string", description: "Filter by team ID" },
|
|
7764
|
+
assigneeId: { type: "string", description: "Filter by assignee user ID" },
|
|
7765
|
+
assigneeMe: { type: "boolean", description: "If true, filter issues assigned to the authenticated user" },
|
|
7766
|
+
stateId: { type: "string", description: "Filter by workflow state ID" },
|
|
7767
|
+
priority: { type: "number", minimum: 0, maximum: 4, description: "0=No priority, 1=Urgent, 2=High, 3=Medium, 4=Low" },
|
|
7768
|
+
limit: { type: "number", minimum: 1, maximum: 250, description: "Max number of issues to return (default 50)" }
|
|
7771
7769
|
},
|
|
7772
|
-
required: ["to", "taskType", "payload"],
|
|
7773
7770
|
additionalProperties: false
|
|
7774
7771
|
},
|
|
7775
|
-
constraints: { rate_bucket: "
|
|
7776
|
-
effects: ["
|
|
7777
|
-
risk: "
|
|
7772
|
+
constraints: { rate_bucket: "linear.read" },
|
|
7773
|
+
effects: ["Read:IssueList"],
|
|
7774
|
+
risk: "low",
|
|
7778
7775
|
target_bindings: {
|
|
7779
|
-
resource_id: { source: "param", param: "
|
|
7776
|
+
resource_id: { source: "param", param: "teamId", required: false }
|
|
7780
7777
|
},
|
|
7781
7778
|
version: "1.0.0"
|
|
7782
7779
|
},
|
|
7783
7780
|
{
|
|
7784
|
-
action: "
|
|
7785
|
-
resource_type: "
|
|
7786
|
-
required_relations: ["editor", "
|
|
7787
|
-
required_scopes: ["
|
|
7788
|
-
capability: "
|
|
7781
|
+
action: "linear.issue.read",
|
|
7782
|
+
resource_type: "linear:issue",
|
|
7783
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
7784
|
+
required_scopes: ["read"],
|
|
7785
|
+
capability: "linear.read.basic",
|
|
7789
7786
|
input_schema: {
|
|
7790
7787
|
type: "object",
|
|
7791
7788
|
properties: {
|
|
7792
|
-
|
|
7793
|
-
action: { type: "string", enum: ["accept", "decline", "counter"], description: "Response action" },
|
|
7794
|
-
data: { type: "object", description: "Optional response data (e.g. counter-proposal)" }
|
|
7789
|
+
issueId: { type: "string", minLength: 1, description: "Issue ID or identifier (e.g. ENG-123)" }
|
|
7795
7790
|
},
|
|
7796
|
-
required: ["
|
|
7791
|
+
required: ["issueId"],
|
|
7797
7792
|
additionalProperties: false
|
|
7798
7793
|
},
|
|
7799
|
-
constraints: { rate_bucket: "
|
|
7800
|
-
effects: ["
|
|
7801
|
-
|
|
7802
|
-
// go through human approval — the Phase 1 "always confirm" guarantee made
|
|
7803
|
-
// enforceable. target_bindings below binds the concrete inbox item id so
|
|
7804
|
-
// the high-risk approval has a specific resource constraint (the public
|
|
7805
|
-
// /scheduling/:token link flow does NOT go through this gate — it calls
|
|
7806
|
-
// InboxService.respond directly, system-key-signed).
|
|
7807
|
-
risk: "high",
|
|
7794
|
+
constraints: { rate_bucket: "linear.read" },
|
|
7795
|
+
effects: ["Read:Issue"],
|
|
7796
|
+
risk: "low",
|
|
7808
7797
|
target_bindings: {
|
|
7809
|
-
resource_id: { source: "param", param: "
|
|
7798
|
+
resource_id: { source: "param", param: "issueId" }
|
|
7810
7799
|
},
|
|
7811
7800
|
version: "1.0.0"
|
|
7812
7801
|
},
|
|
7813
7802
|
{
|
|
7814
|
-
action: "
|
|
7815
|
-
resource_type: "
|
|
7803
|
+
action: "linear.issue.search",
|
|
7804
|
+
resource_type: "linear:issue",
|
|
7816
7805
|
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
7817
|
-
required_scopes: ["
|
|
7818
|
-
capability: "
|
|
7806
|
+
required_scopes: ["read"],
|
|
7807
|
+
capability: "linear.read.basic",
|
|
7819
7808
|
input_schema: {
|
|
7820
7809
|
type: "object",
|
|
7821
7810
|
properties: {
|
|
7822
|
-
|
|
7823
|
-
|
|
7811
|
+
query: { type: "string", minLength: 1, description: "Full-text search query" },
|
|
7812
|
+
teamId: { type: "string", description: "Restrict search to a specific team" },
|
|
7813
|
+
limit: { type: "number", minimum: 1, maximum: 250, description: "Max number of results (default 50)" }
|
|
7824
7814
|
},
|
|
7815
|
+
required: ["query"],
|
|
7825
7816
|
additionalProperties: false
|
|
7826
7817
|
},
|
|
7827
|
-
constraints: { rate_bucket: "
|
|
7828
|
-
effects: ["Read:
|
|
7818
|
+
constraints: { rate_bucket: "linear.read" },
|
|
7819
|
+
effects: ["Read:IssueList"],
|
|
7829
7820
|
risk: "low",
|
|
7830
7821
|
target_bindings: {
|
|
7831
|
-
resource_id: { source: "param", param: "
|
|
7822
|
+
resource_id: { source: "param", param: "teamId", required: false }
|
|
7832
7823
|
},
|
|
7833
7824
|
version: "1.0.0"
|
|
7834
7825
|
},
|
|
7835
7826
|
{
|
|
7836
|
-
action: "
|
|
7837
|
-
resource_type: "
|
|
7838
|
-
required_relations: ["
|
|
7839
|
-
required_scopes: ["
|
|
7840
|
-
capability: "
|
|
7827
|
+
action: "linear.issue.create",
|
|
7828
|
+
resource_type: "linear:issue",
|
|
7829
|
+
required_relations: ["editor", "act_as"],
|
|
7830
|
+
required_scopes: ["issues:create"],
|
|
7831
|
+
capability: "linear.write.basic",
|
|
7841
7832
|
input_schema: {
|
|
7842
7833
|
type: "object",
|
|
7843
7834
|
properties: {
|
|
7844
|
-
|
|
7835
|
+
teamId: { type: "string", minLength: 1, description: "Team ID to create the issue in" },
|
|
7836
|
+
title: { type: "string", minLength: 1, description: "Issue title" },
|
|
7837
|
+
description: { type: "string", description: "Issue description (Markdown)" },
|
|
7838
|
+
assigneeId: { type: "string", description: "Assignee user ID" },
|
|
7839
|
+
stateId: { type: "string", description: "Workflow state ID" },
|
|
7840
|
+
priority: { type: "number", minimum: 0, maximum: 4, description: "0=No priority, 1=Urgent, 2=High, 3=Medium, 4=Low" },
|
|
7841
|
+
labelIds: { type: "array", items: { type: "string" }, description: "Label IDs to attach" }
|
|
7845
7842
|
},
|
|
7846
|
-
required: ["
|
|
7843
|
+
required: ["teamId", "title"],
|
|
7847
7844
|
additionalProperties: false
|
|
7848
7845
|
},
|
|
7849
|
-
constraints: { rate_bucket: "
|
|
7850
|
-
effects: ["
|
|
7851
|
-
risk: "
|
|
7846
|
+
constraints: { rate_bucket: "linear.write" },
|
|
7847
|
+
effects: ["Create:Issue"],
|
|
7848
|
+
risk: "high",
|
|
7852
7849
|
target_bindings: {
|
|
7853
|
-
resource_id: { source: "param", param: "
|
|
7850
|
+
resource_id: { source: "param", param: "teamId" }
|
|
7854
7851
|
},
|
|
7855
7852
|
version: "1.0.0"
|
|
7856
7853
|
},
|
|
7857
7854
|
{
|
|
7858
|
-
action: "
|
|
7859
|
-
resource_type: "
|
|
7855
|
+
action: "linear.issue.update",
|
|
7856
|
+
resource_type: "linear:issue",
|
|
7860
7857
|
required_relations: ["editor", "act_as"],
|
|
7861
|
-
required_scopes: ["
|
|
7862
|
-
capability: "
|
|
7858
|
+
required_scopes: ["write"],
|
|
7859
|
+
capability: "linear.write.basic",
|
|
7863
7860
|
input_schema: {
|
|
7864
7861
|
type: "object",
|
|
7865
7862
|
properties: {
|
|
7866
|
-
|
|
7867
|
-
|
|
7863
|
+
issueId: { type: "string", minLength: 1, description: "Issue ID or identifier (e.g. ENG-123)" },
|
|
7864
|
+
title: { type: "string", description: "New title" },
|
|
7865
|
+
description: { type: "string", description: "New description (Markdown)" },
|
|
7866
|
+
assigneeId: { type: "string", description: "Assignee user ID (null to unassign)" },
|
|
7867
|
+
stateId: { type: "string", description: "Workflow state ID" },
|
|
7868
|
+
priority: { type: "number", minimum: 0, maximum: 4, description: "0=No priority, 1=Urgent, 2=High, 3=Medium, 4=Low" },
|
|
7869
|
+
labelIds: { type: "array", items: { type: "string" }, description: "New set of label IDs" }
|
|
7868
7870
|
},
|
|
7869
|
-
required: ["
|
|
7871
|
+
required: ["issueId"],
|
|
7870
7872
|
additionalProperties: false
|
|
7871
7873
|
},
|
|
7872
|
-
constraints: { rate_bucket: "
|
|
7873
|
-
effects: ["Update:
|
|
7874
|
-
risk: "
|
|
7874
|
+
constraints: { rate_bucket: "linear.write" },
|
|
7875
|
+
effects: ["Update:Issue"],
|
|
7876
|
+
risk: "high",
|
|
7875
7877
|
target_bindings: {
|
|
7876
|
-
resource_id: { source: "param", param: "
|
|
7878
|
+
resource_id: { source: "param", param: "issueId" }
|
|
7877
7879
|
},
|
|
7878
7880
|
version: "1.0.0"
|
|
7879
7881
|
},
|
|
7880
|
-
// ─── Scheduling Actions (internal) ───
|
|
7881
|
-
// scheduling.request is a meeting-time negotiation façade over inbox.send.
|
|
7882
|
-
// Candidate slots may be supplied two ways (server-side EXCLUSIVE — exactly
|
|
7883
|
-
// one): (a) `candidates` — the agent computes them LLM-side from the user
|
|
7884
|
-
// calendar and the server validates + freebusy-filters them, or (b)
|
|
7885
|
-
// `candidateWindow` — the agent hands the server a { start, end } window and
|
|
7886
|
-
// the server generates busy-free candidates from the sender's Google
|
|
7887
|
-
// Calendar. Like the inbox actions it is internal (no external OAuth
|
|
7888
|
-
// provider), so it carries the single nominal base scope `inbox`.
|
|
7889
|
-
//
|
|
7890
|
-
// NOTE: the candidates/candidateWindow exclusivity is expressed here as
|
|
7891
|
-
// `oneOf` for documentation + the deep JSON-Schema authorities, but the SDK's
|
|
7892
|
-
// hand-written `validateActionInput` is a SHALLOW shape gate that does NOT
|
|
7893
|
-
// interpret `oneOf` (neither key is in top-level `required`). The exclusivity
|
|
7894
|
-
// (exactly one of candidates/candidateWindow) is ENFORCED server-side in
|
|
7895
|
-
// SchedulingRequestService — see that service for the 400s on both-given /
|
|
7896
|
-
// both-missing.
|
|
7897
|
-
// Spec: docs/specs/2026-06-10-inbox-intent-routing-design.md §2.1
|
|
7898
7882
|
{
|
|
7899
|
-
action: "
|
|
7900
|
-
resource_type: "
|
|
7883
|
+
action: "linear.comment.create",
|
|
7884
|
+
resource_type: "linear:comment",
|
|
7901
7885
|
required_relations: ["editor", "act_as"],
|
|
7902
|
-
required_scopes: ["
|
|
7903
|
-
capability: "
|
|
7886
|
+
required_scopes: ["comments:create"],
|
|
7887
|
+
capability: "linear.write.basic",
|
|
7904
7888
|
input_schema: {
|
|
7905
7889
|
type: "object",
|
|
7906
7890
|
properties: {
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
durationMinutes: { type: "integer", minimum: 5, maximum: 480, description: "Meeting length in minutes" },
|
|
7910
|
-
candidates: {
|
|
7911
|
-
type: "array",
|
|
7912
|
-
minItems: 1,
|
|
7913
|
-
maxItems: 10,
|
|
7914
|
-
description: "Explicit candidate slots computed by the agent from the user calendar. The server validates them AND (when Google Calendar is connected) filters out any that conflict with the sender's calendar. Mutually exclusive with candidateWindow \u2014 supply exactly one.",
|
|
7915
|
-
items: {
|
|
7916
|
-
type: "object",
|
|
7917
|
-
properties: {
|
|
7918
|
-
start: { type: "string", description: "ISO 8601 start" },
|
|
7919
|
-
end: { type: "string", description: "ISO 8601 end" }
|
|
7920
|
-
},
|
|
7921
|
-
required: ["start", "end"],
|
|
7922
|
-
additionalProperties: false
|
|
7923
|
-
}
|
|
7924
|
-
},
|
|
7925
|
-
candidateWindow: {
|
|
7926
|
-
type: "object",
|
|
7927
|
-
description: "A { start, end } search window (ISO 8601, span \u2264 62 days). The server generates busy-free candidate slots from the sender's Google Calendar within it. Mutually exclusive with candidates \u2014 supply exactly one. Requires a connected Google Calendar.",
|
|
7928
|
-
properties: {
|
|
7929
|
-
start: { type: "string", description: "ISO 8601 window start" },
|
|
7930
|
-
end: { type: "string", description: "ISO 8601 window end" }
|
|
7931
|
-
},
|
|
7932
|
-
required: ["start", "end"],
|
|
7933
|
-
additionalProperties: false
|
|
7934
|
-
},
|
|
7935
|
-
hold: {
|
|
7936
|
-
type: "boolean",
|
|
7937
|
-
description: "When true (or omitted, when the sender's delegation policy has holds enabled), tentatively hold the offered slots on the sender's calendar as [\u4EEE] events until the counterpart responds or the request expires. Pass false to skip holds for this request. Only takes effect when the sender has an enabled scheduling delegation policy."
|
|
7938
|
-
},
|
|
7939
|
-
message: { type: "string", description: "Optional human-readable message" }
|
|
7891
|
+
issueId: { type: "string", minLength: 1, description: "Issue ID to comment on" },
|
|
7892
|
+
body: { type: "string", minLength: 1, description: "Comment body (Markdown)" }
|
|
7940
7893
|
},
|
|
7941
|
-
|
|
7942
|
-
// exclusive-choice is documented via `oneOf` and enforced server-side.
|
|
7943
|
-
// Each oneOf branch re-declares its property locally (empty `properties`
|
|
7944
|
-
// entry) so AJV strict mode (`strictRequired`) sees the required key as
|
|
7945
|
-
// defined within the branch scope — the value shape itself is validated
|
|
7946
|
-
// by the top-level `properties` above.
|
|
7947
|
-
required: ["to", "topic", "durationMinutes"],
|
|
7948
|
-
oneOf: [
|
|
7949
|
-
{ required: ["candidates"], properties: { candidates: {} } },
|
|
7950
|
-
{ required: ["candidateWindow"], properties: { candidateWindow: {} } }
|
|
7951
|
-
],
|
|
7894
|
+
required: ["issueId", "body"],
|
|
7952
7895
|
additionalProperties: false
|
|
7953
7896
|
},
|
|
7954
|
-
constraints: { rate_bucket: "
|
|
7955
|
-
effects: ["Create:
|
|
7897
|
+
constraints: { rate_bucket: "linear.write" },
|
|
7898
|
+
effects: ["Create:Comment"],
|
|
7956
7899
|
risk: "high",
|
|
7957
7900
|
target_bindings: {
|
|
7958
|
-
resource_id: { source: "param", param: "
|
|
7901
|
+
resource_id: { source: "param", param: "issueId" }
|
|
7959
7902
|
},
|
|
7960
7903
|
version: "1.0.0"
|
|
7961
|
-
}
|
|
7962
|
-
],
|
|
7963
|
-
capabilities: [
|
|
7964
|
-
{
|
|
7965
|
-
capability: "slack.messaging.basic",
|
|
7966
|
-
description: "Post, update, and delete messages in channels",
|
|
7967
|
-
includes: ["slack.message.post", "slack.message.update", "slack.message.delete"],
|
|
7968
|
-
version: "1.0.0"
|
|
7969
|
-
},
|
|
7970
|
-
{
|
|
7971
|
-
capability: "slack.read.basic",
|
|
7972
|
-
description: "Read channels, messages, and user info",
|
|
7973
|
-
includes: ["slack.channel.read", "slack.user.read", "slack.message.read", "slack.message.read_paginated", "slack.batch.read"],
|
|
7974
|
-
version: "1.0.0"
|
|
7975
7904
|
},
|
|
7976
7905
|
{
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7906
|
+
action: "linear.comment.list",
|
|
7907
|
+
resource_type: "linear:comment",
|
|
7908
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
7909
|
+
required_scopes: ["read"],
|
|
7910
|
+
capability: "linear.read.basic",
|
|
7911
|
+
input_schema: {
|
|
7912
|
+
type: "object",
|
|
7913
|
+
properties: {
|
|
7914
|
+
issueId: { type: "string", minLength: 1, description: "Issue ID to list comments for" },
|
|
7915
|
+
limit: { type: "number", minimum: 1, maximum: 250, description: "Max number of comments (default 50)" }
|
|
7916
|
+
},
|
|
7917
|
+
required: ["issueId"],
|
|
7918
|
+
additionalProperties: false
|
|
7919
|
+
},
|
|
7920
|
+
constraints: { rate_bucket: "linear.read" },
|
|
7921
|
+
effects: ["Read:CommentList"],
|
|
7922
|
+
risk: "low",
|
|
7923
|
+
target_bindings: {
|
|
7924
|
+
resource_id: { source: "param", param: "issueId" }
|
|
7925
|
+
},
|
|
7980
7926
|
version: "1.0.0"
|
|
7981
7927
|
},
|
|
7982
7928
|
{
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
|
|
7929
|
+
action: "linear.project.list",
|
|
7930
|
+
resource_type: "linear:project",
|
|
7931
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
7932
|
+
required_scopes: ["read"],
|
|
7933
|
+
capability: "linear.read.basic",
|
|
7934
|
+
input_schema: {
|
|
7935
|
+
type: "object",
|
|
7936
|
+
properties: {
|
|
7937
|
+
teamId: { type: "string", description: "Filter by team ID" },
|
|
7938
|
+
limit: { type: "number", minimum: 1, maximum: 250, description: "Max number of projects (default 50)" }
|
|
7939
|
+
},
|
|
7940
|
+
additionalProperties: false
|
|
7941
|
+
},
|
|
7942
|
+
constraints: { rate_bucket: "linear.read" },
|
|
7943
|
+
effects: ["Read:ProjectList"],
|
|
7944
|
+
risk: "low",
|
|
7945
|
+
target_bindings: {
|
|
7946
|
+
resource_id: { source: "param", param: "teamId", required: false }
|
|
7947
|
+
},
|
|
7986
7948
|
version: "1.0.0"
|
|
7987
7949
|
},
|
|
7988
7950
|
{
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
7951
|
+
action: "linear.project.read",
|
|
7952
|
+
resource_type: "linear:project",
|
|
7953
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
7954
|
+
required_scopes: ["read"],
|
|
7955
|
+
capability: "linear.read.basic",
|
|
7956
|
+
input_schema: {
|
|
7957
|
+
type: "object",
|
|
7958
|
+
properties: {
|
|
7959
|
+
projectId: { type: "string", minLength: 1, description: "Project ID" }
|
|
7960
|
+
},
|
|
7961
|
+
required: ["projectId"],
|
|
7962
|
+
additionalProperties: false
|
|
7963
|
+
},
|
|
7964
|
+
constraints: { rate_bucket: "linear.read" },
|
|
7965
|
+
effects: ["Read:Project"],
|
|
7966
|
+
risk: "low",
|
|
7967
|
+
target_bindings: {
|
|
7968
|
+
resource_id: { source: "param", param: "projectId" }
|
|
7969
|
+
},
|
|
7992
7970
|
version: "1.0.0"
|
|
7993
7971
|
},
|
|
7994
7972
|
{
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
7973
|
+
action: "linear.team.list",
|
|
7974
|
+
resource_type: "linear:team",
|
|
7975
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
7976
|
+
required_scopes: ["read"],
|
|
7977
|
+
capability: "linear.read.basic",
|
|
7978
|
+
input_schema: {
|
|
7979
|
+
type: "object",
|
|
7980
|
+
properties: {
|
|
7981
|
+
limit: { type: "number", minimum: 1, maximum: 250, description: "Max number of teams (default 50)" }
|
|
7982
|
+
},
|
|
7983
|
+
additionalProperties: false
|
|
7984
|
+
},
|
|
7985
|
+
constraints: { rate_bucket: "linear.read" },
|
|
7986
|
+
effects: ["Read:TeamList"],
|
|
7987
|
+
risk: "low",
|
|
7988
|
+
// No teamId parameter: this action lists ALL accessible teams — intentionally
|
|
7989
|
+
// not scoped to a single team. required:false signals that missing resource
|
|
7990
|
+
// binding is expected (not an omission), consistent with slack.channel.read.
|
|
7991
|
+
target_bindings: {
|
|
7992
|
+
resource_id: { source: "param", param: "teamId", required: false }
|
|
7993
|
+
},
|
|
7998
7994
|
version: "1.0.0"
|
|
7999
7995
|
},
|
|
8000
7996
|
{
|
|
8001
|
-
|
|
8002
|
-
|
|
8003
|
-
|
|
7997
|
+
action: "linear.workflowState.list",
|
|
7998
|
+
resource_type: "linear:workflowState",
|
|
7999
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
8000
|
+
required_scopes: ["read"],
|
|
8001
|
+
capability: "linear.read.basic",
|
|
8002
|
+
input_schema: {
|
|
8003
|
+
type: "object",
|
|
8004
|
+
properties: {
|
|
8005
|
+
teamId: { type: "string", description: "Filter by team ID" },
|
|
8006
|
+
limit: { type: "number", minimum: 1, maximum: 250, description: "Max number of workflow states to return (default 50)" }
|
|
8007
|
+
},
|
|
8008
|
+
additionalProperties: false
|
|
8009
|
+
},
|
|
8010
|
+
constraints: { rate_bucket: "linear.read" },
|
|
8011
|
+
effects: ["Read:WorkflowStateList"],
|
|
8012
|
+
risk: "low",
|
|
8013
|
+
target_bindings: {
|
|
8014
|
+
resource_id: { source: "param", param: "teamId", required: false }
|
|
8015
|
+
},
|
|
8004
8016
|
version: "1.0.0"
|
|
8005
8017
|
},
|
|
8006
8018
|
{
|
|
8007
|
-
|
|
8008
|
-
|
|
8009
|
-
|
|
8019
|
+
action: "linear.viewer.read",
|
|
8020
|
+
resource_type: "linear:viewer",
|
|
8021
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
8022
|
+
required_scopes: ["read"],
|
|
8023
|
+
capability: "linear.read.basic",
|
|
8024
|
+
input_schema: {
|
|
8025
|
+
type: "object",
|
|
8026
|
+
properties: {},
|
|
8027
|
+
additionalProperties: false
|
|
8028
|
+
},
|
|
8029
|
+
constraints: { rate_bucket: "linear.read" },
|
|
8030
|
+
effects: ["Read:Viewer"],
|
|
8031
|
+
risk: "low",
|
|
8032
|
+
// No parameters: this action reads the currently authenticated user — there is
|
|
8033
|
+
// no resource to scope to. required:false signals intentional exemption, not
|
|
8034
|
+
// omission, consistent with the slack.channel.read precedent.
|
|
8035
|
+
target_bindings: {
|
|
8036
|
+
resource_id: { source: "param", param: "viewerId", required: false }
|
|
8037
|
+
},
|
|
8010
8038
|
version: "1.0.0"
|
|
8011
8039
|
},
|
|
8012
8040
|
{
|
|
8013
|
-
|
|
8014
|
-
|
|
8015
|
-
|
|
8041
|
+
action: "linear.label.list",
|
|
8042
|
+
resource_type: "linear:label",
|
|
8043
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
8044
|
+
required_scopes: ["read"],
|
|
8045
|
+
capability: "linear.read.basic",
|
|
8046
|
+
input_schema: {
|
|
8047
|
+
type: "object",
|
|
8048
|
+
properties: {
|
|
8049
|
+
teamId: { type: "string", description: "Filter labels by team ID" },
|
|
8050
|
+
limit: { type: "number", minimum: 1, maximum: 250, description: "Max number of labels to return (default 50)" }
|
|
8051
|
+
},
|
|
8052
|
+
additionalProperties: false
|
|
8053
|
+
},
|
|
8054
|
+
constraints: { rate_bucket: "linear.read" },
|
|
8055
|
+
effects: ["Read:LabelList"],
|
|
8056
|
+
risk: "low",
|
|
8057
|
+
target_bindings: {
|
|
8058
|
+
resource_id: { source: "param", param: "teamId", required: false }
|
|
8059
|
+
},
|
|
8016
8060
|
version: "1.0.0"
|
|
8017
8061
|
},
|
|
8018
8062
|
{
|
|
8019
|
-
|
|
8020
|
-
|
|
8021
|
-
|
|
8063
|
+
action: "linear.user.list",
|
|
8064
|
+
resource_type: "linear:team",
|
|
8065
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
8066
|
+
required_scopes: ["read"],
|
|
8067
|
+
capability: "linear.read.basic",
|
|
8068
|
+
input_schema: {
|
|
8069
|
+
type: "object",
|
|
8070
|
+
properties: {
|
|
8071
|
+
teamId: { type: "string", description: "Filter by team ID (lists team members only)" },
|
|
8072
|
+
limit: { type: "number", minimum: 1, maximum: 250, description: "Max number of users to return (default 50)" }
|
|
8073
|
+
},
|
|
8074
|
+
additionalProperties: false
|
|
8075
|
+
},
|
|
8076
|
+
constraints: { rate_bucket: "linear.read" },
|
|
8077
|
+
effects: ["Read:UserList"],
|
|
8078
|
+
risk: "low",
|
|
8079
|
+
target_bindings: {
|
|
8080
|
+
resource_id: { source: "param", param: "teamId", required: false }
|
|
8081
|
+
},
|
|
8022
8082
|
version: "1.0.0"
|
|
8023
8083
|
},
|
|
8024
8084
|
{
|
|
8025
|
-
|
|
8026
|
-
|
|
8027
|
-
|
|
8085
|
+
action: "linear.issue.archive",
|
|
8086
|
+
resource_type: "linear:issue",
|
|
8087
|
+
required_relations: ["editor", "act_as"],
|
|
8088
|
+
required_scopes: ["write"],
|
|
8089
|
+
capability: "linear.write.basic",
|
|
8090
|
+
input_schema: {
|
|
8091
|
+
type: "object",
|
|
8092
|
+
properties: {
|
|
8093
|
+
issueId: { type: "string", minLength: 1, description: "Issue ID or identifier to archive (e.g. ENG-123)" }
|
|
8094
|
+
},
|
|
8095
|
+
required: ["issueId"],
|
|
8096
|
+
additionalProperties: false
|
|
8097
|
+
},
|
|
8098
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8099
|
+
effects: ["Archive:Issue"],
|
|
8100
|
+
risk: "high",
|
|
8101
|
+
target_bindings: {
|
|
8102
|
+
resource_id: { source: "param", param: "issueId" }
|
|
8103
|
+
},
|
|
8028
8104
|
version: "1.0.0"
|
|
8029
8105
|
},
|
|
8030
8106
|
{
|
|
8031
|
-
|
|
8032
|
-
|
|
8033
|
-
|
|
8107
|
+
action: "linear.project.create",
|
|
8108
|
+
resource_type: "linear:project",
|
|
8109
|
+
required_relations: ["editor", "act_as"],
|
|
8110
|
+
required_scopes: ["write"],
|
|
8111
|
+
capability: "linear.write.basic",
|
|
8112
|
+
input_schema: {
|
|
8113
|
+
type: "object",
|
|
8114
|
+
properties: {
|
|
8115
|
+
name: { type: "string", minLength: 1, description: "Project name" },
|
|
8116
|
+
teamIds: { type: "array", items: { type: "string" }, minItems: 1, description: "Team IDs to associate with the project (at least one required)" },
|
|
8117
|
+
teamId: { type: "string", description: "Primary team ID (first element of teamIds; used for authorization scope)" },
|
|
8118
|
+
description: { type: "string", description: "Project description (Markdown)" },
|
|
8119
|
+
statusId: { type: "string", description: "Project status ID. Note: this is a ProjectStatus ID, not a WorkflowState ID. ProjectStatus can be retrieved via the Linear API projectStatuses query." },
|
|
8120
|
+
startDate: { type: "string", description: "Start date (ISO 8601, e.g. 2024-01-01)" },
|
|
8121
|
+
targetDate: { type: "string", description: "Target completion date (ISO 8601)" }
|
|
8122
|
+
},
|
|
8123
|
+
required: ["name", "teamIds"],
|
|
8124
|
+
additionalProperties: false
|
|
8125
|
+
},
|
|
8126
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8127
|
+
effects: ["Create:Project"],
|
|
8128
|
+
risk: "high",
|
|
8129
|
+
target_bindings: {
|
|
8130
|
+
// teamId はスキーマの scalar フィールド (teamIds[0] の alias)。
|
|
8131
|
+
// teamId が明示指定されている場合はそれを使い、未指定の場合は
|
|
8132
|
+
// fallback_param: 'teamIds' で teamIds[0] にフォールバック(resolver は
|
|
8133
|
+
// 配列の first element を自動的にスカラーに変換する)。
|
|
8134
|
+
// extractResources も同じ優先順位 (teamId → teamIds[0]) で解決するため
|
|
8135
|
+
// 両者のバインドが常に一致する。required:true で高リスク CREATE の
|
|
8136
|
+
// resource binding 必須契約を明示 (teamIds は minItems:1 なので常に解決する)。
|
|
8137
|
+
resource_id: { source: "param", param: "teamId", fallback_param: "teamIds", required: true }
|
|
8138
|
+
},
|
|
8034
8139
|
version: "1.0.0"
|
|
8035
8140
|
},
|
|
8036
8141
|
{
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
|
|
8142
|
+
action: "linear.project.update",
|
|
8143
|
+
resource_type: "linear:project",
|
|
8144
|
+
required_relations: ["editor", "act_as"],
|
|
8145
|
+
required_scopes: ["write"],
|
|
8146
|
+
capability: "linear.write.basic",
|
|
8147
|
+
input_schema: {
|
|
8148
|
+
type: "object",
|
|
8149
|
+
properties: {
|
|
8150
|
+
projectId: { type: "string", minLength: 1, description: "Project ID to update" },
|
|
8151
|
+
name: { type: "string", description: "New project name" },
|
|
8152
|
+
description: { type: "string", description: "New project description (Markdown)" },
|
|
8153
|
+
statusId: { type: "string", description: "New project status ID. Note: this is a ProjectStatus ID, not a WorkflowState ID." },
|
|
8154
|
+
startDate: { type: "string", description: "New start date (ISO 8601)" },
|
|
8155
|
+
targetDate: { type: "string", description: "New target date (ISO 8601)" }
|
|
8156
|
+
},
|
|
8157
|
+
required: ["projectId"],
|
|
8158
|
+
additionalProperties: false
|
|
8159
|
+
},
|
|
8160
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8161
|
+
effects: ["Update:Project"],
|
|
8162
|
+
risk: "high",
|
|
8163
|
+
target_bindings: {
|
|
8164
|
+
resource_id: { source: "param", param: "projectId" }
|
|
8165
|
+
},
|
|
8040
8166
|
version: "1.0.0"
|
|
8041
8167
|
},
|
|
8168
|
+
// ─── Linear Comment ops ───
|
|
8042
8169
|
{
|
|
8043
|
-
|
|
8044
|
-
|
|
8045
|
-
|
|
8170
|
+
action: "linear.comment.update",
|
|
8171
|
+
resource_type: "linear:comment",
|
|
8172
|
+
required_relations: ["editor", "act_as"],
|
|
8173
|
+
required_scopes: ["comments:create"],
|
|
8174
|
+
capability: "linear.write.basic",
|
|
8175
|
+
input_schema: {
|
|
8176
|
+
type: "object",
|
|
8177
|
+
properties: {
|
|
8178
|
+
commentId: { type: "string", minLength: 1, description: "Comment ID to update" },
|
|
8179
|
+
body: { type: "string", minLength: 1, description: "New comment body (Markdown)" }
|
|
8180
|
+
},
|
|
8181
|
+
required: ["commentId", "body"],
|
|
8182
|
+
additionalProperties: false
|
|
8183
|
+
},
|
|
8184
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8185
|
+
effects: ["Update:Comment"],
|
|
8186
|
+
risk: "high",
|
|
8187
|
+
target_bindings: {
|
|
8188
|
+
resource_id: { source: "param", param: "commentId" }
|
|
8189
|
+
},
|
|
8046
8190
|
version: "1.0.0"
|
|
8047
8191
|
},
|
|
8048
8192
|
{
|
|
8049
|
-
|
|
8050
|
-
|
|
8051
|
-
|
|
8193
|
+
action: "linear.comment.delete",
|
|
8194
|
+
resource_type: "linear:comment",
|
|
8195
|
+
required_relations: ["editor", "act_as"],
|
|
8196
|
+
required_scopes: ["write"],
|
|
8197
|
+
capability: "linear.write.basic",
|
|
8198
|
+
input_schema: {
|
|
8199
|
+
type: "object",
|
|
8200
|
+
properties: {
|
|
8201
|
+
commentId: { type: "string", minLength: 1, description: "Comment ID to delete" }
|
|
8202
|
+
},
|
|
8203
|
+
required: ["commentId"],
|
|
8204
|
+
additionalProperties: false
|
|
8205
|
+
},
|
|
8206
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8207
|
+
effects: ["Delete:Comment"],
|
|
8208
|
+
risk: "high",
|
|
8209
|
+
target_bindings: {
|
|
8210
|
+
resource_id: { source: "param", param: "commentId" }
|
|
8211
|
+
},
|
|
8052
8212
|
version: "1.0.0"
|
|
8053
8213
|
},
|
|
8054
8214
|
{
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8215
|
+
action: "linear.comment.resolve",
|
|
8216
|
+
resource_type: "linear:comment",
|
|
8217
|
+
required_relations: ["editor", "act_as"],
|
|
8218
|
+
required_scopes: ["write"],
|
|
8219
|
+
capability: "linear.write.basic",
|
|
8220
|
+
input_schema: {
|
|
8221
|
+
type: "object",
|
|
8222
|
+
properties: {
|
|
8223
|
+
commentId: { type: "string", minLength: 1, description: "Comment ID to resolve" }
|
|
8224
|
+
},
|
|
8225
|
+
required: ["commentId"],
|
|
8226
|
+
additionalProperties: false
|
|
8227
|
+
},
|
|
8228
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8229
|
+
effects: ["Update:Comment"],
|
|
8230
|
+
risk: "high",
|
|
8231
|
+
target_bindings: {
|
|
8232
|
+
resource_id: { source: "param", param: "commentId" }
|
|
8233
|
+
},
|
|
8058
8234
|
version: "1.0.0"
|
|
8059
8235
|
},
|
|
8060
8236
|
{
|
|
8061
|
-
|
|
8062
|
-
|
|
8063
|
-
|
|
8237
|
+
action: "linear.comment.unresolve",
|
|
8238
|
+
resource_type: "linear:comment",
|
|
8239
|
+
required_relations: ["editor", "act_as"],
|
|
8240
|
+
required_scopes: ["write"],
|
|
8241
|
+
capability: "linear.write.basic",
|
|
8242
|
+
input_schema: {
|
|
8243
|
+
type: "object",
|
|
8244
|
+
properties: {
|
|
8245
|
+
commentId: { type: "string", minLength: 1, description: "Comment ID to unresolve" }
|
|
8246
|
+
},
|
|
8247
|
+
required: ["commentId"],
|
|
8248
|
+
additionalProperties: false
|
|
8249
|
+
},
|
|
8250
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8251
|
+
effects: ["Update:Comment"],
|
|
8252
|
+
risk: "high",
|
|
8253
|
+
target_bindings: {
|
|
8254
|
+
resource_id: { source: "param", param: "commentId" }
|
|
8255
|
+
},
|
|
8064
8256
|
version: "1.0.0"
|
|
8065
|
-
}
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
|
|
8093
|
-
|
|
8094
|
-
|
|
8095
|
-
|
|
8096
|
-
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8100
|
-
|
|
8101
|
-
|
|
8102
|
-
|
|
8103
|
-
|
|
8104
|
-
|
|
8105
|
-
|
|
8106
|
-
|
|
8107
|
-
|
|
8108
|
-
|
|
8109
|
-
|
|
8110
|
-
|
|
8111
|
-
|
|
8112
|
-
|
|
8113
|
-
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
|
|
8125
|
-
|
|
8126
|
-
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
|
|
8139
|
-
|
|
8140
|
-
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
|
|
8145
|
-
|
|
8146
|
-
|
|
8147
|
-
|
|
8148
|
-
}
|
|
8149
|
-
|
|
8150
|
-
|
|
8151
|
-
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
|
|
8158
|
-
|
|
8159
|
-
|
|
8160
|
-
|
|
8161
|
-
|
|
8162
|
-
|
|
8163
|
-
|
|
8164
|
-
|
|
8165
|
-
|
|
8166
|
-
|
|
8167
|
-
|
|
8168
|
-
|
|
8169
|
-
|
|
8170
|
-
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
|
|
8176
|
-
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
}
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
|
|
8197
|
-
|
|
8198
|
-
|
|
8199
|
-
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
|
|
8204
|
-
|
|
8205
|
-
|
|
8206
|
-
|
|
8207
|
-
|
|
8208
|
-
|
|
8209
|
-
|
|
8210
|
-
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8214
|
-
|
|
8215
|
-
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
|
|
8257
|
+
},
|
|
8258
|
+
// ─── Linear Issue ops ───
|
|
8259
|
+
{
|
|
8260
|
+
action: "linear.issue.unarchive",
|
|
8261
|
+
resource_type: "linear:issue",
|
|
8262
|
+
required_relations: ["editor", "act_as"],
|
|
8263
|
+
required_scopes: ["write"],
|
|
8264
|
+
capability: "linear.write.basic",
|
|
8265
|
+
input_schema: {
|
|
8266
|
+
type: "object",
|
|
8267
|
+
properties: {
|
|
8268
|
+
issueId: { type: "string", minLength: 1, description: "Issue ID or identifier to unarchive (e.g. ENG-123)" }
|
|
8269
|
+
},
|
|
8270
|
+
required: ["issueId"],
|
|
8271
|
+
additionalProperties: false
|
|
8272
|
+
},
|
|
8273
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8274
|
+
effects: ["Update:Issue"],
|
|
8275
|
+
risk: "high",
|
|
8276
|
+
target_bindings: {
|
|
8277
|
+
resource_id: { source: "param", param: "issueId" }
|
|
8278
|
+
},
|
|
8279
|
+
version: "1.0.0"
|
|
8280
|
+
},
|
|
8281
|
+
{
|
|
8282
|
+
action: "linear.issue.addLabel",
|
|
8283
|
+
resource_type: "linear:issue",
|
|
8284
|
+
required_relations: ["editor", "act_as"],
|
|
8285
|
+
required_scopes: ["write"],
|
|
8286
|
+
capability: "linear.write.basic",
|
|
8287
|
+
input_schema: {
|
|
8288
|
+
type: "object",
|
|
8289
|
+
properties: {
|
|
8290
|
+
issueId: { type: "string", minLength: 1, description: "Issue ID or identifier" },
|
|
8291
|
+
labelId: { type: "string", minLength: 1, description: "Label ID to add" }
|
|
8292
|
+
},
|
|
8293
|
+
required: ["issueId", "labelId"],
|
|
8294
|
+
additionalProperties: false
|
|
8295
|
+
},
|
|
8296
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8297
|
+
effects: ["Update:Issue"],
|
|
8298
|
+
risk: "high",
|
|
8299
|
+
target_bindings: {
|
|
8300
|
+
resource_id: { source: "param", param: "issueId" }
|
|
8301
|
+
},
|
|
8302
|
+
version: "1.0.0"
|
|
8303
|
+
},
|
|
8304
|
+
{
|
|
8305
|
+
action: "linear.issue.removeLabel",
|
|
8306
|
+
resource_type: "linear:issue",
|
|
8307
|
+
required_relations: ["editor", "act_as"],
|
|
8308
|
+
required_scopes: ["write"],
|
|
8309
|
+
capability: "linear.write.basic",
|
|
8310
|
+
input_schema: {
|
|
8311
|
+
type: "object",
|
|
8312
|
+
properties: {
|
|
8313
|
+
issueId: { type: "string", minLength: 1, description: "Issue ID or identifier" },
|
|
8314
|
+
labelId: { type: "string", minLength: 1, description: "Label ID to remove" }
|
|
8315
|
+
},
|
|
8316
|
+
required: ["issueId", "labelId"],
|
|
8317
|
+
additionalProperties: false
|
|
8318
|
+
},
|
|
8319
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8320
|
+
effects: ["Update:Issue"],
|
|
8321
|
+
risk: "high",
|
|
8322
|
+
target_bindings: {
|
|
8323
|
+
resource_id: { source: "param", param: "issueId" }
|
|
8324
|
+
},
|
|
8325
|
+
version: "1.0.0"
|
|
8326
|
+
},
|
|
8327
|
+
{
|
|
8328
|
+
action: "linear.issue.subscribe",
|
|
8329
|
+
resource_type: "linear:issue",
|
|
8330
|
+
required_relations: ["editor", "act_as"],
|
|
8331
|
+
required_scopes: ["write"],
|
|
8332
|
+
capability: "linear.write.basic",
|
|
8333
|
+
input_schema: {
|
|
8334
|
+
type: "object",
|
|
8335
|
+
properties: {
|
|
8336
|
+
issueId: { type: "string", minLength: 1, description: "Issue ID or identifier to subscribe to" }
|
|
8337
|
+
},
|
|
8338
|
+
required: ["issueId"],
|
|
8339
|
+
additionalProperties: false
|
|
8340
|
+
},
|
|
8341
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8342
|
+
effects: ["Update:Issue"],
|
|
8343
|
+
risk: "high",
|
|
8344
|
+
target_bindings: {
|
|
8345
|
+
resource_id: { source: "param", param: "issueId" }
|
|
8346
|
+
},
|
|
8347
|
+
version: "1.0.0"
|
|
8348
|
+
},
|
|
8349
|
+
{
|
|
8350
|
+
action: "linear.issue.delete",
|
|
8351
|
+
resource_type: "linear:issue",
|
|
8352
|
+
required_relations: ["admin", "owner", "act_as"],
|
|
8353
|
+
required_scopes: ["write"],
|
|
8354
|
+
capability: "linear.write.basic",
|
|
8355
|
+
input_schema: {
|
|
8356
|
+
type: "object",
|
|
8357
|
+
properties: {
|
|
8358
|
+
issueId: { type: "string", minLength: 1, description: "Issue ID or identifier to permanently delete" }
|
|
8359
|
+
},
|
|
8360
|
+
required: ["issueId"],
|
|
8361
|
+
additionalProperties: false
|
|
8362
|
+
},
|
|
8363
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8364
|
+
effects: ["Delete:Issue"],
|
|
8365
|
+
risk: "critical",
|
|
8366
|
+
target_bindings: {
|
|
8367
|
+
resource_id: { source: "param", param: "issueId" }
|
|
8368
|
+
},
|
|
8369
|
+
version: "1.0.0"
|
|
8370
|
+
},
|
|
8371
|
+
// ─── Linear Issue Relations ───
|
|
8372
|
+
{
|
|
8373
|
+
action: "linear.issueRelation.create",
|
|
8374
|
+
resource_type: "linear:issueRelation",
|
|
8375
|
+
required_relations: ["editor", "act_as"],
|
|
8376
|
+
required_scopes: ["write"],
|
|
8377
|
+
capability: "linear.write.basic",
|
|
8378
|
+
input_schema: {
|
|
8379
|
+
type: "object",
|
|
8380
|
+
properties: {
|
|
8381
|
+
issueId: { type: "string", minLength: 1, description: "Issue ID to create a relation from" },
|
|
8382
|
+
relatedIssueId: { type: "string", minLength: 1, description: "Related issue ID" },
|
|
8383
|
+
type: { type: "string", enum: ["blocks", "duplicate", "related", "similar"], description: "Relation type" }
|
|
8384
|
+
},
|
|
8385
|
+
required: ["issueId", "relatedIssueId", "type"],
|
|
8386
|
+
additionalProperties: false
|
|
8387
|
+
},
|
|
8388
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8389
|
+
effects: ["Create:IssueRelation"],
|
|
8390
|
+
risk: "high",
|
|
8391
|
+
target_bindings: {
|
|
8392
|
+
resource_id: { source: "param", param: "issueId" }
|
|
8393
|
+
},
|
|
8394
|
+
version: "1.0.0"
|
|
8395
|
+
},
|
|
8396
|
+
{
|
|
8397
|
+
action: "linear.issueRelation.list",
|
|
8398
|
+
resource_type: "linear:issueRelation",
|
|
8399
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
8400
|
+
required_scopes: ["read"],
|
|
8401
|
+
capability: "linear.read.basic",
|
|
8402
|
+
input_schema: {
|
|
8403
|
+
type: "object",
|
|
8404
|
+
properties: {
|
|
8405
|
+
issueId: { type: "string", minLength: 1, description: "Issue ID to list relations for" }
|
|
8406
|
+
},
|
|
8407
|
+
required: ["issueId"],
|
|
8408
|
+
additionalProperties: false
|
|
8409
|
+
},
|
|
8410
|
+
constraints: { rate_bucket: "linear.read" },
|
|
8411
|
+
effects: ["Read:IssueRelationList"],
|
|
8412
|
+
risk: "low",
|
|
8413
|
+
target_bindings: {
|
|
8414
|
+
resource_id: { source: "param", param: "issueId" }
|
|
8415
|
+
},
|
|
8416
|
+
version: "1.0.0"
|
|
8417
|
+
},
|
|
8418
|
+
{
|
|
8419
|
+
action: "linear.issueRelation.delete",
|
|
8420
|
+
resource_type: "linear:issueRelation",
|
|
8421
|
+
required_relations: ["editor", "act_as"],
|
|
8422
|
+
required_scopes: ["write"],
|
|
8423
|
+
capability: "linear.write.basic",
|
|
8424
|
+
input_schema: {
|
|
8425
|
+
type: "object",
|
|
8426
|
+
properties: {
|
|
8427
|
+
relationId: { type: "string", minLength: 1, description: "Issue relation ID to delete" }
|
|
8428
|
+
},
|
|
8429
|
+
required: ["relationId"],
|
|
8430
|
+
additionalProperties: false
|
|
8431
|
+
},
|
|
8432
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8433
|
+
effects: ["Delete:IssueRelation"],
|
|
8434
|
+
risk: "high",
|
|
8435
|
+
target_bindings: {
|
|
8436
|
+
resource_id: { source: "param", param: "relationId" }
|
|
8437
|
+
},
|
|
8438
|
+
version: "1.0.0"
|
|
8439
|
+
},
|
|
8440
|
+
// ─── Linear Cycles ───
|
|
8441
|
+
{
|
|
8442
|
+
action: "linear.cycle.list",
|
|
8443
|
+
resource_type: "linear:cycle",
|
|
8444
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
8445
|
+
required_scopes: ["read"],
|
|
8446
|
+
capability: "linear.read.basic",
|
|
8447
|
+
input_schema: {
|
|
8448
|
+
type: "object",
|
|
8449
|
+
properties: {
|
|
8450
|
+
teamId: { type: "string", description: "Filter by team ID" },
|
|
8451
|
+
limit: { type: "number", minimum: 1, maximum: 250, description: "Max number of cycles to return (default 50)" }
|
|
8452
|
+
},
|
|
8453
|
+
additionalProperties: false
|
|
8454
|
+
},
|
|
8455
|
+
constraints: { rate_bucket: "linear.read" },
|
|
8456
|
+
effects: ["Read:CycleList"],
|
|
8457
|
+
risk: "low",
|
|
8458
|
+
target_bindings: {
|
|
8459
|
+
resource_id: { source: "param", param: "teamId", required: false }
|
|
8460
|
+
},
|
|
8461
|
+
version: "1.0.0"
|
|
8462
|
+
},
|
|
8463
|
+
{
|
|
8464
|
+
action: "linear.cycle.read",
|
|
8465
|
+
resource_type: "linear:cycle",
|
|
8466
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
8467
|
+
required_scopes: ["read"],
|
|
8468
|
+
capability: "linear.read.basic",
|
|
8469
|
+
input_schema: {
|
|
8470
|
+
type: "object",
|
|
8471
|
+
properties: {
|
|
8472
|
+
cycleId: { type: "string", minLength: 1, description: "Cycle ID" }
|
|
8473
|
+
},
|
|
8474
|
+
required: ["cycleId"],
|
|
8475
|
+
additionalProperties: false
|
|
8476
|
+
},
|
|
8477
|
+
constraints: { rate_bucket: "linear.read" },
|
|
8478
|
+
effects: ["Read:Cycle"],
|
|
8479
|
+
risk: "low",
|
|
8480
|
+
target_bindings: {
|
|
8481
|
+
resource_id: { source: "param", param: "cycleId" }
|
|
8482
|
+
},
|
|
8483
|
+
version: "1.0.0"
|
|
8484
|
+
},
|
|
8485
|
+
{
|
|
8486
|
+
action: "linear.cycle.create",
|
|
8487
|
+
resource_type: "linear:cycle",
|
|
8488
|
+
required_relations: ["editor", "act_as"],
|
|
8489
|
+
required_scopes: ["write"],
|
|
8490
|
+
capability: "linear.write.basic",
|
|
8491
|
+
input_schema: {
|
|
8492
|
+
type: "object",
|
|
8493
|
+
properties: {
|
|
8494
|
+
teamId: { type: "string", minLength: 1, description: "Team ID to create the cycle in" },
|
|
8495
|
+
name: { type: "string", description: "Cycle name" },
|
|
8496
|
+
startsAt: { type: "string", minLength: 1, description: "Cycle start date (ISO 8601)" },
|
|
8497
|
+
endsAt: { type: "string", minLength: 1, description: "Cycle end date (ISO 8601)" },
|
|
8498
|
+
description: { type: "string", description: "Cycle description" }
|
|
8499
|
+
},
|
|
8500
|
+
required: ["teamId", "startsAt", "endsAt"],
|
|
8501
|
+
additionalProperties: false
|
|
8502
|
+
},
|
|
8503
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8504
|
+
effects: ["Create:Cycle"],
|
|
8505
|
+
risk: "high",
|
|
8506
|
+
target_bindings: {
|
|
8507
|
+
resource_id: { source: "param", param: "teamId" }
|
|
8508
|
+
},
|
|
8509
|
+
version: "1.0.0"
|
|
8510
|
+
},
|
|
8511
|
+
{
|
|
8512
|
+
action: "linear.cycle.update",
|
|
8513
|
+
resource_type: "linear:cycle",
|
|
8514
|
+
required_relations: ["editor", "act_as"],
|
|
8515
|
+
required_scopes: ["write"],
|
|
8516
|
+
capability: "linear.write.basic",
|
|
8517
|
+
input_schema: {
|
|
8518
|
+
type: "object",
|
|
8519
|
+
properties: {
|
|
8520
|
+
cycleId: { type: "string", minLength: 1, description: "Cycle ID to update" },
|
|
8521
|
+
name: { type: "string", description: "New cycle name" },
|
|
8522
|
+
startsAt: { type: "string", description: "New start date (ISO 8601)" },
|
|
8523
|
+
endsAt: { type: "string", description: "New end date (ISO 8601)" },
|
|
8524
|
+
description: { type: "string", description: "New description" },
|
|
8525
|
+
completedAt: { type: "string", description: "Completion date (ISO 8601) or null to unset" }
|
|
8526
|
+
},
|
|
8527
|
+
required: ["cycleId"],
|
|
8528
|
+
additionalProperties: false
|
|
8529
|
+
},
|
|
8530
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8531
|
+
effects: ["Update:Cycle"],
|
|
8532
|
+
risk: "high",
|
|
8533
|
+
target_bindings: {
|
|
8534
|
+
resource_id: { source: "param", param: "cycleId" }
|
|
8535
|
+
},
|
|
8536
|
+
version: "1.0.0"
|
|
8537
|
+
},
|
|
8538
|
+
// ─── Linear Labels ───
|
|
8539
|
+
{
|
|
8540
|
+
action: "linear.label.create",
|
|
8541
|
+
resource_type: "linear:label",
|
|
8542
|
+
required_relations: ["editor", "act_as"],
|
|
8543
|
+
required_scopes: ["write"],
|
|
8544
|
+
capability: "linear.write.basic",
|
|
8545
|
+
input_schema: {
|
|
8546
|
+
type: "object",
|
|
8547
|
+
properties: {
|
|
8548
|
+
name: { type: "string", minLength: 1, description: "Label name" },
|
|
8549
|
+
color: { type: "string", description: "Label color (hex, e.g. #FF0000)" },
|
|
8550
|
+
description: { type: "string", description: "Label description" },
|
|
8551
|
+
teamId: { type: "string", description: "Team ID to scope the label to (omit for workspace-level label)" }
|
|
8552
|
+
},
|
|
8553
|
+
required: ["name"],
|
|
8554
|
+
additionalProperties: false
|
|
8555
|
+
},
|
|
8556
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8557
|
+
effects: ["Create:Label"],
|
|
8558
|
+
risk: "high",
|
|
8559
|
+
target_bindings: {
|
|
8560
|
+
resource_id: { source: "param", param: "teamId", required: false }
|
|
8561
|
+
},
|
|
8562
|
+
version: "1.0.0"
|
|
8563
|
+
},
|
|
8564
|
+
{
|
|
8565
|
+
action: "linear.label.update",
|
|
8566
|
+
resource_type: "linear:label",
|
|
8567
|
+
required_relations: ["editor", "act_as"],
|
|
8568
|
+
required_scopes: ["write"],
|
|
8569
|
+
capability: "linear.write.basic",
|
|
8570
|
+
input_schema: {
|
|
8571
|
+
type: "object",
|
|
8572
|
+
properties: {
|
|
8573
|
+
labelId: { type: "string", minLength: 1, description: "Label ID to update" },
|
|
8574
|
+
name: { type: "string", description: "New label name" },
|
|
8575
|
+
color: { type: "string", description: "New label color (hex)" },
|
|
8576
|
+
description: { type: "string", description: "New description" }
|
|
8577
|
+
},
|
|
8578
|
+
required: ["labelId"],
|
|
8579
|
+
additionalProperties: false
|
|
8580
|
+
},
|
|
8581
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8582
|
+
effects: ["Update:Label"],
|
|
8583
|
+
risk: "high",
|
|
8584
|
+
target_bindings: {
|
|
8585
|
+
resource_id: { source: "param", param: "labelId" }
|
|
8586
|
+
},
|
|
8587
|
+
version: "1.0.0"
|
|
8588
|
+
},
|
|
8589
|
+
// ─── Linear Attachments ───
|
|
8590
|
+
{
|
|
8591
|
+
action: "linear.attachment.create",
|
|
8592
|
+
resource_type: "linear:attachment",
|
|
8593
|
+
required_relations: ["editor", "act_as"],
|
|
8594
|
+
required_scopes: ["write"],
|
|
8595
|
+
capability: "linear.write.basic",
|
|
8596
|
+
input_schema: {
|
|
8597
|
+
type: "object",
|
|
8598
|
+
properties: {
|
|
8599
|
+
issueId: { type: "string", minLength: 1, description: "Issue ID to attach to" },
|
|
8600
|
+
title: { type: "string", minLength: 1, description: "Attachment title" },
|
|
8601
|
+
url: { type: "string", minLength: 1, description: "Attachment URL" },
|
|
8602
|
+
subtitle: { type: "string", description: "Attachment subtitle" }
|
|
8603
|
+
},
|
|
8604
|
+
required: ["issueId", "title", "url"],
|
|
8605
|
+
additionalProperties: false
|
|
8606
|
+
},
|
|
8607
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8608
|
+
effects: ["Create:Attachment"],
|
|
8609
|
+
risk: "high",
|
|
8610
|
+
target_bindings: {
|
|
8611
|
+
resource_id: { source: "param", param: "issueId" }
|
|
8612
|
+
},
|
|
8613
|
+
version: "1.0.0"
|
|
8614
|
+
},
|
|
8615
|
+
{
|
|
8616
|
+
action: "linear.attachment.list",
|
|
8617
|
+
resource_type: "linear:attachment",
|
|
8618
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
8619
|
+
required_scopes: ["read"],
|
|
8620
|
+
capability: "linear.read.basic",
|
|
8621
|
+
input_schema: {
|
|
8622
|
+
type: "object",
|
|
8623
|
+
properties: {
|
|
8624
|
+
issueId: { type: "string", minLength: 1, description: "Issue ID to list attachments for" }
|
|
8625
|
+
},
|
|
8626
|
+
required: ["issueId"],
|
|
8627
|
+
additionalProperties: false
|
|
8628
|
+
},
|
|
8629
|
+
constraints: { rate_bucket: "linear.read" },
|
|
8630
|
+
effects: ["Read:AttachmentList"],
|
|
8631
|
+
risk: "low",
|
|
8632
|
+
target_bindings: {
|
|
8633
|
+
resource_id: { source: "param", param: "issueId" }
|
|
8634
|
+
},
|
|
8635
|
+
version: "1.0.0"
|
|
8636
|
+
},
|
|
8637
|
+
{
|
|
8638
|
+
action: "linear.attachment.delete",
|
|
8639
|
+
resource_type: "linear:attachment",
|
|
8640
|
+
required_relations: ["editor", "act_as"],
|
|
8641
|
+
required_scopes: ["write"],
|
|
8642
|
+
capability: "linear.write.basic",
|
|
8643
|
+
input_schema: {
|
|
8644
|
+
type: "object",
|
|
8645
|
+
properties: {
|
|
8646
|
+
attachmentId: { type: "string", minLength: 1, description: "Attachment ID to delete" }
|
|
8647
|
+
},
|
|
8648
|
+
required: ["attachmentId"],
|
|
8649
|
+
additionalProperties: false
|
|
8650
|
+
},
|
|
8651
|
+
constraints: { rate_bucket: "linear.write" },
|
|
8652
|
+
effects: ["Delete:Attachment"],
|
|
8653
|
+
risk: "high",
|
|
8654
|
+
target_bindings: {
|
|
8655
|
+
resource_id: { source: "param", param: "attachmentId" }
|
|
8656
|
+
},
|
|
8657
|
+
version: "1.0.0"
|
|
8658
|
+
},
|
|
8659
|
+
// ─── Agent Inbox Actions (internal) ───
|
|
8660
|
+
// Inbox actions back the Agent Inbox MCP tools (task delegation between
|
|
8661
|
+
// agents/people). They are internal (no external OAuth provider), so they
|
|
8662
|
+
// carry a single nominal base scope `inbox` to satisfy the registry
|
|
8663
|
+
// meta-schema's `minItems: 1` (same pattern as hubspot.account.link.get).
|
|
8664
|
+
{
|
|
8665
|
+
action: "inbox.send",
|
|
8666
|
+
resource_type: "inbox:item",
|
|
8667
|
+
required_relations: ["editor", "act_as"],
|
|
8668
|
+
required_scopes: ["inbox"],
|
|
8669
|
+
capability: "inbox.write",
|
|
8670
|
+
input_schema: {
|
|
8671
|
+
type: "object",
|
|
8672
|
+
properties: {
|
|
8673
|
+
to: { type: "string", minLength: 1, description: "Recipient (user id / handle) the task request is sent to" },
|
|
8674
|
+
taskType: { type: "string", minLength: 1, description: "Type of task being requested" },
|
|
8675
|
+
payload: { type: "object", description: "Task-specific payload data" },
|
|
8676
|
+
message: { type: "string", description: "Optional human-readable message" }
|
|
8677
|
+
},
|
|
8678
|
+
required: ["to", "taskType", "payload"],
|
|
8679
|
+
additionalProperties: false
|
|
8680
|
+
},
|
|
8681
|
+
constraints: { rate_bucket: "inbox.write" },
|
|
8682
|
+
effects: ["Create:InboxItem"],
|
|
8683
|
+
risk: "high",
|
|
8684
|
+
target_bindings: {
|
|
8685
|
+
resource_id: { source: "param", param: "to" }
|
|
8686
|
+
},
|
|
8687
|
+
version: "1.0.0"
|
|
8688
|
+
},
|
|
8689
|
+
{
|
|
8690
|
+
action: "inbox.respond",
|
|
8691
|
+
resource_type: "inbox:item",
|
|
8692
|
+
required_relations: ["editor", "act_as"],
|
|
8693
|
+
required_scopes: ["inbox"],
|
|
8694
|
+
capability: "inbox.write",
|
|
8695
|
+
input_schema: {
|
|
8696
|
+
type: "object",
|
|
8697
|
+
properties: {
|
|
8698
|
+
id: { type: "string", minLength: 1, description: "Inbox item id being responded to" },
|
|
8699
|
+
action: { type: "string", enum: ["accept", "decline", "counter"], description: "Response action" },
|
|
8700
|
+
data: { type: "object", description: "Optional response data (e.g. counter-proposal)" }
|
|
8701
|
+
},
|
|
8702
|
+
required: ["id", "action"],
|
|
8703
|
+
additionalProperties: false
|
|
8704
|
+
},
|
|
8705
|
+
constraints: { rate_bucket: "inbox.write" },
|
|
8706
|
+
effects: ["Update:InboxItem"],
|
|
8707
|
+
// high (not medium): an agent-mediated response (MCP invoke) must always
|
|
8708
|
+
// go through human approval — the Phase 1 "always confirm" guarantee made
|
|
8709
|
+
// enforceable. target_bindings below binds the concrete inbox item id so
|
|
8710
|
+
// the high-risk approval has a specific resource constraint (the public
|
|
8711
|
+
// /scheduling/:token link flow does NOT go through this gate — it calls
|
|
8712
|
+
// InboxService.respond directly, system-key-signed).
|
|
8713
|
+
risk: "high",
|
|
8714
|
+
target_bindings: {
|
|
8715
|
+
resource_id: { source: "param", param: "id" }
|
|
8716
|
+
},
|
|
8717
|
+
version: "1.0.0"
|
|
8718
|
+
},
|
|
8719
|
+
{
|
|
8720
|
+
action: "inbox.check",
|
|
8721
|
+
resource_type: "inbox:item",
|
|
8722
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
8723
|
+
required_scopes: ["inbox"],
|
|
8724
|
+
capability: "inbox.read",
|
|
8725
|
+
input_schema: {
|
|
8726
|
+
type: "object",
|
|
8727
|
+
properties: {
|
|
8728
|
+
types: { type: "array", items: { type: "string" }, description: "Filter by task types" },
|
|
8729
|
+
status: { type: "string", description: "Filter by item status" }
|
|
8730
|
+
},
|
|
8731
|
+
additionalProperties: false
|
|
8732
|
+
},
|
|
8733
|
+
constraints: { rate_bucket: "inbox.read" },
|
|
8734
|
+
effects: ["Read:InboxItem"],
|
|
8735
|
+
risk: "low",
|
|
8736
|
+
target_bindings: {
|
|
8737
|
+
resource_id: { source: "param", param: "id", required: false }
|
|
8738
|
+
},
|
|
8739
|
+
version: "1.0.0"
|
|
8740
|
+
},
|
|
8741
|
+
{
|
|
8742
|
+
action: "inbox.checkByToken",
|
|
8743
|
+
resource_type: "inbox:item",
|
|
8744
|
+
required_relations: ["viewer", "editor", "admin", "owner"],
|
|
8745
|
+
required_scopes: ["inbox"],
|
|
8746
|
+
capability: "inbox.read",
|
|
8747
|
+
input_schema: {
|
|
8748
|
+
type: "object",
|
|
8749
|
+
properties: {
|
|
8750
|
+
token: { type: "string", minLength: 1, description: "Opaque access token for a single inbox item" }
|
|
8751
|
+
},
|
|
8752
|
+
required: ["token"],
|
|
8753
|
+
additionalProperties: false
|
|
8754
|
+
},
|
|
8755
|
+
constraints: { rate_bucket: "inbox.read" },
|
|
8756
|
+
effects: ["Read:InboxItem"],
|
|
8757
|
+
risk: "low",
|
|
8758
|
+
target_bindings: {
|
|
8759
|
+
// inbox.checkByToken authenticates via the opaque HMAC token itself —
|
|
8760
|
+
// the token IS the authorization credential and must NOT appear in logs
|
|
8761
|
+
// or API error responses (resolvedResourceId surfaces on resource mismatch).
|
|
8762
|
+
// This action is dispatched before requireActor() so it bypasses the
|
|
8763
|
+
// normal grant-mediated authz path entirely. We deliberately bind to a
|
|
8764
|
+
// context key that the runtime never populates so that resource_id always
|
|
8765
|
+
// resolves to null and the secret token never reaches resolvedResourceId.
|
|
8766
|
+
resource_id: { source: "context", key: "inbox_item_id" }
|
|
8767
|
+
},
|
|
8768
|
+
version: "1.0.0"
|
|
8769
|
+
},
|
|
8770
|
+
{
|
|
8771
|
+
action: "inbox.complete",
|
|
8772
|
+
resource_type: "inbox:item",
|
|
8773
|
+
required_relations: ["editor", "act_as"],
|
|
8774
|
+
required_scopes: ["inbox"],
|
|
8775
|
+
capability: "inbox.write",
|
|
8776
|
+
input_schema: {
|
|
8777
|
+
type: "object",
|
|
8778
|
+
properties: {
|
|
8779
|
+
id: { type: "string", minLength: 1, description: "Inbox item id being completed" },
|
|
8780
|
+
result: { type: "object", description: "Result payload for the completed task" }
|
|
8781
|
+
},
|
|
8782
|
+
required: ["id", "result"],
|
|
8783
|
+
additionalProperties: false
|
|
8784
|
+
},
|
|
8785
|
+
constraints: { rate_bucket: "inbox.write" },
|
|
8786
|
+
effects: ["Update:InboxItem"],
|
|
8787
|
+
// low: inbox.complete marks an inbox item as done by the owning agent —
|
|
8788
|
+
// this is an internal state update on the agent's own task list, not an
|
|
8789
|
+
// external-facing write that needs human approval. (inbox.send / inbox.respond
|
|
8790
|
+
// are high because they create messages visible to other people.)
|
|
8791
|
+
risk: "low",
|
|
8792
|
+
target_bindings: {
|
|
8793
|
+
resource_id: { source: "param", param: "id" }
|
|
8794
|
+
},
|
|
8795
|
+
version: "1.0.0"
|
|
8796
|
+
},
|
|
8797
|
+
// ─── Scheduling Actions (internal) ───
|
|
8798
|
+
// scheduling.request is a meeting-time negotiation façade over inbox.send.
|
|
8799
|
+
// Candidate slots may be supplied two ways (server-side EXCLUSIVE — exactly
|
|
8800
|
+
// one): (a) `candidates` — the agent computes them LLM-side from the user
|
|
8801
|
+
// calendar and the server validates + freebusy-filters them, or (b)
|
|
8802
|
+
// `candidateWindow` — the agent hands the server a { start, end } window and
|
|
8803
|
+
// the server generates busy-free candidates from the sender's Google
|
|
8804
|
+
// Calendar. Like the inbox actions it is internal (no external OAuth
|
|
8805
|
+
// provider), so it carries the single nominal base scope `inbox`.
|
|
8806
|
+
//
|
|
8807
|
+
// NOTE: the candidates/candidateWindow exclusivity is expressed here as
|
|
8808
|
+
// `oneOf` for documentation + the deep JSON-Schema authorities, but the SDK's
|
|
8809
|
+
// hand-written `validateActionInput` is a SHALLOW shape gate that does NOT
|
|
8810
|
+
// interpret `oneOf` (neither key is in top-level `required`). The exclusivity
|
|
8811
|
+
// (exactly one of candidates/candidateWindow) is ENFORCED server-side in
|
|
8812
|
+
// SchedulingRequestService — see that service for the 400s on both-given /
|
|
8813
|
+
// both-missing.
|
|
8814
|
+
// Spec: docs/specs/2026-06-10-inbox-intent-routing-design.md §2.1
|
|
8815
|
+
{
|
|
8816
|
+
action: "scheduling.request",
|
|
8817
|
+
resource_type: "inbox:item",
|
|
8818
|
+
required_relations: ["editor", "act_as"],
|
|
8819
|
+
required_scopes: ["inbox"],
|
|
8820
|
+
capability: "inbox.write",
|
|
8821
|
+
input_schema: {
|
|
8822
|
+
type: "object",
|
|
8823
|
+
properties: {
|
|
8824
|
+
to: { type: "string", minLength: 1, description: "Counterpart (user id / email) to negotiate a meeting time with" },
|
|
8825
|
+
topic: { type: "string", minLength: 1, description: "Meeting topic shown to the counterpart" },
|
|
8826
|
+
durationMinutes: { type: "integer", minimum: 5, maximum: 480, description: "Meeting length in minutes" },
|
|
8827
|
+
candidates: {
|
|
8828
|
+
type: "array",
|
|
8829
|
+
minItems: 1,
|
|
8830
|
+
maxItems: 10,
|
|
8831
|
+
description: "Explicit candidate slots computed by the agent from the user calendar. The server validates them AND (when Google Calendar is connected) filters out any that conflict with the sender's calendar. Mutually exclusive with candidateWindow \u2014 supply exactly one.",
|
|
8832
|
+
items: {
|
|
8833
|
+
type: "object",
|
|
8834
|
+
properties: {
|
|
8835
|
+
start: { type: "string", description: "ISO 8601 start" },
|
|
8836
|
+
end: { type: "string", description: "ISO 8601 end" }
|
|
8837
|
+
},
|
|
8838
|
+
required: ["start", "end"],
|
|
8839
|
+
additionalProperties: false
|
|
8840
|
+
}
|
|
8841
|
+
},
|
|
8842
|
+
// candidateWindow is `{start,end}` OR an ARRAY of `{start,end}` ranges
|
|
8843
|
+
// (multi-range). We declare `type: ['object', 'array']` — the SDK
|
|
8844
|
+
// shallow validator (matchesType) does not handle an ARRAY of types
|
|
8845
|
+
// (its switch is on a single string), so it hits `default: return true`
|
|
8846
|
+
// and passes BOTH the single object and the array form (B-1 — an array
|
|
8847
|
+
// must NOT be rejected before reaching the server). The union type also
|
|
8848
|
+
// keeps the AJV strict-mode meta-schema happy (a `required`/`properties`
|
|
8849
|
+
// subschema needs SOME type). The nested `properties`/`required` below
|
|
8850
|
+
// describe the object form for the deep JSON-Schema authorities; the
|
|
8851
|
+
// array element shape and the deep constraints (ISO, start<end, ≤5
|
|
8852
|
+
// ranges, ≤62-day total span) are validated server-side in
|
|
8853
|
+
// SchedulingRequestService.validateWindowRanges.
|
|
8854
|
+
candidateWindow: {
|
|
8855
|
+
type: ["object", "array"],
|
|
8856
|
+
description: 'A search window OR an ARRAY of search windows the server fills with busy-free candidate slots from the sender\'s Google Calendar. Each range is `{ start, end }` (ISO 8601) \u2014 an independent contiguous interval the server searches within, spreading candidates across ranges. "\u5E73\u65E5\u5348\u5F8C" = one range per business day (Mon 13-18 / Tue 13-18 / \u2026); "\u6708\u66DC\u5348\u524D or \u6728\u66DC\u5348\u5F8C" = two ranges. A single contiguous span = one range. Max 5 ranges, total span \u2264 62 days. Mutually exclusive with candidates \u2014 supply exactly one. Requires a connected Google Calendar.',
|
|
8857
|
+
properties: {
|
|
8858
|
+
start: { type: "string", description: "ISO 8601 range start" },
|
|
8859
|
+
end: { type: "string", description: "ISO 8601 range end" }
|
|
8860
|
+
},
|
|
8861
|
+
required: ["start", "end"],
|
|
8862
|
+
additionalProperties: false
|
|
8863
|
+
},
|
|
8864
|
+
hold: {
|
|
8865
|
+
type: "boolean",
|
|
8866
|
+
description: "When true (or omitted, when the sender's delegation policy has holds enabled), tentatively hold the offered slots on the sender's calendar as [\u4EEE] events until the counterpart responds or the request expires. Pass false to skip holds for this request. Only takes effect when the sender has an enabled scheduling delegation policy."
|
|
8867
|
+
},
|
|
8868
|
+
message: { type: "string", description: "Optional human-readable message" }
|
|
8869
|
+
},
|
|
8870
|
+
// candidates / candidateWindow are intentionally NOT in `required`: the
|
|
8871
|
+
// exclusive-choice is documented via `oneOf` and enforced server-side.
|
|
8872
|
+
// Each oneOf branch re-declares its property locally (empty `properties`
|
|
8873
|
+
// entry) so AJV strict mode (`strictRequired`) sees the required key as
|
|
8874
|
+
// defined within the branch scope — the value shape itself is validated
|
|
8875
|
+
// by the top-level `properties` above.
|
|
8876
|
+
required: ["to", "topic", "durationMinutes"],
|
|
8877
|
+
oneOf: [
|
|
8878
|
+
{ required: ["candidates"], properties: { candidates: {} } },
|
|
8879
|
+
{ required: ["candidateWindow"], properties: { candidateWindow: {} } }
|
|
8880
|
+
],
|
|
8881
|
+
additionalProperties: false
|
|
8882
|
+
},
|
|
8883
|
+
constraints: { rate_bucket: "inbox.write" },
|
|
8884
|
+
effects: ["Create:InboxItem"],
|
|
8885
|
+
risk: "high",
|
|
8886
|
+
target_bindings: {
|
|
8887
|
+
resource_id: { source: "param", param: "to" }
|
|
8888
|
+
},
|
|
8889
|
+
version: "1.0.0"
|
|
8890
|
+
},
|
|
8891
|
+
// ─── PR-R2 (design §3.2): the raw booking executor's ONE new action ───
|
|
8892
|
+
// The booking agent submits its scheduling proposal through a REAL PEP
|
|
8893
|
+
// crossing instead of a managed custom_tool. Registered here in R2; the
|
|
8894
|
+
// adapter dispatch case lands in R3.
|
|
8895
|
+
//
|
|
8896
|
+
// 🔴 risk: 'high' is deliberate and must NOT be downgraded. Every writing
|
|
8897
|
+
// sibling (inbox.send / inbox.respond / scheduling.request) is high, and
|
|
8898
|
+
// inbox.respond's own comment states that agent-mediated responses must
|
|
8899
|
+
// always go through human approval. The approval basis here is the
|
|
8900
|
+
// visitor's explicit "AIで日程調整する" click (or the flag-gated OIDC
|
|
8901
|
+
// auto-consent), captured at mint time as a first-class ApprovalToken
|
|
8902
|
+
// ledger row — NOT an absence of approval.
|
|
8903
|
+
//
|
|
8904
|
+
// 🪤 target_bindings.resource_id binds the BARE `itemId`. It must equal
|
|
8905
|
+
// canonicalResourceId('scheduling.submit_response', { itemId }) exactly.
|
|
8906
|
+
// A prefixed value (e.g. 'inbox:item/<id>') does not match the approval
|
|
8907
|
+
// assertion at invoke time and the call SILENTLY falls through to
|
|
8908
|
+
// auth_required (202) — no error surfaces, which is why the api side
|
|
8909
|
+
// carries a preflight-parity spec asserting three-way equality
|
|
8910
|
+
// (migration grant resource == assertion resource_id == invoke-time
|
|
8911
|
+
// canonicalResourceId).
|
|
8912
|
+
{
|
|
8913
|
+
action: "scheduling.submit_response",
|
|
8914
|
+
resource_type: "inbox:item",
|
|
8915
|
+
required_relations: ["editor", "act_as"],
|
|
8916
|
+
required_scopes: ["inbox"],
|
|
8917
|
+
capability: "inbox.write",
|
|
8918
|
+
input_schema: {
|
|
8919
|
+
type: "object",
|
|
8920
|
+
properties: {
|
|
8921
|
+
itemId: { type: "string", minLength: 1, description: "The inbox item the proposal answers" },
|
|
8922
|
+
decision: { type: "string", enum: ["propose", "decline"], description: "Whether the agent proposes slots or declines" },
|
|
8923
|
+
slots: {
|
|
8924
|
+
type: "array",
|
|
8925
|
+
maxItems: 10,
|
|
8926
|
+
description: "Proposed candidate slots (empty for a decline)",
|
|
8927
|
+
items: {
|
|
8928
|
+
type: "object",
|
|
8929
|
+
properties: {
|
|
8930
|
+
start: { type: "string", description: "ISO 8601 start" },
|
|
8931
|
+
end: { type: "string", description: "ISO 8601 end" }
|
|
8932
|
+
},
|
|
8933
|
+
required: ["start", "end"],
|
|
8934
|
+
additionalProperties: false
|
|
8935
|
+
}
|
|
8936
|
+
},
|
|
8937
|
+
recommendedSlotIndex: { type: ["integer", "null"], description: "Index into slots of the recommended option, or null" },
|
|
8938
|
+
recommendationReason: { type: "string", description: "Short rationale shown to the visitor" }
|
|
8939
|
+
},
|
|
8940
|
+
required: ["itemId", "decision"],
|
|
8941
|
+
additionalProperties: false
|
|
8942
|
+
},
|
|
8943
|
+
constraints: { rate_bucket: "inbox.write" },
|
|
8944
|
+
effects: ["Update:InboxItem"],
|
|
8945
|
+
risk: "high",
|
|
8946
|
+
target_bindings: {
|
|
8947
|
+
resource_id: { source: "param", param: "itemId" }
|
|
8948
|
+
},
|
|
8949
|
+
version: "1.0.0"
|
|
8950
|
+
}
|
|
8951
|
+
],
|
|
8952
|
+
capabilities: [
|
|
8953
|
+
{
|
|
8954
|
+
capability: "slack.messaging.basic",
|
|
8955
|
+
description: "Post, update, and delete messages in channels",
|
|
8956
|
+
includes: ["slack.message.post", "slack.message.update", "slack.message.delete"],
|
|
8957
|
+
version: "1.0.0"
|
|
8958
|
+
},
|
|
8959
|
+
{
|
|
8960
|
+
capability: "slack.read.basic",
|
|
8961
|
+
description: "Read channels, messages, and user info",
|
|
8962
|
+
includes: ["slack.channel.read", "slack.user.read", "slack.message.read", "slack.message.read_paginated", "slack.batch.read"],
|
|
8963
|
+
version: "1.0.0"
|
|
8964
|
+
},
|
|
8965
|
+
{
|
|
8966
|
+
capability: "github.read.basic",
|
|
8967
|
+
description: "Read issues, pull requests and repository contents from repositories",
|
|
8968
|
+
includes: ["github.issue.list", "github.issue.read", "github.pr.list", "github.pr.read", "github.pr.files.list", "github.pr.review.list", "github.pr.search", "github.repo.search", "github.repo.collaborator.list", "github.content.get", "github.tree.get", "github.branch.list", "github.commit.get", "github.commit.list", "github.commit.search", "github.tag.list", "github.release.list", "github.release.getLatest", "github.release.getByTag", "github.code.search", "github.issue.search", "github.issue.types.list", "github.label.get", "github.label.list", "github.workflow.get", "github.workflow.list", "github.workflow.jobLogs.get", "github.repo.starred.list", "github.user.me.get", "github.org.teams.list", "github.team.members.list", "github.user.search", "github.notification.list", "github.notification.get", "github.gist.get", "github.gist.list"],
|
|
8969
|
+
version: "1.0.0"
|
|
8970
|
+
},
|
|
8971
|
+
{
|
|
8972
|
+
capability: "github.issues.triage",
|
|
8973
|
+
description: "Create and update issues, post issue comments, manage sub-issues and labels",
|
|
8974
|
+
includes: ["github.issue.create", "github.issue.update", "github.issue.comment.create", "github.issue.subissue.write", "github.label.write"],
|
|
8975
|
+
version: "1.0.0"
|
|
8976
|
+
},
|
|
8977
|
+
{
|
|
8978
|
+
capability: "github.pulls.write",
|
|
8979
|
+
description: "Create, update, merge, and review pull requests",
|
|
8980
|
+
includes: ["github.pr.create", "github.pr.update", "github.pr.merge", "github.pr.review.create", "github.pr.comment.reply", "github.pr.branch.update"],
|
|
8981
|
+
version: "1.0.0"
|
|
8982
|
+
},
|
|
8983
|
+
{
|
|
8984
|
+
capability: "github.repos.write",
|
|
8985
|
+
description: "\u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u4F5C\u6210\u30FB\u30D5\u30A9\u30FC\u30AF\u30FB\u30D5\u30A1\u30A4\u30EB\u66F4\u65B0\u30FB\u30D6\u30E9\u30F3\u30C1\u4F5C\u6210\u30FB\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u5B9F\u884C\u30FB\u30B9\u30BF\u30FC\u64CD\u4F5C",
|
|
8986
|
+
includes: ["github.repo.create", "github.repo.fork", "github.content.createOrUpdate", "github.content.delete", "github.branch.create", "github.workflow.run", "github.repo.star", "github.repo.unstar"],
|
|
8987
|
+
version: "1.0.0"
|
|
8988
|
+
},
|
|
8989
|
+
{
|
|
8990
|
+
capability: "github.notifications.write",
|
|
8991
|
+
description: "\u901A\u77E5\u306E\u65E2\u8AAD\u5316\u30FB\u30B9\u30EC\u30C3\u30C9/\u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u8CFC\u8AAD\u8A2D\u5B9A",
|
|
8992
|
+
includes: ["github.notification.markRead", "github.notification.markAllRead", "github.notification.subscription.set", "github.notification.repoSubscription.set"],
|
|
8993
|
+
version: "1.0.0"
|
|
8994
|
+
},
|
|
8995
|
+
{
|
|
8996
|
+
capability: "github.gists.write",
|
|
8997
|
+
description: "Gist \u306E\u4F5C\u6210\u30FB\u66F4\u65B0",
|
|
8998
|
+
includes: ["github.gist.create", "github.gist.update"],
|
|
8999
|
+
version: "1.0.0"
|
|
9000
|
+
},
|
|
9001
|
+
{
|
|
9002
|
+
capability: "gmail.read.basic",
|
|
9003
|
+
description: "Read and search Gmail messages and labels",
|
|
9004
|
+
includes: ["gmail.message.search", "gmail.message.read", "gmail.label.read", "gmail.batch.read"],
|
|
9005
|
+
version: "1.0.0"
|
|
9006
|
+
},
|
|
9007
|
+
{
|
|
9008
|
+
capability: "gmail.compose",
|
|
9009
|
+
description: "Send emails and create drafts via Gmail",
|
|
9010
|
+
includes: ["gmail.message.send", "gmail.draft.create"],
|
|
9011
|
+
version: "1.0.0"
|
|
9012
|
+
},
|
|
9013
|
+
{
|
|
9014
|
+
capability: "gmail.manage",
|
|
9015
|
+
description: "Trash and permanently delete Gmail messages",
|
|
9016
|
+
includes: ["gmail.message.trash", "gmail.message.delete"],
|
|
9017
|
+
version: "1.0.0"
|
|
9018
|
+
},
|
|
9019
|
+
{
|
|
9020
|
+
capability: "calendar.read.basic",
|
|
9021
|
+
description: "Read and list Google Calendar events, and check free/busy availability",
|
|
9022
|
+
includes: ["calendar.event.list", "calendar.event.read", "calendar.freebusy"],
|
|
9023
|
+
version: "1.0.0"
|
|
9024
|
+
},
|
|
9025
|
+
{
|
|
9026
|
+
capability: "calendar.write",
|
|
9027
|
+
description: "Create, update, and delete Google Calendar events",
|
|
9028
|
+
includes: ["calendar.event.create", "calendar.event.update", "calendar.event.delete"],
|
|
9029
|
+
version: "1.0.0"
|
|
9030
|
+
},
|
|
9031
|
+
{
|
|
9032
|
+
capability: "jira.read.basic",
|
|
9033
|
+
description: "Read Jira issues, projects, boards, sprints, issue link types, and users",
|
|
9034
|
+
includes: ["jira.project.read", "jira.board.read", "jira.sprint.read", "jira.issue.list", "jira.issue.search", "jira.worklog.read", "jira.issue.read", "jira.batch.read", "jira.comment.read", "jira.transition.list", "jira.issuelinktype.list", "jira.user.search"],
|
|
9035
|
+
version: "1.0.0"
|
|
9036
|
+
},
|
|
9037
|
+
{
|
|
9038
|
+
capability: "jira.write.basic",
|
|
9039
|
+
description: "Create, update, delete Jira issues, manage issue links, and add/delete comments",
|
|
9040
|
+
includes: ["jira.issue.create", "jira.issue.update", "jira.issue.delete", "jira.comment.create", "jira.comment.delete", "jira.issue.transition", "jira.issuelink.create", "jira.issuelink.delete"],
|
|
9041
|
+
version: "1.0.0"
|
|
9042
|
+
},
|
|
9043
|
+
{
|
|
9044
|
+
capability: "inbox.write",
|
|
9045
|
+
description: "Send and respond to agent inbox tasks",
|
|
9046
|
+
includes: ["inbox.send", "inbox.respond", "inbox.complete", "scheduling.request", "scheduling.submit_response"],
|
|
9047
|
+
version: "1.0.0"
|
|
9048
|
+
},
|
|
9049
|
+
{
|
|
9050
|
+
capability: "inbox.read",
|
|
9051
|
+
description: "Read agent inbox tasks",
|
|
9052
|
+
includes: ["inbox.check", "inbox.checkByToken"],
|
|
9053
|
+
version: "1.0.0"
|
|
9054
|
+
},
|
|
9055
|
+
{
|
|
9056
|
+
capability: "linear.read.basic",
|
|
9057
|
+
description: "Read Linear issues, comments, projects, teams, workflow states, labels, users, viewer info, issue relations, cycles, and attachments",
|
|
9058
|
+
includes: [
|
|
9059
|
+
"linear.issue.list",
|
|
9060
|
+
"linear.issue.read",
|
|
9061
|
+
"linear.issue.search",
|
|
9062
|
+
"linear.comment.list",
|
|
9063
|
+
"linear.project.list",
|
|
9064
|
+
"linear.project.read",
|
|
9065
|
+
"linear.team.list",
|
|
9066
|
+
"linear.workflowState.list",
|
|
9067
|
+
"linear.viewer.read",
|
|
9068
|
+
"linear.label.list",
|
|
9069
|
+
"linear.user.list",
|
|
9070
|
+
"linear.issueRelation.list",
|
|
9071
|
+
"linear.cycle.list",
|
|
9072
|
+
"linear.cycle.read",
|
|
9073
|
+
"linear.attachment.list"
|
|
9074
|
+
],
|
|
9075
|
+
version: "1.0.0"
|
|
9076
|
+
},
|
|
9077
|
+
{
|
|
9078
|
+
capability: "linear.write.basic",
|
|
9079
|
+
description: "Create, update, archive, delete Linear issues, comments, projects, labels, cycles, attachments, and issue relations",
|
|
9080
|
+
includes: [
|
|
9081
|
+
"linear.issue.create",
|
|
9082
|
+
"linear.issue.update",
|
|
9083
|
+
"linear.comment.create",
|
|
9084
|
+
"linear.issue.archive",
|
|
9085
|
+
"linear.project.create",
|
|
9086
|
+
"linear.project.update",
|
|
9087
|
+
"linear.comment.update",
|
|
9088
|
+
"linear.comment.delete",
|
|
9089
|
+
"linear.comment.resolve",
|
|
9090
|
+
"linear.comment.unresolve",
|
|
9091
|
+
"linear.issue.unarchive",
|
|
9092
|
+
"linear.issue.addLabel",
|
|
9093
|
+
"linear.issue.removeLabel",
|
|
9094
|
+
"linear.issue.subscribe",
|
|
9095
|
+
"linear.issue.delete",
|
|
9096
|
+
"linear.issueRelation.create",
|
|
9097
|
+
"linear.issueRelation.delete",
|
|
9098
|
+
"linear.cycle.create",
|
|
9099
|
+
"linear.cycle.update",
|
|
9100
|
+
"linear.label.create",
|
|
9101
|
+
"linear.label.update",
|
|
9102
|
+
"linear.attachment.create",
|
|
9103
|
+
"linear.attachment.delete"
|
|
9104
|
+
],
|
|
9105
|
+
version: "1.0.0"
|
|
9106
|
+
}
|
|
9107
|
+
]
|
|
9108
|
+
};
|
|
9109
|
+
|
|
9110
|
+
// src/registry/resource-type-labels.ts
|
|
9111
|
+
var RESOURCE_TYPE_LABELS = {
|
|
9112
|
+
"github:repo": "\u5BFE\u8C61\u30EA\u30DD\u30B8\u30C8\u30EA",
|
|
9113
|
+
"github:org": "\u5BFE\u8C61\u7D44\u7E54"
|
|
9114
|
+
};
|
|
9115
|
+
|
|
9116
|
+
// src/registry/action-input-validator.ts
|
|
9117
|
+
var SCHEMA_INDEX = (() => {
|
|
9118
|
+
const map = /* @__PURE__ */ new Map();
|
|
9119
|
+
for (const a of ACTION_REGISTRY.actions) {
|
|
9120
|
+
if (a && typeof a.action === "string" && a.input_schema) {
|
|
9121
|
+
map.set(a.action, a.input_schema);
|
|
9122
|
+
}
|
|
9123
|
+
}
|
|
9124
|
+
return map;
|
|
9125
|
+
})();
|
|
9126
|
+
function describeExpectedShape(schema) {
|
|
9127
|
+
const props = schema.properties ?? {};
|
|
9128
|
+
const required = Array.isArray(schema.required) ? schema.required : [];
|
|
9129
|
+
const requiredSet = new Set(required);
|
|
9130
|
+
const parts = [];
|
|
9131
|
+
const orderedKeys = [
|
|
9132
|
+
...required.filter((k) => k in props),
|
|
9133
|
+
...Object.keys(props).filter((k) => !requiredSet.has(k))
|
|
9134
|
+
];
|
|
9135
|
+
for (const key of orderedKeys) {
|
|
9136
|
+
const prop = props[key] || {};
|
|
9137
|
+
const optionalMark = requiredSet.has(key) ? "" : "?";
|
|
9138
|
+
const enumVals = Array.isArray(prop.enum) ? prop.enum : void 0;
|
|
9139
|
+
if (enumVals && enumVals.length > 0) {
|
|
9140
|
+
const rendered = enumVals.map((v) => typeof v === "string" ? `'${v}'` : String(v)).join(" | ");
|
|
9141
|
+
parts.push(`${key}${optionalMark}: ${rendered}`);
|
|
9142
|
+
} else {
|
|
9143
|
+
parts.push(`${key}${optionalMark}`);
|
|
9144
|
+
}
|
|
9145
|
+
}
|
|
9146
|
+
return `{ ${parts.join(", ")} }`;
|
|
9147
|
+
}
|
|
9148
|
+
function matchesType(value, type) {
|
|
9149
|
+
if (!type) return true;
|
|
9150
|
+
switch (type) {
|
|
9151
|
+
case "string":
|
|
9152
|
+
return typeof value === "string";
|
|
9153
|
+
case "integer":
|
|
9154
|
+
return typeof value === "number" && Number.isInteger(value);
|
|
9155
|
+
case "number":
|
|
9156
|
+
return typeof value === "number";
|
|
9157
|
+
case "boolean":
|
|
9158
|
+
return typeof value === "boolean";
|
|
9159
|
+
case "array":
|
|
9160
|
+
return Array.isArray(value);
|
|
9161
|
+
case "object":
|
|
9162
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9163
|
+
default:
|
|
9164
|
+
return true;
|
|
9165
|
+
}
|
|
9166
|
+
}
|
|
9167
|
+
function validateActionInput(action, params) {
|
|
9168
|
+
const schema = SCHEMA_INDEX.get(action);
|
|
9169
|
+
if (!schema) {
|
|
9170
|
+
return { valid: true };
|
|
9171
|
+
}
|
|
9172
|
+
const props = schema.properties ?? {};
|
|
9173
|
+
const required = Array.isArray(schema.required) ? schema.required : [];
|
|
9174
|
+
const additionalProps = schema.additionalProperties;
|
|
9175
|
+
const safeParams = params && typeof params === "object" && !Array.isArray(params) ? params : {};
|
|
9176
|
+
const missing = [];
|
|
9177
|
+
const unknown = [];
|
|
9178
|
+
const enumErrors = [];
|
|
9179
|
+
const typeErrors = [];
|
|
9180
|
+
for (const key of required) {
|
|
9181
|
+
if (!(key in safeParams) || safeParams[key] === void 0 || safeParams[key] === null) {
|
|
9182
|
+
missing.push(key);
|
|
9183
|
+
}
|
|
9184
|
+
}
|
|
9185
|
+
if (additionalProps === false) {
|
|
9186
|
+
for (const key of Object.keys(safeParams)) {
|
|
9187
|
+
if (!(key in props)) {
|
|
9188
|
+
unknown.push(key);
|
|
9189
|
+
}
|
|
9190
|
+
}
|
|
9191
|
+
}
|
|
9192
|
+
for (const key of Object.keys(props)) {
|
|
9193
|
+
if (!(key in safeParams)) continue;
|
|
9194
|
+
const value = safeParams[key];
|
|
9195
|
+
if (value === void 0 || value === null) continue;
|
|
9196
|
+
const prop = props[key] || {};
|
|
9197
|
+
const enumVals = Array.isArray(prop.enum) ? prop.enum : void 0;
|
|
9198
|
+
if (enumVals && enumVals.length > 0) {
|
|
9199
|
+
if (!enumVals.includes(value)) {
|
|
9200
|
+
enumErrors.push(key);
|
|
9201
|
+
continue;
|
|
9202
|
+
}
|
|
9203
|
+
}
|
|
9204
|
+
if (!matchesType(value, prop.type)) {
|
|
9205
|
+
typeErrors.push(key);
|
|
9206
|
+
}
|
|
9207
|
+
}
|
|
9208
|
+
if (missing.length === 0 && unknown.length === 0 && enumErrors.length === 0 && typeErrors.length === 0) {
|
|
9209
|
+
return { valid: true };
|
|
9210
|
+
}
|
|
9211
|
+
const segments = [];
|
|
9212
|
+
if (missing.length > 0) {
|
|
9213
|
+
segments.push(`missing required parameter(s) [${missing.join(", ")}]`);
|
|
9214
|
+
}
|
|
9215
|
+
if (unknown.length > 0) {
|
|
9216
|
+
segments.push(`unknown parameter(s) [${unknown.join(", ")}]`);
|
|
9217
|
+
}
|
|
9218
|
+
if (enumErrors.length > 0) {
|
|
9219
|
+
const details = enumErrors.map((key) => {
|
|
9220
|
+
const enumVals = props[key]?.enum || [];
|
|
9221
|
+
const rendered = enumVals.map((v) => typeof v === "string" ? `'${v}'` : String(v)).join(" | ");
|
|
9222
|
+
return `${key} (allowed: ${rendered})`;
|
|
9223
|
+
}).join(", ");
|
|
9224
|
+
segments.push(`invalid value for enum parameter(s) [${details}]`);
|
|
9225
|
+
}
|
|
9226
|
+
if (typeErrors.length > 0) {
|
|
9227
|
+
const details = typeErrors.map((key) => `${key} (expected ${props[key]?.type})`).join(", ");
|
|
9228
|
+
segments.push(`wrong type for parameter(s) [${details}]`);
|
|
9229
|
+
}
|
|
9230
|
+
const message = `${action}: ${segments.join("; ")}. Expected shape: ${describeExpectedShape(schema)}`;
|
|
9231
|
+
return { valid: false, errors: [message] };
|
|
9232
|
+
}
|
|
9233
|
+
|
|
9234
|
+
// src/registry/resource-types.ts
|
|
9235
|
+
var RESOURCE_TYPES = {
|
|
9236
|
+
// Slack
|
|
9237
|
+
SLACK_CHANNEL: "slack:channel",
|
|
9238
|
+
SLACK_USER: "slack:user",
|
|
9239
|
+
SLACK_WORKSPACE: "slack:workspace",
|
|
9240
|
+
// GitHub
|
|
9241
|
+
GITHUB_REPO: "github:repo",
|
|
9242
|
+
GITHUB_ORG: "github:org",
|
|
9243
|
+
GITHUB_ISSUE: "github:issue",
|
|
9244
|
+
// Google Drive
|
|
9245
|
+
GOOGLE_DRIVE_FILE: "google:drive:file",
|
|
9246
|
+
GOOGLE_DRIVE_FOLDER: "google:drive:folder",
|
|
9247
|
+
// Gmail
|
|
9248
|
+
GMAIL_THREAD: "gmail:thread",
|
|
9249
|
+
GMAIL_LABEL: "gmail:label",
|
|
9250
|
+
// Jira
|
|
9251
|
+
JIRA_PROJECT: "jira:project",
|
|
9252
|
+
JIRA_BOARD: "jira:board",
|
|
9253
|
+
JIRA_ISSUE: "jira:issue",
|
|
9254
|
+
JIRA_SPRINT: "jira:sprint",
|
|
9255
|
+
// HubSpot
|
|
9256
|
+
HUBSPOT_OBJECT: "hubspot:object",
|
|
9257
|
+
HUBSPOT_PROPERTY: "hubspot:property",
|
|
9258
|
+
HUBSPOT_SCHEMA: "hubspot:schema",
|
|
9259
|
+
HUBSPOT_ASSOCIATION: "hubspot:association",
|
|
8219
9260
|
HUBSPOT_ENGAGEMENT: "hubspot:engagement",
|
|
8220
9261
|
HUBSPOT_WORKFLOW: "hubspot:workflow",
|
|
8221
9262
|
HUBSPOT_ACCOUNT: "hubspot:account",
|
|
@@ -8436,188 +9477,773 @@ var ACTION_DISPLAY_CONFIGS = {
|
|
|
8436
9477
|
"slack.message.post": {
|
|
8437
9478
|
summaryTemplate: (p) => {
|
|
8438
9479
|
const parts = [];
|
|
8439
|
-
if (p.channel) parts.push(p.channel + ":");
|
|
8440
|
-
if (p.text) parts.push(String(p.text));
|
|
9480
|
+
if (p.channel) parts.push(p.channel + ":");
|
|
9481
|
+
if (p.text) parts.push(String(p.text));
|
|
9482
|
+
return parts.join(" ");
|
|
9483
|
+
},
|
|
9484
|
+
displayFields: [
|
|
9485
|
+
{ key: "channel", label: "Channel" },
|
|
9486
|
+
{ key: "text", label: "Message" }
|
|
9487
|
+
]
|
|
9488
|
+
},
|
|
9489
|
+
"gmail.message.send": {
|
|
9490
|
+
summaryTemplate: (p) => {
|
|
9491
|
+
const parts = [];
|
|
9492
|
+
if (p.to) parts.push(`To: ${p.to}`);
|
|
9493
|
+
if (p.subject) parts.push(`Subject: ${p.subject}`);
|
|
9494
|
+
return parts.join(", ");
|
|
9495
|
+
},
|
|
9496
|
+
displayFields: [
|
|
9497
|
+
{ key: "to", label: "To" },
|
|
9498
|
+
{ key: "subject", label: "Subject" },
|
|
9499
|
+
{ key: "body", label: "Body" }
|
|
9500
|
+
]
|
|
9501
|
+
},
|
|
9502
|
+
"gmail.draft.create": {
|
|
9503
|
+
summaryTemplate: (p) => {
|
|
9504
|
+
const parts = [];
|
|
9505
|
+
if (p.to) parts.push(`To: ${p.to}`);
|
|
9506
|
+
if (p.subject) parts.push(`Subject: ${p.subject}`);
|
|
9507
|
+
return parts.join(", ");
|
|
9508
|
+
},
|
|
9509
|
+
displayFields: [
|
|
9510
|
+
{ key: "to", label: "To" },
|
|
9511
|
+
{ key: "subject", label: "Subject" },
|
|
9512
|
+
{ key: "body", label: "Body" }
|
|
9513
|
+
]
|
|
9514
|
+
},
|
|
9515
|
+
"calendar.event.create": {
|
|
9516
|
+
summaryTemplate: (p) => {
|
|
9517
|
+
const parts = [];
|
|
9518
|
+
if (p.summary) parts.push(p.summary);
|
|
9519
|
+
if (p.start) parts.push(`(${formatCalendarTime(p.start)})`);
|
|
9520
|
+
return parts.join(" ");
|
|
9521
|
+
},
|
|
9522
|
+
displayFields: [
|
|
9523
|
+
{ key: "summary", label: "Event" },
|
|
9524
|
+
{ key: "start", label: "Start" },
|
|
9525
|
+
{ key: "end", label: "End" },
|
|
9526
|
+
{ key: "attendees", label: "Attendees" }
|
|
9527
|
+
]
|
|
9528
|
+
},
|
|
9529
|
+
"calendar.event.update": {
|
|
9530
|
+
summaryTemplate: (p) => {
|
|
9531
|
+
const parts = [];
|
|
9532
|
+
if (p.summary) parts.push(p.summary);
|
|
9533
|
+
if (p.start) parts.push(`(${formatCalendarTime(p.start)})`);
|
|
9534
|
+
return parts.join(" ");
|
|
9535
|
+
},
|
|
9536
|
+
displayFields: [
|
|
9537
|
+
{ key: "summary", label: "Event" },
|
|
9538
|
+
{ key: "start", label: "Start" },
|
|
9539
|
+
{ key: "end", label: "End" },
|
|
9540
|
+
{ key: "attendees", label: "Attendees" }
|
|
9541
|
+
]
|
|
9542
|
+
},
|
|
9543
|
+
"jira.issue.create": {
|
|
9544
|
+
summaryTemplate: (p) => {
|
|
9545
|
+
const parts = [];
|
|
9546
|
+
const projectKey = jiraField(
|
|
9547
|
+
p,
|
|
9548
|
+
["projectKey", "project"],
|
|
9549
|
+
"project",
|
|
9550
|
+
(v) => typeof v === "string" ? v : v?.key
|
|
9551
|
+
);
|
|
9552
|
+
const summary = jiraField(p, ["summary"], "summary");
|
|
9553
|
+
if (projectKey) parts.push(`${projectKey}:`);
|
|
9554
|
+
if (summary) parts.push(summary);
|
|
9555
|
+
return parts.join(" ");
|
|
9556
|
+
},
|
|
9557
|
+
// AIDENTITY-54: nested `fields.X` 形式と top-level canonical の両方を
|
|
9558
|
+
// 拾えるよう extract を使う。assignee は null (unassign) も表示。
|
|
9559
|
+
// legacy alias (project / issuetype 等) も top-level 候補に含めて後方互換を保つ。
|
|
9560
|
+
displayFields: [
|
|
9561
|
+
{
|
|
9562
|
+
label: "Project",
|
|
9563
|
+
extract: (p) => jiraField(
|
|
9564
|
+
p,
|
|
9565
|
+
["projectKey", "project"],
|
|
9566
|
+
"project",
|
|
9567
|
+
(v) => typeof v === "string" ? v : v?.key
|
|
9568
|
+
)
|
|
9569
|
+
},
|
|
9570
|
+
{
|
|
9571
|
+
label: "Type",
|
|
9572
|
+
extract: (p) => jiraField(
|
|
9573
|
+
p,
|
|
9574
|
+
["issueTypeName", "issueType", "issuetype"],
|
|
9575
|
+
"issuetype",
|
|
9576
|
+
(v) => typeof v === "string" ? v : v?.name
|
|
9577
|
+
)
|
|
9578
|
+
},
|
|
9579
|
+
{ label: "Summary", extract: (p) => jiraField(p, ["summary"], "summary") },
|
|
9580
|
+
{ label: "Description", extract: (p) => jiraField(p, ["description"], "description") },
|
|
9581
|
+
{
|
|
9582
|
+
label: "Priority",
|
|
9583
|
+
extract: (p) => jiraField(
|
|
9584
|
+
p,
|
|
9585
|
+
["priority"],
|
|
9586
|
+
"priority",
|
|
9587
|
+
(v) => typeof v === "string" ? v : v?.name
|
|
9588
|
+
)
|
|
9589
|
+
},
|
|
9590
|
+
{ label: "Assignee", extract: extractJiraAssigneeDisplay },
|
|
9591
|
+
{ label: "Labels", extract: (p) => jiraField(p, ["labels"], "labels") }
|
|
9592
|
+
]
|
|
9593
|
+
},
|
|
9594
|
+
"jira.issue.update": {
|
|
9595
|
+
summaryTemplate: (p) => {
|
|
9596
|
+
const parts = [];
|
|
9597
|
+
const key = p.issueIdOrKey ?? p.issueKey;
|
|
9598
|
+
const summary = jiraField(p, ["summary"], "summary");
|
|
9599
|
+
if (key) parts.push(`${key}:`);
|
|
9600
|
+
if (summary) parts.push(summary);
|
|
9601
|
+
return parts.join(" ");
|
|
9602
|
+
},
|
|
9603
|
+
displayFields: [
|
|
9604
|
+
// canonical は issueIdOrKey、agent が issueKey で送ってくる旧仕様も拾う。
|
|
9605
|
+
{ label: "Issue", extract: (p) => p.issueIdOrKey ?? p.issueKey },
|
|
9606
|
+
{ label: "Summary", extract: (p) => jiraField(p, ["summary"], "summary") },
|
|
9607
|
+
{ label: "Description", extract: (p) => jiraField(p, ["description"], "description") },
|
|
9608
|
+
{
|
|
9609
|
+
label: "Priority",
|
|
9610
|
+
extract: (p) => jiraField(
|
|
9611
|
+
p,
|
|
9612
|
+
["priority"],
|
|
9613
|
+
"priority",
|
|
9614
|
+
(v) => typeof v === "string" ? v : v?.name
|
|
9615
|
+
)
|
|
9616
|
+
},
|
|
9617
|
+
// AIDENTITY-54: top-level alias (string / object) と null (unassign) も解決。
|
|
9618
|
+
{ label: "Assignee", extract: extractJiraAssigneeDisplay },
|
|
9619
|
+
{ label: "Labels", extract: (p) => jiraField(p, ["labels"], "labels") }
|
|
9620
|
+
]
|
|
9621
|
+
},
|
|
9622
|
+
// AIDENTITY-65: comment 本体は string と ADF document の両方を受けるため、
|
|
9623
|
+
// detail 表示の ADF 描画は formatValueFull 側に任せて key 指定で OK。
|
|
9624
|
+
"jira.comment.create": {
|
|
9625
|
+
summaryTemplate: (p) => {
|
|
9626
|
+
const parts = [];
|
|
9627
|
+
if (p.issueIdOrKey) parts.push(`${p.issueIdOrKey}:`);
|
|
9628
|
+
if (p.body) parts.push(typeof p.body === "string" ? p.body : "[ADF]");
|
|
9629
|
+
return parts.join(" ");
|
|
9630
|
+
},
|
|
9631
|
+
displayFields: [
|
|
9632
|
+
{ key: "issueIdOrKey", label: "Issue" },
|
|
9633
|
+
{ key: "body", label: "Comment" }
|
|
9634
|
+
]
|
|
9635
|
+
},
|
|
9636
|
+
// AIDENTITY-66: 破壊的操作なので「どの issue のどの comment を消すか」を明示する
|
|
9637
|
+
// (jira.issue.delete / jira.issuelink.delete と同じ destructive 表現の方針)。
|
|
9638
|
+
"jira.comment.delete": {
|
|
9639
|
+
summaryTemplate: (p) => {
|
|
9640
|
+
const issue = p.issueIdOrKey ?? p.issueKey;
|
|
9641
|
+
const commentId = p.commentId ?? p.id;
|
|
9642
|
+
if (issue && commentId) return `Delete comment ${commentId} on ${issue}`;
|
|
9643
|
+
if (commentId) return `Delete comment ${commentId}`;
|
|
9644
|
+
return "";
|
|
9645
|
+
},
|
|
9646
|
+
displayFields: [
|
|
9647
|
+
{ label: "Issue", extract: (p) => p.issueIdOrKey ?? p.issueKey },
|
|
9648
|
+
{ label: "Comment", extract: (p) => p.commentId ?? p.id }
|
|
9649
|
+
]
|
|
9650
|
+
},
|
|
9651
|
+
// AIDENTITY-65: API enricher が 'Link' label を upsert で書き換える。
|
|
9652
|
+
"jira.issuelink.delete": {
|
|
9653
|
+
summaryTemplate: (p) => {
|
|
9654
|
+
const parts = [];
|
|
9655
|
+
if (p.linkId) parts.push(`Delete link ${p.linkId}`);
|
|
9656
|
+
return parts.join(" ");
|
|
9657
|
+
},
|
|
9658
|
+
displayFields: [
|
|
9659
|
+
{ key: "linkId", label: "Link" }
|
|
9660
|
+
]
|
|
9661
|
+
},
|
|
9662
|
+
// ─── HubSpot ───
|
|
9663
|
+
"hubspot.crm.objects.list": {
|
|
9664
|
+
summaryTemplate: (p) => {
|
|
9665
|
+
const parts = [];
|
|
9666
|
+
if (p.objectType) parts.push(String(p.objectType));
|
|
9667
|
+
parts.push("list");
|
|
9668
|
+
return parts.join(" ");
|
|
9669
|
+
},
|
|
9670
|
+
displayFields: [
|
|
9671
|
+
{ key: "objectType", label: "Object Type" },
|
|
9672
|
+
{ key: "limit", label: "Limit" },
|
|
9673
|
+
{ key: "properties", label: "Properties" }
|
|
9674
|
+
]
|
|
9675
|
+
},
|
|
9676
|
+
"hubspot.crm.objects.search": {
|
|
9677
|
+
summaryTemplate: (p) => {
|
|
9678
|
+
const parts = [];
|
|
9679
|
+
if (p.objectType) parts.push(String(p.objectType));
|
|
9680
|
+
if (p.query) parts.push(`"${String(p.query)}"`);
|
|
9681
|
+
return parts.join(" ");
|
|
9682
|
+
},
|
|
9683
|
+
displayFields: [
|
|
9684
|
+
{ key: "objectType", label: "Object Type" },
|
|
9685
|
+
{ key: "query", label: "Query" },
|
|
9686
|
+
{ key: "limit", label: "Limit" }
|
|
9687
|
+
]
|
|
9688
|
+
},
|
|
9689
|
+
"hubspot.crm.objects.batchRead": {
|
|
9690
|
+
summaryTemplate: (p) => {
|
|
9691
|
+
const parts = [];
|
|
9692
|
+
if (p.objectType) parts.push(String(p.objectType));
|
|
9693
|
+
if (Array.isArray(p.inputs)) parts.push(`(${p.inputs.length} items)`);
|
|
9694
|
+
return parts.join(" ");
|
|
9695
|
+
},
|
|
9696
|
+
displayFields: [
|
|
9697
|
+
{ key: "objectType", label: "Object Type" },
|
|
9698
|
+
{ key: "inputs", label: "Records" }
|
|
9699
|
+
]
|
|
9700
|
+
},
|
|
9701
|
+
"hubspot.crm.objects.batchCreate": {
|
|
9702
|
+
summaryTemplate: (p) => {
|
|
9703
|
+
const parts = [];
|
|
9704
|
+
if (p.objectType) parts.push(String(p.objectType));
|
|
9705
|
+
if (Array.isArray(p.inputs)) parts.push(`create ${p.inputs.length}`);
|
|
9706
|
+
return parts.join(" ");
|
|
9707
|
+
},
|
|
9708
|
+
displayFields: [
|
|
9709
|
+
{ key: "objectType", label: "Object Type" },
|
|
9710
|
+
{ key: "inputs", label: "Records" }
|
|
9711
|
+
]
|
|
9712
|
+
},
|
|
9713
|
+
"hubspot.crm.objects.batchUpdate": {
|
|
9714
|
+
summaryTemplate: (p) => {
|
|
9715
|
+
const parts = [];
|
|
9716
|
+
if (p.objectType) parts.push(String(p.objectType));
|
|
9717
|
+
if (Array.isArray(p.inputs)) parts.push(`update ${p.inputs.length}`);
|
|
9718
|
+
return parts.join(" ");
|
|
9719
|
+
},
|
|
9720
|
+
displayFields: [
|
|
9721
|
+
{ key: "objectType", label: "Object Type" },
|
|
9722
|
+
{ key: "inputs", label: "Records" }
|
|
9723
|
+
]
|
|
9724
|
+
},
|
|
9725
|
+
"hubspot.crm.properties.list": {
|
|
9726
|
+
summaryTemplate: (p) => {
|
|
9727
|
+
const parts = [];
|
|
9728
|
+
if (p.objectType) parts.push(String(p.objectType));
|
|
9729
|
+
parts.push("properties list");
|
|
9730
|
+
return parts.join(" ");
|
|
9731
|
+
},
|
|
9732
|
+
displayFields: [
|
|
9733
|
+
{ key: "objectType", label: "Object Type" }
|
|
9734
|
+
]
|
|
9735
|
+
},
|
|
9736
|
+
"hubspot.crm.properties.create": {
|
|
9737
|
+
summaryTemplate: (p) => {
|
|
9738
|
+
const parts = [];
|
|
9739
|
+
if (p.objectType) parts.push(String(p.objectType));
|
|
9740
|
+
if (p.name) parts.push(String(p.name));
|
|
9741
|
+
return parts.join(" ");
|
|
9742
|
+
},
|
|
9743
|
+
displayFields: [
|
|
9744
|
+
{ key: "objectType", label: "Object Type" },
|
|
9745
|
+
{ key: "name", label: "Property Name" },
|
|
9746
|
+
{ key: "label", label: "Label" },
|
|
9747
|
+
{ key: "type", label: "Type" }
|
|
9748
|
+
]
|
|
9749
|
+
},
|
|
9750
|
+
"hubspot.crm.engagements.create": {
|
|
9751
|
+
summaryTemplate: (p) => {
|
|
9752
|
+
const parts = [];
|
|
9753
|
+
if (p.type) parts.push(String(p.type));
|
|
9754
|
+
parts.push("engagement");
|
|
9755
|
+
return parts.join(" ");
|
|
9756
|
+
},
|
|
9757
|
+
displayFields: [
|
|
9758
|
+
{ key: "type", label: "Type" },
|
|
9759
|
+
{ key: "metadata", label: "Metadata" }
|
|
9760
|
+
]
|
|
9761
|
+
},
|
|
9762
|
+
"hubspot.automation.workflows.list": {
|
|
9763
|
+
summaryTemplate: (_p) => "List workflows",
|
|
9764
|
+
displayFields: [
|
|
9765
|
+
{ key: "limit", label: "Limit" }
|
|
9766
|
+
]
|
|
9767
|
+
},
|
|
9768
|
+
"hubspot.account.userDetails.get": {
|
|
9769
|
+
summaryTemplate: (_p) => "Get HubSpot account details",
|
|
9770
|
+
displayFields: []
|
|
9771
|
+
},
|
|
9772
|
+
"hubspot.account.link.get": {
|
|
9773
|
+
summaryTemplate: (p) => {
|
|
9774
|
+
const parts = [];
|
|
9775
|
+
if (p.portalId) parts.push(`portal:${p.portalId}`);
|
|
9776
|
+
if (Array.isArray(p.pageRequests)) parts.push(`(${p.pageRequests.length} links)`);
|
|
9777
|
+
return parts.join(" ");
|
|
9778
|
+
},
|
|
9779
|
+
displayFields: [
|
|
9780
|
+
{ key: "portalId", label: "Portal ID" },
|
|
9781
|
+
{ key: "pageRequests", label: "Page Requests" }
|
|
9782
|
+
]
|
|
9783
|
+
},
|
|
9784
|
+
// ─── Linear ───
|
|
9785
|
+
"linear.issue.create": {
|
|
9786
|
+
summaryTemplate: (p) => {
|
|
9787
|
+
const parts = [];
|
|
9788
|
+
if (p.teamId) parts.push(`${p.teamId}:`);
|
|
9789
|
+
if (p.title) parts.push(String(p.title));
|
|
9790
|
+
return parts.join(" ");
|
|
9791
|
+
},
|
|
9792
|
+
displayFields: [
|
|
9793
|
+
{ key: "teamId", label: "Team" },
|
|
9794
|
+
{ key: "title", label: "Title" },
|
|
9795
|
+
{ key: "description", label: "Description" },
|
|
9796
|
+
{ key: "stateId", label: "State" },
|
|
9797
|
+
{ key: "assigneeId", label: "Assignee" },
|
|
9798
|
+
{ key: "priority", label: "Priority" },
|
|
9799
|
+
{ key: "labelIds", label: "Labels" }
|
|
9800
|
+
]
|
|
9801
|
+
},
|
|
9802
|
+
"linear.issue.update": {
|
|
9803
|
+
summaryTemplate: (p) => {
|
|
9804
|
+
const parts = [];
|
|
9805
|
+
if (p.issueId) parts.push(`${p.issueId}:`);
|
|
9806
|
+
if (p.title) parts.push(String(p.title));
|
|
9807
|
+
return parts.join(" ");
|
|
9808
|
+
},
|
|
9809
|
+
displayFields: [
|
|
9810
|
+
{ key: "issueId", label: "Issue" },
|
|
9811
|
+
{ key: "title", label: "Title" },
|
|
9812
|
+
{ key: "description", label: "Description" },
|
|
9813
|
+
{ key: "stateId", label: "State" },
|
|
9814
|
+
{ key: "assigneeId", label: "Assignee" },
|
|
9815
|
+
{ key: "priority", label: "Priority" },
|
|
9816
|
+
{ key: "labelIds", label: "Labels" }
|
|
9817
|
+
]
|
|
9818
|
+
},
|
|
9819
|
+
"linear.comment.create": {
|
|
9820
|
+
summaryTemplate: (p) => {
|
|
9821
|
+
const parts = [];
|
|
9822
|
+
if (p.issueId) parts.push(`${p.issueId}:`);
|
|
9823
|
+
if (p.body) parts.push(String(p.body));
|
|
9824
|
+
return parts.join(" ");
|
|
9825
|
+
},
|
|
9826
|
+
displayFields: [
|
|
9827
|
+
{ key: "issueId", label: "Issue" },
|
|
9828
|
+
{ key: "body", label: "Comment" }
|
|
9829
|
+
]
|
|
9830
|
+
},
|
|
9831
|
+
"linear.issue.archive": {
|
|
9832
|
+
summaryTemplate: (p) => {
|
|
9833
|
+
const parts = [];
|
|
9834
|
+
if (p.issueId) parts.push(`${p.issueId}:`);
|
|
9835
|
+
parts.push("Archive");
|
|
9836
|
+
return parts.join(" ");
|
|
9837
|
+
},
|
|
9838
|
+
displayFields: [
|
|
9839
|
+
{ key: "issueId", label: "Issue" }
|
|
9840
|
+
]
|
|
9841
|
+
},
|
|
9842
|
+
"linear.label.list": {
|
|
9843
|
+
summaryTemplate: (p) => {
|
|
9844
|
+
const parts = [];
|
|
9845
|
+
if (p.teamId) parts.push(`${p.teamId}:`);
|
|
9846
|
+
parts.push("List labels");
|
|
9847
|
+
return parts.join(" ");
|
|
9848
|
+
},
|
|
9849
|
+
displayFields: [
|
|
9850
|
+
{ key: "teamId", label: "Team" },
|
|
9851
|
+
{ key: "limit", label: "Limit" }
|
|
9852
|
+
]
|
|
9853
|
+
},
|
|
9854
|
+
"linear.user.list": {
|
|
9855
|
+
summaryTemplate: (p) => {
|
|
9856
|
+
const parts = [];
|
|
9857
|
+
if (p.teamId) parts.push(`${p.teamId}:`);
|
|
9858
|
+
parts.push("List users");
|
|
9859
|
+
return parts.join(" ");
|
|
9860
|
+
},
|
|
9861
|
+
displayFields: [
|
|
9862
|
+
{ key: "teamId", label: "Team" },
|
|
9863
|
+
{ key: "limit", label: "Limit" }
|
|
9864
|
+
]
|
|
9865
|
+
},
|
|
9866
|
+
"linear.project.create": {
|
|
9867
|
+
summaryTemplate: (p) => {
|
|
9868
|
+
const parts = [];
|
|
9869
|
+
if (p.teamIds) parts.push(`${Array.isArray(p.teamIds) ? p.teamIds.join(",") : String(p.teamIds)}:`);
|
|
9870
|
+
if (p.name) parts.push(String(p.name));
|
|
9871
|
+
return parts.join(" ");
|
|
9872
|
+
},
|
|
9873
|
+
displayFields: [
|
|
9874
|
+
{ key: "teamIds", label: "Teams" },
|
|
9875
|
+
{ key: "name", label: "Name" },
|
|
9876
|
+
{ key: "description", label: "Description" },
|
|
9877
|
+
{ key: "statusId", label: "Status ID" },
|
|
9878
|
+
{ key: "startDate", label: "Start Date" },
|
|
9879
|
+
{ key: "targetDate", label: "Target Date" }
|
|
9880
|
+
]
|
|
9881
|
+
},
|
|
9882
|
+
"linear.project.update": {
|
|
9883
|
+
summaryTemplate: (p) => {
|
|
9884
|
+
const parts = [];
|
|
9885
|
+
if (p.projectId) parts.push(`${p.projectId}:`);
|
|
9886
|
+
if (p.name) parts.push(String(p.name));
|
|
9887
|
+
return parts.join(" ");
|
|
9888
|
+
},
|
|
9889
|
+
displayFields: [
|
|
9890
|
+
{ key: "projectId", label: "Project" },
|
|
9891
|
+
{ key: "name", label: "Name" },
|
|
9892
|
+
{ key: "description", label: "Description" },
|
|
9893
|
+
{ key: "statusId", label: "Status ID" },
|
|
9894
|
+
{ key: "startDate", label: "Start Date" },
|
|
9895
|
+
{ key: "targetDate", label: "Target Date" }
|
|
9896
|
+
]
|
|
9897
|
+
},
|
|
9898
|
+
// ─── Linear Comment ops ───
|
|
9899
|
+
"linear.comment.update": {
|
|
9900
|
+
summaryTemplate: (p) => {
|
|
9901
|
+
const parts = [];
|
|
9902
|
+
if (p.commentId) parts.push(`${p.commentId}:`);
|
|
9903
|
+
parts.push("Update comment");
|
|
9904
|
+
return parts.join(" ");
|
|
9905
|
+
},
|
|
9906
|
+
displayFields: [
|
|
9907
|
+
{ key: "commentId", label: "Comment" },
|
|
9908
|
+
{ key: "body", label: "Body" }
|
|
9909
|
+
]
|
|
9910
|
+
},
|
|
9911
|
+
"linear.comment.delete": {
|
|
9912
|
+
summaryTemplate: (p) => {
|
|
9913
|
+
const parts = [];
|
|
9914
|
+
if (p.commentId) parts.push(`Delete comment ${p.commentId}`);
|
|
9915
|
+
return parts.join(" ");
|
|
9916
|
+
},
|
|
9917
|
+
displayFields: [
|
|
9918
|
+
{ key: "commentId", label: "Comment" }
|
|
9919
|
+
]
|
|
9920
|
+
},
|
|
9921
|
+
"linear.comment.resolve": {
|
|
9922
|
+
summaryTemplate: (p) => {
|
|
9923
|
+
const parts = [];
|
|
9924
|
+
if (p.commentId) parts.push(`${p.commentId}:`);
|
|
9925
|
+
parts.push("Resolve comment");
|
|
8441
9926
|
return parts.join(" ");
|
|
8442
9927
|
},
|
|
8443
9928
|
displayFields: [
|
|
8444
|
-
{ key: "
|
|
8445
|
-
{ key: "text", label: "Message" }
|
|
9929
|
+
{ key: "commentId", label: "Comment" }
|
|
8446
9930
|
]
|
|
8447
9931
|
},
|
|
8448
|
-
"
|
|
9932
|
+
"linear.comment.unresolve": {
|
|
8449
9933
|
summaryTemplate: (p) => {
|
|
8450
9934
|
const parts = [];
|
|
8451
|
-
if (p.
|
|
8452
|
-
|
|
8453
|
-
return parts.join("
|
|
9935
|
+
if (p.commentId) parts.push(`${p.commentId}:`);
|
|
9936
|
+
parts.push("Unresolve comment");
|
|
9937
|
+
return parts.join(" ");
|
|
8454
9938
|
},
|
|
8455
9939
|
displayFields: [
|
|
8456
|
-
{ key: "
|
|
8457
|
-
{ key: "subject", label: "Subject" },
|
|
8458
|
-
{ key: "body", label: "Body" }
|
|
9940
|
+
{ key: "commentId", label: "Comment" }
|
|
8459
9941
|
]
|
|
8460
9942
|
},
|
|
8461
|
-
|
|
9943
|
+
// ─── Linear Issue ops ───
|
|
9944
|
+
"linear.issue.unarchive": {
|
|
8462
9945
|
summaryTemplate: (p) => {
|
|
8463
9946
|
const parts = [];
|
|
8464
|
-
if (p.
|
|
8465
|
-
|
|
8466
|
-
return parts.join("
|
|
9947
|
+
if (p.issueId) parts.push(`${p.issueId}:`);
|
|
9948
|
+
parts.push("Unarchive");
|
|
9949
|
+
return parts.join(" ");
|
|
8467
9950
|
},
|
|
8468
9951
|
displayFields: [
|
|
8469
|
-
{ key: "
|
|
8470
|
-
{ key: "subject", label: "Subject" },
|
|
8471
|
-
{ key: "body", label: "Body" }
|
|
9952
|
+
{ key: "issueId", label: "Issue" }
|
|
8472
9953
|
]
|
|
8473
9954
|
},
|
|
8474
|
-
"
|
|
9955
|
+
"linear.issue.addLabel": {
|
|
8475
9956
|
summaryTemplate: (p) => {
|
|
8476
9957
|
const parts = [];
|
|
8477
|
-
if (p.
|
|
8478
|
-
if (p.
|
|
9958
|
+
if (p.issueId) parts.push(`${p.issueId}:`);
|
|
9959
|
+
if (p.labelId) parts.push(`Add label ${p.labelId}`);
|
|
8479
9960
|
return parts.join(" ");
|
|
8480
9961
|
},
|
|
8481
9962
|
displayFields: [
|
|
8482
|
-
{ key: "
|
|
8483
|
-
{ key: "
|
|
8484
|
-
{ key: "end", label: "End" },
|
|
8485
|
-
{ key: "attendees", label: "Attendees" }
|
|
9963
|
+
{ key: "issueId", label: "Issue" },
|
|
9964
|
+
{ key: "labelId", label: "Label" }
|
|
8486
9965
|
]
|
|
8487
9966
|
},
|
|
8488
|
-
"
|
|
9967
|
+
"linear.issue.removeLabel": {
|
|
8489
9968
|
summaryTemplate: (p) => {
|
|
8490
9969
|
const parts = [];
|
|
8491
|
-
if (p.
|
|
8492
|
-
if (p.
|
|
9970
|
+
if (p.issueId) parts.push(`${p.issueId}:`);
|
|
9971
|
+
if (p.labelId) parts.push(`Remove label ${p.labelId}`);
|
|
8493
9972
|
return parts.join(" ");
|
|
8494
9973
|
},
|
|
8495
9974
|
displayFields: [
|
|
8496
|
-
{ key: "
|
|
8497
|
-
{ key: "
|
|
8498
|
-
{ key: "end", label: "End" },
|
|
8499
|
-
{ key: "attendees", label: "Attendees" }
|
|
9975
|
+
{ key: "issueId", label: "Issue" },
|
|
9976
|
+
{ key: "labelId", label: "Label" }
|
|
8500
9977
|
]
|
|
8501
9978
|
},
|
|
8502
|
-
"
|
|
9979
|
+
"linear.issue.subscribe": {
|
|
8503
9980
|
summaryTemplate: (p) => {
|
|
8504
9981
|
const parts = [];
|
|
8505
|
-
|
|
8506
|
-
|
|
8507
|
-
["projectKey", "project"],
|
|
8508
|
-
"project",
|
|
8509
|
-
(v) => typeof v === "string" ? v : v?.key
|
|
8510
|
-
);
|
|
8511
|
-
const summary = jiraField(p, ["summary"], "summary");
|
|
8512
|
-
if (projectKey) parts.push(`${projectKey}:`);
|
|
8513
|
-
if (summary) parts.push(summary);
|
|
9982
|
+
if (p.issueId) parts.push(`${p.issueId}:`);
|
|
9983
|
+
parts.push("Subscribe");
|
|
8514
9984
|
return parts.join(" ");
|
|
8515
9985
|
},
|
|
8516
|
-
// AIDENTITY-54: nested `fields.X` 形式と top-level canonical の両方を
|
|
8517
|
-
// 拾えるよう extract を使う。assignee は null (unassign) も表示。
|
|
8518
|
-
// legacy alias (project / issuetype 等) も top-level 候補に含めて後方互換を保つ。
|
|
8519
9986
|
displayFields: [
|
|
8520
|
-
{
|
|
8521
|
-
label: "Project",
|
|
8522
|
-
extract: (p) => jiraField(
|
|
8523
|
-
p,
|
|
8524
|
-
["projectKey", "project"],
|
|
8525
|
-
"project",
|
|
8526
|
-
(v) => typeof v === "string" ? v : v?.key
|
|
8527
|
-
)
|
|
8528
|
-
},
|
|
8529
|
-
{
|
|
8530
|
-
label: "Type",
|
|
8531
|
-
extract: (p) => jiraField(
|
|
8532
|
-
p,
|
|
8533
|
-
["issueTypeName", "issueType", "issuetype"],
|
|
8534
|
-
"issuetype",
|
|
8535
|
-
(v) => typeof v === "string" ? v : v?.name
|
|
8536
|
-
)
|
|
8537
|
-
},
|
|
8538
|
-
{ label: "Summary", extract: (p) => jiraField(p, ["summary"], "summary") },
|
|
8539
|
-
{ label: "Description", extract: (p) => jiraField(p, ["description"], "description") },
|
|
8540
|
-
{
|
|
8541
|
-
label: "Priority",
|
|
8542
|
-
extract: (p) => jiraField(
|
|
8543
|
-
p,
|
|
8544
|
-
["priority"],
|
|
8545
|
-
"priority",
|
|
8546
|
-
(v) => typeof v === "string" ? v : v?.name
|
|
8547
|
-
)
|
|
8548
|
-
},
|
|
8549
|
-
{ label: "Assignee", extract: extractJiraAssigneeDisplay },
|
|
8550
|
-
{ label: "Labels", extract: (p) => jiraField(p, ["labels"], "labels") }
|
|
9987
|
+
{ key: "issueId", label: "Issue" }
|
|
8551
9988
|
]
|
|
8552
9989
|
},
|
|
8553
|
-
"
|
|
9990
|
+
"linear.issue.delete": {
|
|
8554
9991
|
summaryTemplate: (p) => {
|
|
8555
9992
|
const parts = [];
|
|
8556
|
-
|
|
8557
|
-
const summary = jiraField(p, ["summary"], "summary");
|
|
8558
|
-
if (key) parts.push(`${key}:`);
|
|
8559
|
-
if (summary) parts.push(summary);
|
|
9993
|
+
if (p.issueId) parts.push(`Delete issue ${p.issueId}`);
|
|
8560
9994
|
return parts.join(" ");
|
|
8561
9995
|
},
|
|
8562
9996
|
displayFields: [
|
|
8563
|
-
|
|
8564
|
-
{ label: "Issue", extract: (p) => p.issueIdOrKey ?? p.issueKey },
|
|
8565
|
-
{ label: "Summary", extract: (p) => jiraField(p, ["summary"], "summary") },
|
|
8566
|
-
{ label: "Description", extract: (p) => jiraField(p, ["description"], "description") },
|
|
8567
|
-
{
|
|
8568
|
-
label: "Priority",
|
|
8569
|
-
extract: (p) => jiraField(
|
|
8570
|
-
p,
|
|
8571
|
-
["priority"],
|
|
8572
|
-
"priority",
|
|
8573
|
-
(v) => typeof v === "string" ? v : v?.name
|
|
8574
|
-
)
|
|
8575
|
-
},
|
|
8576
|
-
// AIDENTITY-54: top-level alias (string / object) と null (unassign) も解決。
|
|
8577
|
-
{ label: "Assignee", extract: extractJiraAssigneeDisplay },
|
|
8578
|
-
{ label: "Labels", extract: (p) => jiraField(p, ["labels"], "labels") }
|
|
9997
|
+
{ key: "issueId", label: "Issue" }
|
|
8579
9998
|
]
|
|
8580
9999
|
},
|
|
8581
|
-
//
|
|
8582
|
-
|
|
8583
|
-
"jira.comment.create": {
|
|
10000
|
+
// ─── Linear Issue Relations ───
|
|
10001
|
+
"linear.issueRelation.create": {
|
|
8584
10002
|
summaryTemplate: (p) => {
|
|
8585
10003
|
const parts = [];
|
|
8586
|
-
if (p.
|
|
8587
|
-
if (p.
|
|
10004
|
+
if (p.issueId) parts.push(`${p.issueId}`);
|
|
10005
|
+
if (p.type) parts.push(String(p.type));
|
|
10006
|
+
if (p.relatedIssueId) parts.push(String(p.relatedIssueId));
|
|
8588
10007
|
return parts.join(" ");
|
|
8589
10008
|
},
|
|
8590
10009
|
displayFields: [
|
|
8591
|
-
{ key: "
|
|
8592
|
-
{ key: "
|
|
10010
|
+
{ key: "issueId", label: "Issue" },
|
|
10011
|
+
{ key: "type", label: "Relation Type" },
|
|
10012
|
+
{ key: "relatedIssueId", label: "Related Issue" }
|
|
8593
10013
|
]
|
|
8594
10014
|
},
|
|
8595
|
-
|
|
8596
|
-
// (jira.issue.delete / jira.issuelink.delete と同じ destructive 表現の方針)。
|
|
8597
|
-
"jira.comment.delete": {
|
|
10015
|
+
"linear.issueRelation.list": {
|
|
8598
10016
|
summaryTemplate: (p) => {
|
|
8599
|
-
const
|
|
8600
|
-
|
|
8601
|
-
|
|
8602
|
-
|
|
8603
|
-
return "";
|
|
10017
|
+
const parts = [];
|
|
10018
|
+
if (p.issueId) parts.push(`${p.issueId}:`);
|
|
10019
|
+
parts.push("List relations");
|
|
10020
|
+
return parts.join(" ");
|
|
8604
10021
|
},
|
|
8605
10022
|
displayFields: [
|
|
8606
|
-
{
|
|
8607
|
-
{ label: "Comment", extract: (p) => p.commentId ?? p.id }
|
|
10023
|
+
{ key: "issueId", label: "Issue" }
|
|
8608
10024
|
]
|
|
8609
10025
|
},
|
|
8610
|
-
|
|
8611
|
-
"jira.issuelink.delete": {
|
|
10026
|
+
"linear.issueRelation.delete": {
|
|
8612
10027
|
summaryTemplate: (p) => {
|
|
8613
10028
|
const parts = [];
|
|
8614
|
-
if (p.
|
|
10029
|
+
if (p.relationId) parts.push(`Delete relation ${p.relationId}`);
|
|
8615
10030
|
return parts.join(" ");
|
|
8616
10031
|
},
|
|
8617
10032
|
displayFields: [
|
|
8618
|
-
{ key: "
|
|
10033
|
+
{ key: "relationId", label: "Relation" }
|
|
10034
|
+
]
|
|
10035
|
+
},
|
|
10036
|
+
// ─── Linear Cycles ───
|
|
10037
|
+
"linear.cycle.list": {
|
|
10038
|
+
summaryTemplate: (p) => {
|
|
10039
|
+
const parts = [];
|
|
10040
|
+
if (p.teamId) parts.push(`${p.teamId}:`);
|
|
10041
|
+
parts.push("List cycles");
|
|
10042
|
+
return parts.join(" ");
|
|
10043
|
+
},
|
|
10044
|
+
displayFields: [
|
|
10045
|
+
{ key: "teamId", label: "Team" },
|
|
10046
|
+
{ key: "limit", label: "Limit" }
|
|
10047
|
+
]
|
|
10048
|
+
},
|
|
10049
|
+
"linear.cycle.read": {
|
|
10050
|
+
summaryTemplate: (p) => {
|
|
10051
|
+
const parts = [];
|
|
10052
|
+
if (p.cycleId) parts.push(`${p.cycleId}:`);
|
|
10053
|
+
parts.push("Read cycle");
|
|
10054
|
+
return parts.join(" ");
|
|
10055
|
+
},
|
|
10056
|
+
displayFields: [
|
|
10057
|
+
{ key: "cycleId", label: "Cycle" }
|
|
10058
|
+
]
|
|
10059
|
+
},
|
|
10060
|
+
"linear.cycle.create": {
|
|
10061
|
+
summaryTemplate: (p) => {
|
|
10062
|
+
const parts = [];
|
|
10063
|
+
if (p.teamId) parts.push(`${p.teamId}:`);
|
|
10064
|
+
if (p.name) parts.push(String(p.name));
|
|
10065
|
+
else if (p.startsAt) parts.push(`Cycle ${p.startsAt}`);
|
|
10066
|
+
return parts.join(" ");
|
|
10067
|
+
},
|
|
10068
|
+
displayFields: [
|
|
10069
|
+
{ key: "teamId", label: "Team" },
|
|
10070
|
+
{ key: "name", label: "Name" },
|
|
10071
|
+
{ key: "startsAt", label: "Starts At" },
|
|
10072
|
+
{ key: "endsAt", label: "Ends At" }
|
|
10073
|
+
]
|
|
10074
|
+
},
|
|
10075
|
+
"linear.cycle.update": {
|
|
10076
|
+
summaryTemplate: (p) => {
|
|
10077
|
+
const parts = [];
|
|
10078
|
+
if (p.cycleId) parts.push(`${p.cycleId}:`);
|
|
10079
|
+
if (p.name) parts.push(String(p.name));
|
|
10080
|
+
else parts.push("Update cycle");
|
|
10081
|
+
return parts.join(" ");
|
|
10082
|
+
},
|
|
10083
|
+
displayFields: [
|
|
10084
|
+
{ key: "cycleId", label: "Cycle" },
|
|
10085
|
+
{ key: "name", label: "Name" },
|
|
10086
|
+
{ key: "startsAt", label: "Starts At" },
|
|
10087
|
+
{ key: "endsAt", label: "Ends At" }
|
|
10088
|
+
]
|
|
10089
|
+
},
|
|
10090
|
+
// ─── Linear Labels ───
|
|
10091
|
+
"linear.label.create": {
|
|
10092
|
+
summaryTemplate: (p) => {
|
|
10093
|
+
const parts = [];
|
|
10094
|
+
if (p.name) parts.push(String(p.name));
|
|
10095
|
+
return parts.join(" ");
|
|
10096
|
+
},
|
|
10097
|
+
displayFields: [
|
|
10098
|
+
{ key: "name", label: "Name" },
|
|
10099
|
+
{ key: "color", label: "Color" },
|
|
10100
|
+
{ key: "teamId", label: "Team" }
|
|
10101
|
+
]
|
|
10102
|
+
},
|
|
10103
|
+
"linear.label.update": {
|
|
10104
|
+
summaryTemplate: (p) => {
|
|
10105
|
+
const parts = [];
|
|
10106
|
+
if (p.labelId) parts.push(`${p.labelId}:`);
|
|
10107
|
+
if (p.name) parts.push(String(p.name));
|
|
10108
|
+
else parts.push("Update label");
|
|
10109
|
+
return parts.join(" ");
|
|
10110
|
+
},
|
|
10111
|
+
displayFields: [
|
|
10112
|
+
{ key: "labelId", label: "Label" },
|
|
10113
|
+
{ key: "name", label: "Name" },
|
|
10114
|
+
{ key: "color", label: "Color" }
|
|
10115
|
+
]
|
|
10116
|
+
},
|
|
10117
|
+
// ─── Linear Attachments ───
|
|
10118
|
+
"linear.attachment.create": {
|
|
10119
|
+
summaryTemplate: (p) => {
|
|
10120
|
+
const parts = [];
|
|
10121
|
+
if (p.issueId) parts.push(`${p.issueId}:`);
|
|
10122
|
+
if (p.title) parts.push(String(p.title));
|
|
10123
|
+
return parts.join(" ");
|
|
10124
|
+
},
|
|
10125
|
+
displayFields: [
|
|
10126
|
+
{ key: "issueId", label: "Issue" },
|
|
10127
|
+
{ key: "title", label: "Title" },
|
|
10128
|
+
{ key: "url", label: "URL" }
|
|
10129
|
+
]
|
|
10130
|
+
},
|
|
10131
|
+
"linear.attachment.list": {
|
|
10132
|
+
summaryTemplate: (p) => {
|
|
10133
|
+
const parts = [];
|
|
10134
|
+
if (p.issueId) parts.push(`${p.issueId}:`);
|
|
10135
|
+
parts.push("List attachments");
|
|
10136
|
+
return parts.join(" ");
|
|
10137
|
+
},
|
|
10138
|
+
displayFields: [
|
|
10139
|
+
{ key: "issueId", label: "Issue" }
|
|
10140
|
+
]
|
|
10141
|
+
},
|
|
10142
|
+
"linear.attachment.delete": {
|
|
10143
|
+
summaryTemplate: (p) => {
|
|
10144
|
+
const parts = [];
|
|
10145
|
+
if (p.attachmentId) parts.push(`Delete attachment ${p.attachmentId}`);
|
|
10146
|
+
return parts.join(" ");
|
|
10147
|
+
},
|
|
10148
|
+
displayFields: [
|
|
10149
|
+
{ key: "attachmentId", label: "Attachment" }
|
|
10150
|
+
]
|
|
10151
|
+
},
|
|
10152
|
+
// ─── Linear read actions (登録漏れ補完) ───
|
|
10153
|
+
"linear.issue.list": {
|
|
10154
|
+
summaryTemplate: (p) => {
|
|
10155
|
+
const parts = [];
|
|
10156
|
+
if (p.teamId) parts.push(`${p.teamId}:`);
|
|
10157
|
+
parts.push("List issues");
|
|
10158
|
+
return parts.join(" ");
|
|
10159
|
+
},
|
|
10160
|
+
displayFields: [
|
|
10161
|
+
{ key: "teamId", label: "Team" },
|
|
10162
|
+
{ key: "assigneeId", label: "Assignee" },
|
|
10163
|
+
{ key: "stateId", label: "State" },
|
|
10164
|
+
{ key: "limit", label: "Limit" }
|
|
10165
|
+
]
|
|
10166
|
+
},
|
|
10167
|
+
"linear.issue.read": {
|
|
10168
|
+
summaryTemplate: (p) => {
|
|
10169
|
+
const parts = [];
|
|
10170
|
+
if (p.issueId) parts.push(`${p.issueId}:`);
|
|
10171
|
+
parts.push("Read issue");
|
|
10172
|
+
return parts.join(" ");
|
|
10173
|
+
},
|
|
10174
|
+
displayFields: [
|
|
10175
|
+
{ key: "issueId", label: "Issue" }
|
|
10176
|
+
]
|
|
10177
|
+
},
|
|
10178
|
+
"linear.issue.search": {
|
|
10179
|
+
summaryTemplate: (p) => {
|
|
10180
|
+
const parts = [];
|
|
10181
|
+
if (p.teamId) parts.push(`${p.teamId}:`);
|
|
10182
|
+
if (p.query) parts.push(String(p.query));
|
|
10183
|
+
return parts.join(" ");
|
|
10184
|
+
},
|
|
10185
|
+
displayFields: [
|
|
10186
|
+
{ key: "query", label: "Query" },
|
|
10187
|
+
{ key: "teamId", label: "Team" },
|
|
10188
|
+
{ key: "limit", label: "Limit" }
|
|
10189
|
+
]
|
|
10190
|
+
},
|
|
10191
|
+
"linear.comment.list": {
|
|
10192
|
+
summaryTemplate: (p) => {
|
|
10193
|
+
const parts = [];
|
|
10194
|
+
if (p.issueId) parts.push(`${p.issueId}:`);
|
|
10195
|
+
parts.push("List comments");
|
|
10196
|
+
return parts.join(" ");
|
|
10197
|
+
},
|
|
10198
|
+
displayFields: [
|
|
10199
|
+
{ key: "issueId", label: "Issue" }
|
|
10200
|
+
]
|
|
10201
|
+
},
|
|
10202
|
+
"linear.project.list": {
|
|
10203
|
+
summaryTemplate: (p) => {
|
|
10204
|
+
const parts = [];
|
|
10205
|
+
if (p.teamId) parts.push(`${p.teamId}:`);
|
|
10206
|
+
parts.push("List projects");
|
|
10207
|
+
return parts.join(" ");
|
|
10208
|
+
},
|
|
10209
|
+
displayFields: [
|
|
10210
|
+
{ key: "teamId", label: "Team" },
|
|
10211
|
+
{ key: "limit", label: "Limit" }
|
|
10212
|
+
]
|
|
10213
|
+
},
|
|
10214
|
+
"linear.project.read": {
|
|
10215
|
+
summaryTemplate: (p) => {
|
|
10216
|
+
const parts = [];
|
|
10217
|
+
if (p.projectId) parts.push(`${p.projectId}:`);
|
|
10218
|
+
parts.push("Read project");
|
|
10219
|
+
return parts.join(" ");
|
|
10220
|
+
},
|
|
10221
|
+
displayFields: [
|
|
10222
|
+
{ key: "projectId", label: "Project" }
|
|
10223
|
+
]
|
|
10224
|
+
},
|
|
10225
|
+
"linear.team.list": {
|
|
10226
|
+
summaryTemplate: (_p) => "List teams",
|
|
10227
|
+
displayFields: [
|
|
10228
|
+
{ key: "limit", label: "Limit" }
|
|
10229
|
+
]
|
|
10230
|
+
},
|
|
10231
|
+
"linear.workflowState.list": {
|
|
10232
|
+
summaryTemplate: (p) => {
|
|
10233
|
+
const parts = [];
|
|
10234
|
+
if (p.teamId) parts.push(`${p.teamId}:`);
|
|
10235
|
+
parts.push("List workflow states");
|
|
10236
|
+
return parts.join(" ");
|
|
10237
|
+
},
|
|
10238
|
+
displayFields: [
|
|
10239
|
+
{ key: "teamId", label: "Team" },
|
|
10240
|
+
{ key: "limit", label: "Limit" }
|
|
8619
10241
|
]
|
|
8620
10242
|
},
|
|
10243
|
+
"linear.viewer.read": {
|
|
10244
|
+
summaryTemplate: (_p) => "Read viewer (current user)",
|
|
10245
|
+
displayFields: []
|
|
10246
|
+
},
|
|
8621
10247
|
// AIDENTITY-83: email / displayName から accountId を解決する read action。
|
|
8622
10248
|
"jira.user.search": {
|
|
8623
10249
|
summaryTemplate: (p) => {
|
|
@@ -8640,7 +10266,8 @@ var ACTION_DISPLAY_CONFIGS = {
|
|
|
8640
10266
|
displayFields: [
|
|
8641
10267
|
{ key: "to", label: "To" },
|
|
8642
10268
|
{ key: "taskType", label: "Task" },
|
|
8643
|
-
{ key: "message", label: "Message" }
|
|
10269
|
+
{ key: "message", label: "Message" },
|
|
10270
|
+
{ key: "payload", label: "Payload" }
|
|
8644
10271
|
]
|
|
8645
10272
|
},
|
|
8646
10273
|
"inbox.respond": {
|
|
@@ -8668,15 +10295,40 @@ var ACTION_DISPLAY_CONFIGS = {
|
|
|
8668
10295
|
]
|
|
8669
10296
|
},
|
|
8670
10297
|
"inbox.checkByToken": {
|
|
8671
|
-
|
|
8672
|
-
|
|
8673
|
-
|
|
8674
|
-
]
|
|
10298
|
+
// token is an opaque access credential — never render it in summaries or display fields.
|
|
10299
|
+
summaryTemplate: (_p) => "Check inbox by token",
|
|
10300
|
+
displayFields: []
|
|
8675
10301
|
},
|
|
8676
10302
|
"inbox.complete": {
|
|
8677
10303
|
summaryTemplate: (p) => p.id ? `Complete #${p.id}` : "",
|
|
8678
10304
|
displayFields: [
|
|
8679
|
-
{ key: "id", label: "Item" }
|
|
10305
|
+
{ key: "id", label: "Item" },
|
|
10306
|
+
{ key: "result", label: "Result" }
|
|
10307
|
+
]
|
|
10308
|
+
},
|
|
10309
|
+
"scheduling.request": {
|
|
10310
|
+
summaryTemplate: (p) => p.topic ? `Request scheduling: ${p.topic}` : "Request scheduling",
|
|
10311
|
+
displayFields: [
|
|
10312
|
+
{ key: "to", label: "To" },
|
|
10313
|
+
{ key: "topic", label: "Topic" },
|
|
10314
|
+
{ key: "durationMinutes", label: "Duration (min)" },
|
|
10315
|
+
{ key: "candidates", label: "Candidates" },
|
|
10316
|
+
{ key: "message", label: "Message" }
|
|
10317
|
+
]
|
|
10318
|
+
},
|
|
10319
|
+
// PR-R2 (design §3.2), registry checklist B. This action is risk:'high', so
|
|
10320
|
+
// its summary/displayFields are what a human actually reads in the approval
|
|
10321
|
+
// and audit surfaces — the string is user-facing, not decoration. Names the
|
|
10322
|
+
// item being answered (the counterpart anchor available on this action's
|
|
10323
|
+
// params) the way scheduling.request names its topic.
|
|
10324
|
+
"scheduling.submit_response": {
|
|
10325
|
+
summaryTemplate: (p) => p.decision === "decline" ? `Decline the scheduling request for item ${p.itemId ?? "(unknown)"}` : `Submit a scheduling proposal for item ${p.itemId ?? "(unknown)"}`,
|
|
10326
|
+
displayFields: [
|
|
10327
|
+
{ key: "itemId", label: "Inbox item" },
|
|
10328
|
+
{ key: "decision", label: "Decision" },
|
|
10329
|
+
{ key: "slots", label: "Proposed slots" },
|
|
10330
|
+
{ key: "recommendedSlotIndex", label: "Recommended index" },
|
|
10331
|
+
{ key: "recommendationReason", label: "Reason" }
|
|
8680
10332
|
]
|
|
8681
10333
|
}
|
|
8682
10334
|
};
|
|
@@ -8984,7 +10636,7 @@ function isWriteAction(action) {
|
|
|
8984
10636
|
if (!meta) {
|
|
8985
10637
|
return true;
|
|
8986
10638
|
}
|
|
8987
|
-
const writeEffectPrefixes = ["Create:", "Update:", "Delete:", "Write:", "Execute:", "Merge:", "Run:"];
|
|
10639
|
+
const writeEffectPrefixes = ["Create:", "Update:", "Delete:", "Write:", "Execute:", "Merge:", "Run:", "Archive:"];
|
|
8988
10640
|
if (meta.effects?.some((e) => writeEffectPrefixes.some((p) => e.startsWith(p)))) {
|
|
8989
10641
|
return true;
|
|
8990
10642
|
}
|