crewly 1.20.214 → 1.20.215

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 (70) hide show
  1. package/config/skills/agent/core/project-tickets/SKILL.md +42 -10
  2. package/config/skills/agent/core/project-tickets/execute.sh +45 -12
  3. package/config/skills/agent/core/project-tickets/execute.test.sh +19 -0
  4. package/dist/backend/backend/src/constants.d.ts +57 -9
  5. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  6. package/dist/backend/backend/src/constants.js +75 -8
  7. package/dist/backend/backend/src/constants.js.map +1 -1
  8. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts +9 -1
  9. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts.map +1 -1
  10. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js +13 -1
  11. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js.map +1 -1
  12. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.d.ts +2 -1
  13. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.d.ts.map +1 -1
  14. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.js +4 -2
  15. package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.js.map +1 -1
  16. package/dist/backend/backend/src/index.d.ts.map +1 -1
  17. package/dist/backend/backend/src/index.js +16 -0
  18. package/dist/backend/backend/src/index.js.map +1 -1
  19. package/dist/backend/backend/src/services/project-tickets/autopilot-speed-command.d.ts +108 -0
  20. package/dist/backend/backend/src/services/project-tickets/autopilot-speed-command.d.ts.map +1 -0
  21. package/dist/backend/backend/src/services/project-tickets/autopilot-speed-command.js +223 -0
  22. package/dist/backend/backend/src/services/project-tickets/autopilot-speed-command.js.map +1 -0
  23. package/dist/backend/backend/src/services/project-tickets/autopilot-speed.wiring.d.ts +57 -0
  24. package/dist/backend/backend/src/services/project-tickets/autopilot-speed.wiring.d.ts.map +1 -0
  25. package/dist/backend/backend/src/services/project-tickets/autopilot-speed.wiring.js +90 -0
  26. package/dist/backend/backend/src/services/project-tickets/autopilot-speed.wiring.js.map +1 -0
  27. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts +18 -4
  28. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts.map +1 -1
  29. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js +18 -4
  30. package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js.map +1 -1
  31. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.d.ts +135 -14
  32. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.d.ts.map +1 -1
  33. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.js +111 -18
  34. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.js.map +1 -1
  35. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.d.ts +67 -1
  36. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.d.ts.map +1 -1
  37. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.js +75 -1
  38. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.js.map +1 -1
  39. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-trace.d.ts +1 -1
  40. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-trace.d.ts.map +1 -1
  41. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-trace.js +7 -0
  42. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-trace.js.map +1 -1
  43. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts +99 -4
  44. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts.map +1 -1
  45. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js +422 -11
  46. package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js.map +1 -1
  47. package/dist/backend/backend/src/types/ticket-autopilot.types.d.ts +46 -4
  48. package/dist/backend/backend/src/types/ticket-autopilot.types.d.ts.map +1 -1
  49. package/dist/backend/backend/src/types/ticket-autopilot.types.js +43 -2
  50. package/dist/backend/backend/src/types/ticket-autopilot.types.js.map +1 -1
  51. package/dist/backend/backend/src/types/v2/work-item.types.d.ts +1 -1
  52. package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  53. package/dist/backend/backend/src/types/v2/work-item.types.js +1 -0
  54. package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
  55. package/dist/backend/build-info.json +2 -2
  56. package/dist/cli/backend/src/constants.d.ts +57 -9
  57. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  58. package/dist/cli/backend/src/constants.js +75 -8
  59. package/dist/cli/backend/src/constants.js.map +1 -1
  60. package/dist/cli/backend/src/types/ticket-autopilot.types.d.ts +46 -4
  61. package/dist/cli/backend/src/types/ticket-autopilot.types.d.ts.map +1 -1
  62. package/dist/cli/backend/src/types/ticket-autopilot.types.js +43 -2
  63. package/dist/cli/backend/src/types/ticket-autopilot.types.js.map +1 -1
  64. package/dist/cli/backend/src/types/v2/work-item.types.d.ts +1 -1
  65. package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
  66. package/dist/cli/backend/src/types/v2/work-item.types.js +1 -0
  67. package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
  68. package/frontend/dist/assets/{index-917db1b8.js → index-839f4374.js} +272 -272
  69. package/frontend/dist/index.html +1 -1
  70. package/package.json +1 -1
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Switch a project's autopilot speed from the owner's DM with the orc
3
+ * (specs/2026-10-04-autopilot-speed-modes.md §5). Handled by the backend as
4
+ * an owner command — never by the orc's LLM — and only for the owner's own
5
+ * messages in their DM with the orc (the team pause command's pattern):
6
+ *
7
+ * - `set <project> to rush` / `set <project> autopilot to chill`
8
+ * - `switch <project> to normal` / `put <project> in rush mode`
9
+ * - `<project> rush` / `<project> chill mode`
10
+ * - Chinese: `<project> 切到 rush`, `把 <project> 切换到 chill`,
11
+ * `<project> 改成 正常`, `<project> 调成 冲刺模式`
12
+ * - mode words: rush / normal / chill, and 冲刺·急速·快 / 正常·普通 / 慢·慢速·悠闲·佛系
13
+ *
14
+ * A message is consumed only when its target names a known project (or it
15
+ * says `set project <x> to …` explicitly); anything else goes on to the orc.
16
+ * Replies are English (harness text rule); switching to Rush carries a
17
+ * one-line cost warning.
18
+ *
19
+ * @module services/project-tickets/autopilot-speed-command
20
+ */
21
+ import type { SlackIncomingMessage } from '../../types/slack.types.js';
22
+ import type { AutopilotSpeedMode } from '../../types/ticket-autopilot.types.js';
23
+ import type { TicketAutopilotStatus } from './ticket-autopilot.service.js';
24
+ /** A parsed command. `target` is the project as typed. */
25
+ export interface AutopilotSpeedCommand {
26
+ target: string;
27
+ mode: AutopilotSpeedMode;
28
+ /** Said "project" explicitly: answered even when no project matches */
29
+ explicitProject: boolean;
30
+ }
31
+ /**
32
+ * Parse a speed-mode command.
33
+ *
34
+ * @param text - Message text
35
+ * @returns The command, or null when the message is not one
36
+ *
37
+ * @example
38
+ * parseAutopilotSpeedCommand('set CE to rush') // { target: 'CE', mode: 'rush', explicitProject: false }
39
+ * parseAutopilotSpeedCommand('CE 切到 chill') // { target: 'CE', mode: 'chill', explicitProject: false }
40
+ */
41
+ export declare function parseAutopilotSpeedCommand(text: string | undefined): AutopilotSpeedCommand | null;
42
+ /** The one-line cost warning shown when Rush is switched on. */
43
+ export declare const RUSH_COST_WARNING = "Cost warning: Rush keeps the team busy all day and can use the whole daily budget every day; the budget brake still stops it.";
44
+ /**
45
+ * Mode name for the owner.
46
+ *
47
+ * @param mode - Mode
48
+ * @returns "Rush" / "Normal" / "Chill"
49
+ */
50
+ export declare function modeLabel(mode: AutopilotSpeedMode): string;
51
+ /**
52
+ * The owner's reply after a switch.
53
+ *
54
+ * @param status - The project's status after the change
55
+ * @param previous - The mode before
56
+ * @returns Reply text
57
+ */
58
+ export declare function speedModeReply(status: TicketAutopilotStatus, previous: AutopilotSpeedMode): string;
59
+ /** What the interceptor needs. */
60
+ export interface AutopilotSpeedCommandDeps {
61
+ /** `orc` when the message is the owner writing in their DM with the orc (see SlackReloginDmService.ownerDmScope) */
62
+ ownerDmScope: (message: SlackIncomingMessage) => 'orc' | 'agent' | null;
63
+ /** Reply target for the message */
64
+ replyTargetOf: (message: SlackIncomingMessage) => unknown;
65
+ /** Send a reply to the owner */
66
+ reply: (text: string, target: unknown) => Promise<unknown>;
67
+ /** Known projects, synchronously (a cache the wiring refreshes) */
68
+ knownProjects: () => Array<{
69
+ id: string;
70
+ name: string;
71
+ }>;
72
+ /** The project's current mode */
73
+ currentMode: (projectId: string) => Promise<AutopilotSpeedMode>;
74
+ /** Set the mode as the owner; resolves to the new status */
75
+ setMode: (projectId: string, mode: AutopilotSpeedMode) => Promise<TicketAutopilotStatus>;
76
+ onError?: (err: unknown) => void;
77
+ }
78
+ /**
79
+ * Find a project by id or name (case-insensitive).
80
+ *
81
+ * @param projects - Known projects
82
+ * @param ref - As typed
83
+ * @returns The project, or null
84
+ */
85
+ export declare function findProjectByRef(projects: Array<{
86
+ id: string;
87
+ name: string;
88
+ }>, ref: string): {
89
+ id: string;
90
+ name: string;
91
+ } | null;
92
+ /**
93
+ * Run a parsed command and build the owner's reply.
94
+ *
95
+ * @param cmd - Command
96
+ * @param projectId - Resolved project
97
+ * @param deps - Collaborators
98
+ * @returns Reply text
99
+ */
100
+ export declare function runAutopilotSpeedCommand(cmd: AutopilotSpeedCommand, projectId: string, deps: AutopilotSpeedCommandDeps): Promise<string>;
101
+ /**
102
+ * The Slack bridge interceptor for the owner's orc DM.
103
+ *
104
+ * @param deps - Collaborators
105
+ * @returns Interceptor: true when the message was a speed command (consumed)
106
+ */
107
+ export declare function createAutopilotSpeedInterceptor(deps: AutopilotSpeedCommandDeps): (message: SlackIncomingMessage) => boolean;
108
+ //# sourceMappingURL=autopilot-speed-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autopilot-speed-command.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/project-tickets/autopilot-speed-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAE3E,0DAA0D;AAC1D,MAAM,WAAW,qBAAqB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,kBAAkB,CAAC;IACzB,uEAAuE;IACvE,eAAe,EAAE,OAAO,CAAC;CACzB;AA+DD;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,qBAAqB,GAAG,IAAI,CAuBjG;AASD,gEAAgE;AAChE,eAAO,MAAM,iBAAiB,kIACkG,CAAC;AAEjI;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAE1D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,qBAAqB,EAAE,QAAQ,EAAE,kBAAkB,GAAG,MAAM,CAclG;AAED,kCAAkC;AAClC,MAAM,WAAW,yBAAyB;IACzC,oHAAoH;IACpH,YAAY,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,KAAK,GAAG,OAAO,GAAG,IAAI,CAAC;IACxE,mCAAmC;IACnC,aAAa,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC;IAC1D,gCAAgC;IAChC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,mEAAmE;IACnE,aAAa,EAAE,MAAM,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,iCAAiC;IACjC,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAChE,4DAA4D;IAC5D,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACzF,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAIhI;AAED;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC,CAI9I;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,yBAAyB,GAAG,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CA0B3H"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Switch a project's autopilot speed from the owner's DM with the orc
3
+ * (specs/2026-10-04-autopilot-speed-modes.md §5). Handled by the backend as
4
+ * an owner command — never by the orc's LLM — and only for the owner's own
5
+ * messages in their DM with the orc (the team pause command's pattern):
6
+ *
7
+ * - `set <project> to rush` / `set <project> autopilot to chill`
8
+ * - `switch <project> to normal` / `put <project> in rush mode`
9
+ * - `<project> rush` / `<project> chill mode`
10
+ * - Chinese: `<project> 切到 rush`, `把 <project> 切换到 chill`,
11
+ * `<project> 改成 正常`, `<project> 调成 冲刺模式`
12
+ * - mode words: rush / normal / chill, and 冲刺·急速·快 / 正常·普通 / 慢·慢速·悠闲·佛系
13
+ *
14
+ * A message is consumed only when its target names a known project (or it
15
+ * says `set project <x> to …` explicitly); anything else goes on to the orc.
16
+ * Replies are English (harness text rule); switching to Rush carries a
17
+ * one-line cost warning.
18
+ *
19
+ * @module services/project-tickets/autopilot-speed-command
20
+ */
21
+ import { compactTokens } from '../usage/token-format.js';
22
+ /** Mode words (lower-case) → mode. */
23
+ const MODE_WORDS = {
24
+ rush: 'rush',
25
+ normal: 'normal',
26
+ chill: 'chill',
27
+ 冲刺: 'rush',
28
+ 急速: 'rush',
29
+ 快: 'rush',
30
+ 快速: 'rush',
31
+ 正常: 'normal',
32
+ 普通: 'normal',
33
+ 慢: 'chill',
34
+ 慢速: 'chill',
35
+ 悠闲: 'chill',
36
+ 佛系: 'chill',
37
+ };
38
+ /** Alternation of the mode words, longest first (regex source). */
39
+ const MODE_RE = Object.keys(MODE_WORDS)
40
+ .sort((a, b) => b.length - a.length)
41
+ .join('|');
42
+ /**
43
+ * Normalise a message for matching.
44
+ *
45
+ * @param text - Raw text
46
+ * @returns Mentions, emphasis and trailing punctuation removed; whitespace collapsed
47
+ */
48
+ function norm(text) {
49
+ return text
50
+ .replace(/<@[A-Z0-9]+>/g, '')
51
+ .replace(/[`*_]/g, '')
52
+ .replace(/[\s.。!!~~]+$/u, '')
53
+ .replace(/^\s*(?:please|pls|请)\s*/iu, '')
54
+ .replace(/\s+/g, ' ')
55
+ .trim();
56
+ }
57
+ /**
58
+ * Clean the typed project: drop "project", "the", "'s autopilot", "speed", "mode".
59
+ *
60
+ * @param raw - Target as typed
61
+ * @returns Project reference and whether "project" was said
62
+ */
63
+ function cleanTarget(raw) {
64
+ let t = raw.trim();
65
+ let explicitProject = false;
66
+ const lead = /^(?:the\s+)?(?:project\s+|项目\s*)/iu.exec(t);
67
+ if (lead) {
68
+ explicitProject = /project|项目/iu.test(lead[0]);
69
+ t = t.slice(lead[0].length);
70
+ }
71
+ t = t
72
+ .replace(/^the\s+/i, '')
73
+ .replace(/(?:'s)?\s+(?:autopilot|speed|pace|mode)(?:\s+(?:speed|mode|pace))?$/i, '')
74
+ .replace(/\s*(?:的)?(?:自动驾驶|速度|模式)$/u, '')
75
+ .replace(/\s+project$/i, '')
76
+ .trim();
77
+ return { target: t, explicitProject };
78
+ }
79
+ /**
80
+ * Parse a speed-mode command.
81
+ *
82
+ * @param text - Message text
83
+ * @returns The command, or null when the message is not one
84
+ *
85
+ * @example
86
+ * parseAutopilotSpeedCommand('set CE to rush') // { target: 'CE', mode: 'rush', explicitProject: false }
87
+ * parseAutopilotSpeedCommand('CE 切到 chill') // { target: 'CE', mode: 'chill', explicitProject: false }
88
+ */
89
+ export function parseAutopilotSpeedCommand(text) {
90
+ if (!text)
91
+ return null;
92
+ const t = norm(text);
93
+ if (!t || t.includes('\n'))
94
+ return null;
95
+ const modeTail = `(${MODE_RE})(?:\\s*(?:mode|模式))?`;
96
+ const patterns = [
97
+ // set / switch / put / change / turn … to|in|into <mode>
98
+ new RegExp(`^(?:set|switch|put|change|turn|move)\\s+(.+?)\\s+(?:to|in|into|on)\\s+${modeTail}$`, 'iu'),
99
+ // 把 <project> 切到 / 切换到 / 改成 / 调成 / 调到 / 设为 <mode>
100
+ new RegExp(`^(?:把\\s*)?(.+?)\\s*(?:切到|切换到|切换成|切成|改成|改为|调成|调到|调为|设为|设成|设置为)\\s*${modeTail}$`, 'iu'),
101
+ // <project> <mode> [mode]
102
+ new RegExp(`^(.+?)\\s+${modeTail}$`, 'iu'),
103
+ ];
104
+ for (const re of patterns) {
105
+ const m = re.exec(t);
106
+ if (!m)
107
+ continue;
108
+ const mode = MODE_WORDS[m[2].toLowerCase()];
109
+ if (!mode)
110
+ continue;
111
+ const { target, explicitProject } = cleanTarget(m[1]);
112
+ if (!target)
113
+ return null;
114
+ return { target, mode, explicitProject };
115
+ }
116
+ return null;
117
+ }
118
+ /** What each mode does, in one line (owner reply). */
119
+ const MODE_LINES = {
120
+ rush: 'replans whenever the queue runs dry (at least 1 h apart, at most 12 a day), self-review every hour, and an empty replan is retried after 1 h',
121
+ normal: 'replans when the queue runs dry (at least 3 h apart, at most 4 a day), self-review daily, and an empty replan is retried the next day',
122
+ chill: 'at most 1 replan a day, self-review weekly, and an empty replan is retried the next week',
123
+ };
124
+ /** The one-line cost warning shown when Rush is switched on. */
125
+ export const RUSH_COST_WARNING = 'Cost warning: Rush keeps the team busy all day and can use the whole daily budget every day; the budget brake still stops it.';
126
+ /**
127
+ * Mode name for the owner.
128
+ *
129
+ * @param mode - Mode
130
+ * @returns "Rush" / "Normal" / "Chill"
131
+ */
132
+ export function modeLabel(mode) {
133
+ return mode.charAt(0).toUpperCase() + mode.slice(1);
134
+ }
135
+ /**
136
+ * The owner's reply after a switch.
137
+ *
138
+ * @param status - The project's status after the change
139
+ * @param previous - The mode before
140
+ * @returns Reply text
141
+ */
142
+ export function speedModeReply(status, previous) {
143
+ const s = status.settings;
144
+ const name = status.project.name;
145
+ const mode = s.speedMode;
146
+ const parts = [
147
+ previous === mode ? `${name} is already on ${modeLabel(mode)}: ${MODE_LINES[mode]}.` : `${name} is on ${modeLabel(mode)} now (was ${modeLabel(previous)}): ${MODE_LINES[mode]}.`,
148
+ s.budgetSource === 'explicit'
149
+ ? `Daily budget: ${compactTokens(s.dailyBudgetTokens)} tokens (your setting, unchanged).`
150
+ : `Daily budget: ${compactTokens(s.dailyBudgetTokens)} tokens (the ${modeLabel(mode)} default).`,
151
+ ];
152
+ if (s.replansPerDaySource === 'explicit')
153
+ parts.push(`Your replans-per-day setting (${s.replansPerDay}) still caps replans.`);
154
+ if (!s.enabled)
155
+ parts.push(`The autopilot is off on ${name}, so nothing runs until it is switched on.`);
156
+ if (mode === 'rush' && previous !== 'rush')
157
+ parts.push(RUSH_COST_WARNING);
158
+ return parts.join(' ');
159
+ }
160
+ /**
161
+ * Find a project by id or name (case-insensitive).
162
+ *
163
+ * @param projects - Known projects
164
+ * @param ref - As typed
165
+ * @returns The project, or null
166
+ */
167
+ export function findProjectByRef(projects, ref) {
168
+ const wanted = ref.trim().toLowerCase();
169
+ if (!wanted)
170
+ return null;
171
+ return projects.find((p) => p.id === ref.trim()) ?? projects.find((p) => p.name.trim().toLowerCase() === wanted) ?? null;
172
+ }
173
+ /**
174
+ * Run a parsed command and build the owner's reply.
175
+ *
176
+ * @param cmd - Command
177
+ * @param projectId - Resolved project
178
+ * @param deps - Collaborators
179
+ * @returns Reply text
180
+ */
181
+ export async function runAutopilotSpeedCommand(cmd, projectId, deps) {
182
+ const previous = await deps.currentMode(projectId);
183
+ const status = await deps.setMode(projectId, cmd.mode);
184
+ return speedModeReply(status, previous);
185
+ }
186
+ /**
187
+ * The Slack bridge interceptor for the owner's orc DM.
188
+ *
189
+ * @param deps - Collaborators
190
+ * @returns Interceptor: true when the message was a speed command (consumed)
191
+ */
192
+ export function createAutopilotSpeedInterceptor(deps) {
193
+ return (message) => {
194
+ if (message.hasFiles)
195
+ return false;
196
+ if (deps.ownerDmScope(message) !== 'orc')
197
+ return false;
198
+ const cmd = parseAutopilotSpeedCommand(message.text);
199
+ if (!cmd)
200
+ return false;
201
+ const projects = deps.knownProjects();
202
+ const project = findProjectByRef(projects, cmd.target);
203
+ const target = deps.replyTargetOf(message);
204
+ if (!project) {
205
+ // "set project X to rush" is unmistakably a command: answer it.
206
+ // Anything else ("let's rush") is the orc's.
207
+ if (!cmd.explicitProject)
208
+ return false;
209
+ void deps
210
+ .reply(`No project named "${cmd.target}". Projects: ${projects.map((p) => p.name).join(', ') || 'none'}.`, target)
211
+ .catch((err) => deps.onError?.(err));
212
+ return true;
213
+ }
214
+ void runAutopilotSpeedCommand(cmd, project.id, deps)
215
+ .then((text) => deps.reply(text, target))
216
+ .catch((err) => {
217
+ deps.onError?.(err);
218
+ return deps.reply(`Couldn't switch ${project.name} to ${modeLabel(cmd.mode)}: ${err instanceof Error ? err.message : String(err)}`, target).catch(() => undefined);
219
+ });
220
+ return true;
221
+ };
222
+ }
223
+ //# sourceMappingURL=autopilot-speed-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autopilot-speed-command.js","sourceRoot":"","sources":["../../../../../../backend/src/services/project-tickets/autopilot-speed-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Autopilot speed modes — boot wiring (specs/2026-10-04-autopilot-speed-modes.md §5):
3
+ * registers the owner's "set <project> to rush|normal|chill" DM commands
4
+ * with the Slack bridge (handled here, never by the orc's LLM). The
5
+ * interceptor is synchronous, so the project names it matches against are a
6
+ * cache refreshed from storage on a timer.
7
+ *
8
+ * Heavy modules are imported lazily so index.ts gains no import cycles.
9
+ *
10
+ * @module services/project-tickets/autopilot-speed.wiring
11
+ */
12
+ import type { Project } from '../../types/index.js';
13
+ import type { TicketAutopilotService } from './ticket-autopilot.service.js';
14
+ /** What index.ts provides. */
15
+ export interface AutopilotSpeedWiringInput {
16
+ /** All projects (storage) */
17
+ getProjects: () => Promise<Project[]>;
18
+ /** The running autopilot */
19
+ autopilot: () => TicketAutopilotService;
20
+ logger: {
21
+ info(msg: string, meta?: Record<string, unknown>): void;
22
+ warn(msg: string, meta?: Record<string, unknown>): void;
23
+ };
24
+ }
25
+ /** A cache of project ids / names for the synchronous interceptor. */
26
+ export declare class KnownProjectsCache {
27
+ private readonly load;
28
+ private projects;
29
+ private timer;
30
+ /**
31
+ * @param load - Reads the projects
32
+ */
33
+ constructor(load: () => Promise<Project[]>);
34
+ /** The cached projects. */
35
+ list(): Array<{
36
+ id: string;
37
+ name: string;
38
+ }>;
39
+ /** Re-read the projects (a failed read keeps the old list). */
40
+ refresh(): Promise<void>;
41
+ /**
42
+ * Refresh on a timer.
43
+ *
44
+ * @param intervalMs - How often
45
+ */
46
+ start(intervalMs: number): void;
47
+ /** Stop the timer. */
48
+ stop(): void;
49
+ }
50
+ /**
51
+ * Wire the speed-mode DM commands.
52
+ *
53
+ * @param input - Projects, the autopilot, a logger
54
+ * @returns The project cache (running)
55
+ */
56
+ export declare function startAutopilotSpeedCommands(input: AutopilotSpeedWiringInput): Promise<KnownProjectsCache>;
57
+ //# sourceMappingURL=autopilot-speed.wiring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autopilot-speed.wiring.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/project-tickets/autopilot-speed.wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E,8BAA8B;AAC9B,MAAM,WAAW,yBAAyB;IACzC,6BAA6B;IAC7B,WAAW,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACtC,4BAA4B;IAC5B,SAAS,EAAE,MAAM,sBAAsB,CAAC;IACxC,MAAM,EAAE;QAAE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;QAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;KAAE,CAAC;CAC7H;AAED,sEAAsE;AACtE,qBAAa,kBAAkB;IAOlB,OAAO,CAAC,QAAQ,CAAC,IAAI;IANjC,OAAO,CAAC,QAAQ,CAA2C;IAC3D,OAAO,CAAC,KAAK,CAA+C;IAE5D;;OAEG;gBAC0B,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IAE3D,2BAA2B;IAC3B,IAAI,IAAI,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAI3C,+DAA+D;IACzD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;;;OAIG;IACH,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAM/B,sBAAsB;IACtB,IAAI,IAAI,IAAI;CAIZ;AAED;;;;;GAKG;AACH,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAkC/G"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Autopilot speed modes — boot wiring (specs/2026-10-04-autopilot-speed-modes.md §5):
3
+ * registers the owner's "set <project> to rush|normal|chill" DM commands
4
+ * with the Slack bridge (handled here, never by the orc's LLM). The
5
+ * interceptor is synchronous, so the project names it matches against are a
6
+ * cache refreshed from storage on a timer.
7
+ *
8
+ * Heavy modules are imported lazily so index.ts gains no import cycles.
9
+ *
10
+ * @module services/project-tickets/autopilot-speed.wiring
11
+ */
12
+ import { TICKET_AUTOPILOT_CONSTANTS } from '../../constants.js';
13
+ import { resolveTicketAutopilotSettings } from '../../types/ticket-autopilot.types.js';
14
+ import { createAutopilotSpeedInterceptor } from './autopilot-speed-command.js';
15
+ /** A cache of project ids / names for the synchronous interceptor. */
16
+ export class KnownProjectsCache {
17
+ load;
18
+ projects = [];
19
+ timer = null;
20
+ /**
21
+ * @param load - Reads the projects
22
+ */
23
+ constructor(load) {
24
+ this.load = load;
25
+ }
26
+ /** The cached projects. */
27
+ list() {
28
+ return this.projects;
29
+ }
30
+ /** Re-read the projects (a failed read keeps the old list). */
31
+ async refresh() {
32
+ try {
33
+ this.projects = (await this.load()).map((p) => ({ id: p.id, name: p.name }));
34
+ }
35
+ catch {
36
+ // Keep what we had: a stale list only delays a brand-new project's name.
37
+ }
38
+ }
39
+ /**
40
+ * Refresh on a timer.
41
+ *
42
+ * @param intervalMs - How often
43
+ */
44
+ start(intervalMs) {
45
+ if (this.timer)
46
+ return;
47
+ this.timer = setInterval(() => void this.refresh(), intervalMs);
48
+ this.timer.unref?.();
49
+ }
50
+ /** Stop the timer. */
51
+ stop() {
52
+ if (this.timer)
53
+ clearInterval(this.timer);
54
+ this.timer = null;
55
+ }
56
+ }
57
+ /**
58
+ * Wire the speed-mode DM commands.
59
+ *
60
+ * @param input - Projects, the autopilot, a logger
61
+ * @returns The project cache (running)
62
+ */
63
+ export async function startAutopilotSpeedCommands(input) {
64
+ const cache = new KnownProjectsCache(input.getProjects);
65
+ await cache.refresh();
66
+ cache.start(TICKET_AUTOPILOT_CONSTANTS.SPEED_PROJECT_CACHE_REFRESH_MS);
67
+ const { SlackReloginDmService } = await import('../slack/slack-relogin-dm.service.js');
68
+ const { getSlackService } = await import('../slack/slack.service.js');
69
+ const { getSlackAgentIdentityService } = await import('../slack/slack-agent-identity.service.js');
70
+ const dm = new SlackReloginDmService(() => getSlackService(), undefined, (agentSession) => getSlackAgentIdentityService()?.getInstalled(agentSession)?.botToken ?? null);
71
+ try {
72
+ const { getSlackOrchestratorBridge } = await import('../slack/slack-orchestrator-bridge.js');
73
+ getSlackOrchestratorBridge().addInboundInterceptor('the autopilot speed commands', createAutopilotSpeedInterceptor({
74
+ ownerDmScope: (m) => dm.ownerDmScope(m),
75
+ replyTargetOf: (m) => dm.replyTargetOf(m),
76
+ reply: (text, target) => dm.sendToOwner(text, target),
77
+ knownProjects: () => cache.list(),
78
+ currentMode: async (projectId) => resolveTicketAutopilotSettings((await input.getProjects()).find((p) => p.id === projectId)?.ticketAutopilot).speedMode,
79
+ // The owner's own command: the owner caller (no session).
80
+ setMode: (projectId, mode) => input.autopilot().updateSettings(projectId, { speedMode: mode }, {}),
81
+ onError: (err) => input.logger.warn('Autopilot speed command failed', { error: err instanceof Error ? err.message : String(err) }),
82
+ }));
83
+ }
84
+ catch (err) {
85
+ input.logger.warn('Autopilot speed Slack commands not wired (non-critical)', { error: err instanceof Error ? err.message : String(err) });
86
+ }
87
+ input.logger.info('Autopilot speed commands wired');
88
+ return cache;
89
+ }
90
+ //# sourceMappingURL=autopilot-speed.wiring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autopilot-speed.wiring.js","sourceRoot":"","sources":["../../../../../../backend/src/services/project-tickets/autopilot-speed.wiring.ts"],"names":[],"mappings":"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"}
@@ -57,6 +57,15 @@ export interface ProjectTicketAutopilotPolicy {
57
57
  isAutoClaimPaused(project: Project): Promise<boolean>;
58
58
  /** In-progress tickets one member may hold when the project's autopilot is on, or null when it is off */
59
59
  maxInFlightPerMember(project: Project): Promise<number | null>;
60
+ /**
61
+ * Checks a new ticket before it is written (the metric rule of goal-replan
62
+ * tickets, specs/2026-10-04-autopilot-speed-modes.md §3).
63
+ *
64
+ * @returns Why it is refused (answered as a 400 the agent can act on), or null
65
+ */
66
+ checkCreate?(project: Project, caller: ProjectTicketCaller, input: CreateProjectTicketInput & {
67
+ metric?: string;
68
+ }): Promise<string | null>;
60
69
  }
61
70
  /** Dependencies. */
62
71
  export interface ProjectTicketWorkflowDeps {
@@ -239,15 +248,20 @@ export declare class ProjectTicketWorkflowService {
239
248
  status?: string;
240
249
  }): Promise<ProjectTicketsOfProject[]>;
241
250
  /**
242
- * Create a ticket. Workers' tickets always start in `backlog`.
251
+ * Create a ticket. Workers' tickets always start in `backlog`. `metric`
252
+ * (the goal metric it moves and the expected effect) is written as the
253
+ * description's first line, `Metric: …`; a ticket the driver opens during
254
+ * a goal replan is refused without one (the autopilot policy).
243
255
  *
244
256
  * @param ref - Project reference
245
- * @param input - Content
257
+ * @param input - Content (+ optional `metric`)
246
258
  * @param caller - Caller
247
259
  * @returns New ticket
248
- * @throws ProjectTicketError(403) for outsiders, (400) for a team not on the project
260
+ * @throws ProjectTicketError(403) for outsiders, (400) for a team not on the project or a replan ticket without a metric
249
261
  */
250
- create(ref: string, input: CreateProjectTicketInput, caller: ProjectTicketCaller): Promise<ProjectTicket>;
262
+ create(ref: string, rawInput: CreateProjectTicketInput & {
263
+ metric?: string;
264
+ }, caller: ProjectTicketCaller): Promise<ProjectTicket>;
251
265
  /**
252
266
  * Change fields / sections, optionally followed by a status transition.
253
267
  *
@@ -1 +1 @@
1
- {"version":3,"file":"project-ticket-workflow.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/project-tickets/project-ticket-workflow.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project-ticket-workflow.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/project-tickets/project-ticket-workflow.service.ts"],"names":[],"mappings":"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"}
@@ -285,18 +285,32 @@ export class ProjectTicketWorkflowService {
285
285
  // Writes
286
286
  // ---------------------------------------------------------------------------
287
287
  /**
288
- * Create a ticket. Workers' tickets always start in `backlog`.
288
+ * Create a ticket. Workers' tickets always start in `backlog`. `metric`
289
+ * (the goal metric it moves and the expected effect) is written as the
290
+ * description's first line, `Metric: …`; a ticket the driver opens during
291
+ * a goal replan is refused without one (the autopilot policy).
289
292
  *
290
293
  * @param ref - Project reference
291
- * @param input - Content
294
+ * @param input - Content (+ optional `metric`)
292
295
  * @param caller - Caller
293
296
  * @returns New ticket
294
- * @throws ProjectTicketError(403) for outsiders, (400) for a team not on the project
297
+ * @throws ProjectTicketError(403) for outsiders, (400) for a team not on the project or a replan ticket without a metric
295
298
  */
296
- async create(ref, input, caller) {
299
+ async create(ref, rawInput, caller) {
297
300
  const project = await this.resolveProject(ref);
298
301
  const { access } = await this.accessOf(caller, project);
299
302
  this.requireAccess(access, ['owner', 'orchestrator', 'lead', 'member'], 'create tickets');
303
+ const { metric: rawMetric, ...rest } = rawInput;
304
+ const metric = typeof rawMetric === 'string' ? rawMetric.replace(/\s+/g, ' ').trim() : '';
305
+ if (metric.length > TICKET_AUTOPILOT_CONSTANTS.METRIC_MAX_CHARS) {
306
+ throw new ProjectTicketError(400, `metric is longer than ${TICKET_AUTOPILOT_CONSTANTS.METRIC_MAX_CHARS} characters`);
307
+ }
308
+ const input = metric
309
+ ? { ...rest, description: [`${TICKET_AUTOPILOT_CONSTANTS.METRIC_LINE_PREFIX}${metric}`, rest.description?.trim() ?? ''].filter((l) => l).join('\n\n') }
310
+ : rest;
311
+ const refusal = await this.autopilotPolicy?.checkCreate?.(project, caller, { ...input, ...(metric ? { metric } : {}) });
312
+ if (refusal)
313
+ throw new ProjectTicketError(400, refusal);
300
314
  await this.assertTeamOnProject(project, input.team);
301
315
  const status = access === 'member' ? 'backlog' : input.status ?? 'backlog';
302
316
  if (status === 'in_progress' || status === 'review' || status === 'done') {