crewly 1.20.161 → 1.20.162
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.
- package/config/roles/orchestrator/prompt.md +2 -0
- package/config/roles/team-leader/prompt.md +12 -0
- package/config/roles/team-leader/tl-addon.md +12 -0
- package/config/skills/agent/core/project-tickets/SKILL.md +32 -1
- package/config/skills/agent/core/project-tickets/execute.sh +56 -2
- package/config/skills/agent/core/project-tickets/execute.test.sh +22 -0
- package/dist/backend/backend/src/constants.d.ts +84 -1
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +105 -16
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts +43 -0
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js +85 -0
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.d.ts +12 -0
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.js +19 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +30 -1
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/models/Project.d.ts +3 -0
- package/dist/backend/backend/src/models/Project.d.ts.map +1 -1
- package/dist/backend/backend/src/models/Project.js +7 -0
- package/dist/backend/backend/src/models/Project.js.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +3 -1
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +66 -13
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js +161 -32
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts +48 -0
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js +77 -1
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.d.ts +223 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.d.ts.map +1 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.js +240 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.js.map +1 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.d.ts +94 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.d.ts.map +1 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.js +195 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.js.map +1 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts +286 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js +626 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js.map +1 -0
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts +37 -3
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.js +57 -6
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts +21 -1
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js +62 -4
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts +6 -0
- package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler.service.js +9 -5
- package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/claim.service.d.ts +23 -3
- package/dist/backend/backend/src/services/task-pool/claim.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/claim.service.js +52 -11
- package/dist/backend/backend/src/services/task-pool/claim.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +42 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js +82 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/ticket-claim-policy.d.ts +19 -0
- package/dist/backend/backend/src/services/task-pool/ticket-claim-policy.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/ticket-claim-policy.js +33 -0
- package/dist/backend/backend/src/services/task-pool/ticket-claim-policy.js.map +1 -1
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts +28 -0
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js +74 -29
- package/dist/backend/backend/src/services/v3/agent-auto-claim.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +3 -2
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
- package/dist/backend/backend/src/types/index.d.ts +6 -0
- package/dist/backend/backend/src/types/index.d.ts.map +1 -1
- package/dist/backend/backend/src/types/index.js.map +1 -1
- package/dist/backend/backend/src/types/ticket-autopilot.types.d.ts +73 -0
- package/dist/backend/backend/src/types/ticket-autopilot.types.d.ts.map +1 -0
- package/dist/backend/backend/src/types/ticket-autopilot.types.js +88 -0
- package/dist/backend/backend/src/types/ticket-autopilot.types.js.map +1 -0
- package/dist/backend/backend/src/types/v2/claim.types.d.ts +27 -0
- package/dist/backend/backend/src/types/v2/claim.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/v2/claim.types.js +37 -0
- package/dist/backend/backend/src/types/v2/claim.types.js.map +1 -1
- package/dist/backend/backend/src/types/v2/work-item.types.d.ts +1 -1
- package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/v2/work-item.types.js +1 -0
- package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +84 -1
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +105 -16
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/models/Project.d.ts +3 -0
- package/dist/cli/backend/src/models/Project.d.ts.map +1 -1
- package/dist/cli/backend/src/models/Project.js +7 -0
- package/dist/cli/backend/src/models/Project.js.map +1 -1
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +66 -13
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js +161 -32
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/claim.service.d.ts +23 -3
- package/dist/cli/backend/src/services/task-pool/claim.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/claim.service.js +52 -11
- package/dist/cli/backend/src/services/task-pool/claim.service.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +42 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js +82 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/ticket-claim-policy.d.ts +19 -0
- package/dist/cli/backend/src/services/task-pool/ticket-claim-policy.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/ticket-claim-policy.js +33 -0
- package/dist/cli/backend/src/services/task-pool/ticket-claim-policy.js.map +1 -1
- package/dist/cli/backend/src/types/index.d.ts +6 -0
- package/dist/cli/backend/src/types/index.d.ts.map +1 -1
- package/dist/cli/backend/src/types/index.js.map +1 -1
- package/dist/cli/backend/src/types/ticket-autopilot.types.d.ts +73 -0
- package/dist/cli/backend/src/types/ticket-autopilot.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/ticket-autopilot.types.js +88 -0
- package/dist/cli/backend/src/types/ticket-autopilot.types.js.map +1 -0
- package/dist/cli/backend/src/types/v2/claim.types.d.ts +27 -0
- package/dist/cli/backend/src/types/v2/claim.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/v2/claim.types.js +37 -0
- package/dist/cli/backend/src/types/v2/claim.types.js.map +1 -1
- package/dist/cli/backend/src/types/v2/work-item.types.d.ts +1 -1
- package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/v2/work-item.types.js +1 -0
- package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
- package/frontend/dist/assets/{index-8f30aa74.js → index-64c8a616.js} +2 -2
- package/frontend/dist/index.html +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ticket autopilot (specs/2026-09-30-ticket-autopilot.md).
|
|
3
|
+
*
|
|
4
|
+
* A per-project switch (default off). While it is on:
|
|
5
|
+
* - the project's driver (its team lead) is woken with ONE `ticket_triage`
|
|
6
|
+
* WorkItem listing the backlog tickets to decide (ready + assign, split,
|
|
7
|
+
* ask the owner, cancel) — only when someone on the team is idle, at most
|
|
8
|
+
* one live triage per project, at most every 30 min (sooner when a member
|
|
9
|
+
* goes idle with nothing ready);
|
|
10
|
+
* - brakes hold: a daily USD budget over the team's agents (pauses the
|
|
11
|
+
* autopilot and ticket auto-claim for the day, owner told once) and an
|
|
12
|
+
* in-progress cap per member ({@link ProjectTicketAutopilotPolicy});
|
|
13
|
+
* - the owner gets the open `needs-owner` questions batched into one phone
|
|
14
|
+
* message (at most every 2 h unless a new P0 one appears) and one evening
|
|
15
|
+
* digest (skipped when nothing changed).
|
|
16
|
+
*
|
|
17
|
+
* The approval boundary is unchanged: the autopilot only wakes the lead and
|
|
18
|
+
* talks to the owner; it never makes a ticket ready or starts work itself.
|
|
19
|
+
*
|
|
20
|
+
* @module services/project-tickets/ticket-autopilot.service
|
|
21
|
+
*/
|
|
22
|
+
import * as path from 'path';
|
|
23
|
+
import { TICKET_AUTOPILOT_CONSTANTS } from '../../constants.js';
|
|
24
|
+
import { LoggerService } from '../core/logger.service.js';
|
|
25
|
+
import { atomicWriteJson, safeReadJson } from '../../utils/file-io.utils.js';
|
|
26
|
+
import { createWorkItem, MAX_BRIEF_MARKDOWN_BYTES } from '../../types/v2/work-item.types.js';
|
|
27
|
+
import { applyTicketAutopilotInput, resolveTicketAutopilotSettings, } from '../../types/ticket-autopilot.types.js';
|
|
28
|
+
import { ProjectTicketError } from './project-ticket.service.js';
|
|
29
|
+
import { isTeamLead, } from './project-ticket-workflow.service.js';
|
|
30
|
+
import { OPEN_TICKET_STATUSES, decideDigest, decideOwnerQuestions, decideTriage, hasNeedsOwnerLabel, inFlightByAssignee, isMemberIdle, localDateKey, localMidnight, readOwnerQuestion, selectTriageCandidates, } from './ticket-autopilot-decision.js';
|
|
31
|
+
import { buildBudgetPausedMessage, buildDigestMessage, buildOwnerQuestionsMessage, buildTriageBrief, } from './ticket-autopilot-messages.js';
|
|
32
|
+
/** WorkItem statuses that keep a triage "live" (one per project). */
|
|
33
|
+
const LIVE_STATUSES = new Set([
|
|
34
|
+
'queued',
|
|
35
|
+
'scheduled',
|
|
36
|
+
'proposed',
|
|
37
|
+
'accepted',
|
|
38
|
+
'running',
|
|
39
|
+
'blocked',
|
|
40
|
+
'escalated',
|
|
41
|
+
'done_by_worker',
|
|
42
|
+
]);
|
|
43
|
+
/**
|
|
44
|
+
* Session of a member (the running session, else its stable agent id).
|
|
45
|
+
*
|
|
46
|
+
* @param m - Team member
|
|
47
|
+
* @returns Session name or empty string
|
|
48
|
+
*/
|
|
49
|
+
function sessionOf(m) {
|
|
50
|
+
return m.sessionName || m.agentId || '';
|
|
51
|
+
}
|
|
52
|
+
export class TicketAutopilotService {
|
|
53
|
+
static instance = null;
|
|
54
|
+
deps;
|
|
55
|
+
logger;
|
|
56
|
+
now;
|
|
57
|
+
state = null;
|
|
58
|
+
timer = null;
|
|
59
|
+
/** Serialises evaluations so an idle event and the tick never create two triages */
|
|
60
|
+
chain = Promise.resolve();
|
|
61
|
+
/**
|
|
62
|
+
* @param deps - Stores, pool, ledger, owner notifier, state file, clock
|
|
63
|
+
*/
|
|
64
|
+
constructor(deps) {
|
|
65
|
+
this.deps = deps;
|
|
66
|
+
this.logger = deps.logger ?? LoggerService.getInstance().createComponentLogger('TicketAutopilot');
|
|
67
|
+
this.now = deps.now ?? (() => new Date());
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The wired process-wide instance, or null before boot wired it.
|
|
71
|
+
*
|
|
72
|
+
* @returns Instance or null
|
|
73
|
+
*/
|
|
74
|
+
static getInstance() {
|
|
75
|
+
return TicketAutopilotService.instance;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Install the process-wide instance (boot path).
|
|
79
|
+
*
|
|
80
|
+
* @param service - Instance, or null to clear (tests)
|
|
81
|
+
*/
|
|
82
|
+
static setInstance(service) {
|
|
83
|
+
TicketAutopilotService.instance = service;
|
|
84
|
+
}
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// Lifecycle
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
/**
|
|
89
|
+
* Install the brakes on the ticket workflow and start the periodic tick.
|
|
90
|
+
*
|
|
91
|
+
* @param intervalMs - Tick interval (0 = no timer; tests call {@link tick})
|
|
92
|
+
*/
|
|
93
|
+
start(intervalMs = TICKET_AUTOPILOT_CONSTANTS.TICK_INTERVAL_MS) {
|
|
94
|
+
this.deps.workflow.setAutopilotPolicy?.(this.policy());
|
|
95
|
+
if (intervalMs > 0 && !this.timer) {
|
|
96
|
+
this.timer = setInterval(() => {
|
|
97
|
+
void this.tick().catch((err) => this.logger.warn('Ticket autopilot tick failed (non-fatal)', { error: err instanceof Error ? err.message : String(err) }));
|
|
98
|
+
}, intervalMs);
|
|
99
|
+
this.timer.unref?.();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** Stop the tick and remove the brakes. */
|
|
103
|
+
stop() {
|
|
104
|
+
if (this.timer)
|
|
105
|
+
clearInterval(this.timer);
|
|
106
|
+
this.timer = null;
|
|
107
|
+
this.deps.workflow.setAutopilotPolicy?.(null);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* The brakes the ticket workflow asks about.
|
|
111
|
+
*
|
|
112
|
+
* @returns Policy bound to this service
|
|
113
|
+
*/
|
|
114
|
+
policy() {
|
|
115
|
+
return {
|
|
116
|
+
isAutoClaimPaused: async (project) => {
|
|
117
|
+
const settings = resolveTicketAutopilotSettings(project.ticketAutopilot);
|
|
118
|
+
if (!settings.enabled)
|
|
119
|
+
return false;
|
|
120
|
+
const teams = await this.projectTeams(project);
|
|
121
|
+
return this.spentToday(teams) >= settings.dailyBudgetUsd;
|
|
122
|
+
},
|
|
123
|
+
maxInFlightPerMember: async (project) => {
|
|
124
|
+
const settings = resolveTicketAutopilotSettings(project.ticketAutopilot);
|
|
125
|
+
return settings.enabled ? settings.maxInFlightPerMember : null;
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// Settings (owner / orchestrator only)
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
/**
|
|
133
|
+
* The project's autopilot settings and live status.
|
|
134
|
+
*
|
|
135
|
+
* @param ref - Project id, name or path
|
|
136
|
+
* @param caller - Owner or orchestrator
|
|
137
|
+
* @returns Settings, driver, today's spend, pause / triage state
|
|
138
|
+
* @throws ProjectTicketError(403/404)
|
|
139
|
+
*/
|
|
140
|
+
async getStatus(ref, caller) {
|
|
141
|
+
const project = await this.deps.workflow.resolveProject(ref);
|
|
142
|
+
await this.requireOwnerOrOrc(caller, project);
|
|
143
|
+
return this.statusOf(project);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Change the project's autopilot settings.
|
|
147
|
+
*
|
|
148
|
+
* @param ref - Project id, name or path
|
|
149
|
+
* @param input - `enabled`, `driver`, `dailyBudgetUsd`, `maxInFlightPerMember` (null resets one)
|
|
150
|
+
* @param caller - Owner or orchestrator
|
|
151
|
+
* @returns The new status
|
|
152
|
+
* @throws ProjectTicketError(400) on invalid input or a driver who is not a lead of a project team; (403/404)
|
|
153
|
+
*/
|
|
154
|
+
async updateSettings(ref, input, caller) {
|
|
155
|
+
const resolved = await this.deps.workflow.resolveProject(ref);
|
|
156
|
+
await this.requireOwnerOrOrc(caller, resolved);
|
|
157
|
+
// Re-read the stored record right before the write so a concurrent change
|
|
158
|
+
// of another field is not lost.
|
|
159
|
+
const project = (await this.deps.directory.getProjects()).find((p) => p.id === resolved.id) ?? resolved;
|
|
160
|
+
const result = applyTicketAutopilotInput(project.ticketAutopilot, input);
|
|
161
|
+
if (!result.ok)
|
|
162
|
+
throw new ProjectTicketError(400, result.error);
|
|
163
|
+
const teams = await this.projectTeams(project);
|
|
164
|
+
if (result.settings.driver && !this.findLead(teams, result.settings.driver)) {
|
|
165
|
+
throw new ProjectTicketError(400, `driver ${result.settings.driver} is not a team lead on a team that works on ${project.name}`);
|
|
166
|
+
}
|
|
167
|
+
const updated = { ...project, ticketAutopilot: result.settings, updatedAt: this.now().toISOString() };
|
|
168
|
+
await this.deps.directory.saveProject(updated);
|
|
169
|
+
this.logger.info('Ticket autopilot settings changed', {
|
|
170
|
+
projectId: project.id,
|
|
171
|
+
by: caller.session ?? 'owner',
|
|
172
|
+
settings: result.settings,
|
|
173
|
+
});
|
|
174
|
+
return this.statusOf(updated);
|
|
175
|
+
}
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
// Triggers
|
|
178
|
+
// ---------------------------------------------------------------------------
|
|
179
|
+
/**
|
|
180
|
+
* Periodic pass: evaluate every enabled project, then the owner questions
|
|
181
|
+
* and the daily digest.
|
|
182
|
+
*
|
|
183
|
+
* @returns Per-project evaluations
|
|
184
|
+
*/
|
|
185
|
+
async tick() {
|
|
186
|
+
return this.serial(async () => {
|
|
187
|
+
const projects = (await this.deps.directory.getProjects()).filter((p) => resolveTicketAutopilotSettings(p.ticketAutopilot).enabled);
|
|
188
|
+
const out = [];
|
|
189
|
+
for (const project of projects) {
|
|
190
|
+
try {
|
|
191
|
+
out.push(await this.evaluateProject(project, 'tick'));
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
this.logger.warn('Ticket autopilot evaluation failed', { projectId: project.id, error: err instanceof Error ? err.message : String(err) });
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (projects.length > 0) {
|
|
198
|
+
await this.processOwnerQuestions(projects).catch((err) => this.logger.warn('Owner questions pass failed', { error: err instanceof Error ? err.message : String(err) }));
|
|
199
|
+
await this.processDigest(projects).catch((err) => this.logger.warn('Ticket digest pass failed', { error: err instanceof Error ? err.message : String(err) }));
|
|
200
|
+
}
|
|
201
|
+
return out;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* A member went idle and AutoClaim found nothing ready for it: evaluate
|
|
206
|
+
* the enabled projects it works on right away (bounded by
|
|
207
|
+
* {@link TICKET_AUTOPILOT_CONSTANTS.IDLE_TRIGGER_MIN_INTERVAL_MS}).
|
|
208
|
+
*
|
|
209
|
+
* @param session - The idle agent
|
|
210
|
+
* @returns Per-project evaluations
|
|
211
|
+
*/
|
|
212
|
+
async onMemberIdle(session) {
|
|
213
|
+
if (!session)
|
|
214
|
+
return [];
|
|
215
|
+
return this.serial(async () => {
|
|
216
|
+
const teams = (await this.deps.directory.getTeams()).filter((t) => !t.archived && (t.members ?? []).some((m) => sessionOf(m) === session || m.sessionName === session));
|
|
217
|
+
const projectIds = new Set(teams.flatMap((t) => t.projectIds ?? []));
|
|
218
|
+
if (projectIds.size === 0)
|
|
219
|
+
return [];
|
|
220
|
+
const projects = (await this.deps.directory.getProjects()).filter((p) => projectIds.has(p.id) && resolveTicketAutopilotSettings(p.ticketAutopilot).enabled);
|
|
221
|
+
const out = [];
|
|
222
|
+
for (const project of projects) {
|
|
223
|
+
try {
|
|
224
|
+
out.push(await this.evaluateProject(project, 'member_idle', session));
|
|
225
|
+
}
|
|
226
|
+
catch (err) {
|
|
227
|
+
this.logger.warn('Ticket autopilot idle evaluation failed', { projectId: project.id, error: err instanceof Error ? err.message : String(err) });
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return out;
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
// ---------------------------------------------------------------------------
|
|
234
|
+
// Evaluation
|
|
235
|
+
// ---------------------------------------------------------------------------
|
|
236
|
+
/**
|
|
237
|
+
* Evaluate one project and, when {@link decideTriage} says so, wake its
|
|
238
|
+
* driver with a triage WorkItem.
|
|
239
|
+
*
|
|
240
|
+
* @param project - Project (with its stored settings)
|
|
241
|
+
* @param trigger - Periodic tick or a member going idle
|
|
242
|
+
* @param idleSession - The member that just went idle
|
|
243
|
+
* @returns The decision (and the WorkItem when one was created)
|
|
244
|
+
*/
|
|
245
|
+
async evaluateProject(project, trigger, idleSession) {
|
|
246
|
+
const settings = resolveTicketAutopilotSettings(project.ticketAutopilot);
|
|
247
|
+
const state = await this.loadState();
|
|
248
|
+
const ps = (state.projects[project.id] ??= {});
|
|
249
|
+
const now = this.now();
|
|
250
|
+
const nowMs = now.getTime();
|
|
251
|
+
const teams = await this.projectTeams(project);
|
|
252
|
+
const driver = this.resolveDriver(settings, teams);
|
|
253
|
+
const spent = this.spentToday(teams);
|
|
254
|
+
if (settings.enabled && spent >= settings.dailyBudgetUsd)
|
|
255
|
+
await this.noticeBudgetPaused(project, ps, spent, settings.dailyBudgetUsd, now);
|
|
256
|
+
const { tickets } = await this.deps.tickets.list(project.path);
|
|
257
|
+
const live = await this.liveTriageItem(project, nowMs);
|
|
258
|
+
const selection = selectTriageCandidates({ tickets, teams, now: nowMs, listed: ps.listed });
|
|
259
|
+
const members = teams.flatMap((t) => t.members ?? []);
|
|
260
|
+
const anyoneIdle = (!!idleSession && members.some((m) => sessionOf(m) === idleSession || m.sessionName === idleSession)) || members.some((m) => isMemberIdle(m));
|
|
261
|
+
const decision = decideTriage({
|
|
262
|
+
enabled: settings.enabled,
|
|
263
|
+
driver: driver?.session ?? null,
|
|
264
|
+
trigger,
|
|
265
|
+
now: nowMs,
|
|
266
|
+
candidateCount: selection.candidates.length,
|
|
267
|
+
liveTriage: !!live,
|
|
268
|
+
lastTriageAt: ps.lastTriageAt,
|
|
269
|
+
anyoneIdle,
|
|
270
|
+
spentTodayUsd: spent,
|
|
271
|
+
dailyBudgetUsd: settings.dailyBudgetUsd,
|
|
272
|
+
});
|
|
273
|
+
if (decision.action === 'skip' || !driver) {
|
|
274
|
+
this.logger.debug('Ticket autopilot: no triage', { projectId: project.id, trigger, decision });
|
|
275
|
+
await this.saveState();
|
|
276
|
+
return { projectId: project.id, decision };
|
|
277
|
+
}
|
|
278
|
+
const inFlight = inFlightByAssignee(tickets);
|
|
279
|
+
const seen = new Set();
|
|
280
|
+
const briefMembers = teams.flatMap((t) => (t.members ?? [])
|
|
281
|
+
.filter((m) => {
|
|
282
|
+
const s = sessionOf(m);
|
|
283
|
+
if (!s || seen.has(s))
|
|
284
|
+
return false;
|
|
285
|
+
seen.add(s);
|
|
286
|
+
return true;
|
|
287
|
+
})
|
|
288
|
+
.map((m) => ({
|
|
289
|
+
session: sessionOf(m),
|
|
290
|
+
name: m.name,
|
|
291
|
+
role: isTeamLead(t, m) ? 'lead' : m.role,
|
|
292
|
+
idle: isMemberIdle(m) || sessionOf(m) === idleSession,
|
|
293
|
+
inFlight: inFlight.get(sessionOf(m)) ?? 0,
|
|
294
|
+
})));
|
|
295
|
+
const brief = buildTriageBrief({
|
|
296
|
+
project: { id: project.id, name: project.name },
|
|
297
|
+
candidates: selection.candidates,
|
|
298
|
+
more: selection.more,
|
|
299
|
+
members: briefMembers,
|
|
300
|
+
maxInFlightPerMember: settings.maxInFlightPerMember,
|
|
301
|
+
now: nowMs,
|
|
302
|
+
});
|
|
303
|
+
const n = selection.candidates.length;
|
|
304
|
+
const workItem = createWorkItem({
|
|
305
|
+
type: TICKET_AUTOPILOT_CONSTANTS.TRIAGE_WORK_ITEM_TYPE,
|
|
306
|
+
owner: 'team_lead',
|
|
307
|
+
target: driver.session,
|
|
308
|
+
title: `Ticket triage: ${project.name} (${n} ticket${n === 1 ? '' : 's'})`,
|
|
309
|
+
description: `Decide ${n} ticket${n === 1 ? '' : 's'} of ${project.name}: ready + assign, split, ask the owner, or cancel.`,
|
|
310
|
+
briefMarkdown: capBrief(brief),
|
|
311
|
+
metadata: {
|
|
312
|
+
kind: TICKET_AUTOPILOT_CONSTANTS.TRIAGE_METADATA_KIND,
|
|
313
|
+
projectId: project.id,
|
|
314
|
+
projectPath: project.path,
|
|
315
|
+
teamId: driver.teamId,
|
|
316
|
+
requiresVerification: false,
|
|
317
|
+
ticketIds: selection.candidates.map((c) => c.ticket.id),
|
|
318
|
+
trigger,
|
|
319
|
+
},
|
|
320
|
+
});
|
|
321
|
+
workItem.createdAt = now.toISOString();
|
|
322
|
+
workItem.targetSource = 'assigned';
|
|
323
|
+
await this.deps.pool.addToPool(workItem);
|
|
324
|
+
ps.lastTriageAt = nowMs;
|
|
325
|
+
ps.lastTriageWorkItemId = workItem.id;
|
|
326
|
+
const listed = {};
|
|
327
|
+
const openIds = new Set(tickets.map((t) => t.id));
|
|
328
|
+
for (const [id, entry] of Object.entries(ps.listed ?? {}))
|
|
329
|
+
if (openIds.has(id))
|
|
330
|
+
listed[id] = entry;
|
|
331
|
+
for (const c of selection.candidates)
|
|
332
|
+
listed[c.ticket.id] = { updatedAt: c.ticket.updatedAt, at: nowMs };
|
|
333
|
+
ps.listed = listed;
|
|
334
|
+
await this.saveState();
|
|
335
|
+
this.logger.info('Ticket autopilot woke the driver to triage', {
|
|
336
|
+
projectId: project.id,
|
|
337
|
+
driver: driver.session,
|
|
338
|
+
trigger,
|
|
339
|
+
tickets: workItem.metadata?.ticketIds,
|
|
340
|
+
workItemId: workItem.id,
|
|
341
|
+
});
|
|
342
|
+
return { projectId: project.id, decision, workItem };
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* The project's live triage item, if any. A triage item still queued
|
|
346
|
+
* (never picked up) after {@link TICKET_AUTOPILOT_CONSTANTS.TRIAGE_STALE_QUEUED_MS}
|
|
347
|
+
* is cancelled so a fresh one can replace it.
|
|
348
|
+
*
|
|
349
|
+
* @param project - Project
|
|
350
|
+
* @param nowMs - Clock
|
|
351
|
+
* @returns The live item, or null
|
|
352
|
+
*/
|
|
353
|
+
async liveTriageItem(project, nowMs) {
|
|
354
|
+
const items = (await this.deps.pool.getAllItems()).filter((wi) => wi.metadata?.kind === TICKET_AUTOPILOT_CONSTANTS.TRIAGE_METADATA_KIND && wi.metadata?.projectId === project.id && LIVE_STATUSES.has(wi.status));
|
|
355
|
+
let live = null;
|
|
356
|
+
for (const wi of items) {
|
|
357
|
+
const age = nowMs - (Date.parse(wi.createdAt) || nowMs);
|
|
358
|
+
if (wi.status === 'queued' && age >= TICKET_AUTOPILOT_CONSTANTS.TRIAGE_STALE_QUEUED_MS) {
|
|
359
|
+
await this.deps.pool.cancelQueued(wi.id, 'ticket triage never picked up; replaced by a fresh one').catch(() => undefined);
|
|
360
|
+
this.logger.info('Stale ticket triage cancelled', { projectId: project.id, workItemId: wi.id });
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
live = wi;
|
|
364
|
+
}
|
|
365
|
+
return live;
|
|
366
|
+
}
|
|
367
|
+
// ---------------------------------------------------------------------------
|
|
368
|
+
// Owner notifications
|
|
369
|
+
// ---------------------------------------------------------------------------
|
|
370
|
+
/**
|
|
371
|
+
* Send the batched owner questions of every enabled project when due.
|
|
372
|
+
*
|
|
373
|
+
* @param projects - Enabled projects
|
|
374
|
+
* @returns True when a batch went out
|
|
375
|
+
*/
|
|
376
|
+
async processOwnerQuestions(projects) {
|
|
377
|
+
const state = await this.loadState();
|
|
378
|
+
const items = [];
|
|
379
|
+
for (const project of projects) {
|
|
380
|
+
const { tickets } = await this.deps.tickets.list(project.path);
|
|
381
|
+
for (const t of tickets) {
|
|
382
|
+
if (!OPEN_TICKET_STATUSES.has(t.status) || !hasNeedsOwnerLabel(t))
|
|
383
|
+
continue;
|
|
384
|
+
const question = readOwnerQuestion(t) ?? 'needs your decision';
|
|
385
|
+
items.push({ key: `${project.id}:${t.id}:${question}`, priority: t.priority, projectName: project.name, ticketId: t.id, title: t.title, question });
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
const pendingKeys = new Set(items.map((i) => i.key));
|
|
389
|
+
const sent = new Set(state.questions.sentKeys.filter((k) => pendingKeys.has(k)));
|
|
390
|
+
const decision = decideOwnerQuestions({ pending: items, sentKeys: sent, lastSentAt: state.questions.lastSentAt, now: this.now().getTime() });
|
|
391
|
+
state.questions.sentKeys = [...sent];
|
|
392
|
+
if (!decision.send) {
|
|
393
|
+
await this.saveState();
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
items.sort((a, b) => a.priority.localeCompare(b.priority) || a.projectName.localeCompare(b.projectName) || a.ticketId.localeCompare(b.ticketId));
|
|
397
|
+
const ok = await this.deps
|
|
398
|
+
.notifyOwner({ title: 'Tickets waiting on you', message: buildOwnerQuestionsMessage(items), urgent: decision.reason === 'urgent' })
|
|
399
|
+
.catch(() => false);
|
|
400
|
+
if (ok) {
|
|
401
|
+
state.questions.sentKeys = items.map((i) => i.key);
|
|
402
|
+
state.questions.lastSentAt = this.now().getTime();
|
|
403
|
+
this.logger.info('Owner questions sent', { count: items.length, reason: decision.reason });
|
|
404
|
+
}
|
|
405
|
+
await this.saveState();
|
|
406
|
+
return ok;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Send the evening digest of the enabled projects when due.
|
|
410
|
+
*
|
|
411
|
+
* @param projects - Enabled projects
|
|
412
|
+
* @returns True when a digest went out
|
|
413
|
+
*/
|
|
414
|
+
async processDigest(projects) {
|
|
415
|
+
const state = await this.loadState();
|
|
416
|
+
const now = this.now();
|
|
417
|
+
const lists = [];
|
|
418
|
+
let latest = 0;
|
|
419
|
+
for (const project of projects) {
|
|
420
|
+
const { tickets } = await this.deps.tickets.list(project.path);
|
|
421
|
+
lists.push({ project, tickets });
|
|
422
|
+
for (const t of tickets)
|
|
423
|
+
latest = Math.max(latest, Date.parse(t.updatedAt) || 0);
|
|
424
|
+
}
|
|
425
|
+
const decision = decideDigest({ now, lastSentDate: state.digest.lastSentDate, lastSentAt: state.digest.lastSentAt, latestTicketChangeAt: latest });
|
|
426
|
+
if (!decision.send)
|
|
427
|
+
return false;
|
|
428
|
+
const midnight = localMidnight(now).getTime();
|
|
429
|
+
const sections = lists.map(({ project, tickets }) => ({
|
|
430
|
+
name: project.name,
|
|
431
|
+
doneToday: tickets.filter((t) => t.status === 'done' && (Date.parse(t.updatedAt) || 0) >= midnight),
|
|
432
|
+
inProgress: tickets.filter((t) => t.status === 'in_progress'),
|
|
433
|
+
waitingOnOwner: tickets.filter((t) => t.status === 'review' || (OPEN_TICKET_STATUSES.has(t.status) && hasNeedsOwnerLabel(t))),
|
|
434
|
+
}));
|
|
435
|
+
const message = buildDigestMessage(sections);
|
|
436
|
+
const ok = message
|
|
437
|
+
? await this.deps.notifyOwner({ title: 'Tickets today', message, urgent: false }).catch(() => false)
|
|
438
|
+
: true; // nothing worth a message: count the day as done
|
|
439
|
+
if (ok) {
|
|
440
|
+
state.digest = { lastSentDate: localDateKey(now), lastSentAt: now.getTime() };
|
|
441
|
+
await this.saveState();
|
|
442
|
+
if (message)
|
|
443
|
+
this.logger.info('Ticket digest sent', { projects: sections.length });
|
|
444
|
+
}
|
|
445
|
+
return ok && !!message;
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Tell the owner once per day that a project's autopilot paused on its budget.
|
|
449
|
+
*
|
|
450
|
+
* @param project - Project
|
|
451
|
+
* @param ps - Its bookkeeping
|
|
452
|
+
* @param spent - Spent today
|
|
453
|
+
* @param budget - Daily budget
|
|
454
|
+
* @param now - Clock
|
|
455
|
+
*/
|
|
456
|
+
async noticeBudgetPaused(project, ps, spent, budget, now) {
|
|
457
|
+
const today = localDateKey(now);
|
|
458
|
+
if (ps.budgetNoticeDate === today)
|
|
459
|
+
return;
|
|
460
|
+
const ok = await this.deps
|
|
461
|
+
.notifyOwner({ title: 'Ticket autopilot paused', message: buildBudgetPausedMessage(project.name, spent, budget), urgent: false })
|
|
462
|
+
.catch(() => false);
|
|
463
|
+
if (ok) {
|
|
464
|
+
ps.budgetNoticeDate = today;
|
|
465
|
+
this.logger.info('Ticket autopilot paused on its daily budget', { projectId: project.id, spent, budget });
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
// ---------------------------------------------------------------------------
|
|
469
|
+
// Helpers
|
|
470
|
+
// ---------------------------------------------------------------------------
|
|
471
|
+
/**
|
|
472
|
+
* The settings view plus live status of a project.
|
|
473
|
+
*
|
|
474
|
+
* @param project - Project
|
|
475
|
+
* @returns Status
|
|
476
|
+
*/
|
|
477
|
+
async statusOf(project) {
|
|
478
|
+
const settings = resolveTicketAutopilotSettings(project.ticketAutopilot);
|
|
479
|
+
const teams = await this.projectTeams(project);
|
|
480
|
+
const spent = this.spentToday(teams);
|
|
481
|
+
const state = await this.loadState();
|
|
482
|
+
const ps = state.projects[project.id];
|
|
483
|
+
const live = (await this.deps.pool.getAllItems()).some((wi) => wi.metadata?.kind === TICKET_AUTOPILOT_CONSTANTS.TRIAGE_METADATA_KIND && wi.metadata?.projectId === project.id && LIVE_STATUSES.has(wi.status));
|
|
484
|
+
return {
|
|
485
|
+
project: { id: project.id, name: project.name, path: project.path },
|
|
486
|
+
settings,
|
|
487
|
+
driver: this.resolveDriver(settings, teams),
|
|
488
|
+
spentTodayUsd: Math.round(spent * 100) / 100,
|
|
489
|
+
pausedForToday: settings.enabled && spent >= settings.dailyBudgetUsd,
|
|
490
|
+
triageInFlight: live,
|
|
491
|
+
lastTriageAt: ps?.lastTriageAt ? new Date(ps.lastTriageAt).toISOString() : null,
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Refuse anyone but the owner and the orchestrator.
|
|
496
|
+
*
|
|
497
|
+
* @param caller - Caller
|
|
498
|
+
* @param project - Project
|
|
499
|
+
* @throws ProjectTicketError(403)
|
|
500
|
+
*/
|
|
501
|
+
async requireOwnerOrOrc(caller, project) {
|
|
502
|
+
const { access } = await this.deps.workflow.accessOf(caller, project);
|
|
503
|
+
if (access !== 'owner' && access !== 'orchestrator') {
|
|
504
|
+
throw new ProjectTicketError(403, 'Only the owner or the orchestrator can see or change the ticket autopilot');
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Non-archived teams working on a project.
|
|
509
|
+
*
|
|
510
|
+
* @param project - Project
|
|
511
|
+
* @returns Teams
|
|
512
|
+
*/
|
|
513
|
+
async projectTeams(project) {
|
|
514
|
+
return (await this.deps.directory.getTeams()).filter((t) => !t.archived && (t.projectIds ?? []).includes(project.id));
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* A lead of one of the teams running as `session`.
|
|
518
|
+
*
|
|
519
|
+
* @param teams - Project teams
|
|
520
|
+
* @param session - Session
|
|
521
|
+
* @returns The team id, or null
|
|
522
|
+
*/
|
|
523
|
+
findLead(teams, session) {
|
|
524
|
+
for (const team of teams) {
|
|
525
|
+
for (const m of team.members ?? []) {
|
|
526
|
+
if ((m.sessionName === session || m.agentId === session) && isTeamLead(team, m))
|
|
527
|
+
return team.id;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return null;
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Who triages: the configured driver (must be a lead of a project team),
|
|
534
|
+
* else the first lead found on the project's teams.
|
|
535
|
+
*
|
|
536
|
+
* @param settings - Resolved settings
|
|
537
|
+
* @param teams - Project teams
|
|
538
|
+
* @returns Driver, or null when there is none
|
|
539
|
+
*/
|
|
540
|
+
resolveDriver(settings, teams) {
|
|
541
|
+
if (settings.driver) {
|
|
542
|
+
const teamId = this.findLead(teams, settings.driver);
|
|
543
|
+
return teamId ? { session: settings.driver, teamId, source: 'setting' } : null;
|
|
544
|
+
}
|
|
545
|
+
for (const team of teams) {
|
|
546
|
+
const lead = (team.members ?? []).find((m) => isTeamLead(team, m) && sessionOf(m));
|
|
547
|
+
if (lead)
|
|
548
|
+
return { session: sessionOf(lead), teamId: team.id, source: 'team_lead' };
|
|
549
|
+
}
|
|
550
|
+
return null;
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* USD spent since local midnight by the agents of the given teams.
|
|
554
|
+
*
|
|
555
|
+
* @param teams - Teams
|
|
556
|
+
* @returns Spend
|
|
557
|
+
*/
|
|
558
|
+
spentToday(teams) {
|
|
559
|
+
const since = localMidnight(this.now());
|
|
560
|
+
const sessions = new Set(teams.flatMap((t) => (t.members ?? []).map(sessionOf)).filter((s) => !!s));
|
|
561
|
+
let total = 0;
|
|
562
|
+
for (const s of sessions) {
|
|
563
|
+
try {
|
|
564
|
+
total += this.deps.ledger.getSessionUsageSince(s, since).cost;
|
|
565
|
+
}
|
|
566
|
+
catch {
|
|
567
|
+
// A ledger read failure never blocks the autopilot on its own.
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
return total;
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Run `fn` after every evaluation queued before it.
|
|
574
|
+
*
|
|
575
|
+
* @param fn - Work
|
|
576
|
+
* @returns Its result
|
|
577
|
+
*/
|
|
578
|
+
serial(fn) {
|
|
579
|
+
const run = this.chain.then(fn, fn);
|
|
580
|
+
this.chain = run.catch(() => undefined);
|
|
581
|
+
return run;
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Load the bookkeeping (once per process).
|
|
585
|
+
*
|
|
586
|
+
* @returns State
|
|
587
|
+
*/
|
|
588
|
+
async loadState() {
|
|
589
|
+
if (this.state)
|
|
590
|
+
return this.state;
|
|
591
|
+
const raw = await safeReadJson(this.deps.stateFile, {});
|
|
592
|
+
const sentKeys = raw.questions?.sentKeys;
|
|
593
|
+
this.state = {
|
|
594
|
+
projects: raw.projects && typeof raw.projects === 'object' ? raw.projects : {},
|
|
595
|
+
questions: { lastSentAt: raw.questions?.lastSentAt, sentKeys: Array.isArray(sentKeys) ? sentKeys : [] },
|
|
596
|
+
digest: raw.digest && typeof raw.digest === 'object' ? raw.digest : {},
|
|
597
|
+
};
|
|
598
|
+
return this.state;
|
|
599
|
+
}
|
|
600
|
+
/** Persist the bookkeeping (best-effort). */
|
|
601
|
+
async saveState() {
|
|
602
|
+
if (!this.state)
|
|
603
|
+
return;
|
|
604
|
+
try {
|
|
605
|
+
await atomicWriteJson(this.deps.stateFile, this.state);
|
|
606
|
+
}
|
|
607
|
+
catch (err) {
|
|
608
|
+
this.logger.warn('Could not save ticket autopilot state', { file: path.basename(this.deps.stateFile), error: err instanceof Error ? err.message : String(err) });
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Keep a brief within the WorkItem brief budget.
|
|
614
|
+
*
|
|
615
|
+
* @param text - Brief
|
|
616
|
+
* @returns Brief within {@link MAX_BRIEF_MARKDOWN_BYTES}
|
|
617
|
+
*/
|
|
618
|
+
function capBrief(text) {
|
|
619
|
+
if (Buffer.byteLength(text, 'utf8') <= MAX_BRIEF_MARKDOWN_BYTES)
|
|
620
|
+
return text;
|
|
621
|
+
let out = text.slice(0, MAX_BRIEF_MARKDOWN_BYTES);
|
|
622
|
+
while (Buffer.byteLength(out, 'utf8') > MAX_BRIEF_MARKDOWN_BYTES - 64)
|
|
623
|
+
out = out.slice(0, -64);
|
|
624
|
+
return `${out}\n\n…(truncated — list the tickets with project-tickets)`;
|
|
625
|
+
}
|
|
626
|
+
//# sourceMappingURL=ticket-autopilot.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ticket-autopilot.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/project-tickets/ticket-autopilot.service.ts"],"names":[],"mappings":"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"}
|