agenthub-multiagent-mcp 1.75.0 → 1.76.1

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 (112) hide show
  1. package/dist/client.d.ts +19 -1
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +31 -0
  4. package/dist/client.js.map +1 -1
  5. package/dist/commands/setup-shell.js +11 -11
  6. package/dist/currentCaptureSession.d.ts +31 -0
  7. package/dist/currentCaptureSession.d.ts.map +1 -0
  8. package/dist/currentCaptureSession.js +54 -0
  9. package/dist/currentCaptureSession.js.map +1 -0
  10. package/dist/currentCaptureSession.test.d.ts +2 -0
  11. package/dist/currentCaptureSession.test.d.ts.map +1 -0
  12. package/dist/currentCaptureSession.test.js +55 -0
  13. package/dist/currentCaptureSession.test.js.map +1 -0
  14. package/dist/employee.d.ts +11 -0
  15. package/dist/employee.d.ts.map +1 -1
  16. package/dist/employee.js +64 -1
  17. package/dist/employee.js.map +1 -1
  18. package/dist/employee.test.js +88 -1
  19. package/dist/employee.test.js.map +1 -1
  20. package/dist/goshtiChannel/client.d.ts +9 -0
  21. package/dist/goshtiChannel/client.d.ts.map +1 -0
  22. package/dist/goshtiChannel/client.js +63 -0
  23. package/dist/goshtiChannel/client.js.map +1 -0
  24. package/dist/goshtiChannel/config.d.ts +42 -0
  25. package/dist/goshtiChannel/config.d.ts.map +1 -0
  26. package/dist/goshtiChannel/config.js +129 -0
  27. package/dist/goshtiChannel/config.js.map +1 -0
  28. package/dist/goshtiChannel/config.test.d.ts +2 -0
  29. package/dist/goshtiChannel/config.test.d.ts.map +1 -0
  30. package/dist/goshtiChannel/config.test.js +73 -0
  31. package/dist/goshtiChannel/config.test.js.map +1 -0
  32. package/dist/goshtiChannel/core.d.ts +63 -0
  33. package/dist/goshtiChannel/core.d.ts.map +1 -0
  34. package/dist/goshtiChannel/core.js +237 -0
  35. package/dist/goshtiChannel/core.js.map +1 -0
  36. package/dist/goshtiChannel/core.test.d.ts +2 -0
  37. package/dist/goshtiChannel/core.test.d.ts.map +1 -0
  38. package/dist/goshtiChannel/core.test.js +250 -0
  39. package/dist/goshtiChannel/core.test.js.map +1 -0
  40. package/dist/goshtiChannel/credential.d.ts +29 -0
  41. package/dist/goshtiChannel/credential.d.ts.map +1 -0
  42. package/dist/goshtiChannel/credential.js +160 -0
  43. package/dist/goshtiChannel/credential.js.map +1 -0
  44. package/dist/goshtiChannel/credential.test.d.ts +2 -0
  45. package/dist/goshtiChannel/credential.test.d.ts.map +1 -0
  46. package/dist/goshtiChannel/credential.test.js +127 -0
  47. package/dist/goshtiChannel/credential.test.js.map +1 -0
  48. package/dist/goshtiChannel/e2e.test.d.ts +2 -0
  49. package/dist/goshtiChannel/e2e.test.d.ts.map +1 -0
  50. package/dist/goshtiChannel/e2e.test.js +163 -0
  51. package/dist/goshtiChannel/e2e.test.js.map +1 -0
  52. package/dist/goshtiChannel/policy.d.ts +154 -0
  53. package/dist/goshtiChannel/policy.d.ts.map +1 -0
  54. package/dist/goshtiChannel/policy.js +240 -0
  55. package/dist/goshtiChannel/policy.js.map +1 -0
  56. package/dist/goshtiChannel/policy.test.d.ts +2 -0
  57. package/dist/goshtiChannel/policy.test.d.ts.map +1 -0
  58. package/dist/goshtiChannel/policy.test.js +263 -0
  59. package/dist/goshtiChannel/policy.test.js.map +1 -0
  60. package/dist/goshtiChannel/setup.d.ts +15 -0
  61. package/dist/goshtiChannel/setup.d.ts.map +1 -0
  62. package/dist/goshtiChannel/setup.js +125 -0
  63. package/dist/goshtiChannel/setup.js.map +1 -0
  64. package/dist/goshtiChannel/setup.test.d.ts +2 -0
  65. package/dist/goshtiChannel/setup.test.d.ts.map +1 -0
  66. package/dist/goshtiChannel/setup.test.js +96 -0
  67. package/dist/goshtiChannel/setup.test.js.map +1 -0
  68. package/dist/goshtiChannel/stream.d.ts +39 -0
  69. package/dist/goshtiChannel/stream.d.ts.map +1 -0
  70. package/dist/goshtiChannel/stream.js +174 -0
  71. package/dist/goshtiChannel/stream.js.map +1 -0
  72. package/dist/goshtiChannel/stream.test.d.ts +2 -0
  73. package/dist/goshtiChannel/stream.test.d.ts.map +1 -0
  74. package/dist/goshtiChannel/stream.test.js +164 -0
  75. package/dist/goshtiChannel/stream.test.js.map +1 -0
  76. package/dist/goshtiChannel.d.ts +22 -0
  77. package/dist/goshtiChannel.d.ts.map +1 -0
  78. package/dist/goshtiChannel.js +193 -0
  79. package/dist/goshtiChannel.js.map +1 -0
  80. package/dist/state.d.ts +2 -0
  81. package/dist/state.d.ts.map +1 -1
  82. package/dist/state.js.map +1 -1
  83. package/dist/tools/brainWriteCheck.test.d.ts +10 -0
  84. package/dist/tools/brainWriteCheck.test.d.ts.map +1 -0
  85. package/dist/tools/brainWriteCheck.test.js +67 -0
  86. package/dist/tools/brainWriteCheck.test.js.map +1 -0
  87. package/dist/tools/employeeTraining.d.ts +46 -0
  88. package/dist/tools/employeeTraining.d.ts.map +1 -0
  89. package/dist/tools/employeeTraining.js +329 -0
  90. package/dist/tools/employeeTraining.js.map +1 -0
  91. package/dist/tools/employeeTraining.test.d.ts +7 -0
  92. package/dist/tools/employeeTraining.test.d.ts.map +1 -0
  93. package/dist/tools/employeeTraining.test.js +190 -0
  94. package/dist/tools/employeeTraining.test.js.map +1 -0
  95. package/dist/tools/index.d.ts.map +1 -1
  96. package/dist/tools/index.js +155 -5
  97. package/dist/tools/index.js.map +1 -1
  98. package/dist/tools/runs.d.ts +43 -0
  99. package/dist/tools/runs.d.ts.map +1 -0
  100. package/dist/tools/runs.js +280 -0
  101. package/dist/tools/runs.js.map +1 -0
  102. package/dist/tools/runs.test.d.ts +9 -0
  103. package/dist/tools/runs.test.d.ts.map +1 -0
  104. package/dist/tools/runs.test.js +114 -0
  105. package/dist/tools/runs.test.js.map +1 -0
  106. package/dist/tools/tools.test.js +82 -2
  107. package/dist/tools/tools.test.js.map +1 -1
  108. package/package.json +79 -78
  109. package/skills/catalog.json +104 -102
  110. package/skills/commands/close-session.md +2 -2
  111. package/skills/commands/start-session.md +2 -2
  112. package/skills/manifest.json +67 -65
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Employee training MCP tools (add-employee-training-loops §1.3 manual trigger,
3
+ * §2–§3). Handlers against a mocked ApiClient for result/refusal shaping, and
4
+ * the real ApiClient with fetch stubbed for the wire contract.
5
+ */
6
+ import { afterEach, describe, expect, it, vi } from "vitest";
7
+ import { EMPLOYEE_TRAINING_TOOLS, handleEmployeeTrainingToolCall, isEmployeeTrainingTool, registerEmployeeTrainingTools, } from "./employeeTraining.js";
8
+ import { ApiClient } from "../client.js";
9
+ function mockClient(overrides = {}) {
10
+ return {
11
+ getTrainingObservations: vi.fn(),
12
+ runTrainingPass: vi.fn(),
13
+ listTrainingRecords: vi.fn(),
14
+ getTrainingCurriculum: vi.fn(),
15
+ ...overrides,
16
+ };
17
+ }
18
+ const ok = (data, status = 200) => ({ ok: true, status, data });
19
+ const fail = (status, error, message) => ({
20
+ ok: false,
21
+ status,
22
+ error,
23
+ message,
24
+ data: { error, message },
25
+ });
26
+ afterEach(() => {
27
+ vi.unstubAllGlobals();
28
+ vi.restoreAllMocks();
29
+ });
30
+ describe("employee training tool registration", () => {
31
+ it("registers the four training tools", () => {
32
+ expect(registerEmployeeTrainingTools().map((t) => t.name)).toEqual([...EMPLOYEE_TRAINING_TOOLS]);
33
+ expect(EMPLOYEE_TRAINING_TOOLS).toEqual([
34
+ "employee_training_observe",
35
+ "employee_training_run",
36
+ "employee_training_history",
37
+ "employee_training_curriculum",
38
+ ]);
39
+ expect(isEmployeeTrainingTool("employee_training_run")).toBe(true);
40
+ expect(isEmployeeTrainingTool("employee_get")).toBe(false);
41
+ });
42
+ it("offers only the charter fields the server accepts", () => {
43
+ const run = registerEmployeeTrainingTools().find((t) => t.name === "employee_training_run");
44
+ const edits = run.inputSchema.properties.charter_edits;
45
+ expect(edits.items.properties.field.enum).toEqual(["mission", "responsibilities", "scope", "success_metrics"]);
46
+ expect(run.inputSchema.required).toEqual(["agent_id"]);
47
+ });
48
+ it("says a charter edit is only a proposal", () => {
49
+ const run = registerEmployeeTrainingTools().find((t) => t.name === "employee_training_run");
50
+ expect(run.description).toMatch(/person/i);
51
+ expect(run.description).toMatch(/not applied|never applied|nothing changes/i);
52
+ });
53
+ });
54
+ describe("employee_training_run", () => {
55
+ it("passes lessons, edits and spend through and summarises the record", async () => {
56
+ const runTrainingPass = vi.fn().mockResolvedValue(ok({
57
+ record: {
58
+ id: "rec-1",
59
+ status: "completed",
60
+ lessons: [{ text: "a", duplicate: false }, { text: "b", duplicate: true }],
61
+ proposed_charter_edits: [{ field: "scope", review_id: "rev-1", state: "pending" }],
62
+ budget_spent: 900,
63
+ budget_limit: 50000,
64
+ },
65
+ scorecard: { score: 72, ladder: { decision: "hold" } },
66
+ }));
67
+ const client = mockClient({ runTrainingPass });
68
+ const out = (await handleEmployeeTrainingToolCall("employee_training_run", {
69
+ agent_id: "eng-ic-test",
70
+ lessons: ["a", "b"],
71
+ charter_edits: [{ field: "scope", after: "x", rationale: "y" }],
72
+ tokens_spent: 900,
73
+ window_days: 7,
74
+ }, client));
75
+ expect(runTrainingPass).toHaveBeenCalledWith("eng-ic-test", {
76
+ lessons: ["a", "b"],
77
+ charter_edits: [{ field: "scope", after: "x", rationale: "y" }],
78
+ tokens_spent: 900,
79
+ window_days: 7,
80
+ });
81
+ expect(out.ok).toBe(true);
82
+ expect(out.record_id).toBe("rec-1");
83
+ expect(out.message).toContain("1 new lesson");
84
+ expect(out.message).toContain("1 already known");
85
+ expect(out.message).toContain("rev-1");
86
+ expect(out.message).toMatch(/person/i);
87
+ });
88
+ it("passes practice and skills through and summarises them", async () => {
89
+ const runTrainingPass = vi.fn().mockResolvedValue(ok({
90
+ record: {
91
+ id: "rec-3",
92
+ status: "partial",
93
+ stop_reason: "budget_exhausted",
94
+ lessons: [],
95
+ proposed_charter_edits: [],
96
+ practice_scores: [
97
+ { item_id: "cur-blocked", state: "graded", passed: true },
98
+ { item_id: "cur-planning", state: "assigned" },
99
+ { item_id: "cur-guardrails", state: "skipped_budget" },
100
+ ],
101
+ skills_added: [
102
+ { name: "brag", state: "install_sent" },
103
+ { name: "cybersecurity", state: "pending_approval", review_id: "rev-s" },
104
+ ],
105
+ },
106
+ scorecard: {},
107
+ }));
108
+ const client = mockClient({ runTrainingPass });
109
+ const practice = { item_ids: ["cur-blocked", "cur-planning", "cur-guardrails"] };
110
+ const skills = [{ pack: "brag" }, { pack: "cybersecurity", gap: "secrets" }];
111
+ const out = (await handleEmployeeTrainingToolCall("employee_training_run", { agent_id: "e", practice, skills }, client));
112
+ expect(runTrainingPass).toHaveBeenCalledWith("e", { practice, skills });
113
+ expect(out.message).toContain("1 graded (1 passed), 1 sent");
114
+ expect(out.message).toContain("1 not sent (budget)");
115
+ expect(out.message).toContain("rev-s");
116
+ expect(out.message).toMatch(/person/i);
117
+ });
118
+ it("describes the governed skill install", () => {
119
+ const run = registerEmployeeTrainingTools().find((t) => t.name === "employee_training_run");
120
+ const skills = run.inputSchema.properties.skills;
121
+ expect(skills.description).toMatch(/skill-pack:<name>/);
122
+ expect(skills.description).toMatch(/No agent can approve/);
123
+ });
124
+ it("reports a partial pass as stopped by the budget", async () => {
125
+ const client = mockClient({
126
+ runTrainingPass: vi.fn().mockResolvedValue(ok({
127
+ record: { id: "rec-2", status: "partial", stop_reason: "budget_exhausted", lessons: [], proposed_charter_edits: [] },
128
+ scorecard: {},
129
+ })),
130
+ });
131
+ const out = (await handleEmployeeTrainingToolCall("employee_training_run", { agent_id: "e" }, client));
132
+ expect(out.status).toBe("partial");
133
+ expect(out.message).toMatch(/budget/i);
134
+ });
135
+ it.each([
136
+ ["training_disabled", 503, /AGENTHUB_EMPLOYEE_TRAINING_ENABLED/],
137
+ ["self_training", 403, /cannot train itself/i],
138
+ ["trainer_required", 403, /trainer/i],
139
+ ["not_employee", 404, /not an employee/i],
140
+ ])("turns %s into an actionable refusal", async (code, status, pattern) => {
141
+ const client = mockClient({ runTrainingPass: vi.fn().mockResolvedValue(fail(status, code)) });
142
+ const out = (await handleEmployeeTrainingToolCall("employee_training_run", { agent_id: "e" }, client));
143
+ expect(out.ok).toBe(false);
144
+ expect(out.error).toBe(code);
145
+ expect(out.message).toMatch(pattern);
146
+ });
147
+ it("requires agent_id", async () => {
148
+ await expect(handleEmployeeTrainingToolCall("employee_training_run", {}, mockClient())).rejects.toThrow(/agent_id/);
149
+ });
150
+ });
151
+ describe("observe and history", () => {
152
+ it("returns observations unchanged", async () => {
153
+ const obs = { agent_id: "e", shifts: [{ message_id: "m1" }] };
154
+ const client = mockClient({ getTrainingObservations: vi.fn().mockResolvedValue(ok(obs)) });
155
+ const out = (await handleEmployeeTrainingToolCall("employee_training_observe", { agent_id: "e", window_days: 3 }, client));
156
+ expect(client.getTrainingObservations).toHaveBeenCalledWith("e", 3);
157
+ expect(out.ok).toBe(true);
158
+ expect(out.observations).toEqual(obs);
159
+ });
160
+ it("lists history", async () => {
161
+ const client = mockClient({ listTrainingRecords: vi.fn().mockResolvedValue(ok({ records: [{ id: "r" }], total: 1 })) });
162
+ const out = (await handleEmployeeTrainingToolCall("employee_training_history", { agent_id: "e" }, client));
163
+ expect(client.listTrainingRecords).toHaveBeenCalledWith("e", undefined);
164
+ expect(out.records).toEqual([{ id: "r" }]);
165
+ });
166
+ });
167
+ describe("wire contract", () => {
168
+ it("hits the employee training routes", async () => {
169
+ const fetchSpy = vi.fn(async () => ({
170
+ ok: true,
171
+ status: 200,
172
+ text: async () => JSON.stringify({ record: { id: "r" } }),
173
+ }));
174
+ vi.stubGlobal("fetch", fetchSpy);
175
+ const client = new ApiClient("https://hub.example/api", "key");
176
+ await client.runTrainingPass("eng ic", { lessons: ["x"] });
177
+ await client.getTrainingObservations("eng ic", 5);
178
+ await client.listTrainingRecords("eng ic", 10);
179
+ await client.getTrainingCurriculum("eng ic", 2);
180
+ const calls = fetchSpy.mock.calls;
181
+ expect(calls[0][0]).toBe("https://hub.example/api/employees/eng%20ic/training");
182
+ expect(calls[0][1].method).toBe("POST");
183
+ expect(JSON.parse(String(calls[0][1].body))).toEqual({ lessons: ["x"] });
184
+ expect(calls[1][0]).toBe("https://hub.example/api/employees/eng%20ic/training/observations?window_days=5");
185
+ expect(calls[1][1].method).toBe("GET");
186
+ expect(calls[2][0]).toBe("https://hub.example/api/employees/eng%20ic/training?limit=10");
187
+ expect(calls[3][0]).toBe("https://hub.example/api/employees/eng%20ic/training/curriculum?tickets=2");
188
+ });
189
+ });
190
+ //# sourceMappingURL=employeeTraining.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"employeeTraining.test.js","sourceRoot":"","sources":["../../src/tools/employeeTraining.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,OAAO,EAAqD,MAAM,cAAc,CAAC;AAOrG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AA4G/D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,iBAAiB,EAAE,MAAM,MAAM,CAAC;IAChC,iBAAiB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;;;OAGG;IACH,cAAc,EAAE,MAAM,WAAW,CAAC;IAClC,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,WAAW,CAAC;IACpC,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAC7B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;KACvB,KAAK,IAAI,CAAC;CACZ;AAED,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAyLD,wBAAgB,aAAa,IAAI,IAAI,EAAE,CA47FtC;AAqCD,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,OAAO,CAAC,CAwuFlB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,OAAO,EAAqD,MAAM,cAAc,CAAC;AAOrG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAmH/D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,iBAAiB,EAAE,MAAM,MAAM,CAAC;IAChC,iBAAiB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;;;OAGG;IACH,cAAc,EAAE,MAAM,WAAW,CAAC;IAClC,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,WAAW,CAAC;IACpC,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAC7B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;KACvB,KAAK,IAAI,CAAC;CACZ;AAED,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAyLD,wBAAgB,aAAa,IAAI,IAAI,EAAE,CAohGtC;AAqCD,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,OAAO,CAAC,CA6yFlB"}
@@ -12,8 +12,10 @@ import open from "open";
12
12
  import { registerOpenSpecVizTools, handleOpenSpecVizToolCall } from "./openspec-viz/index.js";
13
13
  import { syncTaskGroups, describeTaskSync } from "./openspec-viz/taskSync.js";
14
14
  import { registerIntakeRequestTools, handleIntakeRequestToolCall, isIntakeRequestTool, } from "./intakeRequests.js";
15
+ import { handleEmployeeTrainingToolCall, isEmployeeTrainingTool, registerEmployeeTrainingTools, } from "./employeeTraining.js";
15
16
  import { registerSessionControlTools, handleSessionControlToolCall, isSessionControlTool, } from "./sessionControl.js";
16
17
  import { registerGoshtiReadTools, handleGoshtiReadToolCall, isGoshtiReadTool, } from "./goshtiRead.js";
18
+ import { registerRunTools, handleRunToolCall, isRunTool } from "./runs.js";
17
19
  import { installPackFromArchive } from "../skillPackInstaller.js";
18
20
  import { getServerTime, useTimeInjection } from "../lib/server-time.js";
19
21
  import { getPendingItems } from "../lib/pending-items.js";
@@ -24,6 +26,7 @@ import * as path from "node:path";
24
26
  import { describeSendResult } from "../messageIdempotency.js";
25
27
  import { readZohoAttachments } from "../zohoAttachments.js";
26
28
  import { isUnknownSendOutcome, unknownSendOutcomeError } from "../zohoSendOutcome.js";
29
+ import { currentCaptureSessionId } from "../currentCaptureSession.js";
27
30
  // fix-message-send-idempotency — shared by the four message tools.
28
31
  const IDEMPOTENCY_KEY_DESCRIPTION = "Optional. Leave unset: a key derived from the message content is sent, so " +
29
32
  "re-issuing this exact call (e.g. after a timeout) never delivers it twice. " +
@@ -2216,8 +2219,11 @@ export function registerTools() {
2216
2219
  ...registerSessionControlTools(),
2217
2220
  // Intake requests: file, triage, scope check (add-intake-requests §6.1)
2218
2221
  ...registerIntakeRequestTools(),
2222
+ ...registerEmployeeTrainingTools(),
2219
2223
  // Reading Goshti as the agent's owner (add-agent-goshti-read §3.1)
2220
2224
  ...registerGoshtiReadTools(),
2225
+ // Orchestrated runs for the dashboard Run view (add-live-animated-views §1.8)
2226
+ ...registerRunTools(),
2221
2227
  // OpenSpec Visualizer tools
2222
2228
  ...registerOpenSpecVizTools(),
2223
2229
  // Intel layer tools (§2.5 — read-only MCP surface for intel.search + source catalog)
@@ -2373,7 +2379,7 @@ export function registerTools() {
2373
2379
  },
2374
2380
  {
2375
2381
  name: "brain_write_knowledge",
2376
- description: "Write an org knowledge fact (decision, convention, architecture insight, blocker, or alert) to the shared org brain.",
2382
+ description: "Write an org knowledge fact (decision, convention, architecture insight, blocker, or alert) to the shared org brain. The result carries `check`: `created` for a new row (with its `id`), or `deduped` when an identical active fact already exists — then `canonical_id` names the existing row if it is your organization's, and nothing is named if the match belongs to another organization. A refusal (missing fact, unknown category) is an error.",
2377
2383
  inputSchema: {
2378
2384
  type: "object",
2379
2385
  properties: {
@@ -2456,13 +2462,13 @@ export function registerTools() {
2456
2462
  // Session handoff tools (add-session-handoff)
2457
2463
  {
2458
2464
  name: "session_close_report",
2459
- description: "Upload a session-close handoff report to AgentHub. Call this at the end of every session after running the close-session skill. Shares what shipped + what the next session should pick up, so /start-session on the next run (any machine) can resume cleanly.",
2465
+ description: "Upload a session-close handoff report to AgentHub. Call this at the end of every session after running the close-session skill. Shares what shipped + what the next session should pick up, so /start-session on the next run (any machine) can resume cleanly. The reply carries `display_number` (the report's own `h-YYYYMMDD-NNN`, always) and `session_display_number` (the captured coding session's `s-YYYYMMDD-NNN`, only when this session is captured).",
2460
2466
  inputSchema: {
2461
2467
  type: "object",
2462
2468
  properties: {
2463
2469
  summary: { type: "string", description: "Markdown summary of what shipped this session" },
2464
2470
  next_plan: { type: "string", description: "Markdown of what the next session should pick up" },
2465
- session_id: { type: "string", description: "Optional session UUID or display number `s-YYYYMMDD-NNN` for upsert keying. Server resolves either form to the canonical UUID before storing." },
2471
+ session_id: { type: "string", description: "Optional session UUID or display number `s-YYYYMMDD-NNN` for upsert keying. Server resolves either form to the canonical UUID before storing. Omit it normally: when this session is being captured, the tool attaches the capture session itself." },
2466
2472
  commits: {
2467
2473
  type: "array",
2468
2474
  description: "Commits pushed this session",
@@ -2827,6 +2833,86 @@ export function registerTools() {
2827
2833
  required: ["project_id"],
2828
2834
  },
2829
2835
  },
2836
+ // ── Scheduled Reporting (add-scheduled-reporting §6.2) ──
2837
+ // Report schedules are their own rows — create_cron_job cannot express a
2838
+ // report (its schema has no action field). Every tool answers
2839
+ // 503 reporting_disabled while AGENTHUB_REPORTING_ENABLED is off.
2840
+ {
2841
+ name: "report_schedule_create",
2842
+ description: "Create a recurring report schedule. The report composes the chosen sections (shipped_tickets, meeting_decisions, session_digests, roadmap, brain_knowledge, token_usage) over a lookback window, filters them for the audience, and delivers to Slack/chat channels and/or email. Members may deliver to channels and their own email; any other email recipient needs an org owner/admin (a person). Returns the schedule.",
2843
+ inputSchema: {
2844
+ type: "object",
2845
+ properties: {
2846
+ name: { type: "string", description: "Unique name within the org" },
2847
+ schedule: { type: "string", description: "5-field cron, evaluated in UTC (e.g. '0 9 * * 1' = Mondays 09:00)" },
2848
+ sections: {
2849
+ type: "array",
2850
+ items: {
2851
+ type: "string",
2852
+ enum: ["shipped_tickets", "meeting_decisions", "session_digests", "roadmap", "brain_knowledge", "token_usage"],
2853
+ },
2854
+ description: "Sections to include (at least one)",
2855
+ },
2856
+ delivery_targets: {
2857
+ type: "array",
2858
+ items: {
2859
+ type: "object",
2860
+ properties: {
2861
+ kind: { type: "string", enum: ["slack", "email"] },
2862
+ target: { type: "string", description: "Channel (e.g. #leadership) or email address" },
2863
+ },
2864
+ required: ["kind", "target"],
2865
+ },
2866
+ description: "Where to deliver (at least one)",
2867
+ },
2868
+ project_id: { type: "string", description: "Optional project (required for the roadmap section)" },
2869
+ window: { type: "string", description: "Lookback as a Go duration, default 168h, at most 2160h" },
2870
+ audience: {
2871
+ type: "string",
2872
+ enum: ["investor", "leadership", "customer", "product"],
2873
+ description: "Audience filter. Omit for internal. customer/product strip sensitive entries (finance, partners, token spend).",
2874
+ },
2875
+ enabled: { type: "boolean", description: "Default true" },
2876
+ },
2877
+ required: ["name", "schedule", "sections", "delivery_targets"],
2878
+ },
2879
+ },
2880
+ {
2881
+ name: "report_schedule_list",
2882
+ description: "List your org's report schedules (enabled flag, watermark, consecutive failures).",
2883
+ inputSchema: { type: "object", properties: {} },
2884
+ },
2885
+ {
2886
+ name: "report_schedule_delete",
2887
+ description: "Delete a report schedule. Past runs stay readable only while the schedule exists.",
2888
+ inputSchema: {
2889
+ type: "object",
2890
+ properties: { schedule_id: { type: "string", description: "Schedule id" } },
2891
+ required: ["schedule_id"],
2892
+ },
2893
+ },
2894
+ {
2895
+ name: "report_run_now",
2896
+ description: "Force a run of a schedule now, through the same code the cron uses (it delivers, and advances the watermark on delivery). Returns the run: status success|partial|failed, window, per-source availability, per-channel delivery outcome, token accounting.",
2897
+ inputSchema: {
2898
+ type: "object",
2899
+ properties: { schedule_id: { type: "string", description: "Schedule id" } },
2900
+ required: ["schedule_id"],
2901
+ },
2902
+ },
2903
+ {
2904
+ name: "report_get",
2905
+ description: "Read report runs. With run_id: one run, its snapshot, and (format=markdown, the default) the report as delivered. With schedule_id: that schedule's run history, newest first.",
2906
+ inputSchema: {
2907
+ type: "object",
2908
+ properties: {
2909
+ run_id: { type: "string", description: "Run id" },
2910
+ schedule_id: { type: "string", description: "Schedule id (lists runs)" },
2911
+ format: { type: "string", enum: ["json", "markdown"], description: "For run_id: include the rendered markdown (default markdown)" },
2912
+ limit: { type: "number", description: "For schedule_id: max runs (default 50)" },
2913
+ },
2914
+ },
2915
+ },
2830
2916
  // ── Secrets Vault ──
2831
2917
  {
2832
2918
  name: "secret_set",
@@ -3155,6 +3241,10 @@ export async function handleToolCall(name, args, client, context) {
3155
3241
  if (isIntakeRequestTool(name)) {
3156
3242
  return handleIntakeRequestToolCall(name, args, client, () => state.loadState(context.getWorkingDir())?.project_id);
3157
3243
  }
3244
+ // Employee training (add-employee-training-loops). Same module pattern.
3245
+ if (isEmployeeTrainingTool(name)) {
3246
+ return handleEmployeeTrainingToolCall(name, args, client);
3247
+ }
3158
3248
  // Goshti reads (add-agent-goshti-read §3.1). Same module pattern. The owner's
3159
3249
  // grant, the per-agent switch and the fixed tool list are all the server's
3160
3250
  // decisions; this only shapes the call and labels the answer as other
@@ -3162,6 +3252,20 @@ export async function handleToolCall(name, args, client, context) {
3162
3252
  if (isGoshtiReadTool(name)) {
3163
3253
  return handleGoshtiReadToolCall(name, args, client);
3164
3254
  }
3255
+ // Orchestrated runs (add-live-animated-views §1.8). Same module pattern. The
3256
+ // run id run_open returns is kept in .agenthub/state, so the other run tools
3257
+ // (and sub-agents sharing the checkout's state) default to it.
3258
+ if (isRunTool(name)) {
3259
+ const workingDir = context.getWorkingDir();
3260
+ return handleRunToolCall(name, args, client, {
3261
+ get: () => state.loadState(workingDir)?.run_id,
3262
+ set: (runId) => {
3263
+ const current = state.loadState(workingDir);
3264
+ if (current)
3265
+ state.saveState(workingDir, { ...current, run_id: runId });
3266
+ },
3267
+ });
3268
+ }
3165
3269
  switch (name) {
3166
3270
  // Registration
3167
3271
  case "agent_register": {
@@ -5245,8 +5349,12 @@ export async function handleToolCall(name, args, client, context) {
5245
5349
  summary,
5246
5350
  next_plan: nextPlan,
5247
5351
  };
5248
- if (args.session_id)
5249
- body.session_id = args.session_id;
5352
+ // add-session-report-numbers: a caller's session_id wins; otherwise link
5353
+ // the session this work is being captured into, when there is one.
5354
+ const sessionId = args.session_id ||
5355
+ currentCaptureSessionId({ workingDir: context.getWorkingDir() });
5356
+ if (sessionId)
5357
+ body.session_id = sessionId;
5250
5358
  if (args.commits)
5251
5359
  body.commits = args.commits;
5252
5360
  if (args.open_threads)
@@ -5461,6 +5569,48 @@ export async function handleToolCall(name, args, client, context) {
5461
5569
  body.audience = args.audience;
5462
5570
  return client.post(`/projects/${projectId}/roadmap/share/slack`, body);
5463
5571
  }
5572
+ // ── Scheduled Reporting (add-scheduled-reporting §6.2) ──
5573
+ case "report_schedule_create": {
5574
+ const body = {
5575
+ name: args.name,
5576
+ schedule: args.schedule,
5577
+ sections: args.sections,
5578
+ delivery_targets: args.delivery_targets,
5579
+ };
5580
+ for (const k of ["project_id", "window", "audience", "enabled"]) {
5581
+ if (args[k] !== undefined)
5582
+ body[k] = args[k];
5583
+ }
5584
+ return client.post("/reports/schedules", body);
5585
+ }
5586
+ case "report_schedule_list":
5587
+ return client.get("/reports/schedules");
5588
+ case "report_schedule_delete": {
5589
+ const id = args.schedule_id;
5590
+ if (!id)
5591
+ throw new Error("schedule_id is required");
5592
+ return client.del(`/reports/schedules/${encodeURIComponent(id)}`);
5593
+ }
5594
+ case "report_run_now": {
5595
+ const id = args.schedule_id;
5596
+ if (!id)
5597
+ throw new Error("schedule_id is required");
5598
+ return client.post(`/reports/schedules/${encodeURIComponent(id)}/run`, {});
5599
+ }
5600
+ case "report_get": {
5601
+ const runId = args.run_id;
5602
+ const scheduleId = args.schedule_id;
5603
+ if (runId) {
5604
+ const format = (args.format || "markdown").toLowerCase();
5605
+ const suffix = format === "markdown" ? "?format=markdown" : "";
5606
+ return client.get(`/reports/runs/${encodeURIComponent(runId)}${suffix}`);
5607
+ }
5608
+ if (scheduleId) {
5609
+ const limit = args.limit !== undefined ? `?limit=${Number(args.limit)}` : "";
5610
+ return client.get(`/reports/schedules/${encodeURIComponent(scheduleId)}/runs${limit}`);
5611
+ }
5612
+ throw new Error("run_id or schedule_id is required");
5613
+ }
5464
5614
  // ── Capabilities (add-agent-capabilities Phase 2 §2.3) ──
5465
5615
  case "capability_list": {
5466
5616
  if (!agentId) {