@rubytech/taskmaster 1.2.1 → 1.4.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.
Files changed (92) hide show
  1. package/dist/agents/auth-profiles/oauth.js +24 -0
  2. package/dist/agents/auth-profiles/profiles.js +37 -0
  3. package/dist/agents/auth-profiles.js +1 -1
  4. package/dist/agents/pi-tools.policy.js +4 -0
  5. package/dist/agents/taskmaster-tools.js +14 -0
  6. package/dist/agents/tool-policy.js +5 -2
  7. package/dist/agents/tools/apikeys-tool.js +16 -5
  8. package/dist/agents/tools/contact-create-tool.js +59 -0
  9. package/dist/agents/tools/contact-delete-tool.js +48 -0
  10. package/dist/agents/tools/contact-update-tool.js +17 -2
  11. package/dist/agents/tools/file-delete-tool.js +137 -0
  12. package/dist/agents/tools/file-list-tool.js +127 -0
  13. package/dist/agents/tools/message-history-tool.js +2 -3
  14. package/dist/auto-reply/media-note.js +11 -0
  15. package/dist/auto-reply/reply/commands-tts.js +7 -2
  16. package/dist/auto-reply/reply/get-reply.js +4 -0
  17. package/dist/build-info.json +3 -3
  18. package/dist/cli/provision-seed.js +1 -2
  19. package/dist/commands/doctor-config-flow.js +13 -0
  20. package/dist/config/agent-tools-reconcile.js +53 -0
  21. package/dist/config/defaults.js +10 -1
  22. package/dist/config/legacy.migrations.part-3.js +26 -0
  23. package/dist/config/zod-schema.core.js +9 -1
  24. package/dist/config/zod-schema.js +1 -0
  25. package/dist/control-ui/assets/{index-N8du4fwV.js → index-BDETQp97.js} +692 -600
  26. package/dist/control-ui/assets/index-BDETQp97.js.map +1 -0
  27. package/dist/control-ui/assets/index-CPawOl_z.css +1 -0
  28. package/dist/control-ui/index.html +2 -2
  29. package/dist/gateway/chat-sanitize.js +5 -1
  30. package/dist/gateway/config-reload.js +1 -0
  31. package/dist/gateway/media-http.js +28 -0
  32. package/dist/gateway/server/tls.js +2 -2
  33. package/dist/gateway/server-http.js +34 -4
  34. package/dist/gateway/server-methods/apikeys.js +56 -4
  35. package/dist/gateway/server-methods/chat.js +64 -25
  36. package/dist/gateway/server-methods/tts.js +11 -2
  37. package/dist/gateway/server.impl.js +38 -5
  38. package/dist/infra/tls/gateway.js +19 -3
  39. package/dist/media-understanding/apply.js +35 -0
  40. package/dist/media-understanding/providers/deepgram/audio.js +1 -1
  41. package/dist/media-understanding/providers/google/audio.js +1 -1
  42. package/dist/media-understanding/providers/google/video.js +1 -1
  43. package/dist/media-understanding/providers/index.js +2 -0
  44. package/dist/media-understanding/providers/openai/audio.js +1 -1
  45. package/dist/media-understanding/providers/sherpa-onnx/index.js +10 -0
  46. package/dist/media-understanding/runner.js +61 -72
  47. package/dist/media-understanding/sherpa-onnx-local.js +223 -0
  48. package/dist/memory/audit.js +9 -0
  49. package/dist/memory/manager.js +1 -1
  50. package/dist/records/records-manager.js +10 -0
  51. package/dist/tts/tts.js +98 -10
  52. package/dist/web/auto-reply/monitor/process-message.js +45 -17
  53. package/dist/web/inbound/monitor.js +9 -1
  54. package/extensions/diagnostics-otel/node_modules/.bin/acorn +0 -0
  55. package/extensions/googlechat/node_modules/.bin/taskmaster +2 -2
  56. package/extensions/googlechat/package.json +2 -2
  57. package/extensions/line/node_modules/.bin/taskmaster +2 -2
  58. package/extensions/line/package.json +1 -1
  59. package/extensions/matrix/node_modules/.bin/markdown-it +0 -0
  60. package/extensions/matrix/node_modules/.bin/taskmaster +2 -2
  61. package/extensions/matrix/package.json +1 -1
  62. package/extensions/memory-lancedb/node_modules/.bin/arrow2csv +0 -0
  63. package/extensions/memory-lancedb/node_modules/.bin/openai +0 -0
  64. package/extensions/msteams/node_modules/.bin/taskmaster +2 -2
  65. package/extensions/msteams/package.json +1 -1
  66. package/extensions/nostr/node_modules/.bin/taskmaster +2 -2
  67. package/extensions/nostr/node_modules/.bin/tsc +0 -0
  68. package/extensions/nostr/node_modules/.bin/tsserver +0 -0
  69. package/extensions/nostr/package.json +1 -1
  70. package/extensions/zalo/node_modules/.bin/taskmaster +2 -2
  71. package/extensions/zalo/package.json +1 -1
  72. package/extensions/zalouser/node_modules/.bin/taskmaster +2 -2
  73. package/extensions/zalouser/package.json +1 -1
  74. package/package.json +56 -65
  75. package/scripts/install.sh +0 -0
  76. package/scripts/postinstall.js +76 -0
  77. package/skills/business-assistant/references/crm.md +32 -8
  78. package/taskmaster-docs/USER-GUIDE.md +111 -6
  79. package/templates/.DS_Store +0 -0
  80. package/templates/beagle/agents/admin/AGENTS.md +4 -2
  81. package/templates/customer/.DS_Store +0 -0
  82. package/templates/customer/agents/.DS_Store +0 -0
  83. package/templates/maxy/.DS_Store +0 -0
  84. package/templates/maxy/.gitignore +1 -0
  85. package/templates/maxy/agents/.DS_Store +0 -0
  86. package/templates/maxy/agents/admin/.DS_Store +0 -0
  87. package/templates/maxy/memory/.DS_Store +0 -0
  88. package/templates/maxy/skills/.DS_Store +0 -0
  89. package/templates/taskmaster/.gitignore +1 -0
  90. package/templates/taskmaster/agents/admin/AGENTS.md +1 -0
  91. package/dist/control-ui/assets/index-DtQHRIVD.css +0 -1
  92. package/dist/control-ui/assets/index-N8du4fwV.js.map +0 -1
@@ -115,6 +115,7 @@ export const handleTtsCommands = async (params, allowTextCommands) => {
115
115
  .filter((provider) => isTtsProviderConfigured(config, provider));
116
116
  const hasOpenAI = Boolean(resolveTtsApiKey(config, "openai"));
117
117
  const hasElevenLabs = Boolean(resolveTtsApiKey(config, "elevenlabs"));
118
+ const hasHume = Boolean(resolveTtsApiKey(config, "hume"));
118
119
  const hasEdge = isTtsProviderConfigured(config, "edge");
119
120
  return {
120
121
  shouldContinue: false,
@@ -124,13 +125,17 @@ export const handleTtsCommands = async (params, allowTextCommands) => {
124
125
  `Fallbacks: ${fallback.join(", ") || "none"}\n` +
125
126
  `OpenAI key: ${hasOpenAI ? "✅" : "❌"}\n` +
126
127
  `ElevenLabs key: ${hasElevenLabs ? "✅" : "❌"}\n` +
128
+ `Hume key: ${hasHume ? "✅" : "❌"}\n` +
127
129
  `Edge enabled: ${hasEdge ? "✅" : "❌"}\n` +
128
- `Usage: /tts provider openai | elevenlabs | edge`,
130
+ `Usage: /tts provider openai | elevenlabs | hume | edge`,
129
131
  },
130
132
  };
131
133
  }
132
134
  const requested = args.trim().toLowerCase();
133
- if (requested !== "openai" && requested !== "elevenlabs" && requested !== "edge") {
135
+ if (requested !== "openai" &&
136
+ requested !== "elevenlabs" &&
137
+ requested !== "hume" &&
138
+ requested !== "edge") {
134
139
  return { shouldContinue: false, reply: ttsUsage() };
135
140
  }
136
141
  setTtsProvider(prefsPath, requested);
@@ -81,6 +81,10 @@ export async function getReplyFromConfig(ctx, opts, configOverride) {
81
81
  cfg,
82
82
  });
83
83
  }
84
+ // Notify caller that media understanding is complete. The ctx body now
85
+ // contains the transcript / description instead of a raw <media:*> placeholder.
86
+ // Fires before the agent reply pipeline so archive hooks can record the resolved text.
87
+ opts?.onMediaResolved?.();
84
88
  const commandAuthorized = finalized.CommandAuthorized;
85
89
  resolveCommandAuthorization({
86
90
  ctx: finalized,
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.2.1",
3
- "commit": "238dd4da7156480a565ebe14908d0b24ded34899",
4
- "builtAt": "2026-02-24T15:34:23.973Z"
2
+ "version": "1.4.0",
3
+ "commit": "34222eeabd71481db3a4cc2fd6a0918657150079",
4
+ "builtAt": "2026-02-25T10:21:06.215Z"
5
5
  }
@@ -137,8 +137,7 @@ export function buildDefaultAgentList(workspaceRoot) {
137
137
  "session_status",
138
138
  "cron",
139
139
  "license_generate",
140
- "contact_lookup",
141
- "contact_update",
140
+ "group:contacts",
142
141
  "authorize_admin",
143
142
  "revoke_admin",
144
143
  "list_admins",
@@ -1,4 +1,5 @@
1
1
  import { TaskmasterSchema, CONFIG_PATH_TASKMASTER, migrateLegacyConfig, readConfigFileSnapshot, } from "../config/config.js";
2
+ import { reconcileAgentContactTools } from "../config/agent-tools-reconcile.js";
2
3
  import { applyPluginAutoEnable } from "../config/plugin-auto-enable.js";
3
4
  import { formatCliCommand } from "../cli/command-format.js";
4
5
  import { note } from "../terminal/note.js";
@@ -156,6 +157,18 @@ export async function loadAndMaybeMigrateDoctorConfig(params) {
156
157
  fixHints.push(`Run "${formatCliCommand("taskmaster doctor --fix")}" to apply these changes.`);
157
158
  }
158
159
  }
160
+ const toolReconcile = reconcileAgentContactTools({ config: candidate });
161
+ if (toolReconcile.changes.length > 0) {
162
+ note(toolReconcile.changes.join("\n"), "Doctor changes");
163
+ candidate = toolReconcile.config;
164
+ pendingChanges = true;
165
+ if (shouldRepair) {
166
+ cfg = toolReconcile.config;
167
+ }
168
+ else {
169
+ fixHints.push(`Run "${formatCliCommand("taskmaster doctor --fix")}" to apply these changes.`);
170
+ }
171
+ }
159
172
  const unknown = stripUnknownConfigKeys(candidate);
160
173
  if (unknown.removed.length > 0) {
161
174
  const lines = unknown.removed.map((path) => `- ${path}`).join("\n");
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Individual contact tool names that should be replaced by `group:contacts`.
3
+ * Order does not matter — all are removed and replaced with the group.
4
+ */
5
+ const INDIVIDUAL_CONTACT_TOOLS = [
6
+ "contact_create",
7
+ "contact_delete",
8
+ "contact_lookup",
9
+ "contact_update",
10
+ ];
11
+ function isAdminAgent(agent) {
12
+ const id = agent.id?.trim() ?? "";
13
+ return id === "admin" || id.endsWith("-admin");
14
+ }
15
+ /**
16
+ * Ensure admin agents use `group:contacts` instead of individual contact tools.
17
+ *
18
+ * Runs unconditionally on gateway startup (like `applyPluginAutoEnable`).
19
+ * Idempotent — if the allow list already contains `group:contacts`, no changes.
20
+ */
21
+ export function reconcileAgentContactTools(params) {
22
+ const config = structuredClone(params.config);
23
+ const changes = [];
24
+ const agents = config.agents?.list;
25
+ if (!Array.isArray(agents))
26
+ return { config, changes };
27
+ for (const agent of agents) {
28
+ if (!agent || !isAdminAgent(agent))
29
+ continue;
30
+ const allow = agent.tools?.allow;
31
+ if (!Array.isArray(allow))
32
+ continue;
33
+ // Already using the group — nothing to do
34
+ if (allow.includes("group:contacts"))
35
+ continue;
36
+ // Check if any individual contact tools are present
37
+ const hasAny = INDIVIDUAL_CONTACT_TOOLS.some((t) => allow.includes(t));
38
+ if (!hasAny)
39
+ continue;
40
+ // Remove individual entries, add group
41
+ const removed = [];
42
+ for (const tool of INDIVIDUAL_CONTACT_TOOLS) {
43
+ const idx = allow.indexOf(tool);
44
+ if (idx !== -1) {
45
+ allow.splice(idx, 1);
46
+ removed.push(tool);
47
+ }
48
+ }
49
+ allow.push("group:contacts");
50
+ changes.push(`Replaced ${removed.join(", ")} with group:contacts in agent "${agent.id}" tools.allow.`);
51
+ }
52
+ return { config, changes };
53
+ }
@@ -1,6 +1,6 @@
1
1
  import { DEFAULT_CONTEXT_TOKENS } from "../agents/defaults.js";
2
2
  import { parseModelRef } from "../agents/model-selection.js";
3
- import { upsertAuthProfile } from "../agents/auth-profiles.js";
3
+ import { upsertAuthProfile, removeAuthProfile } from "../agents/auth-profiles.js";
4
4
  import { resolveTalkApiKey } from "./talk.js";
5
5
  import { DEFAULT_AGENT_MAX_CONCURRENT, DEFAULT_SUBAGENT_MAX_CONCURRENT } from "./agent-limits.js";
6
6
  let defaultWarnState = { warned: false };
@@ -372,10 +372,19 @@ export function applyApiKeys(config) {
372
372
  const keys = config.apiKeys;
373
373
  if (!keys || Object.keys(keys).length === 0)
374
374
  return config;
375
+ const disabled = config.apiKeysDisabled ?? {};
375
376
  let cfg = config;
376
377
  for (const [provider, key] of Object.entries(keys)) {
377
378
  if (!key?.trim())
378
379
  continue;
380
+ if (disabled[provider]) {
381
+ // Actively remove auth profiles for disabled model providers so stale
382
+ // credentials from a previous config load don't persist in memory.
383
+ if (API_KEY_MODEL_PROVIDERS.has(provider)) {
384
+ removeAuthProfile({ profileId: `${provider}:api-key` });
385
+ }
386
+ continue;
387
+ }
379
388
  const trimmedKey = key.trim();
380
389
  if (API_KEY_MODEL_PROVIDERS.has(provider)) {
381
390
  upsertAuthProfile({
@@ -216,4 +216,30 @@ export const LEGACY_CONFIG_MIGRATIONS_PART_3 = [
216
216
  }
217
217
  },
218
218
  },
219
+ {
220
+ id: "agents-tools-remove-sessions_send",
221
+ describe: "Remove sessions_send from agent tools.allow (tool removed for security)",
222
+ apply: (raw, changes) => {
223
+ const agents = getRecord(raw.agents);
224
+ const list = getAgentsList(agents);
225
+ for (const entry of list) {
226
+ if (!isRecord(entry))
227
+ continue;
228
+ const id = typeof entry.id === "string" ? entry.id.trim() : "";
229
+ if (!id)
230
+ continue;
231
+ const tools = getRecord(entry.tools);
232
+ if (!tools)
233
+ continue;
234
+ if (!Array.isArray(tools.allow))
235
+ continue;
236
+ const allow = tools.allow;
237
+ const index = allow.indexOf("sessions_send");
238
+ if (index !== -1) {
239
+ allow.splice(index, 1);
240
+ changes.push(`Removed sessions_send from agent "${id}" tools.allow.`);
241
+ }
242
+ }
243
+ },
244
+ },
219
245
  ];
@@ -138,7 +138,7 @@ export const MarkdownConfigSchema = z
138
138
  })
139
139
  .strict()
140
140
  .optional();
141
- export const TtsProviderSchema = z.enum(["elevenlabs", "openai", "edge"]);
141
+ export const TtsProviderSchema = z.enum(["elevenlabs", "openai", "hume", "edge"]);
142
142
  export const TtsModeSchema = z.enum(["final", "all"]);
143
143
  export const TtsAutoSchema = z.enum(["off", "always", "inbound", "tagged"]);
144
144
  export const TtsConfigSchema = z
@@ -191,6 +191,14 @@ export const TtsConfigSchema = z
191
191
  })
192
192
  .strict()
193
193
  .optional(),
194
+ hume: z
195
+ .object({
196
+ apiKey: z.string().optional(),
197
+ voice: z.string().optional(),
198
+ description: z.string().optional(),
199
+ })
200
+ .strict()
201
+ .optional(),
194
202
  edge: z
195
203
  .object({
196
204
  enabled: z.boolean().optional(),
@@ -552,6 +552,7 @@ export const TaskmasterSchema = z
552
552
  .strict())
553
553
  .optional(),
554
554
  apiKeys: z.record(z.string(), z.string()).optional(),
555
+ apiKeysDisabled: z.record(z.string(), z.boolean()).optional(),
555
556
  access: z
556
557
  .object({
557
558
  masterPin: z