@songsid/agend 2.1.5 → 2.1.6-beta.10

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.
Files changed (184) hide show
  1. package/dist/agent-endpoint.d.ts +18 -0
  2. package/dist/agent-endpoint.js +53 -2
  3. package/dist/agent-endpoint.js.map +1 -1
  4. package/dist/apply-job.d.ts +114 -0
  5. package/dist/apply-job.js +214 -0
  6. package/dist/apply-job.js.map +1 -0
  7. package/dist/backend/claude-code.d.ts +25 -0
  8. package/dist/backend/claude-code.js +127 -0
  9. package/dist/backend/claude-code.js.map +1 -1
  10. package/dist/backend/codex.d.ts +57 -0
  11. package/dist/backend/codex.js +183 -0
  12. package/dist/backend/codex.js.map +1 -1
  13. package/dist/backend/credential-profile.d.ts +159 -0
  14. package/dist/backend/credential-profile.js +340 -0
  15. package/dist/backend/credential-profile.js.map +1 -0
  16. package/dist/backend/factory.js +4 -1
  17. package/dist/backend/factory.js.map +1 -1
  18. package/dist/backend/kiro-auth-store.d.ts +25 -0
  19. package/dist/backend/kiro-auth-store.js +61 -0
  20. package/dist/backend/kiro-auth-store.js.map +1 -0
  21. package/dist/backend/kiro.d.ts +8 -0
  22. package/dist/backend/kiro.js +31 -2
  23. package/dist/backend/kiro.js.map +1 -1
  24. package/dist/backend/muse.d.ts +90 -0
  25. package/dist/backend/muse.js +437 -0
  26. package/dist/backend/muse.js.map +1 -0
  27. package/dist/backend/types.d.ts +54 -0
  28. package/dist/backend/types.js.map +1 -1
  29. package/dist/channel/access-manager.d.ts +20 -0
  30. package/dist/channel/access-manager.js +25 -0
  31. package/dist/channel/access-manager.js.map +1 -1
  32. package/dist/channel/adapters/discord.d.ts +17 -0
  33. package/dist/channel/adapters/discord.js +72 -11
  34. package/dist/channel/adapters/discord.js.map +1 -1
  35. package/dist/channel/adapters/telegram.d.ts +6 -0
  36. package/dist/channel/adapters/telegram.js +36 -0
  37. package/dist/channel/adapters/telegram.js.map +1 -1
  38. package/dist/channel/markdown-chunk.d.ts +8 -3
  39. package/dist/channel/markdown-chunk.js +12 -3
  40. package/dist/channel/markdown-chunk.js.map +1 -1
  41. package/dist/channel/mcp-server.js +9 -12
  42. package/dist/channel/mcp-server.js.map +1 -1
  43. package/dist/channel/mcp-tools.d.ts +6 -2
  44. package/dist/channel/mcp-tools.js +6 -36
  45. package/dist/channel/mcp-tools.js.map +1 -1
  46. package/dist/channel/tool-router.js +32 -3
  47. package/dist/channel/tool-router.js.map +1 -1
  48. package/dist/channel/types.d.ts +18 -0
  49. package/dist/cli.js +113 -0
  50. package/dist/cli.js.map +1 -1
  51. package/dist/config-validator.js +45 -5
  52. package/dist/config-validator.js.map +1 -1
  53. package/dist/connection-secrets.d.ts +96 -0
  54. package/dist/connection-secrets.js +25 -0
  55. package/dist/connection-secrets.js.map +1 -0
  56. package/dist/daemon.d.ts +76 -0
  57. package/dist/daemon.js +489 -103
  58. package/dist/daemon.js.map +1 -1
  59. package/dist/event-log.d.ts +9 -0
  60. package/dist/event-log.js +21 -0
  61. package/dist/event-log.js.map +1 -1
  62. package/dist/fleet-level-config.d.ts +42 -0
  63. package/dist/fleet-level-config.js +78 -0
  64. package/dist/fleet-level-config.js.map +1 -0
  65. package/dist/fleet-lock.d.ts +21 -0
  66. package/dist/fleet-lock.js +42 -8
  67. package/dist/fleet-lock.js.map +1 -1
  68. package/dist/fleet-manager.d.ts +425 -2
  69. package/dist/fleet-manager.js +2055 -182
  70. package/dist/fleet-manager.js.map +1 -1
  71. package/dist/general-knowledge/skills/credential-profiles/SKILL.md +145 -0
  72. package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +11 -1
  73. package/dist/instance-config-impact.d.ts +55 -0
  74. package/dist/instance-config-impact.js +152 -0
  75. package/dist/instance-config-impact.js.map +1 -0
  76. package/dist/instance-lifecycle.js +8 -4
  77. package/dist/instance-lifecycle.js.map +1 -1
  78. package/dist/locale.js +24 -0
  79. package/dist/locale.js.map +1 -1
  80. package/dist/logger.js +42 -25
  81. package/dist/logger.js.map +1 -1
  82. package/dist/muse-usage-relay.d.ts +72 -0
  83. package/dist/muse-usage-relay.js +419 -0
  84. package/dist/muse-usage-relay.js.map +1 -0
  85. package/dist/outbound-handlers.d.ts +5 -1
  86. package/dist/outbound-handlers.js +199 -1
  87. package/dist/outbound-handlers.js.map +1 -1
  88. package/dist/outbound-schemas.d.ts +7 -5
  89. package/dist/outbound-schemas.js +3 -2
  90. package/dist/outbound-schemas.js.map +1 -1
  91. package/dist/provider-probe.d.ts +48 -0
  92. package/dist/provider-probe.js +121 -0
  93. package/dist/provider-probe.js.map +1 -0
  94. package/dist/provider-secret-registry.d.ts +98 -0
  95. package/dist/provider-secret-registry.js +334 -0
  96. package/dist/provider-secret-registry.js.map +1 -0
  97. package/dist/quickstart-api.d.ts +164 -0
  98. package/dist/quickstart-api.js +351 -0
  99. package/dist/quickstart-api.js.map +1 -0
  100. package/dist/quickstart.js +23 -50
  101. package/dist/quickstart.js.map +1 -1
  102. package/dist/scheduler/db.js +17 -5
  103. package/dist/scheduler/db.js.map +1 -1
  104. package/dist/scheduler/db.test.js +34 -1
  105. package/dist/scheduler/db.test.js.map +1 -1
  106. package/dist/scheduler/types.d.ts +4 -0
  107. package/dist/scheduler/types.js.map +1 -1
  108. package/dist/secret-store.d.ts +25 -0
  109. package/dist/secret-store.js +165 -0
  110. package/dist/secret-store.js.map +1 -0
  111. package/dist/self-restart-limit.d.ts +21 -0
  112. package/dist/self-restart-limit.js +129 -0
  113. package/dist/self-restart-limit.js.map +1 -0
  114. package/dist/settings-api.d.ts +116 -0
  115. package/dist/settings-api.js +530 -5
  116. package/dist/settings-api.js.map +1 -1
  117. package/dist/setup-auth.d.ts +113 -0
  118. package/dist/setup-auth.js +181 -0
  119. package/dist/setup-auth.js.map +1 -0
  120. package/dist/setup-form.d.ts +18 -0
  121. package/dist/setup-form.js +315 -0
  122. package/dist/setup-form.js.map +1 -0
  123. package/dist/setup-host.d.ts +162 -0
  124. package/dist/setup-host.js +496 -0
  125. package/dist/setup-host.js.map +1 -0
  126. package/dist/setup-marker.d.ts +8 -0
  127. package/dist/setup-marker.js +39 -0
  128. package/dist/setup-marker.js.map +1 -0
  129. package/dist/setup-tunnel-consent.d.ts +53 -0
  130. package/dist/setup-tunnel-consent.js +82 -0
  131. package/dist/setup-tunnel-consent.js.map +1 -0
  132. package/dist/setup-wizard.js +4 -0
  133. package/dist/setup-wizard.js.map +1 -1
  134. package/dist/steer-capability.js +4 -1
  135. package/dist/steer-capability.js.map +1 -1
  136. package/dist/tips.js +1 -1
  137. package/dist/tips.js.map +1 -1
  138. package/dist/tmux-manager.js +29 -4
  139. package/dist/tmux-manager.js.map +1 -1
  140. package/dist/tool-permissions-notice.d.ts +38 -0
  141. package/dist/tool-permissions-notice.js +92 -0
  142. package/dist/tool-permissions-notice.js.map +1 -0
  143. package/dist/tool-permissions.d.ts +120 -0
  144. package/dist/tool-permissions.js +277 -0
  145. package/dist/tool-permissions.js.map +1 -0
  146. package/dist/topic-commands.js +1 -0
  147. package/dist/topic-commands.js.map +1 -1
  148. package/dist/transcript-sources.d.ts +12 -1
  149. package/dist/transcript-sources.js +19 -3
  150. package/dist/transcript-sources.js.map +1 -1
  151. package/dist/tunnel/cloudflared.d.ts +71 -0
  152. package/dist/tunnel/cloudflared.js +447 -0
  153. package/dist/tunnel/cloudflared.js.map +1 -0
  154. package/dist/tunnel/lease.d.ts +75 -0
  155. package/dist/tunnel/lease.js +209 -0
  156. package/dist/tunnel/lease.js.map +1 -0
  157. package/dist/tunnel/manager.d.ts +56 -0
  158. package/dist/tunnel/manager.js +167 -0
  159. package/dist/tunnel/manager.js.map +1 -0
  160. package/dist/tunnel/types.d.ts +119 -0
  161. package/dist/tunnel/types.js +33 -0
  162. package/dist/tunnel/types.js.map +1 -0
  163. package/dist/types.d.ts +2 -0
  164. package/dist/ui/dashboard.html +4 -3
  165. package/dist/ui/settings.html +808 -156
  166. package/dist/ui/view.html +2 -2
  167. package/dist/usage/i18n-keys.d.ts +1 -1
  168. package/dist/usage/i18n-keys.js +1 -1
  169. package/dist/usage/i18n-keys.js.map +1 -1
  170. package/dist/usage/providers.d.ts +23 -14
  171. package/dist/usage/providers.js +220 -58
  172. package/dist/usage/providers.js.map +1 -1
  173. package/dist/usage/usage-api.d.ts +13 -0
  174. package/dist/usage/usage-api.js +69 -1
  175. package/dist/usage/usage-api.js.map +1 -1
  176. package/dist/web-api.js +8 -5
  177. package/dist/web-api.js.map +1 -1
  178. package/dist/web-auth.d.ts +75 -0
  179. package/dist/web-auth.js +208 -2
  180. package/dist/web-auth.js.map +1 -1
  181. package/dist/web-terminal.d.ts +30 -1
  182. package/dist/web-terminal.js +86 -3
  183. package/dist/web-terminal.js.map +1 -1
  184. package/package.json +2 -1
@@ -0,0 +1,92 @@
1
+ /**
2
+ * What to tell an operator whose fleet predates the `worker` default.
3
+ *
4
+ * Two things can be true of an existing installation and neither of them is
5
+ * something to fix on the operator's behalf:
6
+ *
7
+ * - `defaults.tool_set: full` may be written in their `fleet.yaml`, in which
8
+ * case the new code default never applies and every worker still holds the
9
+ * whole toolbox. Rewriting that line would be a surprise placed inside their
10
+ * own file.
11
+ * - Some instances really are coordinating, and marking them is a judgement
12
+ * about how their fleet is organised.
13
+ *
14
+ * So this computes the advice and says it once, naming the instances that will
15
+ * actually break rather than the ones that merely look like coordinators. A
16
+ * notice that asks someone to mark twenty instances they did not need to mark
17
+ * is a notice they stop reading.
18
+ */
19
+ import { mayUseTool, resolveToolSet } from "./tool-permissions.js";
20
+ /**
21
+ * Which instances would lose something they have actually been using.
22
+ *
23
+ * The rule is "called a tool the resolved profile refuses" — that is the
24
+ * definition of breaking, not a guess at intent. An instance that only ever
25
+ * called `delegate_task` does not appear, because `delegate_task` stays with
26
+ * the worker and nothing about it changes.
27
+ */
28
+ export function coordinatorCandidates(input) {
29
+ const out = [];
30
+ for (const use of input.recent) {
31
+ // The activity log outlives the config. An instance that has since been
32
+ // deleted resolves to `worker` like any other unknown name, and would be
33
+ // named in a list of things to go and edit that no longer exist.
34
+ if (!Object.hasOwn(input.instances, use.instance))
35
+ continue;
36
+ const config = input.instances[use.instance];
37
+ // An instance that is already explicitly widened, or is a general, is not
38
+ // about to lose anything.
39
+ const profile = resolveToolSet(config, use.instance);
40
+ const refused = [...use.tools.entries()]
41
+ .filter(([tool]) => !mayUseTool(profile, tool))
42
+ .sort((a, b) => b[1] - a[1]);
43
+ if (refused.length > 0)
44
+ out.push({ instance: use.instance, refusedTools: refused });
45
+ }
46
+ return out.sort((a, b) => b.refusedTools.reduce((n, [, c]) => n + c, 0) - a.refusedTools.reduce((n, [, c]) => n + c, 0));
47
+ }
48
+ /** True when this fleet asked for `full` out loud, so the new default cannot reach it. */
49
+ export function hasExplicitFullDefault(input) {
50
+ return input.defaultsToolSet === "full";
51
+ }
52
+ export function instancesExplicitlyFull(input) {
53
+ return Object.entries(input.instances)
54
+ .filter(([, config]) => config?.tool_set === "full")
55
+ .map(([name]) => name)
56
+ .sort();
57
+ }
58
+ /**
59
+ * The whole notice, or null when there is nothing worth saying.
60
+ *
61
+ * One message rather than two: an operator who needs to hear both hears them
62
+ * together, in the order they have to act on them.
63
+ */
64
+ export function buildToolPermissionsNotice(input) {
65
+ const lines = [];
66
+ const explicitFull = hasExplicitFullDefault(input);
67
+ const alsoFull = instancesExplicitlyFull(input);
68
+ const candidates = coordinatorCandidates(input);
69
+ if (explicitFull) {
70
+ lines.push("Your fleet.yaml sets `defaults.tool_set: full`, so every agent still gets all of AgEnD's tools —", "including create_instance, delete_instance and update_fleet_defaults. AgEnD's own default is now", "`worker`, but an explicit setting wins and yours has not been changed.", "", "To take the new default, remove that line (or set it to `worker`).");
71
+ }
72
+ else if (alsoFull.length > 0) {
73
+ lines.push(`These instances are set to \`tool_set: full\` and keep every tool: ${alsoFull.join(", ")}.`, "AgEnD's default is now `worker`; an explicit setting wins and yours have not been changed.");
74
+ }
75
+ if (candidates.length > 0) {
76
+ if (lines.length > 0)
77
+ lines.push("");
78
+ lines.push(`${candidates.length} instance${candidates.length === 1 ? " has" : "s have"} used tools a worker does not get.`, "Mark them `tool_set: coordinator` so they keep working:", "");
79
+ for (const c of candidates) {
80
+ const used = c.refusedTools.map(([tool, count]) => `${tool}×${count}`).join(" ");
81
+ lines.push(` ${c.instance} ${used}`);
82
+ }
83
+ lines.push("",
84
+ // The derivation only sees one of the three paths a tool call can take,
85
+ // so this says what it found rather than claiming it found everything.
86
+ "That list is what recent activity shows; an agent that has been quiet may still need marking.");
87
+ }
88
+ if (lines.length === 0)
89
+ return null;
90
+ return ["AgEnD tool permissions have changed.", "", ...lines].join("\n");
91
+ }
92
+ //# sourceMappingURL=tool-permissions-notice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-permissions-notice.js","sourceRoot":"","sources":["../src/tool-permissions-notice.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,120 @@
1
+ export type ToolSetName = "full" | "standard" | "worker" | "coordinator" | "minimal" | "general";
2
+ /**
3
+ * Three tiers plus the three that already existed.
4
+ *
5
+ * `general` is not `coordinator` plus channel I/O — it is deliberately smaller:
6
+ * a dispatcher has no business deleting instances or rewriting fleet defaults.
7
+ */
8
+ export declare const TOOL_PROFILES: Readonly<Record<ToolSetName, readonly string[]>>;
9
+ /**
10
+ * `Object.hasOwn`, not `in`.
11
+ *
12
+ * `"constructor" in PROFILE_SETS` is true — every object inherits it — so an
13
+ * instance whose `tool_set` was written as `constructor` or `__proto__` used to
14
+ * pass this check and then reach `PROFILE_SETS[...].has(...)` on a function,
15
+ * which throws inside the sink. A name that is not a profile has to answer no,
16
+ * whatever Object.prototype happens to carry.
17
+ */
18
+ export declare function isToolSetName(value: unknown): value is ToolSetName;
19
+ export declare function toolsFor(profile: ToolSetName): ReadonlySet<string>;
20
+ export declare function mayUseTool(profile: ToolSetName, tool: string): boolean;
21
+ /**
22
+ * Which profile an instance runs under.
23
+ *
24
+ * An explicit `tool_set` always wins, including `full`: a general that has been
25
+ * deliberately narrowed must stay narrowed, and a worker that has been
26
+ * deliberately widened must stay wide. Only when nothing was written does the
27
+ * role decide.
28
+ *
29
+ * `unsetDefault` is the answer for an ordinary instance that said nothing, and
30
+ * it is `"worker"`. It used to be every tool there is, which is what #804
31
+ * actually was: nobody chose to give a worker `create_instance`, it arrived by
32
+ * saying nothing. An instance that needs more says so.
33
+ *
34
+ * A value that is not a profile is not an explicit choice, and falls to the
35
+ * role rather than to the toolbox. Before, an unrecognised `AGEND_TOOL_SET`
36
+ * fell back to all 47 tools — a typo was the shortest path to maximum
37
+ * privilege, which is the wrong direction for a mistake to travel.
38
+ */
39
+ export declare function resolveToolSet(config: {
40
+ tool_set?: string;
41
+ general_topic?: boolean;
42
+ } | undefined, name: string, unsetDefault?: ToolSetName): ToolSetName;
43
+ /**
44
+ * The profile for a process that only has the environment variable.
45
+ *
46
+ * mcp-server runs on the other side of a spawn and never sees fleet.yaml, so it
47
+ * resolves from `AGEND_TOOL_SET` alone. Same rules, same fallback, one function
48
+ * — the alternative is two copies of "what does an unknown name mean" that
49
+ * drift the first time one of them is edited.
50
+ */
51
+ export declare function resolveToolSetFromEnv(value: string | undefined): ToolSetName;
52
+ /**
53
+ * The IPC message types that reach a handler of their own.
54
+ *
55
+ * `fleet_outbound` carries its tool name in the body; everything below is a
56
+ * type that IS a tool, dispatched at `fleet-manager`'s IPC switch without ever
57
+ * passing through the outbound handler. They were invisible to the permission
58
+ * question until this table existed, which is how `update_decision` — a tool on
59
+ * the coordinator-only list — kept a way through.
60
+ */
61
+ /**
62
+ * The tool an IPC message type means, or null if it is not one.
63
+ *
64
+ * Own-property only, for the same reason as `isToolSetName`: a message with
65
+ * `type: "constructor"` would otherwise pass the gate and hand a function to
66
+ * the permission check.
67
+ */
68
+ export declare function toolForIpcType(type: unknown): string | null;
69
+ export declare const IPC_TYPE_TOOLS: Readonly<Record<string, string>>;
70
+ /**
71
+ * Agent-endpoint ops that never reach its `OP_MAP`.
72
+ *
73
+ * `dispatchAgentOperation` answers these before the map is consulted, so a
74
+ * table built from the map alone would have six gaps in it.
75
+ */
76
+ export declare const EARLY_AGENT_OP_TOOLS: Readonly<Record<string, string>>;
77
+ /**
78
+ * What to say to an agent that was refused.
79
+ *
80
+ * It will read this as an instruction, so it says what to do instead rather
81
+ * than only what went wrong. Naming the profile matters too: "not allowed" with
82
+ * no reason invites retrying.
83
+ */
84
+ export declare function toolRefusedMessage(profile: ToolSetName, tool: string): string;
85
+ export type ScheduleOp = "create" | "update" | "delete";
86
+ /**
87
+ * Whether a schedule write is allowed, decided on its TARGET (#895).
88
+ *
89
+ * Having the tool is not the control: a worker holds create/update/delete so it
90
+ * can schedule its own heartbeats and follow-ups. The control is here, and it
91
+ * is pure so every case can be enumerated in a test.
92
+ *
93
+ * - `caller` is the instance the SERVER resolved for the request — the IPC
94
+ * connection or the agent token. Never a field of the request.
95
+ * - create: the target is `requestedTarget`, or the caller when omitted.
96
+ * - update: the existing schedule, AND `requestedTarget` when present. Checking
97
+ * only the existing one would let a worker create a schedule for itself and
98
+ * then `update {target: other}` — a bypass in two calls.
99
+ * - update/delete: a non-coordinator may only touch a schedule it OWNS, meaning
100
+ * it targets the caller AND the caller created it. A heartbeat a coordinator
101
+ * put on a worker stays the coordinator's to change.
102
+ *
103
+ * Returns null when allowed, or the refusal to hand back to the agent.
104
+ */
105
+ export declare function scheduleOpRefusal(profile: ToolSetName, caller: string, op: ScheduleOp, subject: {
106
+ requestedTarget?: string | null;
107
+ existing?: {
108
+ target: string;
109
+ source: string;
110
+ } | null;
111
+ }): string | null;
112
+ /** Where a permission question came from. Recorded so the gaps stay visible. */
113
+ export type ToolSink = "ipc-outbound" | "ipc-typed" | "agent-endpoint";
114
+ export interface ToolUseRecord {
115
+ readonly sink: ToolSink;
116
+ readonly instance: string;
117
+ readonly profile: ToolSetName;
118
+ readonly tool: string;
119
+ readonly allowed: boolean;
120
+ }
@@ -0,0 +1,277 @@
1
+ /**
2
+ * One answer to "may this instance use this tool", for every way of asking.
3
+ *
4
+ * There are four ways an agent can reach a fleet tool and only one of them ever
5
+ * consulted a tool list:
6
+ *
7
+ * 1. MCP `tools/list` — the model sees a filtered menu.
8
+ * 2. MCP `tools/call` — takes the name it was given and forwards it. The filter
9
+ * from (1) is never consulted, so a guessed name runs.
10
+ * 3. Writing `channel.sock` directly. It is a 0600 socket in the instance
11
+ * directory and the backend CLI runs as the same user with a shell, so an
12
+ * agent that can open a file can send `fleet_outbound` without mcp-server
13
+ * existing at all.
14
+ * 4. `POST /agent` with `agent.token`, which every instance gets on every spawn
15
+ * — not only the ones in cli mode.
16
+ *
17
+ * Which is why keeping a tool out of the schema is a way to spend fewer tokens
18
+ * and get a clearer error, and is not a control. The control is this module,
19
+ * called at the points where those four paths converge: the fleet's IPC
20
+ * dispatch and the agent endpoint. See
21
+ * `docs/design/coordinator-tool-perms.zh-TW.md`.
22
+ *
23
+ * Stage 1 wires the callers and records what they would have decided. Nothing
24
+ * here denies anything yet.
25
+ */
26
+ import { TOOLS } from "./channel/mcp-tools.js";
27
+ /** Everything an agent that is doing the work needs, and nothing that runs the fleet. */
28
+ const WORKER = [
29
+ // Talking to people.
30
+ "reply", "react", "edit_message", "download_attachment",
31
+ // Talking to peers. `report_result` is why `standard` was never usable as a
32
+ // worker profile: without it the delegate → work → report protocol has no
33
+ // last step. `delegate_task` is here because it creates nothing and needs a
34
+ // target that already exists — it is `send_to_instance` with a correlation
35
+ // id, and a month of real traffic showed 572 of its 574 calls coming from
36
+ // instances this would otherwise have silenced.
37
+ "send_to_instance", "report_result", "request_information", "broadcast", "delegate_task",
38
+ // Knowing where it is and who is next to it. All read-only.
39
+ "list_instances", "describe_instance", "list_teams", "list_models",
40
+ "get_fleet_status", "get_fleet_config", "get_usage", "get_effort", "get_instance_logs",
41
+ "list_decisions", "list_schedules", "list_deployments", "validate_config",
42
+ // Its own things.
43
+ "task", "post_decision", "set_display_name", "set_description",
44
+ // Its own schedules. Present here, but not a free hand: scheduleOpRefusal
45
+ // limits a non-coordinator to schedules that target itself and that it
46
+ // created (#895). The target is the control, not whether the tool is listed.
47
+ "create_schedule", "update_schedule", "delete_schedule",
48
+ // The repo it works in: a lease on the work itself, not a way to run the fleet.
49
+ "checkout_repo", "release_repo",
50
+ ];
51
+ /**
52
+ * The verbs that run the fleet rather than do the work.
53
+ *
54
+ * Every one of them either creates, destroys, silences or reconfigures
55
+ * something that belongs to somebody else.
56
+ */
57
+ const ORCHESTRATION = [
58
+ "create_instance", "delete_instance", "replace_instance",
59
+ "start_instance", "stop_instance", "pause_instance", "wake_instance", "restart_instance",
60
+ "deploy_template", "teardown_deployment",
61
+ "create_team", "delete_team", "update_team",
62
+ "update_fleet_defaults", "update_instance_config",
63
+ // Changing a decision somebody else recorded; `post_decision` adds, and stays.
64
+ "update_decision",
65
+ ];
66
+ const ALL_TOOLS = TOOLS.map(t => t.name);
67
+ /**
68
+ * Three tiers plus the three that already existed.
69
+ *
70
+ * `general` is not `coordinator` plus channel I/O — it is deliberately smaller:
71
+ * a dispatcher has no business deleting instances or rewriting fleet defaults.
72
+ */
73
+ export const TOOL_PROFILES = {
74
+ full: ALL_TOOLS,
75
+ worker: WORKER,
76
+ coordinator: [...WORKER, ...ORCHESTRATION],
77
+ general: [
78
+ "reply", "react", "edit_message", "download_attachment",
79
+ "list_teams", "list_instances", "describe_instance", "get_fleet_status", "get_usage", "get_effort", "list_models",
80
+ "send_to_instance", "delegate_task", "request_information", "report_result", "broadcast",
81
+ "create_instance", "start_instance", "restart_instance", "wake_instance",
82
+ "task", "list_decisions", "post_decision",
83
+ "create_schedule", "list_schedules", "update_schedule", "delete_schedule",
84
+ ],
85
+ standard: [
86
+ "reply", "react", "edit_message",
87
+ "send_to_instance", "broadcast", "list_instances", "describe_instance",
88
+ "list_decisions", "post_decision", "task", "set_display_name", "set_description",
89
+ "validate_config", "get_fleet_status", "get_usage", "get_effort", "get_instance_logs", "get_fleet_config",
90
+ // Self-scheduling, same scope as worker (#895).
91
+ "create_schedule", "list_schedules", "update_schedule", "delete_schedule",
92
+ ],
93
+ // No schedules: an explicit `minimal` is a deliberate narrowing, and three
94
+ // more schemas would cost the one profile whose point is having few.
95
+ minimal: ["reply", "send_to_instance", "list_decisions", "download_attachment"],
96
+ };
97
+ const PROFILE_SETS = Object.fromEntries(Object.entries(TOOL_PROFILES).map(([name, tools]) => [name, new Set(tools)]));
98
+ /**
99
+ * `Object.hasOwn`, not `in`.
100
+ *
101
+ * `"constructor" in PROFILE_SETS` is true — every object inherits it — so an
102
+ * instance whose `tool_set` was written as `constructor` or `__proto__` used to
103
+ * pass this check and then reach `PROFILE_SETS[...].has(...)` on a function,
104
+ * which throws inside the sink. A name that is not a profile has to answer no,
105
+ * whatever Object.prototype happens to carry.
106
+ */
107
+ export function isToolSetName(value) {
108
+ return typeof value === "string" && Object.hasOwn(PROFILE_SETS, value);
109
+ }
110
+ export function toolsFor(profile) {
111
+ return PROFILE_SETS[profile];
112
+ }
113
+ export function mayUseTool(profile, tool) {
114
+ return PROFILE_SETS[profile].has(tool);
115
+ }
116
+ /**
117
+ * Which profile an instance runs under.
118
+ *
119
+ * An explicit `tool_set` always wins, including `full`: a general that has been
120
+ * deliberately narrowed must stay narrowed, and a worker that has been
121
+ * deliberately widened must stay wide. Only when nothing was written does the
122
+ * role decide.
123
+ *
124
+ * `unsetDefault` is the answer for an ordinary instance that said nothing, and
125
+ * it is `"worker"`. It used to be every tool there is, which is what #804
126
+ * actually was: nobody chose to give a worker `create_instance`, it arrived by
127
+ * saying nothing. An instance that needs more says so.
128
+ *
129
+ * A value that is not a profile is not an explicit choice, and falls to the
130
+ * role rather than to the toolbox. Before, an unrecognised `AGEND_TOOL_SET`
131
+ * fell back to all 47 tools — a typo was the shortest path to maximum
132
+ * privilege, which is the wrong direction for a mistake to travel.
133
+ */
134
+ export function resolveToolSet(config, name, unsetDefault = "worker") {
135
+ const explicit = config?.tool_set;
136
+ if (isToolSetName(explicit))
137
+ return explicit;
138
+ if (config?.general_topic === true || name === "general")
139
+ return "general";
140
+ return unsetDefault;
141
+ }
142
+ /**
143
+ * The profile for a process that only has the environment variable.
144
+ *
145
+ * mcp-server runs on the other side of a spawn and never sees fleet.yaml, so it
146
+ * resolves from `AGEND_TOOL_SET` alone. Same rules, same fallback, one function
147
+ * — the alternative is two copies of "what does an unknown name mean" that
148
+ * drift the first time one of them is edited.
149
+ */
150
+ export function resolveToolSetFromEnv(value) {
151
+ if (!value)
152
+ return "full";
153
+ if (isToolSetName(value))
154
+ return value;
155
+ return "worker";
156
+ }
157
+ /**
158
+ * The IPC message types that reach a handler of their own.
159
+ *
160
+ * `fleet_outbound` carries its tool name in the body; everything below is a
161
+ * type that IS a tool, dispatched at `fleet-manager`'s IPC switch without ever
162
+ * passing through the outbound handler. They were invisible to the permission
163
+ * question until this table existed, which is how `update_decision` — a tool on
164
+ * the coordinator-only list — kept a way through.
165
+ */
166
+ /**
167
+ * The tool an IPC message type means, or null if it is not one.
168
+ *
169
+ * Own-property only, for the same reason as `isToolSetName`: a message with
170
+ * `type: "constructor"` would otherwise pass the gate and hand a function to
171
+ * the permission check.
172
+ */
173
+ export function toolForIpcType(type) {
174
+ return typeof type === "string" && Object.hasOwn(IPC_TYPE_TOOLS, type) ? IPC_TYPE_TOOLS[type] : null;
175
+ }
176
+ export const IPC_TYPE_TOOLS = {
177
+ fleet_schedule_create: "create_schedule",
178
+ fleet_schedule_list: "list_schedules",
179
+ fleet_schedule_update: "update_schedule",
180
+ fleet_schedule_delete: "delete_schedule",
181
+ fleet_decision_create: "post_decision",
182
+ fleet_decision_list: "list_decisions",
183
+ fleet_decision_update: "update_decision",
184
+ fleet_task: "task",
185
+ fleet_set_display_name: "set_display_name",
186
+ fleet_set_description: "set_description",
187
+ };
188
+ /**
189
+ * Agent-endpoint ops that never reach its `OP_MAP`.
190
+ *
191
+ * `dispatchAgentOperation` answers these before the map is consulted, so a
192
+ * table built from the map alone would have six gaps in it.
193
+ */
194
+ export const EARLY_AGENT_OP_TOOLS = {
195
+ "schedule-create": "create_schedule",
196
+ "schedule-list": "list_schedules",
197
+ "schedule-update": "update_schedule",
198
+ "schedule-delete": "delete_schedule",
199
+ // `decision-post` is what agent-cli sends; the endpoint only looks at the
200
+ // prefix, so both spellings reach the same handler and both need a name.
201
+ "decision-post": "post_decision",
202
+ "decision-create": "post_decision",
203
+ "decision-list": "list_decisions",
204
+ "decision-update": "update_decision",
205
+ task: "task",
206
+ usage: "get_usage",
207
+ rename: "set_display_name",
208
+ "set-description": "set_description",
209
+ };
210
+ /**
211
+ * What to say to an agent that was refused.
212
+ *
213
+ * It will read this as an instruction, so it says what to do instead rather
214
+ * than only what went wrong. Naming the profile matters too: "not allowed" with
215
+ * no reason invites retrying.
216
+ */
217
+ export function toolRefusedMessage(profile, tool) {
218
+ return `${tool} is not available to this instance: it runs with the "${profile}" tool set, and ${tool} belongs to a coordinator. `
219
+ + "Report what you need with report_result and let the coordinator do it, "
220
+ + 'or ask an administrator to set `tool_set: coordinator` for this instance.';
221
+ }
222
+ /**
223
+ * The profiles that may schedule work for, or manage the schedules of, OTHER
224
+ * instances. Everyone else may still schedule — for itself only.
225
+ */
226
+ const SCHEDULES_OTHERS = new Set(["full", "coordinator", "general"]);
227
+ /**
228
+ * Whether a schedule write is allowed, decided on its TARGET (#895).
229
+ *
230
+ * Having the tool is not the control: a worker holds create/update/delete so it
231
+ * can schedule its own heartbeats and follow-ups. The control is here, and it
232
+ * is pure so every case can be enumerated in a test.
233
+ *
234
+ * - `caller` is the instance the SERVER resolved for the request — the IPC
235
+ * connection or the agent token. Never a field of the request.
236
+ * - create: the target is `requestedTarget`, or the caller when omitted.
237
+ * - update: the existing schedule, AND `requestedTarget` when present. Checking
238
+ * only the existing one would let a worker create a schedule for itself and
239
+ * then `update {target: other}` — a bypass in two calls.
240
+ * - update/delete: a non-coordinator may only touch a schedule it OWNS, meaning
241
+ * it targets the caller AND the caller created it. A heartbeat a coordinator
242
+ * put on a worker stays the coordinator's to change.
243
+ *
244
+ * Returns null when allowed, or the refusal to hand back to the agent.
245
+ */
246
+ export function scheduleOpRefusal(profile, caller, op, subject) {
247
+ if (SCHEDULES_OTHERS.has(profile))
248
+ return null;
249
+ const tool = `${op}_schedule`;
250
+ const requested = subject.requestedTarget?.trim() || null;
251
+ if (op === "create") {
252
+ const target = requested ?? caller;
253
+ return target === caller ? null : scheduleRefusedMessage(profile, tool, caller, `schedule work for "${target}"`);
254
+ }
255
+ const existing = subject.existing;
256
+ // A schedule that does not exist is the scheduler's error to report; there
257
+ // is nothing here to own or not own.
258
+ if (!existing)
259
+ return null;
260
+ if (existing.target !== caller || existing.source !== caller) {
261
+ return scheduleRefusedMessage(profile, tool, caller, existing.target !== caller
262
+ ? `change a schedule that targets "${existing.target}"`
263
+ : `change a schedule "${existing.source}" set for you`);
264
+ }
265
+ if (op === "update" && requested && requested !== caller) {
266
+ return scheduleRefusedMessage(profile, tool, caller, `move a schedule onto "${requested}"`);
267
+ }
268
+ return null;
269
+ }
270
+ /** A schedule refusal the agent can act on, in the #884 shape: why, and what to do instead. */
271
+ function scheduleRefusedMessage(profile, tool, caller, attempted) {
272
+ return `${tool} refused: under the "${profile}" tool set an instance may only manage its own schedules — `
273
+ + `ones that target it ("${caller}") and that it created — so it cannot ${attempted}. `
274
+ + "To schedule work for another instance, or change one set for you, ask a coordinator "
275
+ + "with report_result or send_to_instance.";
276
+ }
277
+ //# sourceMappingURL=tool-permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-permissions.js","sourceRoot":"","sources":["../src/tool-permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAI/C,yFAAyF;AACzF,MAAM,MAAM,GAAsB;IAChC,qBAAqB;IACrB,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,qBAAqB;IACvD,4EAA4E;IAC5E,0EAA0E;IAC1E,4EAA4E;IAC5E,2EAA2E;IAC3E,0EAA0E;IAC1E,gDAAgD;IAChD,kBAAkB,EAAE,eAAe,EAAE,qBAAqB,EAAE,WAAW,EAAE,eAAe;IACxF,4DAA4D;IAC5D,gBAAgB,EAAE,mBAAmB,EAAE,YAAY,EAAE,aAAa;IAClE,kBAAkB,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB;IACtF,gBAAgB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,iBAAiB;IACzE,kBAAkB;IAClB,MAAM,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB;IAC9D,0EAA0E;IAC1E,uEAAuE;IACvE,6EAA6E;IAC7E,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB;IACvD,gFAAgF;IAChF,eAAe,EAAE,cAAc;CAChC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,aAAa,GAAsB;IACvC,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB;IACxD,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,kBAAkB;IACxF,iBAAiB,EAAE,qBAAqB;IACxC,aAAa,EAAE,aAAa,EAAE,aAAa;IAC3C,uBAAuB,EAAE,wBAAwB;IACjD,+EAA+E;IAC/E,iBAAiB;CAClB,CAAC;AAEF,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAqD;IAC7E,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,MAAM;IACd,WAAW,EAAE,CAAC,GAAG,MAAM,EAAE,GAAG,aAAa,CAAC;IAC1C,OAAO,EAAE;QACP,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,qBAAqB;QACvD,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa;QACjH,kBAAkB,EAAE,eAAe,EAAE,qBAAqB,EAAE,eAAe,EAAE,WAAW;QACxF,iBAAiB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,eAAe;QACxE,MAAM,EAAE,gBAAgB,EAAE,eAAe;QACzC,iBAAiB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB;KAC1E;IACD,QAAQ,EAAE;QACR,OAAO,EAAE,OAAO,EAAE,cAAc;QAChC,kBAAkB,EAAE,WAAW,EAAE,gBAAgB,EAAE,mBAAmB;QACtE,gBAAgB,EAAE,eAAe,EAAE,MAAM,EAAE,kBAAkB,EAAE,iBAAiB;QAChF,iBAAiB,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB;QACzG,gDAAgD;QAChD,iBAAiB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB;KAC1E;IACD,2EAA2E;IAC3E,qEAAqE;IACrE,OAAO,EAAE,CAAC,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,qBAAqB,CAAC;CAChF,CAAC;AAEF,MAAM,YAAY,GAAG,MAAM,CAAC,WAAW,CACrC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CACZ,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAoB;IAC3C,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAoB,EAAE,IAAY;IAC3D,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAkE,EAClE,IAAY,EACZ,eAA4B,QAAQ;IAEpC,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,CAAC;IAClC,IAAI,aAAa,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC7C,IAAI,MAAM,EAAE,aAAa,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3E,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAyB;IAC7D,IAAI,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC;IAC1B,IAAI,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;GAQG;AACH;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,IAAa;IAC1C,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACxG,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAqC;IAC9D,qBAAqB,EAAE,iBAAiB;IACxC,mBAAmB,EAAE,gBAAgB;IACrC,qBAAqB,EAAE,iBAAiB;IACxC,qBAAqB,EAAE,iBAAiB;IACxC,qBAAqB,EAAE,eAAe;IACtC,mBAAmB,EAAE,gBAAgB;IACrC,qBAAqB,EAAE,iBAAiB;IACxC,UAAU,EAAE,MAAM;IAClB,sBAAsB,EAAE,kBAAkB;IAC1C,qBAAqB,EAAE,iBAAiB;CACzC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAqC;IACpE,iBAAiB,EAAE,iBAAiB;IACpC,eAAe,EAAE,gBAAgB;IACjC,iBAAiB,EAAE,iBAAiB;IACpC,iBAAiB,EAAE,iBAAiB;IACpC,0EAA0E;IAC1E,yEAAyE;IACzE,eAAe,EAAE,eAAe;IAChC,iBAAiB,EAAE,eAAe;IAClC,eAAe,EAAE,gBAAgB;IACjC,iBAAiB,EAAE,iBAAiB;IACpC,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,WAAW;IAClB,MAAM,EAAE,kBAAkB;IAC1B,iBAAiB,EAAE,iBAAiB;CACrC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAoB,EAAE,IAAY;IACnE,OAAO,GAAG,IAAI,yDAAyD,OAAO,mBAAmB,IAAI,6BAA6B;UAC9H,yEAAyE;UACzE,2EAA2E,CAAC;AAClF,CAAC;AAED;;;GAGG;AACH,MAAM,gBAAgB,GAA6B,IAAI,GAAG,CAAc,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC;AAI5G;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAAoB,EACpB,MAAc,EACd,EAAc,EACd,OAAkG;IAElG,IAAI,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,IAAI,GAAG,GAAG,EAAE,WAAW,CAAC;IAC9B,MAAM,SAAS,GAAG,OAAO,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;IAC1D,IAAI,EAAE,KAAK,QAAQ,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,SAAS,IAAI,MAAM,CAAC;QACnC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,sBAAsB,MAAM,GAAG,CAAC,CAAC;IACnH,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,2EAA2E;IAC3E,qCAAqC;IACrC,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC7D,OAAO,sBAAsB,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EACjD,QAAQ,CAAC,MAAM,KAAK,MAAM;YACxB,CAAC,CAAC,mCAAmC,QAAQ,CAAC,MAAM,GAAG;YACvD,CAAC,CAAC,sBAAsB,QAAQ,CAAC,MAAM,eAAe,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,EAAE,KAAK,QAAQ,IAAI,SAAS,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QACzD,OAAO,sBAAsB,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,yBAAyB,SAAS,GAAG,CAAC,CAAC;IAC9F,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+FAA+F;AAC/F,SAAS,sBAAsB,CAAC,OAAoB,EAAE,IAAY,EAAE,MAAc,EAAE,SAAiB;IACnG,OAAO,GAAG,IAAI,wBAAwB,OAAO,6DAA6D;UACtG,yBAAyB,MAAM,yCAAyC,SAAS,IAAI;UACrF,sFAAsF;UACtF,yCAAyC,CAAC;AAChD,CAAC"}
@@ -98,6 +98,7 @@ export function clearCommandForBackend(backend) {
98
98
  case "kiro-cli":
99
99
  case "antigravity":
100
100
  case "opencode":
101
+ case "muse":
101
102
  case "mock":
102
103
  return "/clear";
103
104
  case "grok":