@marcopeg/hal 1.0.16 → 1.0.18

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/README.md +125 -33
  2. package/dist/bot/commands/clear.d.ts +0 -3
  3. package/dist/bot/commands/clear.d.ts.map +1 -1
  4. package/dist/bot/commands/clear.js +5 -4
  5. package/dist/bot/commands/clear.js.map +1 -1
  6. package/dist/bot/commands/help.d.ts +2 -1
  7. package/dist/bot/commands/help.d.ts.map +1 -1
  8. package/dist/bot/commands/help.js +10 -14
  9. package/dist/bot/commands/help.js.map +1 -1
  10. package/dist/bot/commands/loader.d.ts +1 -0
  11. package/dist/bot/commands/loader.d.ts.map +1 -1
  12. package/dist/bot/commands/loader.js +9 -3
  13. package/dist/bot/commands/loader.js.map +1 -1
  14. package/dist/bot/commands/message.d.ts +8 -0
  15. package/dist/bot/commands/message.d.ts.map +1 -0
  16. package/dist/bot/commands/message.js +65 -0
  17. package/dist/bot/commands/message.js.map +1 -0
  18. package/dist/bot/commands/reset.d.ts +4 -0
  19. package/dist/bot/commands/reset.d.ts.map +1 -0
  20. package/dist/bot/commands/reset.js +24 -0
  21. package/dist/bot/commands/reset.js.map +1 -0
  22. package/dist/bot/commands/session.d.ts +15 -5
  23. package/dist/bot/commands/session.d.ts.map +1 -1
  24. package/dist/bot/commands/session.js +63 -48
  25. package/dist/bot/commands/session.js.map +1 -1
  26. package/dist/bot/commands/start.d.ts +2 -1
  27. package/dist/bot/commands/start.d.ts.map +1 -1
  28. package/dist/bot/commands/start.js +20 -8
  29. package/dist/bot/commands/start.js.map +1 -1
  30. package/dist/bot.d.ts.map +1 -1
  31. package/dist/bot.js +8 -10
  32. package/dist/bot.js.map +1 -1
  33. package/dist/config.d.ts +131 -0
  34. package/dist/config.d.ts.map +1 -1
  35. package/dist/config.js +74 -2
  36. package/dist/config.js.map +1 -1
  37. package/dist/context/resolver.d.ts +6 -0
  38. package/dist/context/resolver.d.ts.map +1 -1
  39. package/dist/context/resolver.js +11 -0
  40. package/dist/context/resolver.js.map +1 -1
  41. package/dist/engine/adapters/copilot.js +1 -1
  42. package/dist/engine/adapters/copilot.js.map +1 -1
  43. package/dist/engine/types.d.ts +1 -1
  44. package/dist/engine/types.d.ts.map +1 -1
  45. package/dist/user/setup.d.ts +2 -2
  46. package/dist/user/setup.js +2 -2
  47. package/package.json +9 -4
@@ -1,11 +1,21 @@
1
1
  import type { Context } from "grammy";
2
2
  import type { ProjectContext } from "../../types.js";
3
3
  /**
4
- * Returns a handler for the /new and /clean commands.
5
- * Resets the session without wiping uploads/downloads.
4
+ * Shared session-reset logic used by /clean and /start (when configured).
6
5
  *
7
- * - Claude (and other engines): passive reset — delete session.json, static reply.
8
- * - Copilot, Codex: active reset send sessionMsg without continue flag, reply with engine output.
6
+ * - Always clears local session state (session.json).
7
+ * - For active-reset engines (copilot, codex): sends sessionMsg without
8
+ * continueSession to force a new engine session, replies with engine output.
9
+ * - For passive engines (claude, etc.): static confirmation reply.
10
+ *
11
+ * When `silent` is true, no reply is sent to the user (caller handles messaging).
12
+ */
13
+ export declare function resetSession(ctx: ProjectContext, gramCtx: Context, options?: {
14
+ silent?: boolean;
15
+ }): Promise<void>;
16
+ /**
17
+ * Returns a handler for the /clean command.
18
+ * Resets the session, then sends a customizable confirmation message.
9
19
  */
10
- export declare function createSessionHandler(ctx: ProjectContext): (gramCtx: Context) => Promise<void>;
20
+ export declare function createCleanHandler(ctx: ProjectContext): (gramCtx: Context) => Promise<void>;
11
21
  //# sourceMappingURL=session.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,cAAc,IACxC,SAAS,OAAO,KAAG,OAAO,CAAC,IAAI,CAAC,CAkE/C"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAOrD;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,OAAO,CAAC,IAAI,CAAC,CAiDf;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,cAAc,IACtC,SAAS,OAAO,KAAG,OAAO,CAAC,IAAI,CAAC,CAgB/C"}
@@ -2,63 +2,78 @@ import { join } from "node:path";
2
2
  import { createAgent } from "../../agent/index.js";
3
3
  import { sendChunkedResponse } from "../../telegram/chunker.js";
4
4
  import { clearSessionData } from "../../user/setup.js";
5
+ import { resolveCommandMessage } from "./message.js";
6
+ const DEFAULT_CLEAN_TEMPLATE = "Session reset. Your next message starts a new conversation.";
5
7
  /**
6
- * Returns a handler for the /new and /clean commands.
7
- * Resets the session without wiping uploads/downloads.
8
+ * Shared session-reset logic used by /clean and /start (when configured).
8
9
  *
9
- * - Claude (and other engines): passive reset — delete session.json, static reply.
10
- * - Copilot, Codex: active reset send sessionMsg without continue flag, reply with engine output.
10
+ * - Always clears local session state (session.json).
11
+ * - For active-reset engines (copilot, codex): sends sessionMsg without
12
+ * continueSession to force a new engine session, replies with engine output.
13
+ * - For passive engines (claude, etc.): static confirmation reply.
14
+ *
15
+ * When `silent` is true, no reply is sent to the user (caller handles messaging).
11
16
  */
12
- export function createSessionHandler(ctx) {
13
- return async (gramCtx) => {
14
- const { config, logger } = ctx;
15
- const userId = gramCtx.from?.id;
16
- if (!userId) {
17
+ export async function resetSession(ctx, gramCtx, options) {
18
+ const { config, logger } = ctx;
19
+ const userId = gramCtx.from?.id;
20
+ if (!userId) {
21
+ if (!options?.silent)
17
22
  await gramCtx.reply("Could not identify user.");
18
- return;
19
- }
20
- const userDir = join(config.dataDir, String(userId));
23
+ return;
24
+ }
25
+ const userDir = join(config.dataDir, String(userId));
26
+ await clearSessionData(userDir);
27
+ logger.info({ userId }, "Session data cleared");
28
+ if (config.engine === "copilot" || config.engine === "codex") {
29
+ const statusMsg = await gramCtx.reply("_Starting new session..._", {
30
+ parse_mode: "Markdown",
31
+ });
21
32
  try {
22
- // Always clear local session state
23
- await clearSessionData(userDir);
24
- logger.info({ userId }, "Session data cleared");
25
- if (config.engine === "copilot" || config.engine === "codex") {
26
- // Active reset: send sessionMsg without --continue to force a new session
27
- const statusMsg = await gramCtx.reply("_Starting new session..._", {
28
- parse_mode: "Markdown",
29
- });
30
- try {
31
- const agent = createAgent(ctx);
32
- const result = await agent.call(config.engineSessionMsg, {
33
- continueSession: false,
34
- });
35
- try {
36
- await gramCtx.api.deleteMessage(gramCtx.chat.id, statusMsg.message_id);
37
- }
38
- catch {
39
- // Ignore delete errors
40
- }
41
- await sendChunkedResponse(gramCtx, result);
42
- }
43
- catch (err) {
44
- try {
45
- await gramCtx.api.deleteMessage(gramCtx.chat.id, statusMsg.message_id);
46
- }
47
- catch {
48
- // Ignore delete errors
49
- }
50
- logger.error({ error: err instanceof Error ? err.message : String(err) }, "Session renewal engine call failed");
51
- await gramCtx.reply("Failed to start new session. Please try again.");
52
- }
33
+ const agent = createAgent(ctx);
34
+ const result = await agent.call(config.engineSessionMsg, {
35
+ continueSession: false,
36
+ });
37
+ try {
38
+ await gramCtx.api.deleteMessage(gramCtx.chat.id, statusMsg.message_id);
39
+ }
40
+ catch {
41
+ // Ignore delete errors
42
+ }
43
+ if (!options?.silent)
44
+ await sendChunkedResponse(gramCtx, result);
45
+ }
46
+ catch (err) {
47
+ try {
48
+ await gramCtx.api.deleteMessage(gramCtx.chat.id, statusMsg.message_id);
53
49
  }
54
- else {
55
- // Passive reset for Claude and other engines
56
- await gramCtx.reply("New session started.");
50
+ catch {
51
+ // Ignore delete errors
57
52
  }
53
+ logger.error({ error: err instanceof Error ? err.message : String(err) }, "Session renewal engine call failed");
54
+ if (!options?.silent)
55
+ await gramCtx.reply("Failed to start new session. Please try again.");
56
+ }
57
+ }
58
+ else if (!options?.silent) {
59
+ await gramCtx.reply("New session started.");
60
+ }
61
+ }
62
+ /**
63
+ * Returns a handler for the /clean command.
64
+ * Resets the session, then sends a customizable confirmation message.
65
+ */
66
+ export function createCleanHandler(ctx) {
67
+ return async (gramCtx) => {
68
+ try {
69
+ await resetSession(ctx, gramCtx, { silent: true });
70
+ const template = ctx.config.commands.clean?.message ?? DEFAULT_CLEAN_TEMPLATE;
71
+ const message = await resolveCommandMessage(template, ctx, gramCtx);
72
+ await gramCtx.reply(message, { parse_mode: "Markdown" });
58
73
  }
59
74
  catch (error) {
60
- logger.error({ error: error instanceof Error ? error.message : String(error) }, "Session renewal failed");
61
- await gramCtx.reply("Failed to start new session. Please try again.");
75
+ ctx.logger.error({ error: error instanceof Error ? error.message : String(error) }, "Session renewal failed");
76
+ await gramCtx.reply("Failed to reset session. Please try again.");
62
77
  }
63
78
  };
64
79
  }
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/bot/commands/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/bot/commands/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,MAAM,sBAAsB,GAC1B,6DAA6D,CAAC;AAEhE;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAmB,EACnB,OAAgB,EAChB,OAA8B;IAE9B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;IAEhC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,CAAC,OAAO,EAAE,MAAM;YAAE,MAAM,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QACtE,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAErD,MAAM,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,sBAAsB,CAAC,CAAC;IAEhD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC7D,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE;YACjE,UAAU,EAAE,UAAU;SACvB,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE;gBACvD,eAAe,EAAE,KAAK;aACvB,CAAC,CAAC;YAEH,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,IAAK,CAAC,EAAE,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;YAC1E,CAAC;YAAC,MAAM,CAAC;gBACP,uBAAuB;YACzB,CAAC;YAED,IAAI,CAAC,OAAO,EAAE,MAAM;gBAAE,MAAM,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,IAAK,CAAC,EAAE,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;YAC1E,CAAC;YAAC,MAAM,CAAC;gBACP,uBAAuB;YACzB,CAAC;YAED,MAAM,CAAC,KAAK,CACV,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAC3D,oCAAoC,CACrC,CAAC;YACF,IAAI,CAAC,OAAO,EAAE,MAAM;gBAClB,MAAM,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QAC5B,MAAM,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAmB;IACpD,OAAO,KAAK,EAAE,OAAgB,EAAiB,EAAE;QAC/C,IAAI,CAAC;YACH,MAAM,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAEnD,MAAM,QAAQ,GACZ,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,IAAI,sBAAsB,CAAC;YAC/D,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;YACpE,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;QAC3D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,MAAM,CAAC,KAAK,CACd,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EACjE,wBAAwB,CACzB,CAAC;YACF,MAAM,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QACpE,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -1,3 +1,4 @@
1
1
  import type { Context } from "grammy";
2
- export declare function startHandler(ctx: Context): Promise<void>;
2
+ import type { ProjectContext } from "../../types.js";
3
+ export declare function createStartHandler(ctx: ProjectContext): (gramCtx: Context) => Promise<void>;
3
4
  //# sourceMappingURL=start.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/start.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,wBAAsB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAW9D"}
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/bot/commands/start.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAOrD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,cAAc,IACtC,SAAS,OAAO,KAAG,OAAO,CAAC,IAAI,CAAC,CAmB/C"}
@@ -1,10 +1,22 @@
1
- export async function startHandler(ctx) {
2
- const username = ctx.from?.first_name || "there";
3
- await ctx.reply(`Hello ${username}! I'm a Claude Code assistant bot.\n\n` +
4
- `You can:\n` +
5
- `- Send any message to chat with me\n` +
6
- `- Send images or documents for analysis\n` +
7
- `- Use /clear to start a new conversation\n\n` +
8
- `Type /help for more information.`);
1
+ import { resolveCommandMessage } from "./message.js";
2
+ import { resetSession } from "./session.js";
3
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: HAL placeholder syntax, not JS template
4
+ const DEFAULT_TEMPLATE = "Welcome to ${project.name}!\n\n${HAL_COMMANDS}";
5
+ export function createStartHandler(ctx) {
6
+ return async (gramCtx) => {
7
+ const { config, logger } = ctx;
8
+ const startCfg = config.commands.start;
9
+ const template = startCfg?.message ?? DEFAULT_TEMPLATE;
10
+ const message = await resolveCommandMessage(template, ctx, gramCtx);
11
+ await gramCtx.reply(message, { parse_mode: "Markdown" });
12
+ if (startCfg?.sessionReset) {
13
+ try {
14
+ await resetSession(ctx, gramCtx, { silent: true });
15
+ }
16
+ catch (err) {
17
+ logger.error({ error: err instanceof Error ? err.message : String(err) }, "/start session reset failed");
18
+ }
19
+ }
20
+ };
9
21
  }
10
22
  //# sourceMappingURL=start.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/bot/commands/start.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAY;IAC7C,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,EAAE,UAAU,IAAI,OAAO,CAAC;IAEjD,MAAM,GAAG,CAAC,KAAK,CACb,SAAS,QAAQ,wCAAwC;QACvD,YAAY;QACZ,sCAAsC;QACtC,2CAA2C;QAC3C,8CAA8C;QAC9C,kCAAkC,CACrC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/bot/commands/start.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,gGAAgG;AAChG,MAAM,gBAAgB,GAAG,gDAAgD,CAAC;AAE1E,MAAM,UAAU,kBAAkB,CAAC,GAAmB;IACpD,OAAO,KAAK,EAAE,OAAgB,EAAiB,EAAE;QAC/C,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;QAC/B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAEvC,MAAM,QAAQ,GAAG,QAAQ,EAAE,OAAO,IAAI,gBAAgB,CAAC;QACvD,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QACpE,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;QAEzD,IAAI,QAAQ,EAAE,YAAY,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YACrD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CACV,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAC3D,6BAA6B,CAC9B,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
package/dist/bot.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CAwG7E"}
1
+ {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CAsG7E"}
package/dist/bot.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { Bot } from "grammy";
2
- import { createClearHandler } from "./bot/commands/clear.js";
3
- import { helpHandler } from "./bot/commands/help.js";
2
+ import { createHelpHandler } from "./bot/commands/help.js";
4
3
  import { loadCommands } from "./bot/commands/loader.js";
5
- import { createSessionHandler } from "./bot/commands/session.js";
6
- import { startHandler } from "./bot/commands/start.js";
4
+ import { createResetHandler } from "./bot/commands/reset.js";
5
+ import { createCleanHandler } from "./bot/commands/session.js";
6
+ import { createStartHandler } from "./bot/commands/start.js";
7
7
  import { startCommandWatcher } from "./bot/commands/watcher.js";
8
8
  import { createDocumentHandler, createPhotoHandler, createTextHandler, createVoiceHandler, } from "./bot/handlers/index.js";
9
9
  import { createAuthMiddleware } from "./bot/middleware/auth.js";
@@ -26,12 +26,10 @@ export async function startBot(projectCtx) {
26
26
  bot.use(createAuthMiddleware(projectCtx));
27
27
  bot.use(rateLimitMw);
28
28
  // Wire commands
29
- bot.command("start", startHandler);
30
- bot.command("help", helpHandler);
31
- bot.command("clear", createClearHandler(projectCtx));
32
- const sessionHandler = createSessionHandler(projectCtx);
33
- bot.command("new", sessionHandler);
34
- bot.command("clean", sessionHandler);
29
+ bot.command("start", createStartHandler(projectCtx));
30
+ bot.command("help", createHelpHandler(projectCtx));
31
+ bot.command("reset", createResetHandler(projectCtx));
32
+ bot.command("clean", createCleanHandler(projectCtx));
35
33
  // Wire handlers
36
34
  bot.on("message:text", createTextHandler(projectCtx));
37
35
  bot.on("message:photo", createPhotoHandler(projectCtx));
package/dist/bot.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bot.js","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAO1E;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,UAA0B;IACvD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;IAE9C,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;IAE1E,yDAAyD;IACzD,MAAM,CAAC,KAAK,CACV,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,EAClD,qBAAqB,CACtB,CAAC;IACF,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,MAAM,CAAC,IAAI,CACT,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,EAClD,qBAAqB,CACtB,CAAC;IAEF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAE9C,0BAA0B;IAC1B,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAC1D,yBAAyB,CAAC,UAAU,CAAC,CAAC;IACxC,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1C,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAErB,gBAAgB;IAChB,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACnC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACjC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC;IACrD,MAAM,cAAc,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACxD,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IACnC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAErC,gBAAgB;IAChB,GAAG,CAAC,EAAE,CAAC,cAAc,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC;IACtD,GAAG,CAAC,EAAE,CAAC,eAAe,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC;IACxD,GAAG,CAAC,EAAE,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,UAAU,CAAC,CAAC,CAAC;IAC9D,GAAG,CAAC,EAAE,CAAC,eAAe,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC;IAExD,gBAAgB;IAChB,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QAChB,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,uDAAuD;IACvD,IAAI,cAA0B,CAAC;IAC/B,IAAI,aAAqC,CAAC;IAC1C,MAAM,cAAc,GAAG,IAAI,OAAO,CAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACpD,cAAc,GAAG,GAAG,CAAC;QACrB,aAAa,GAAG,GAAG,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,oDAAoD;IACpD,MAAM,cAAc,GAAG,GAAG;SACvB,KAAK,CAAC;QACL,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE;YACnB,MAAM,CAAC,IAAI,CACT,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EACjD,gBAAgB,CACjB,CAAC;YACF,cAAc,EAAE,CAAC;QACnB,CAAC;KACF,CAAC;SACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACb,aAAa,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC,CAAC,CAAC;IAEL,qDAAqD;IACrD,MAAM,cAAc,CAAC;IAErB,yEAAyE;IACzE,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,MAAM,YAAY,CACjC,MAAM,CAAC,GAAG,EACV,MAAM,CAAC,SAAS,EAChB,MAAM,EACN,SAAS,CACV,CAAC;IACF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,GAAG,CAAC,GAAG,CAAC,aAAa,CACzB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAC1E,CAAC;QACF,MAAM,CAAC,IAAI,CACT,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,EAC1B,mCAAmC,CACpC,CAAC;IACJ,CAAC;IAED,+DAA+D;IAC/D,MAAM,OAAO,GAAG,mBAAmB,CACjC,GAAG,EACH,MAAM,CAAC,GAAG,EACV,MAAM,CAAC,SAAS,EAChB,MAAM,EACN,SAAS,CACV,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,gBAAgB,EAAE,CAAC;YACnB,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,cAAc,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"bot.js","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -52,6 +52,35 @@ declare const GlobalsFileSchema: z.ZodOptional<z.ZodObject<{
52
52
  showTranscription: z.ZodOptional<z.ZodBoolean>;
53
53
  }, z.core.$strip>>;
54
54
  dataDir: z.ZodOptional<z.ZodString>;
55
+ commands: z.ZodOptional<z.ZodObject<{
56
+ start: z.ZodOptional<z.ZodObject<{
57
+ session: z.ZodOptional<z.ZodObject<{
58
+ reset: z.ZodOptional<z.ZodBoolean>;
59
+ }, z.core.$strip>>;
60
+ message: z.ZodObject<{
61
+ text: z.ZodOptional<z.ZodString>;
62
+ from: z.ZodOptional<z.ZodString>;
63
+ }, z.core.$strip>;
64
+ }, z.core.$strip>>;
65
+ help: z.ZodOptional<z.ZodObject<{
66
+ message: z.ZodObject<{
67
+ text: z.ZodOptional<z.ZodString>;
68
+ from: z.ZodOptional<z.ZodString>;
69
+ }, z.core.$strip>;
70
+ }, z.core.$strip>>;
71
+ reset: z.ZodOptional<z.ZodObject<{
72
+ message: z.ZodObject<{
73
+ text: z.ZodOptional<z.ZodString>;
74
+ from: z.ZodOptional<z.ZodString>;
75
+ }, z.core.$strip>;
76
+ }, z.core.$strip>>;
77
+ clean: z.ZodOptional<z.ZodObject<{
78
+ message: z.ZodObject<{
79
+ text: z.ZodOptional<z.ZodString>;
80
+ from: z.ZodOptional<z.ZodString>;
81
+ }, z.core.$strip>;
82
+ }, z.core.$strip>>;
83
+ }, z.core.$strip>>;
55
84
  }, z.core.$strip>>;
56
85
  declare const ProjectFileSchema: z.ZodObject<{
57
86
  name: z.ZodOptional<z.ZodString>;
@@ -107,6 +136,35 @@ declare const ProjectFileSchema: z.ZodObject<{
107
136
  }, z.core.$strip>>;
108
137
  dataDir: z.ZodOptional<z.ZodString>;
109
138
  context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
139
+ commands: z.ZodOptional<z.ZodObject<{
140
+ start: z.ZodOptional<z.ZodObject<{
141
+ session: z.ZodOptional<z.ZodObject<{
142
+ reset: z.ZodOptional<z.ZodBoolean>;
143
+ }, z.core.$strip>>;
144
+ message: z.ZodObject<{
145
+ text: z.ZodOptional<z.ZodString>;
146
+ from: z.ZodOptional<z.ZodString>;
147
+ }, z.core.$strip>;
148
+ }, z.core.$strip>>;
149
+ help: z.ZodOptional<z.ZodObject<{
150
+ message: z.ZodObject<{
151
+ text: z.ZodOptional<z.ZodString>;
152
+ from: z.ZodOptional<z.ZodString>;
153
+ }, z.core.$strip>;
154
+ }, z.core.$strip>>;
155
+ reset: z.ZodOptional<z.ZodObject<{
156
+ message: z.ZodObject<{
157
+ text: z.ZodOptional<z.ZodString>;
158
+ from: z.ZodOptional<z.ZodString>;
159
+ }, z.core.$strip>;
160
+ }, z.core.$strip>>;
161
+ clean: z.ZodOptional<z.ZodObject<{
162
+ message: z.ZodObject<{
163
+ text: z.ZodOptional<z.ZodString>;
164
+ from: z.ZodOptional<z.ZodString>;
165
+ }, z.core.$strip>;
166
+ }, z.core.$strip>>;
167
+ }, z.core.$strip>>;
110
168
  }, z.core.$strip>;
111
169
  declare const MultiConfigFileSchema: z.ZodObject<{
112
170
  globals: z.ZodOptional<z.ZodObject<{
@@ -156,6 +214,35 @@ declare const MultiConfigFileSchema: z.ZodObject<{
156
214
  showTranscription: z.ZodOptional<z.ZodBoolean>;
157
215
  }, z.core.$strip>>;
158
216
  dataDir: z.ZodOptional<z.ZodString>;
217
+ commands: z.ZodOptional<z.ZodObject<{
218
+ start: z.ZodOptional<z.ZodObject<{
219
+ session: z.ZodOptional<z.ZodObject<{
220
+ reset: z.ZodOptional<z.ZodBoolean>;
221
+ }, z.core.$strip>>;
222
+ message: z.ZodObject<{
223
+ text: z.ZodOptional<z.ZodString>;
224
+ from: z.ZodOptional<z.ZodString>;
225
+ }, z.core.$strip>;
226
+ }, z.core.$strip>>;
227
+ help: z.ZodOptional<z.ZodObject<{
228
+ message: z.ZodObject<{
229
+ text: z.ZodOptional<z.ZodString>;
230
+ from: z.ZodOptional<z.ZodString>;
231
+ }, z.core.$strip>;
232
+ }, z.core.$strip>>;
233
+ reset: z.ZodOptional<z.ZodObject<{
234
+ message: z.ZodObject<{
235
+ text: z.ZodOptional<z.ZodString>;
236
+ from: z.ZodOptional<z.ZodString>;
237
+ }, z.core.$strip>;
238
+ }, z.core.$strip>>;
239
+ clean: z.ZodOptional<z.ZodObject<{
240
+ message: z.ZodObject<{
241
+ text: z.ZodOptional<z.ZodString>;
242
+ from: z.ZodOptional<z.ZodString>;
243
+ }, z.core.$strip>;
244
+ }, z.core.$strip>>;
245
+ }, z.core.$strip>>;
159
246
  }, z.core.$strip>>;
160
247
  context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
161
248
  projects: z.ZodArray<z.ZodObject<{
@@ -212,6 +299,35 @@ declare const MultiConfigFileSchema: z.ZodObject<{
212
299
  }, z.core.$strip>>;
213
300
  dataDir: z.ZodOptional<z.ZodString>;
214
301
  context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
302
+ commands: z.ZodOptional<z.ZodObject<{
303
+ start: z.ZodOptional<z.ZodObject<{
304
+ session: z.ZodOptional<z.ZodObject<{
305
+ reset: z.ZodOptional<z.ZodBoolean>;
306
+ }, z.core.$strip>>;
307
+ message: z.ZodObject<{
308
+ text: z.ZodOptional<z.ZodString>;
309
+ from: z.ZodOptional<z.ZodString>;
310
+ }, z.core.$strip>;
311
+ }, z.core.$strip>>;
312
+ help: z.ZodOptional<z.ZodObject<{
313
+ message: z.ZodObject<{
314
+ text: z.ZodOptional<z.ZodString>;
315
+ from: z.ZodOptional<z.ZodString>;
316
+ }, z.core.$strip>;
317
+ }, z.core.$strip>>;
318
+ reset: z.ZodOptional<z.ZodObject<{
319
+ message: z.ZodObject<{
320
+ text: z.ZodOptional<z.ZodString>;
321
+ from: z.ZodOptional<z.ZodString>;
322
+ }, z.core.$strip>;
323
+ }, z.core.$strip>>;
324
+ clean: z.ZodOptional<z.ZodObject<{
325
+ message: z.ZodObject<{
326
+ text: z.ZodOptional<z.ZodString>;
327
+ from: z.ZodOptional<z.ZodString>;
328
+ }, z.core.$strip>;
329
+ }, z.core.$strip>>;
330
+ }, z.core.$strip>>;
215
331
  }, z.core.$strip>>;
216
332
  }, z.core.$strip>;
217
333
  type ProjectFileEntry = z.infer<typeof ProjectFileSchema>;
@@ -250,6 +366,21 @@ export interface ResolvedProjectConfig {
250
366
  showTranscription: boolean;
251
367
  } | undefined;
252
368
  context: Record<string, string> | undefined;
369
+ commands: {
370
+ start?: {
371
+ sessionReset: boolean;
372
+ message: string;
373
+ };
374
+ help?: {
375
+ message: string;
376
+ };
377
+ reset?: {
378
+ message: string;
379
+ };
380
+ clean?: {
381
+ message: string;
382
+ };
383
+ };
253
384
  }
254
385
  export interface LoadedConfigResult {
255
386
  config: MultiConfigFile;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAsBxB,QAAA,MAAM,gBAAgB;;;;;EAAqD,CAAC;AAa5E,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA4BV,CAAC;AAId,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiCrB,CAAC;AAIH,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAMzB,CAAC;AAiBH,KAAK,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC1D,KAAK,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC;AAClE,KAAK,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAK7D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/B,MAAM,EAAE;QAAE,cAAc,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACrC,MAAM,EAAE,UAAU,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAC5D,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,aAAa,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;IACzE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;CAC7C;AAID,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,eAAe,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAID,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CASxE;AAwBD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,qBAAqB,CAqEvB;AAID,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,qBAAqB,EAAE,GAAG,IAAI,CAgCxE;AA0MD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,CA0ErE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -29,6 +29,33 @@ const EngineConfigSchema = z
29
29
  })
30
30
  .partial()
31
31
  .optional();
32
+ const CommandMessageSchema = z
33
+ .object({
34
+ text: z.string().optional(),
35
+ from: z.string().optional(),
36
+ })
37
+ .refine((m) => !!m.text !== !!m.from, {
38
+ message: "commands.*.message must have exactly one of 'text' or 'from'",
39
+ });
40
+ const StartConfigSchema = z
41
+ .object({
42
+ session: z.object({ reset: z.boolean() }).partial().optional(),
43
+ message: CommandMessageSchema,
44
+ })
45
+ .optional();
46
+ const SimpleCommandConfigSchema = z
47
+ .object({
48
+ message: CommandMessageSchema,
49
+ })
50
+ .optional();
51
+ const CommandsConfigSchema = z
52
+ .object({
53
+ start: StartConfigSchema,
54
+ help: SimpleCommandConfigSchema,
55
+ reset: SimpleCommandConfigSchema,
56
+ clean: SimpleCommandConfigSchema,
57
+ })
58
+ .optional();
32
59
  const GlobalsFileSchema = z
33
60
  .object({
34
61
  access: z
@@ -56,6 +83,7 @@ const GlobalsFileSchema = z
56
83
  .partial()
57
84
  .optional(),
58
85
  dataDir: z.string().optional(),
86
+ commands: CommandsConfigSchema,
59
87
  })
60
88
  .optional();
61
89
  // ─── Per-project schema ────────────────────────────────────────────────────────
@@ -92,6 +120,7 @@ const ProjectFileSchema = z.object({
92
120
  .optional(),
93
121
  dataDir: z.string().optional(),
94
122
  context: z.record(z.string(), z.string()).optional(),
123
+ commands: CommandsConfigSchema,
95
124
  });
96
125
  // ─── Multi-project config file schema ─────────────────────────────────────────
97
126
  const MultiConfigFileSchema = z.object({
@@ -148,6 +177,43 @@ export function resolveProjectConfig(project, globals, configDir, rootContext) {
148
177
  const dataDir = resolveDataDir(project.dataDir ?? globals.dataDir, resolvedCwd, configDir, slug);
149
178
  const hasTranscription = project.transcription !== undefined || globals.transcription !== undefined;
150
179
  const hasContext = rootContext !== undefined || project.context !== undefined;
180
+ function resolveMessageTemplate(msg, label) {
181
+ if (msg.from) {
182
+ const filePath = resolve(resolvedCwd, msg.from);
183
+ if (!existsSync(filePath)) {
184
+ console.error(`Configuration error: ${label}.message.from file not found: ${filePath}`);
185
+ process.exit(1);
186
+ }
187
+ try {
188
+ return readFileSync(filePath, "utf-8");
189
+ }
190
+ catch (err) {
191
+ console.error(`Configuration error: cannot read ${label}.message.from file: ${filePath} — ${err instanceof Error ? err.message : String(err)}`);
192
+ process.exit(1);
193
+ }
194
+ }
195
+ return msg.text;
196
+ }
197
+ const rawStart = project.commands?.start ?? globals.commands?.start;
198
+ let resolvedStart;
199
+ if (rawStart) {
200
+ resolvedStart = {
201
+ sessionReset: rawStart.session?.reset ?? false,
202
+ message: resolveMessageTemplate(rawStart.message, "commands.start"),
203
+ };
204
+ }
205
+ const rawHelp = project.commands?.help ?? globals.commands?.help;
206
+ const resolvedHelp = rawHelp
207
+ ? { message: resolveMessageTemplate(rawHelp.message, "commands.help") }
208
+ : undefined;
209
+ const rawReset = project.commands?.reset ?? globals.commands?.reset;
210
+ const resolvedReset = rawReset
211
+ ? { message: resolveMessageTemplate(rawReset.message, "commands.reset") }
212
+ : undefined;
213
+ const rawClean = project.commands?.clean ?? globals.commands?.clean;
214
+ const resolvedClean = rawClean
215
+ ? { message: resolveMessageTemplate(rawClean.message, "commands.clean") }
216
+ : undefined;
151
217
  return {
152
218
  slug,
153
219
  name: project.name,
@@ -190,6 +256,12 @@ export function resolveProjectConfig(project, globals, configDir, rootContext) {
190
256
  }
191
257
  : undefined,
192
258
  context: hasContext ? { ...rootContext, ...project.context } : undefined,
259
+ commands: {
260
+ start: resolvedStart,
261
+ help: resolvedHelp,
262
+ reset: resolvedReset,
263
+ clean: resolvedClean,
264
+ },
193
265
  };
194
266
  }
195
267
  // ─── Boot-time uniqueness validation ──────────────────────────────────────────
@@ -264,9 +336,9 @@ function substituteEnvVars(obj, env, path = "") {
264
336
  if (obj !== null && typeof obj === "object") {
265
337
  const result = {};
266
338
  for (const [key, value] of Object.entries(obj)) {
267
- // Skip "context" keys their ${} patterns are resolved at message time
339
+ // Skip keys whose ${} patterns are resolved at message time
268
340
  // by the context resolver, not at boot time as env vars.
269
- if (key === "context") {
341
+ if (key === "context" || key === "commands") {
270
342
  result[key] = value;
271
343
  continue;
272
344
  }