@rubytech/taskmaster 1.16.2 → 1.17.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 (47) hide show
  1. package/dist/agents/taskmaster-tools.js +1 -1
  2. package/dist/agents/tools/logs-read-tool.js +9 -0
  3. package/dist/agents/tools/memory-tool.js +1 -0
  4. package/dist/agents/tools/qr-generate-tool.js +7 -3
  5. package/dist/auto-reply/group-activation.js +2 -0
  6. package/dist/auto-reply/reply/commands-session.js +28 -11
  7. package/dist/build-info.json +3 -3
  8. package/dist/config/group-policy.js +16 -0
  9. package/dist/config/zod-schema.providers-whatsapp.js +2 -0
  10. package/dist/control-ui/assets/{index-Bd75cI7J.js → index-Beuhzjy_.js} +525 -492
  11. package/dist/control-ui/assets/index-Beuhzjy_.js.map +1 -0
  12. package/dist/control-ui/assets/index-XqRo9tNW.css +1 -0
  13. package/dist/control-ui/index.html +2 -2
  14. package/dist/cron/preloaded.js +27 -23
  15. package/dist/gateway/protocol/index.js +7 -2
  16. package/dist/gateway/protocol/schema/logs-chat.js +6 -0
  17. package/dist/gateway/protocol/schema/protocol-schemas.js +6 -0
  18. package/dist/gateway/protocol/schema/sessions-transcript.js +1 -0
  19. package/dist/gateway/protocol/schema/sessions.js +6 -1
  20. package/dist/gateway/protocol/schema/whatsapp.js +24 -0
  21. package/dist/gateway/protocol/schema.js +1 -0
  22. package/dist/gateway/public-chat/session-token.js +52 -0
  23. package/dist/gateway/public-chat-api.js +40 -13
  24. package/dist/gateway/server-methods/logs.js +17 -1
  25. package/dist/gateway/server-methods/public-chat.js +5 -0
  26. package/dist/gateway/server-methods/sessions-transcript.js +30 -6
  27. package/dist/gateway/server-methods/whatsapp-conversations.js +387 -0
  28. package/dist/gateway/server-methods-list.js +6 -0
  29. package/dist/gateway/server-methods.js +7 -0
  30. package/dist/gateway/server.impl.js +3 -1
  31. package/dist/gateway/sessions-patch.js +1 -1
  32. package/dist/hooks/bundled/ride-dispatch/HOOK.md +7 -6
  33. package/dist/hooks/bundled/ride-dispatch/handler.js +75 -30
  34. package/dist/memory/manager.js +3 -3
  35. package/dist/tui/tui-command-handlers.js +1 -1
  36. package/dist/web/auto-reply/monitor/group-activation.js +12 -10
  37. package/dist/web/auto-reply/monitor/group-gating.js +23 -2
  38. package/dist/web/auto-reply/monitor/on-message.js +27 -5
  39. package/dist/web/auto-reply/monitor/process-message.js +64 -53
  40. package/dist/web/inbound/monitor.js +30 -0
  41. package/extensions/whatsapp/src/channel.ts +1 -1
  42. package/package.json +1 -1
  43. package/skills/log-review/SKILL.md +17 -4
  44. package/skills/log-review/references/review-protocol.md +4 -4
  45. package/taskmaster-docs/USER-GUIDE.md +14 -0
  46. package/dist/control-ui/assets/index-Bd75cI7J.js.map +0 -1
  47. package/dist/control-ui/assets/index-BkymP95Y.css +0 -1
@@ -149,7 +149,7 @@ export function createTaskmasterTools(options) {
149
149
  agentSessionKey: options?.agentSessionKey,
150
150
  sandboxRoot: options?.sandboxRoot,
151
151
  }),
152
- createQrGenerateTool(),
152
+ createQrGenerateTool({ workspaceDir: options?.workspaceDir }),
153
153
  createCurrentTimeTool({ config: options?.config }),
154
154
  createAuthorizeAdminTool({ agentAccountId: options?.agentAccountId }),
155
155
  createRevokeAdminTool({ agentAccountId: options?.agentAccountId }),
@@ -24,6 +24,9 @@ const LogsReadSchema = Type.Object({
24
24
  agents: Type.Optional(Type.Array(Type.String(), {
25
25
  description: 'Filter session logs to specific agent IDs (e.g. ["admin", "public"]). Sessions action only.',
26
26
  })),
27
+ minLevel: Type.Optional(stringEnum(["fatal", "error", "warn", "info"], {
28
+ description: 'Filter system log entries to this severity or above. Use "warn" for health checks to avoid context overflow. Only applies to action: "system".',
29
+ })),
27
30
  });
28
31
  export function createLogsReadTool() {
29
32
  return {
@@ -44,19 +47,25 @@ export function createLogsReadTool() {
44
47
  const cursor = typeof params.cursor === "number" && Number.isFinite(params.cursor)
45
48
  ? Math.max(0, Math.floor(params.cursor))
46
49
  : undefined;
50
+ const minLevel = typeof params.minLevel === "string" ? params.minLevel : undefined;
47
51
  const result = await callGatewayTool("logs.tail", {}, {
48
52
  limit,
49
53
  ...(cursor !== undefined ? { cursor } : {}),
54
+ ...(minLevel !== undefined ? { minLevel } : {}),
50
55
  });
51
56
  return jsonResult(result);
52
57
  }
53
58
  if (action === "sessions") {
59
+ if (params.minLevel !== undefined) {
60
+ throw new Error('minLevel is not supported for action "sessions"');
61
+ }
54
62
  const limit = typeof params.limit === "number" && Number.isFinite(params.limit)
55
63
  ? Math.max(1, Math.floor(params.limit))
56
64
  : 100;
57
65
  const agents = readStringArrayParam(params, "agents");
58
66
  const result = await callGatewayTool("sessions.transcript", {}, {
59
67
  limit,
68
+ errorsOnly: true,
60
69
  ...(agents ? { agents } : {}),
61
70
  });
62
71
  return jsonResult(result);
@@ -148,6 +148,7 @@ export function createMemoryWriteTool(options) {
148
148
  description: "Write or append content to a file in the memory/ directory. " +
149
149
  "Path must be within the session's allowed scope. " +
150
150
  "Phone numbers in paths MUST include the + prefix (e.g., memory/users/+447734875155/profile.md). " +
151
+ "Group IDs in paths MUST include the @g.us suffix (e.g., memory/groups/120363425419890848@g.us/context.md). " +
151
152
  "Creates parent directories if needed. Use mode='append' to add to existing content.",
152
153
  parameters: MemoryWriteSchema,
153
154
  execute: async (_toolCallId, params) => {
@@ -1,5 +1,4 @@
1
1
  import fs from "node:fs/promises";
2
- import os from "node:os";
3
2
  import path from "node:path";
4
3
  import { Type } from "@sinclair/typebox";
5
4
  import { renderQrPngBase64 } from "../../web/qr-image.js";
@@ -10,7 +9,7 @@ const QrGenerateSchema = Type.Object({
10
9
  "a URL, plain text, a vCard block, or a wa.me deep link.",
11
10
  }),
12
11
  });
13
- export function createQrGenerateTool() {
12
+ export function createQrGenerateTool(options) {
14
13
  return {
15
14
  label: "QR Code Generator",
16
15
  name: "qr_generate",
@@ -25,8 +24,13 @@ export function createQrGenerateTool() {
25
24
  try {
26
25
  const base64 = await renderQrPngBase64(data);
27
26
  const buf = Buffer.from(base64, "base64");
27
+ const workspaceDir = options?.workspaceDir?.trim();
28
+ const outputDir = workspaceDir
29
+ ? path.join(workspaceDir, "uploads", "generated")
30
+ : path.join(process.cwd(), "uploads", "generated");
31
+ await fs.mkdir(outputDir, { recursive: true });
28
32
  const filename = `qr-${Date.now()}.png`;
29
- const pngPath = path.join(os.tmpdir(), filename);
33
+ const pngPath = path.join(outputDir, filename);
30
34
  await fs.writeFile(pngPath, buf);
31
35
  return {
32
36
  content: [
@@ -5,6 +5,8 @@ export function normalizeGroupActivation(raw) {
5
5
  return "mention";
6
6
  if (value === "always")
7
7
  return "always";
8
+ if (value === "off")
9
+ return "off";
8
10
  return undefined;
9
11
  }
10
12
  export function parseActivationCommand(raw) {
@@ -1,8 +1,10 @@
1
1
  import { abortEmbeddedPiRun } from "../../agents/pi-embedded.js";
2
+ import { loadConfig, writeConfigFile } from "../../config/config.js";
2
3
  import { updateSessionStore } from "../../config/sessions.js";
3
4
  import { logVerbose } from "../../globals.js";
4
5
  import { createInternalHookEvent, triggerInternalHook } from "../../hooks/internal-hooks.js";
5
6
  import { scheduleGatewaySigusr1Restart, triggerTaskmasterRestart } from "../../infra/restart.js";
7
+ import { normalizeAccountId } from "../../routing/session-key.js";
6
8
  import { parseActivationCommand } from "../group-activation.js";
7
9
  import { parseSendPolicyCommand } from "../send-policy.js";
8
10
  import { normalizeUsageDisplay, resolveResponseUsageMode } from "../thinking.js";
@@ -51,20 +53,35 @@ export const handleActivationCommand = async (params, allowTextCommands) => {
51
53
  if (!activationCommand.mode) {
52
54
  return {
53
55
  shouldContinue: false,
54
- reply: { text: "⚙️ Usage: /activation mention|always" },
56
+ reply: { text: "⚙️ Usage: /activation mention|always|off" },
55
57
  };
56
58
  }
57
- if (params.sessionEntry && params.sessionStore && params.sessionKey) {
58
- params.sessionEntry.groupActivation = activationCommand.mode;
59
- params.sessionEntry.groupActivationNeedsSystemIntro = true;
60
- params.sessionEntry.updatedAt = Date.now();
61
- params.sessionStore[params.sessionKey] = params.sessionEntry;
62
- if (params.storePath) {
63
- await updateSessionStore(params.storePath, (store) => {
64
- store[params.sessionKey] = params.sessionEntry;
65
- });
66
- }
59
+ const groupId = params.ctx.From ?? params.sessionKey;
60
+ const accountId = normalizeAccountId(params.ctx.AccountId);
61
+ const cfg = loadConfig();
62
+ if (!cfg.channels)
63
+ cfg.channels = {};
64
+ if (!cfg.channels.whatsapp)
65
+ cfg.channels.whatsapp = {};
66
+ const wa = cfg.channels.whatsapp;
67
+ if (accountId !== "default") {
68
+ if (!wa.accounts)
69
+ wa.accounts = {};
70
+ const accounts = wa.accounts;
71
+ if (!accounts[accountId])
72
+ accounts[accountId] = {};
73
+ if (!accounts[accountId].groups)
74
+ accounts[accountId].groups = {};
75
+ const groups = accounts[accountId].groups;
76
+ groups[groupId] = { ...groups[groupId], activation: activationCommand.mode };
77
+ }
78
+ else {
79
+ if (!wa.groups)
80
+ wa.groups = {};
81
+ const groups = wa.groups;
82
+ groups[groupId] = { ...groups[groupId], activation: activationCommand.mode };
67
83
  }
84
+ await writeConfigFile(cfg);
68
85
  return {
69
86
  shouldContinue: false,
70
87
  reply: {
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.16.2",
3
- "commit": "5b738cb70310248225f83f6a39d49c7f9abcbe71",
4
- "builtAt": "2026-03-04T17:48:55.756Z"
2
+ "version": "1.17.0",
3
+ "commit": "7deaa743cc1e5cad0749a0be393ecd275ca27e1a",
4
+ "builtAt": "2026-03-05T12:59:30.901Z"
5
5
  }
@@ -52,3 +52,19 @@ export function resolveChannelGroupToolsPolicy(params) {
52
52
  return defaultConfig.tools;
53
53
  return undefined;
54
54
  }
55
+ export function resolveChannelGroupActivation(params) {
56
+ const { groupConfig, defaultConfig } = resolveChannelGroupPolicy(params);
57
+ // Prefer explicit `activation` field over deprecated `requireMention`
58
+ if (groupConfig?.activation != null)
59
+ return groupConfig.activation;
60
+ if (defaultConfig?.activation != null)
61
+ return defaultConfig.activation;
62
+ // Fall back to legacy requireMention boolean
63
+ if (typeof groupConfig?.requireMention === "boolean") {
64
+ return groupConfig.requireMention ? "mention" : "always";
65
+ }
66
+ if (typeof defaultConfig?.requireMention === "boolean") {
67
+ return defaultConfig.requireMention ? "mention" : "always";
68
+ }
69
+ return undefined;
70
+ }
@@ -31,6 +31,7 @@ export const WhatsAppAccountSchema = z
31
31
  groups: z
32
32
  .record(z.string(), z
33
33
  .object({
34
+ activation: z.enum(["always", "mention", "off"]).optional(),
34
35
  requireMention: z.boolean().optional(),
35
36
  tools: ToolPolicySchema,
36
37
  })
@@ -93,6 +94,7 @@ export const WhatsAppConfigSchema = z
93
94
  groups: z
94
95
  .record(z.string(), z
95
96
  .object({
97
+ activation: z.enum(["always", "mention", "off"]).optional(),
96
98
  requireMention: z.boolean().optional(),
97
99
  tools: ToolPolicySchema,
98
100
  })